Skip to: Site menu | Main content

Blogs

New website: nationalsignsanddesign.com

I just finished the website for National Signs and Design, a Chicago sign company. Also built in Ruby on Rails, with the photoshop template/design built by Dipti Jariwala.

I enabled page caching for static pages and it’s pretty fast on dreamhost. We have only a few dynamic pages: the contact form for the sign company and the send a file (designs or photos) – they were using a ftp site to upload file and I hope this form makes it easier for their clients to send their designs.

I’m in charge of their google adwords campaign goes now! I guess I’m moving into advertising & marketing :)

New website: greencitylandscapes.com

I launched this website: www.greencitylandscapes.com for a landscaping company in Chicago. The design was done by Patrick Milani, and the whole project was managed by Angela from Green City Landscapes.

It got started initially as a wordpress theme modification, but we ended up in writing it from scratch in Ruby on Rails. We have a gallery, some nice slides in design + build process – an idea that I took from goldfishmc.com, only that I wrote it from scratch in prototype.js (they had it in jquery).

Other plugins that were used: lightbox, exception_notifier.

The Microsoft ecosystem is boring.

I just came from the “Windows 7 conference” in West Chicago and it was a big disappointment. The atmosphere was apathetic, the attendees lacked the enthusiasm and the drive that you see normally at open source conferences.

My experience at Flourish, Barcamp and WindycityRails was miles away it terms of experience: sessions that were really interesting and not just vendor sales pitches and an audience actually interested, proven by the engaging Q&A sessions at the end. I regret not having the time to attend RubyConf this year.

At the Microsoft presentations, by contrast, the Q&A were anemic at best, non-existent mostly: the presenter would ask: “Questions?”, and then an awkward silence and the end… crickets.

I guess most people at the Microsoft event were there to get the Windows 7 for free or because the company sent them. The people at open source conferences and meetings are there because they share a common passion of tinkering with technology.

I am so glad that I work in a domain that makes me passionate about my work. That’s it. I am thankful, really thankful.

I shot my stack or the freedoms that C programming give you

I just fixed an interesting bug in one of my contract jobs as a linux C programmer.

I had program that was crashing. Great, I thought, I’ll run it in a debugger and I’ll see where it crashes. I loaded the progam in gdb and I got no information of the stack:

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()

I started setting up breakpoints in the program and after 15 minutes I found the function that crashed the program. The thing is that the program crashed right on the exit of the function.

Then it hit me. Somewhere before the function exit there was some code that was overwriting the stack. Then I remembered the old and legendary article “Smashing The Stack For Fun And Profit”. I was doing just that, only that I had an invalid return point in the stack, the null pointer.

So I put a breakpoint earlier in the function. And there you go, you can see the stack being smashed here:

Breakpoint 4, StandardRateTimeDeclParms () at plotterf.c:1035
1035 Fr for (i = 0; i < 18; i++)
(gdb) where- ------
#0 StandardRateTimeDeclParms () at plotterf.c:1035
#1 0x0827b080 in ?? ()
#2 0x00000000 in ?? ()

We still know where we are now, but we don’t know where to come back. After a little more iterations, I started to get

(gdb)
Cannot find bounds of current function

I found the array that was not sized properly, increased the size then the program returned successfuly:

Plotting...request id is cl4600raw-2065 (1 file(s))
Program exited normally.
(gdb)

Leason learned: Next time I’ll see a smashed stack I’ll recognize it.

New website: frenchchicago.com using Ruby on Rails and Calagator

I created a website where I centralize the French speaking events in Chicago.

I really got involved in learning French. I got a “Voila Francais” textbook, a few audiobooks and the Michel Thomas method, then I started meeting people to improve my conversation skills.

I noticed that there is a very rich calendar of events in Chicago. I started attending as many as I could, but I was still missing some because I kept forgetting about them.

I thought, I’m a web programmer by day, let’s put that skill to work for me and for the common good. I found out that the Portland geeks built a Ruby on Rails calendaring application that functions like a wiki. Perfect! I pulled it of github, made it work on my computer (after a few glitches) and deployed in production here: frenchchicago.com. Enjoy and contribute, Internet!

Progamming Ruby: The dangers of comparing Floats (and of programming tutorials with mistakes in them)

I’m training an out of college programmer in Ruby and Rails. After a week of coding just Ruby, I made her complete her first Rails tutorial: Developing Rails Applications On Mac OS X Leopard

def total_expenses
expenses.sum(:amount) || BigDecimal("0.0")
end

At the end of to tutorial, the programmer is supposed to learn about unit testing and is building a test_budget:

def test_budget
#...
assert_equal BigDecimal("30.50"), event.total_expenses
#...
end

The problem is, one of the tests was failing, even though the apple web page showed that the same code ran fine on their computers: “4 tests, 6 assertions, 0 failures, 0 errors”. Our 5th assertion failed.

Turns out, the function expenses.sum(:amount) returned a Float object. Because of rounding errors, comparing that Float object with a BigDecimal lead to a inequality.

>> BigDecimal(“30.5”) == 30.5
=> false

For Fixnum, it works fine:

>> BigDecimal(“30”) == 30
=> true

Other Floats don’t work either:

>> BigDecimal(“30.4”) == 30.4
=> false

But, surprise, some Floats are equal on our architecture with the BigDecimal.

>> BigDecimal(“30.3”) == 30.3
=> true

My results were on tested on a 32 bit x86 Windows XP and a Linux with Ruby 1.8.6 and Rails 2.1.

This the fixed function in the Event class that leads to consistent results no matter what:

def total_expenses
BigDecimal(expenses.sum(:amount).to_s) || BigDecimal("0.0")
end

I'm a Certified Linux Administator

I just took the Brainbench Linux Administration (General) and I passed at the Master’s Level with a score of 4.69 which puts me on the 1% top of this test takers. I made me feel a little better after screwing up half of the questions of my Google interview for a Linux administrator.

The skills certification I earned today is supposed to be a step towards a bigger certification for Systems Architect Network Support Specialist, Linux System Administrator or Information Security Administrator if I was willing to pay for more tests.

The test was pretty good, and the questions were not that outdated as on other tests. I thought it insisted too much on LILO, when almost all the big Linux distributions use GRUB bootloader. Also, I got no questions on iptables/netfilter. It told me that I have no weak areas, and I know I have. Taking the test I realized that I don’t know about pam_auth as much as I want.

This is my scouts badge for mastering the Linux Administration test:


Master in Linux Administration

My Google interview

I got interviewed by a junior HR at Google for a Linux administration position. Now, I know that I know some stuff, but I also know that there’s so much to know that I don’t think I’m ready for Google yet. But Google didn’t knew that, so they wanted to talk to me. I said, what the hell, I might as well talk to them.

On the phone interview, the recruiter asked me first some self assessment questions, in which I could have rated myself from 0 (know nothing) to 9 (wrote the book). I think I competent enough to know that are some really tough Linux gurus out there in the Stratosphere to rate myself below 5 on all questions. So my self-assessed score was between 0 and 5 out of 9.

Then the recruiter gave me a small three questions test. I could have chosen from “Linux Administration”, “TCP/IP” and “Computer Science”. Since Linux Administration is such a huge field and I forgot almost all Computer Science that I learned in University, I chose TCP/IP networking, a much smaller field.

The first question was: how many bits are in a mac address? I thought, six groups of hex numbers, a hexadecimal letter is 4 bits, so 4×6=24. Since I did that in my mind and my registers are limited, I forgot that there are TWO letters in each group, so it’s 4×2×6=48. Whoops, got that wrong! Next one was to describe the first exchanges in a TCP handshake. I mumbled something along the lines: SYN, ACK, then SYN. Forgot about the ACK. The third question was how many usable IP addresses are in /23 network. I knew that if they asked usable it means that they want me to not count the broadcast and the network address… so the answer was 512-2=510. Got that right!

The recruiter congratulated me on the answer I got right and the one I got almost right (the TCP handshake) and told me to send him my resume so people up the line can have a look at it. Yeah, sure I will… k tnx bye, Bill (ironically, his name was Bill).

The question is: would I trade the experience that I’m gaining now working for diverse projects to working for the geek heaven that it’s Google (even the recruiter, which was supposedly a business major had a typical geeky nasal voice). It’s like going into a monogamous relationship. Would I go for that if I got a really good offer? Or would I still consider my independence more important?

Easy cloning of a linux workstation or router (Debian)

I made a pretty complicated dev box / router for a client, which has three ethernet network cards and a wireless card, some complicated routing and bridging setup, an asterisk sip server, http server, ftp, smtp and pop3. Also, a lot of perl CPAN modules are installed and C and kernel development libraries.

Then I was asked make another one. I’m paid by the hour as a contractor, but even if it brings money into the bank I didn’t want to spend another two days going to the process of reinstalling and configuring everything again.

I finished the job in one hour in a half using just netcat and dd (with some help for sfdisk for fixing partitions after that).

Boot with a live CD on the slave box, and open a listening socket:
slave# ip address add 192.168.0.254/24 dev eth0
slave# nc -l -p 8823 | dd of=/dev/sda

Then on the master, go to runlevel 1:
master# init 1
The bring up the interface:
master# ip address add 192.168.0.253/24 dev eth0
master# ip link set eth0 up
master# dd if=/dev/sda | nc 192.168.0.254 8823

In my situation, the slave disk was 20gig and the master was 40gig. Fortunately, I just needed the first 10 gigs. Unfortunately, the partition table was invalid and linux complained every time it booted. Fdisk and Cfdisk refuse to work on an invalid partition, so I had to use sfdisk
slave# sfdisk -d /dev/hda > partitions
This command will write the current tables on the file “partitions”. Edit the file and feed it back to sfdisk
slave# sfdisk /dev/hda < partitions

Then, just edit the /etc/udev/rules.d/z25_persistent-net.rules for the new ethernet cards (This is on Debian testing, which uses udev).

That’s it. Full cloning, over the network with basic tools. No Norton Ghost or other black box software.

Puppy Linux on a thin profile, cdrom-less Toshiba Portege laptop

Puppy Linux is a very lightweight Linux distribution very suitable for older laptops. A customer called me and asked about installing Linux on his recently bought off Ebay Toshiba Portege. He also wanted to replace the hard drive with a Compact Flash with an IDE adapter. Another problem was that the laptop was designed to be so lightweight and small that it didn’t even had a CDROM drive. In this post I will describe how I installed Puppy Linux over the network, using PXE, LTSP and my trusty dev box which sits under my desk, running Ubuntu Linux.

The laptop cannot boot from a fixed drive, because it does not have a CDROM or a floppy. But… it can boot from the network with PXE! I can even “send” the operating” system over the network and have a fully working machine, even without a hard-disk. In Ubuntu, this is pretty easy, as documented here: https://help.ubuntu.com/community/UbuntuLTSP/LTSPQuickInstall
You basically have to do just:
sudo apt-get install ltsp-server-standalone openssh-server sudo ltsp-build-client

Activate the LTSP shell on the client:
Do this on your “server” (I did this on my Ubuntu workstation):
Chroot to /opt/ltsp/i386. (chroot /opt/ltsp/i386)
Copy /usr/sbin/sshd to /opt/ltsp/i386/usr/sbin.
Copy /etc/init.d/ssh to /opt/ltsp/i386/etc/init.d
Duplicate the symlink structure in /etc/rc*.d to the corresponding directories in the lstp tree so that ssh will start on boot.
Edit passwd and shadow in /opt/ltsp/i386/etc and add the entries for sshd from the files of the same name in /etc/
Create an appropriate set of host keys with ssh-keygen.

Or do it the smart & easy way (which I didn’t think of):
apt-get install ssh (while you are chroot-ed).
Got this idea from https://help.ubuntu.com/community/HowToSetupLTSPDevelEnvironment

Run passwd to set a root password in the local /etc/passwd shadow. (passwd root)
OR
Add the user debug. (adduser debug)
Set a password for the debug user (passwd debug)
Add debug to sudoers (use visudo to see de sudo config file), add debug to the group that can sudo.

Now, login to your LTSP client (my Toshiba Portege):
ssh debug@192.168.0.250
(it may take a long time before you get a prompt, it’s because you don’t have a DNS, just wait for about 30 seconds for the DNS request to timeout)
Then on the box, type the folowing commands:
sudo cfdisk Here you delete all partitions, and create a 1 gig partition on hda and mark it as bootable and make a extended partion and for your swap partition.
After that, create the filesystems:
sudo mkfs.ext3 /dev/hda1
sudo mkswap /dev/hda5

On the LTSP client the root filesystem is readonly, but you can write on /tmp. Tmp is a ramdrive device.
sudo mkdir /tmp/hda1
sudo mount /dev/hda1 /tmp/hda1
cd /tmp/hda1
sudo tar -xvf /srv/puppy.tar
puppy.tar is an archive of puppy linux.
sudo mv /tmp/hda1/media/hda1/* /tmp/hda1
sudo grub
You are now in the grub shell.
grub- root (hd0) (choosing the first partition of the harddrive)

grub- setup (hd0) you are installing grub in your hard drive MBR
you may want to install the boot loader on your bootable partition too (hda1): “setup (hd0,0)” does this.

grub- quit

Reboot your laptop and remove your ethernet cable so you can boot from the harddrive. You are done.