A collection of computer systems and programming tips that you may find useful.
Brought to you by Craic Computing LLC, a bioinformatics consulting company.

Friday, June 19, 2009

Sending Email from a Linux machine

Sending a notification email from a server to a remote address is a very common requirement. If all you want to do is send email and not receive any (from local or remote sources) then installing good old sendmail is overkill.

A simple alternative is to install ssmtp. On ubuntu:
$ sudo aptitude install ssmtp
and then edit /etc/ssmtp/ssmtp.conf. Here is an example configuration that uses a Gmail account for relaying:
# Config file for sSMTP sendmail
# The full hostname of this machine
# Allow users to set their own From: address?

You send mail using /usr/sbin/ssmtp just as you would with sendmail, but without any of the sendmail.cf configuration business.

As a bonus, ssmtp sets up symlinks for /usr/lib/sendmail and /usr/sbin/sendmail such that if you have an existing script that calls sendmail it will probably work as is one a system with ssmtp installed.

Here is a ssmtp man page.


Thursday, June 18, 2009

Erasing Disks on Linux Machines

I'm decommissioning a couple of Linux boxes and want to erase the disks before passing them on to a recycler. There are a couple of favored options:
1: Boot from a Knoppix LiveCD and use the 'shred' utility
2: Use DBAN - Darik's Boot and Nuke

Using Knoppix ought to give you more control over the process but I found it to be less than ideal. This is how you would use it:
1: Boot the machine from a burned copy of the Live CD
2: Open a console in the desktop that appears
3: Run shred with suitable parameters on each partition on your machine, e.g.:
# shred -n 10 -z -v /dev/hdb
This would run 10 rounds of writing random date to the specified disk (-n 10), followed by one round of writing zeroes (-z).

The problem I had was that I didn't remember the disk ids on that machine. Normally you could just run 'fdisk -l' and see what was there... BUT the Knoppix version of fdisk doesn't give you that - dang it - so I had to reboot the machine under its own linux and see what was there. That was annoying - must be another way to do that but I don't know it.

DBAN does what it says on the tin. It boots a machine and then nukes the contents of every disk it can find. It is designed for disk erasing and gives you various degrees of erasure, including the Dept. of Defense standards.

1: Boot your machine with a CD version of the DBAN iso (only 2MB!)
2: Look at the options or just type 'autonuke' at the boot prompt (this gives you the default 'DoD short' level of erasing.
3: Go away and do something else - it takes ages (as in an hour or more)
4: Done...

One thing to note - the current version (as of June 2009) is 1.0.7 - the DBAN site mentions that for Core 2 Duo processors you need version 2 which is a pre-release at this stage.


Wednesday, June 17, 2009

Removing a Linux machine from LDAP

You'll find loads of guides to setting up LDAP authentication, etc. on a network and loads of information about Linux and LDAP. But I want to convert a Linux node that gets its users from a LDAP server into a standalone system with one or two local users and no NFS mounted filesystems. I can't find any information on how to do that. So here is what I came up with...

I have a 'mature' Linux system probably pushing 9 years old (Red Hat 7.3). It gets its user accounts from another Linux system set up as a LDAP server. At the moment I'm trying to simplify my network and as I'm the only user I really don't need LDAP (it is convenient but the systems overhead is not worth it right now.)

The LDAP server handles the user accounts, passwords and the mounting of user home directories via NFS from a third server. I just want one user account on the client with a local home directory.

Before making any changes I can log into the client as 'jones' and get all my home directory files mounted via NFS. If I look in /etc/passwd there is no line for 'jones', but there is one for local user 'root'.

1: Edit /etc/nsswitch.conf (you need to be root) and remove the ldap option from the following lines.
passwd:     files nisplus ldap
shadow: files nisplus ldap
group: files nisplus ldap
So your line will look like this:
passwd:     files nisplus
shadow: files nisplus
group: files nisplus
These options define the search order for each item. So for a password the order is the password file on the local machine (files), nisplus (if that is still used these days?) and finally LDAP. Removing the 'ldap' option means that if the system can't find the requested user in the local password file it will give up.

2: You also need to rename /etc/ldap.conf to something else
# mv /etc/ldap.conf /etc/ldap.conf.bak

3: Reboot the machine.

Now try logging in as root (root should always be a local user). Now try changing to a user account that was previously valid (e.g. jones in my case). The user should be unknown as we've broken the connection to the LDAP server.

To recreate that user on this client machine do the regular steps:
# /usr/sbin/adduser jones
# passwd jones
Now if I look in /etc/passwd there is a line for 'jones' and I can 'cd' to /home/jones, where I will find an empty directory.

That seems to be all there is to it. There are probably other lines in /etc/nsswitch.conf with 'ldap' in them. Try removing the ldap options, rebooting and verifying that everything still works the way you expect.

You might also want to check /etc/fstab, /etc/auto.master and /etc/auto.misc to make sure you're not mounting any other filesystems from remote machines.

At this point your system should be completely standalone (perhaps save for DHCP). Try unplugging the network cable, rebooting and verifying that it functions as expected.


Finding the Address of your DHCP Server

Firewalls and routers are often configured as DHCP servers by default. That can cause issues if you already have a server on your internal network. How do tell which DHCP server any given client is using?

Mac OS X:
$ ipconfig getpacket en0
Where en0 is your Ethernet interface (you might want en1 if you are using a wireless connection)

ipconfig /all

$ more /var/lib/dhcp3/dhclient.eth0.leases
Where eth0 is your Ethernet interface.


Tuesday, June 16, 2009

Migrating a MySQL 3.23 database to 5.0

I'm trying to move a old server and database into the modern world and that involves migrating a database from MySQL 3.23 to MySQL 5.0. The official MySQL line is to migrate from one version to the next and not try skipping one - but that's not very practical in my situation and as it turns out is not strictly necessary.

I took some of my steps from this post by Paul Williams (for which I am very grateful!). I didn't need to do everything he did but did need to figure out a critical additional step. Note that your mileage may very much vary - my tables are pretty basic. Here are the steps that worked for me:

Migrating FROM MySQL 3.23.54 on Red Hat Linux 7.3 (Valhalla)
Migrating TO MySQL 5.0.75 on Ubuntu 9.04 (Jaunty)
All my tables were in MyISAM format - if they were not I would have to convert them - look at the older MySQL docs for info.

On the OLD system:
1: Dump out the tables
$ mysqldump --add-drop-table --add-locks --all
--quick --lock-tables mydatabase > mydatabase.sql
2: Convert from Latin1 character encoding to UTF8
$ iconv -f latin1 -t utf8 < mydatabase.sql > mydatabase_utf8.sql
3: Update auto_increment SQL definitions
Williams shows how to update these with this line
$ sed -e "/auto_increment/ s/DEFAULT '0'//" database_utf8.sql > mydatabase_utf8_filtered.sql
In my case this resulted in no changes to the SQL, so it was unnecessary but harmless.

4: Transfer the file to the new system

On the NEW system:

5: Create a short file of SQL header lines with this content:
set names utf8;
drop database if exists mydatabase;
create database mydatabase_inv character set utf8;
use chem_mydatabase;
Brian Williams suggests doing this rather than adding the lines to the top of your SQL file. I put mine into a file called 'sql_headers'.

6: Remove the leading comments on the SQL file
Williams did not include this step but for me it was essential. MySQL barfed on the first few comment lines of my SQL dump so I had to remove these. Basically I stripped everything down to the first real SQL statement. Other comments in the file were not a problem. Here is what I cut out - my hunch is that the long line of dashes is the culprit:
-- MySQL dump 8.22
-- Host: localhost Database: mydatabase
-- Server version 3.23.54

-- Table structure for table 'table1'
7: Load the SQL into your database
cat sql_headers mydatabase_utf8.sql | mysql -u root -p
8: Done! (At least for me...)
Open up your mysql client and poke around to see if everything is there.

... now onto recreating an old Perl CGI app on the new system ... fingers crossed ...


Friday, June 12, 2009

Simple Example of using the YUI Tooltip Widget for Online Help

I've written an example HTML page that uses the Yahoo! YUI Tooltip Widget to popup a small informational window when your mouse hovers over a specific class of web page element. It works pretty well and is easy to set up.

You can download the example page from Github HERE.

The YUI JavaScript libraries and stylesheets are substantial, which is both good and bad. I haven't figured out how to modify the style of my tooltips yet - that'll take a bit of digging. But even this simple code is coming in very handy.

Thursday, June 11, 2009

Combing PDF pages using Preview in Mac OS X

Combining multiple PDF documents into one is remarkably easy in Mac OS X.

Open up Preview with a copy of your first document.

Open the Sidebar if not already open.

Drag additional PDF documents into the Sidebar.

Save the document.

Simple - I love it...

Tuesday, June 2, 2009

Resizing Browser windows to a Fixed Size

I'm trying my hand at some basic screencasts as a way to provide practical online help for an application. I'm using Jing to capture simple screen video clips and screencast.com to host them.

Video editing software and hosting sites prefer to use standard aspect ratios - either 4:3 or 16:9. If you record video at some other ratio and then convert it you risk losing detail in your video and for screencasts, where you want the text to be crisp, this can be a problem.

I'm trying to record my actions in a browser window and so to maximize my useful screen space while keeping in a preferred aspect ratio I want to do several things. (I'm using Firefox on a Mac - it also works in Safari - not tried it with IE on Windows)

1: Get rid of the Bookmarks toolbar (View -> Toolbars -> Bookmarks Toolbar)
2: Get rid of the Status Bar
3: Keep the Navigation toolbar so viewers can see the URLs I'm typing
4: (The Good Part!) Resize the browser window to a specific width and height.
In the URL entry field enter this line:

This just sets the size directly to one of the standard 4:3 aspect ratio sizes. Other choices might be (800, 600) or (640, 480). I need the larger size to capture all the text in my pages.

It is trivial to create a bookmarklet to do this. First bookmark an arbitrary page. Go into your Bookmarks collection and change the bookmark Title to something like 'Resize Browser' and then replace the URL with the magic command as shown above. Now when you go to that bookmark it will resize your browser.

A very simple solution, very cool...

Sending Email from Rails via Gmail

Sending email from a Rails application requires you to configure ActionMailer to use a SMTP mail server that is willing to handle your messages.

Using Google's Gmail is a good way to do this - reliable, free and likely to be around for a while. But going that route you need a slightly non-standard configuration and another gem as ActionMailer does not support the SSL/TLS (Transport Layer Security) that Gmail uses.

Various ways to do this show up in a web search but some of these seem a little outdated (Please add publication dates to your technical web posts!).

As of June 2009 with Rails 2.2.2, this post from Sam Pierson works for me.

1: sudo gem install tlsmail
2: Add the block he shows to the end of your environment.rb file (after the end of the Rails::Initializer.run block)

I use Gmail as part of Google Apps and in this case you want your gmail username to be your Google Apps email address (e.g. myname@mydomain.com and not just myname).


Archive of Tips