Blog

Running sshd on gentoo (1 comment)

Added by Christoph Kappel over 6 years ago

I got this new vserver and I decided to use it as Gentoo buildslave. Just after installing the image I had no working ssh. Reading the log I stumbled across this:

Jun 17 14:46:17 vadmin234 sshd[3519]: Server listening on :: port 22.
Jun 17 14:46:17 vadmin234 sshd[3519]: error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
Jun 17 14:46:23 vadmin234 sshd[3519]: Received signal 15; terminating.

Looks like sshd binds port 22 on :: and tries to bind then the same port on 0.0.0.0 which obviously can't work. This is overall a bit cumbersome, because I don't have any ipv6 address for this machine.

A solution is either to remove ipv6 support from the kernel or even better say sshd which address it should use:

ListenAddress 0.0.0.0

Ingate offers 55 free vserver (1 comment)

Added by Christoph Kappel over 6 years ago

I just discovered this on a blog of a friend, sorry it's a german blog and therefore a german company: Wir verschenken 55 VServer!

Actually I never heared anything about this company, but this offer is just unique. The prices sound solid and we will see who gets a server. Whenever I am that lucky to be one of the 55 and I will report about the overall experience with it too.

The vserver (VServer Basic) itself has following stats:

  • 5GB disk space (RAID1)
  • 200MB RAM (min)
  • 200MB Swap
  • Traffic flatrate
  • Full root-access over ssh
  • IP-Addresses (RIPE)

Edit: I am currently setting it up as another buildhost for subforge.

Inheritance of Ruby classes defined in C

Added by Christoph Kappel over 6 years ago

Creating a Ruby class directly via C is really painless, under normal circumstances you don't even have to worry about the alloc stuff. Just supply a #initialize when needed and you are done.

Numbers: on /off1 klass = rb_define_class("Test", rb_cObject);
2 rb_define_method(klass, "initialize", TestInit, 0);

Inheritance in this case works like a charm, your initialize will be called like expected. It get's more tricky when you need to call Data_Wrap_Struct. The function itself allocates an object and returns it with your supplied data pointer attached.

First solution you will most likely come up with is defining your own .new like this:

Numbers: on /off1 klass = rb_define_class("Test", rb_cObject);
2 rb_define_singleton_method(klass, "new", TestNew, -1);

Since we overwrite the default .new we need to do the call to #initialize by ourself:

Numbers: on /off 1 VALUE
 2 TextNew(int argc,
 3   VALUE *argv,
 4   VALUE self)
 5 {
 6   VALUE instance = Qnil;
 7   void *ptr = NULL;
 8 
 9   /* Fill ptr with something reasonable */
10 
11   instance = Data_Wrap_Struct(self, NULL, NULL, ptr);
12 
13   /* Pass arguments to initialize */
14   rb_obj_call_init(instance, argc, argv);
15 
16   return instance;
17 }

This will wrap our data pointer and call #initialize with all arguments - no problems so far.

Problems start when someone wants to inherit from this class:

Numbers: on /off1 class AnotherTest < Test
2   :attr_reader = arg3
3 
4   def initialize(arg1, arg2, arg3)
5     super(arg1, arg2)
6     @var = arg3
7   end
8 end

Now rb_obj_call_init calls the default #initialize and not the one from the inherited class - this will most likely end with an ArgumentError.

Remember that the first version just worked and Data_Wrap_Struct creates a new object - so we can't call it in #initialize where self is immutable.

The solution is easy, don't create your own .new. We can use allocate to just allocate our object, let Ruby do the dirty stuff and rely on it to call our #initialize.

In C it looks like this:

Numbers: on /off 1 klass = rb_define_class("Test", rb_cObject);
 2 
 3 /* This defines our alloc function, slightly changed syntax */
 4 rb_define_alloc_func(klass, TestAlloc);
 5 
 6 rb_define_method(klass, "initialize", TestInit, 0);
 7 
 8 VALUE
 9 TestAlloc(VALUE self)
10 {
11   VALUE instance = Qnil;
12   void *ptr = NULL;
13 
14   /* Fill ptr with something reasonable */
15 
16   instance = Data_Wrap_Struct(self, NULL, NULL, ptr);
17 
18   return instance;
19 }
20 
21 VALUE
22 TestInit(VALUE self)
23 {
24   /* Do initialization here */
25 
26   return Qnil;
27 }

Linux and Huawei E160

Added by Christoph Kappel almost 7 years ago

I recently bought the prepaid UMTS stick from Tschibo as a backup and mostly for mobility. After unpacking it I discovered it's the Huawei E160 which is generally the same as the E220. It just comes with an additionally USB cable and a micro SD-card reader - which causes just trouble: You will need USB_ModeSwitch to change the device from card reader mode to modem. Otherwise you will have a cdrom - no don't ask.

Asking Google about linux and UMTS will lead to lots of wiki and forum entries, but most of them had one thing in common for me: They usually don't work.

Common solutions first, I tried umtsmon which is really odd. Only available for Qt - too bad, it freezes shortly while doing stuff - worse, it doesn't work for me - next!

Next suggestion is using NetworkManager whis utilizes a server/client concept with fancy applets that can't find my stick - out of question.

The harder way is to use wvdial directly - let's go for it. The tricky part is the config and the right/order of the AT strings. After reading some non-working examples I came up with a solution that works:

 1 [Dialer Defaults]
 2 Phone = *99#
 3 Username = o2
 4 Password = o2
 5 Stupid Mode = 1
 6 Carrier Check = no
 7 Dial Command = ATDT
 8 Modem = /dev/ttyUSB0
 9 Baud = 460800
10 Init2 = ATZ
11 Init3 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
12 ISDN = 0
13 Modem Type = Analog Modem
14 Init5 = AT+CGDCONT=1,"IP","webmobil1";

If you don't use the Tschibo stick you will probably change in the Init5 line the webmobil1 to something your ISP uses. Also phone needs sometimes to be changed to *99***1#.

Additionally if your card still wants a PIN add this to your config:

1 Init1 = AT+CPIN=YOUR_PIN

Finally just fire up wvdial and it should work!

Installing Ruby19 on Gentoo

Added by Christoph Kappel almost 7 years ago

Installing Ruby 19 isn't an easy task, the (hard)masking stuff in Gentoo is really a nightmare. The API of Ruby changed a lot from 18 to 19, therefore you can easily say it's not compatible. Until Gentoo has a better version management for slotted Ruby is basically, it's just masked and up to the user installing it if needed and live with the consequences.

There exists the fancy RUBY_TARGETS mechanism, which is intended to allow packages be build for different flavors like ruby18, ruby19, jruby and ree (Ruby Enterprise Edition). According to the manpage and the nice guys in #gentoo-ruby on Freenode you just need to add RUBY_TARGETS="ruby19" in your /etc/make.conf - it doesn't.

After a bit of talk and testing various possible solutions suggestions I found it: You need to override the mask of the flag for ruby19 which is ruby_targets_ruby19 and this can be done in /etc/portage/profile/use.mask.

To make long story short just do this:

Numbers: on /off1 mkdir -p /etc/portage/profile
2 echo "dev-lang/ruby ~x86" >> /etc/portage/package.keywords
3 echo "dev-lang/eselect-ruby ~x86" >> /etc/portage/package.keywords
4 echo "dev-lang/ruby" >> /etc/portage/package.unmask
5 echo "dev-lang/eselect-ruby" >> /etc/portage/package.unmask
6 echo "-ruby_targets_ruby19" >> /etc/portage/profile/use.mask
7 echo 'RUBY_TARGETS="ruby19"' >> /etc/make.conf

In case you also need rake:

Numbers: on /off1 echo "dev-ruby/rake ~x86" >> /etc/portage/package.keywords
2 echo "dev-ruby/rubygems ~x86" >> /etc/portage/package.keywords
3 echo "dev-ruby/rake" >> /etc/portage/package.unmask
4 echo "dev-ruby/rubygems" >> /etc/portage/package.unmask

Using xmlrpc in sinatra

Added by Christoph Kappel almost 7 years ago

During my experiments with buildbot I discovered the xmlrpc interface and think it would be a nice addition to the Sinatra based surserver - actually I don't like XML at all. Once you know how to get the XML document from a rack request the rest is trivial:

Sinatra

Numbers: on /off 1 require "rubygems" 
 2 require "sinatra" 
 3 require "xmlrpc/marshal" 
 4 
 5 helpers do
 6   def upper_case(args)
 7     XMLRPC::Marshal.dump_response(args[0].upcase)
 8   end
 9 end
10 
11 post "/xmlrpc" do
12   xml = @request.body.read
13 
14   if(xml.empty?)
15     error = 400
16     return
17   end
18 
19   # Parse xml
20   method, arguments = XMLRPC::Marshal.load_call(xml)
21   method = method.gsub(/([A-Z])/, '_ ').downcase
22 
23   # Check if method exists
24   if(respond_to?(method))
25     content_type("text/xml", :charset => "utf-8")
26     send(method, arguments)
27   else
28     error = 404
29   end
30 end

Basically we parse the incoming XML, dispatch the call to a matching handler method and send a XML response back.

Client

Numbers: on /off1 require "xmlrpc/client" 
2 
3 server = XMLRPC::Client.new("127.0.0.1", "/xmlrpc", 4567)
4 puts server.call("upper_case", ARGV[0])

The client is a mere call of the XMLRPC::Client API to get the result.

Output

1 % ruby xmlrpc.rb foobar
2 FOOBAR

Setup gems load path in embedded ruby (1 comment)

Added by Christoph Kappel almost 7 years ago

Ruby lacks a way to proper init the load path for gems without using stuff like ruby_options(), which will make things even worse. Generally this is, because Ruby wasn't developed to be embedded in the first place, that also explains the lack of docs about this topic.

Reading through the code these lines here are exactly what we are looking for:

Numbers: on /off 1 /* ruby.c:1055: */
 2 void Init_prelude(void);
 3 
 4 static void                                            
 5 ruby_init_gems(int enable)                                
 6 {
 7   if (enable) rb_define_module("Gem");                                   
 8   Init_prelude();                                             
 9 }

Looks good, but ruby_init_gems() is static and thus not accessable by third party like us. The workaround is to mimic the function in our code, this includes the forward declaration of Init_prelude() or our compiler will complain about it.

In subtle I use the following to init the vm:

Numbers: on /off 1 void Init_prelude(void);
 2 
 3 RUBY_INIT_STACK;
 4 ruby_init();
 5 ruby_init_loadpath();
 6 ruby_script("subtle");
 7 
 8 /* FIXME: Fake ruby_init_gems(Qtrue) */
 9 rb_define_module("Gem");
10 Init_prelude();

If you insist to know what Init_prelude() really does have a look at the miniprelude.c file of the Ruby tarball.

« Previous 1 2

Also available in: Atom RSS