Bundle error
Posted by Nucc
Using bundler it throws the following error after running bundle exec rake spec/Library/Ruby/Gems/1.8/gems/bundler-1.0.0.beta.5/lib/bundler/shared_helpers.rb:128:in `bin_path': can't find executable bundle (Gem::Exception)I’ve tried to find a nice solution for the problem, but finally I made a very dirty workaround to make it work. I created an executable bundle file in [bundle_dir]/bin and now it’s work properly.
Ruby on Rails - Balabit Meetup
Posted by Nucc
Rails is the best framework to build web applications using agile techniques. On Balabit Meetup we had a journey in the world of Rails, created a sample application that stored products in sqlite database. You can find the result of demo here!
Ruby presentation - Balabit Meetup
Posted by Nucc
On Wednesday I did a presentation on Balabit Meetup. I talked about a programming language that’s very close to me. It’s called, Ruby. You can check my presentation on the next few slides, moreover if you wanna try this brilliant language out, check the tryruby.org!
Mr Geek
Posted by Nucc
Tonight I’m going to a masquerade party and dressing to Mr Geek. Here is the result…
![]() |
| Masquerade |
Announcement!
Posted by Nucc
Bonanza Team supports the Tinu open source C/C++ unit test framework. You can find more information about the project on the tracker site, and you can read a short interview with the owner of the project, Herczy.
My new server - Part 2
Posted by Nucc
As I’ve mentioned my server provides Ruby On Rails service for companies also, so I’d like to write in short about Rails hosting. Rails is a framework written in Ruby. There’s a ruby application repository called rubygems like apt-get. So when you want to upgrade your Rails, as in apt-get, you can do it by the gem management application. The current rails version is over the 2.0 release and rubygems is over the 1.3. When we were working on the sites (those are being hosted currently), we used Rails 1.2.3 and rubygems 0.7. Today these versions are unsupported, and the upgrade is not so trivial.
Rails application opens ports by its own server engine (you should only call script/server in the project to start a process on the 3000 port), or you can use other software, for example Mongrel (there is another solution with fastcgi, but the restart is complicated). You can specify the number of the listening ports and the number of the parallel threads to response to the requests. You need to bunch these ports to port 80, so you need a server that proxies the requests coming on the port 80 to the Rails processes. So briefly, you need a web server to proxy, and Mongrel processes which run the Rails applications.
Currently the Passenger module to Nginx and Apache skips the application server part of the previous process (the Mongrel processes), and creates Rails instances directly from the web server, so you should specify only your application’s public directory in the web server’s configuration file, and it works out of the box. So, I have an old active system with the 3-step-process, and there is a better solution that I would like to support and would be comfortable in the future.
I was sitting on a fence how I should solve this problem, how I could separate similar environments to different scopes. Building a virtual server park could be an alternative, but I don’t want to run a lot of apache web servers and ssh daemons concurrently. My other problem was ssh protocol doesn’t not support virtual hosts, and since I haven’t got different IP addresses to each virtual server, I should support ssh access on different ports, which I don’t want.
I tried to make a solution for this hosting problem, and finally the result was different chrooted environments for the old and the new version of Rails. I decided to use that kind of separation for all bigger components, like database services, name server, mail server, developer part, so I would call these bigger environments as racks. Backuping files is very important on servers, therefore I needed to found a solution for that problem also, so I’d like to show some tricks which is very comfortable later.
Receipt:
You will need squashfs and aufs first. Aufs is an union filesystem in kernel space (using postfix caused some aufs ooops in kernel, so I recommend to use fuse-unionfs in this case, the problem it’s running in user space, so the context switches cause performance decrease)
First create a minimal chroot environment that will be extended to service oriented rack. Using mksquashfs, we pack it to an image file that will be the hibernated service. Using aufs, make a merge of the read only image file’s content with a writable directory on the file system. All changes in this rack appear in this writable directory, so when you want to make a backup, you have to save only the writable partition. So the goal is each read only image (created by mksquashfs) contains (only) the whole software environment for a service (like mail-server, database-server), and each more file like configurations, created and modified files will be on the writable partition.
My directory structure is the following:
/racks - all the data of the racks
/racks/iso - iso files which contain the services
/racks/readonly - readonly directories mounted by loopback
/racks/readwrite - modified files
/racks/active - merged readonly and a readwrite directories
/var/share - shared files like unix sockets, common log files...
/racks/share/dev - dev directory into chroot environments
Building steps:Let webserver-1.0.iso is the web server environment. Building racks will be in the next part of this thread, till then you can create chroot environment with debootstrap in Debian or Ubuntu (of course it won’t contain webserver components), or download a Gentoo stage 3 archive.
debootstrap --variant=minbase lenny /tmp/chroot_base
mksquashfs /tmp/chroot_base /racks/iso/webserver-1.0.iso
webserver-1.0.iso is in the /racks/iso directory, and you can burn it to a disc for backup. According to the previous directory roles, you need to create the corresponding directories in the rack structure, so you need
/racks/readonly/webserver
/racks/readwrite/webserver
/racks/active/webserver
Mount the image to the readonly directory:
mount -o loop,ro /racks/iso/webserver-1.0.iso /racks/readonly/webserver
Merge it with the readwrite part to the active directory
mount -t aufs -o br=/racks/readwrite/webserver=rw:/racks/readonly/webserver=ro none /racks/active/webserver
After merge is ready, we have to mount the default directories:
Mount /proc
mount -t proc none /racks/active/webserver/proc
Mount /devmount -o bind /racks/share/dev /racks/active/webserver/dev
Mount /var/share
mount -o bind /var/share /racks/active/webserver/dev
Mount /home
mount -o bind /home /racks/active/webserver/home
And finally, jump to the rack with
chroot /racks/active/webserver
I have a script that runs these steps, starts daemon applications after the mount process, when you want to stop the rack it stops all daemons and processes and unmount the directories in the right order.When you have a new upgrade from a software (for example when a new Nginx or Apache is released), just extract the current image to somewhere, upgrade the software in the new one, test it by chroot into it, when everything seems to be good, make a new iso with squashfs and edit your script to use webserver-2.0.iso instead of 1.0. The writable layer is the same, and if something goes wrong, you just back up to 1.0.
In the next part I’m going to show how you can create environments from scratch, which contain only that software you need.
Back up mail
Posted by Nucc
I ran into a problem, when I built my new mail server environment. I used the backup files to create the maildirs of the accounts, and I experienced my mailbox was empty in my imap client, however there were a lot of mails in it.
maildrop -V 3 -d nick@example.foo
throwed the next message:
Unable to open mailbox
despite of permissions was good.
People are disposed to exclude tmp directories from the backup files, but tmp is very important in maildir. Without tmp directory the mailbox looks empty. So modify your backup script to store the tmp directories without content to avoid the latter headaches.
My new server - part 1
Posted by Nucc
I’ve been managing a server for 3 years in a data-park. That time we had a small project that was made in Ruby on Rails (it was a pilot project). Rails deployment wasn’t so easy, however these days there are good solutions with apache and nginx specific passenger module. So we didn’t have any choice, we invested into a machine and took it to a Data park. After the work I stayed alone, and the management of the server stayed on me. Currently it’s hosting five sites with email and domain services.
It’s running Gentoo, the reason is I like specifying those features of a software that I would like to use (I don’t need graphical extension for git with x11-common package on a webserver), and other package managers usually try to find out what I should need (and usually it doesn’t succeed). The drawbacks are compile and install all the necessary packages are very-very slow, and you need to have a gcc or g++, which causes security problems.
As I mentioned, the machine has been working for 3 years, so I decided to change it (although it’s configuration would be enough, but change the whole system without any longtime stop is not so trivial). My new configuration is (thx for Imi @ Balabit!):
Intel Core2Quad Q9300 2500 Mhz- Intel DG45ID motherboard (it’s a desktop board)
- 4 x 2Gb Kingmax memory slots
- 2 x 500Gb Seagate Raid edition disk, ST3500320NS
- Chieftec BH01BBB400 box
After a lot of tests I decided it would run Debian, but exactly it’s only the base of the system. The system contains lightly separated racks, where each rack has one specified function, but share some common resources with each other. I’m going to write more about the construction of racks, by the way of the introduction they are simple chroot environments managed by Gentoo’s package manager, Portage.
You can ask me why Debian, why not Ubuntu or Gentoo. I’d like to build a thin layer, which handles only the hardware and the basic system tasks. I’d like to create a system in an hour and not in a day. I guess Ubuntu is rather a desktop instead of a server operating system. Ubuntu has the newest packages of a software, but in a server I prefer security to the rapid package building.
So, I chose software raid, I didn’t want to pay a lot of bucks for a hardware raid. I can have problems at blackout, but in a Data park it is very rare.
So my partitions:
- 150Mb /boot, ext2 (RAID1)
- 8Gb Swap | /tmp (sda|sdb)
- 5G / , XFS (RAID1)
- 453G logical partition with raid1 and lvm
Different partitions on lvm:
- /usr XFS
- /var XFS
- /backup XFS (for local backups)
- /racks XFS (storage for the racks, it’s comming later)
- /home XFS (with quota support)
I wasn’t so brave to take the / partition to a logical volume, but I hope 5G will be enough (although we know Bill Gates’ famous phrase about memory consumption)
I’ve installed the following software to the base system (without editors and other non-important stuffs):
- sshd (remote management with chroot support)
- mdadm (raid management)
- smartmontools (monitoring hard disks)
- syslog-ng (for logging)
- git (version control for /etc and rack manager software)
- backup-manager (creating backup from /etc and the racks’ rw partitions (later) with remote upload support)
- jailkit ( I’ve built a debian package in a buildd debootstrap environment because I found it only in source version, however it’s a very good tool to build and manage chroot environments)
- python (for jailkit and for my rack manager)
- aufs (for the rack environment, but I’m thinking about funionfs because aufs is a kernel module while funionfs is running in user-space by fuse. So at a crash only the fuse dies, not the whole system.)
- squashfs (for creating racks and snapshots)
The rack system will be in the next part…
Protected methods in objective-c
Posted by Nucc
In objective-c there is no language supported solution for private and protected class methods as in C++ or Java. The reason is Objective-c is only a layer on the language C which is (as it is known) not an object oriented langauge. The @protected and @private tags are only directives for the compiler to throw an error when other objects call methods in their scopes.
This compiler directives unfortunetly don’t work for methods, only for instance variables.
There are two workarounds to implement protected and private methods.
1. Let the private methods be part of the implementation file only. For instance:
-
-
Car.h:
-
-
@interface Car {
-
int tires;
-
}
-
-
-(id) init;
-
-
@end
-
-
Car.m:
-
-
@implementation Car
-
-
-(id) init
-
{
-
[super init];
-
[self setupDefaultValues];
-
return self;
-
}
-
-
// private function
-
-(void) setupDefaultValues
-
{
-
; // Custom code
-
}
-
-
@end
Using this approach your methods can be only private, which may occures problems in the future, when you try to overload a derived method, and you can not change its visibility to protected.
The compiler will throw a warning message for [self setupDefaultValues], because the compiler will be looking for this method in the @interface definition.
2. The second solution uses category pattern, which splits the header file into two parts. The main part contains the public, and the other includes the private part of your class.
In this example the Car.h is the same as in the first example, so I’ll just write the additional lines.
Car.h
----------------
@interface Car (PrivateMethods)
- (void) setupDefaultValues
@end
Car.m
----------------
@implementation Car (PrivateMethods)
- (void) setupDefaultValues
{
; // Custom code
}
@end
I haven’t found nice solution for protected methods yet. There is a convention to begin protected methods with _ mark, but I like when the compiler warns me to somebody tries to call a protected method, and I’m not forced to dig up the code for checking prefixes.
Prototype 1.6.1-rc2
Posted by Nucc
PrototypeJS developers has announced 1.6.1-rc2 on March 27. The new release provides full IE8 compatibility, DOM functions have extended with clone method, you can store key value pairs binding to a node, and moreover better performance in bind() and DOM explorer functions.
Clone method: The javascript engines provide cloneNode() method for cloning an element of a DOM, but there were problems in IE, because IE copied only the node’s initialized version, every latter modifications (like attached event handling) lost. This prototype version calls cloneNode() method, so be careful with previous IE versions.
-
clone: function(element, deep) {
-
if (!(element = $(element))) return;
-
var clone = element.cloneNode(deep);
-
clone._prototypeUID = void 0;
-
if (deep) {
-
var descendants = Element.select(clone, ‘*’),
-
i = descendants.length;
-
while (i–) {
-
descendants[i]._prototypeUID = void 0;
-
}
-
}
-
return Element.extend(clone);
-
}
Storage: The storage engine provides capability to store key value pairs binding to a node. It’s very useful when some variables are in connection with a specified DOM element. If the element was dropped, you should remove all variables, which would become unusable. If we didn’t do this, after a while our site would eat the user’s memory, or have to clean the trashes by us.
Usage:
-
// Creating new storage
-
var storage = Element.getStorage( $(‘foobar’) );
-
-
// Attaching {foo: "bar"} to node foobar
-
$(‘foobar’).store("foo", "bar");
-
-
// Get the value
-
alert(storage.get("foo"));
-
-
// Remove node
-
$(‘foobar’).remove();
The only problem is IE8 doesn’t release the memory in my tests. I’ve tried to store 50000 strings to observe memory statistic. IE8 reserved 2 megabytes, and dropping the node didn’t realize in memory state. In FF 3.0.7 memory release works fine (it’s not strange).
New events: Events mouseenter and mouseleave are the same as mouseover and mouseout, new namings are introduced because Microsoft prefers the first pair.
