How to update your blog from the middle of the ocean
We are currently at 15°14’54.77″N 75°15’12.63″W, somewhere between Jamaica and Colombia, en route to Cartagena, Colombia. We should be arriving there tomorrow afternoon. I am posting this (and anything else that begins with GPS coordinates) using a Wideye Sabre 1 BGAN Terminal (or in layman’s terms: a satellite modem).
When we started planning this trip, I had resigned myself to a month without access to the internet. It sounded like a badge of courage when people asked me, “So, does the container ship have wireless?” and I answered: “Nope.” The last time I didn’t have access to the internet for 28 days straight was probably before I had access to the internet at all.
I’ll admit, I am weak. I did some cursory looking into satellite phones, Iridium and such. But they were just blindingly expensive. And I didn’t want to make calls, I just wanted an IP address! Eventually I stumbled upon Inmarsat’s BGAN, which stands for Broadband Global Area Network. Unlike the various satellite phone options, many of which only guaranteed coverage on land, BGAN covers the whole planet, continents and oceans, with the exception of the poles. It was almost too good to be true.
Ubuntu on a Lenovo ThinkPad X100e
Stephanie’s brand new ThinkPad X100e arrived today, so I got to have some fun tonight and set up Ubuntu on it for her.
Installation via memory key
This was the first time I’d installed Ubuntu via memory key. Means I might not need my portable CD-ROM drive anymore…
- Downloaded the latest Ubuntu AMD64 Desktop ISO using BitTorrent
- Ran
usb-creatorto copy the ISO to my 2GB USB memory key (based on these instructions: Installation From USB Stick) - Got the “DBus error” like the instructions anticipated, so ran the following command to format my memory key:
sudo mkfs -t vfat /dev/sdb1
- Then I reran
usb-creator - Plugged the memory key into the X100e, booted it up, and installed Ubuntu
Getting wireless to work
Of course, bane of Linux, wireless didn’t work out of the box. This tends to be expected with brand new hardware, and it took me a while to piece together the right steps to get it working.
- Basically run exactly these commands (even
sudo su):sudo apt-get install build-essential wget http://launchpadlibrarian.net/34090404/rtl8192se_linux_2.6.0010.1012.2009_64bit.tar.gz sudo tar -xvzf rtl8192se_linux_2.6.0010.1012.2009_64bit.tar.gz cd rtl8192se_linux_2.6.0010.1020.2009_64bit sudo su make make install
- Then reboot and you have wireless
Note: If you run the Update Manager and it contains a new Linux kernel, you’ll need to rerun make install in ~/rtl8192se_linux_2.6.0010.1020.2009_64bit to reinstall the wireless drivers. So don’t get rid of the rtl8192se… directory. Hopefully this will cease to be a problem in the next release of Ubuntu.
Getting the TrackPoint scroll button to work
Apparently xorg.conf is a thing of the past, which kind of obsoletes my previous TrackPoint “scroll button” instructions. Oh well. This is how you do it now.
- Install and run gpointing-device-settings
sudo apt-get install gpointing-device-settings gpointing-device-settings
- Select TPPS/2 IBM TrackPoint on the left
- Check “Use wheel emulation”
- Select button #2
Getting the headphone jack to work
I didn’t realize this was a problem at first, but thanks to all the comments, folks got to the bottom of the issue. This is what worked for me.
- Edit /etc/modprobe.d/alsa-base.conf
sudo gedit /etc/modprobe.d/alsa-base.conf
- Add the following two lines at the end of the file:
options snd-hda-intel model=lenovo-101e options snd-hda-intel position_fix=1 enable=yes
- Restart the computer
Ubuntu crashing randomly? Run Memtest86+!
Shortly after I upgraded Stephanie’s desktop computer to Ubuntu’s Intrepid Ibex (8.10), it started acting up. Most noticeably when she scrolled Google Maps or Firefox too quickly, the display would get all garbled. I figured something in the upgrade broke support for her video card, but it happened infrequently enough that she just ignored it.
Then she started having problems where programs would just randomly crash. The symptoms were always kind of funky, like if Firefox crashed (not unusual with Flash video everywhere), we’d try to open up the System Monitor—but even that wouldn’t open. It would act like it was going to open, but then nothing would happen. Later on, I discovered that the program was segfaulting when we tried to open it:
Feb 8 21:29:55 soleil kernel: [ 4439.299147] gedit[5829]: segfault at 18 ip b70f8408 sp 00000000 error 6 in libpcre.so.3.12.1[b70e7000+28000] Feb 8 21:30:17 soleil kernel: [ 4461.417410] gedit[7173]: segfault at bf645f9c ip b704834d sp bfa45e00 error 4 in libpcre.so.3.12.1[b7036000+28000] Feb 8 21:30:37 soleil kernel: [ 4481.458719] gnome-system-mo[7180]: segfault at 18 ip b6c6a408 sp 00000000 error 6 in libpcre.so.3.12.1[b6c59000+28000] Feb 8 21:30:56 soleil kernel: [ 4500.786623] gnome-system-mo[7190]: segfault at 18 ip b6c3d408 sp 00000000 error 6 in libpcre.so.3.12.1[b6c2c000+28000] Feb 8 21:31:27 soleil kernel: [ 4531.479833] gnome-system-mo[7225]: segfault at 18 ip b6bfd408 sp 00000000 error 6 in libpcre.so.3.12.1[b6bec000+28000] Feb 8 21:32:13 soleil kernel: [ 4577.436491] gnome-system-mo[7243]: segfault at 18 ip b6c20408 sp 00000000 error 6 in libpcre.so.3.12.1[b6c0f000+28000]
It started getting so bad that all of Gnome would crash after a while, dropping down to text-only screen of various kernel diagnostic and error info. And I honestly had no clue what was going on. So I started Googling around the other weekend, and I stumbled upon this aptly named Ubuntu support page, Debugging System Crash. The very first line said:
If your system crashes at random intervals, perform a MemoryTest first before filing any bug reports or support requests
The MemoryTest page explained how to run Memtest86+. So I did that. When GRUB started loading, I pressed Esc:

And then I selected memtest86+:

At first it looked normal:

AND THEN it started barfing out all these red errors!

The errors started accumulating so fast they were just a blur:

The verdict seemed clear. In all my history of computer ownership I’ve never witnessed memory go bad—until now. So we ordered 2 gigs of shiny new memory (only $28!), which arrived tonight, I installed, and now she’s back in business.

Random Custom Fields
The latest version is 1.0, released February 24, 2009, compatible with WordPress v2.7 (and probably 2.6)
This is an esoteric WordPress plugin (and widget) that will randomly extract one or more custom fields from your posts and display them in a format of your choosing.
For example if you’ve stored geographic coordinates (longitude and latitude) for your posts in a custom field, you can use this plugin to randomly generate a link to Google Maps. Perhaps you could even generate a random embedded Google Map centered on that spot. I know that some people use Custom Fields to store images with special meanings. They could use this plugin to randomly display an image linking back to the post it came from, similar to my Random Image Plugin.
As always, please let me know if you have any problems or questions. I’m happy to help.
Screenshot
This is not a sexy plugin, but it just might save the day. Here’s a screenshot of the admin interface.
Instructions
- Download and unzip random-custom-fields-1.0.zip (v1.0)
- Upload the file random-custom-fields.php to your plugins directory:
/path/to/wordpress/wp-content/plugins - Activate the plugin (don’t forget!)
- If your theme is widget-enabled, goto Design > Widgets and add “Random Custom Fields” to your sidebar
- If your theme is not widget-enabled, edit the index.php or sidebar.php template file in your theme’s directory:
/path/to/wordpress/wp-content/themes/name-of-theme
and add the following line of code where you want a random custom fields to appear:
<?php random_custom_fields(); ?> - Configure the plugin from within WordPress under Settings > Random Custom Fields
Options
The <?php random_custom_fields(); ?> function can take 9 optional parameters in between its parentheses. If you specify any parameters this way, all settings made through the configuration interface will be ignored. Note: this behavior could be useful if you wanted to have several different random custom fields each with different settings appearing throughout your site.
<?php random_custom_fields(custom_field_name,
include_posts,
include_pages,
sort_randomly,
count,
value_separator,
html_template,
html_between_templates,
category_filter); ?>
- custom_field_name is a required string that determines which custom field name to display.
- include_posts is a boolean (default is true) that determines whether to pull custom fields from posts.
- include_pages is a boolean (default is false) that determines whether to pull custom fields from pages.
- sort_randomly is a boolean (default is true) that determines whether to pull custom fields from posts in random order, or in date descending order.
- count is an integer (default is 1) that determines how many custom fields to display.
- value_separator is a string (default is newline) that allows you to break up the custom field value into multiple pieces for use in the html_template.
- html_template is a string (default is
%0) that determines how the plugin should display the custom field. There are several variables that the plugin can output by default, including%title,%permalink, and%excerpt, all from post of the custom field. The variable%0will be replaced with the entire custom field value. If you’ve entered a custom value_separator (default is a newline) the variables%1,%2,%3, etc will be replaced with each piece of the custom field value divided by the value_separator delimiter. - html_between_templates is a string (default is
<br /><br />) that gets printed between custom fields if the count parameter is greater than 1. - category_filter is a comma-separated list of category or tag ids (default is blank) that limits the custom fields posts within certain categories or tags.
Ubuntu Home Server FAQ
Basically this is the stuff I can’t remember how to do when I’m setting up Ubuntu as a backup server. Tested with Ubuntu Server 8.04.1 (Hardy Heron).
How do I turn off the dang bell (aka PC speaker beep)?
sudo rmmod pcspkr sudo vi /etc/modprobe.d/blacklist
Then add:
blacklist pcspkr
How do I make arrow keys work in vi?
sudo apt-get install vim
How do I configure Ubuntu to have a static IP address?
sudo vi /etc/network/interfaces
Then replace:
auto eth0 iface eth0 inet dhcp
with:
auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1
Note: This assumes your router’s (aka gateway’s) IP address is 192.168.1.1 and you want to assign a static IP of 192.168.1.100.
Finally run:
sudo /etc/init.d/networking restart
How do I install an SSH server?
sudo apt-get install openssh-server
How do I find out information about my processor (CPU)?
cat /proc/cpuinfo
How do I find out my external USB drive’s device location?
sudo fdisk -l
How do I manually mount an external USB drive?
sudo mkdir /media/usb0 sudo mount /dev/sdb1 /media/usb0
Note: Your USB drive may have been assigned a different device location than /dev/sdb1. Use sudo fdisk -l to find out.
How do I format an external USB drive?
sudo mkfs.ext3 /dev/sdb1
Note: Be very careful with this command. Make sure you have the correct device location.
Broken blog = man obsessed
Databases are supposed to be these monolithic paragons of correctness and uniformity. So it’s a little unsettling to discover a database that returns grossly incorrect results. At least I wouldn’t expect WordPress to put version 5 of MySQL through its paces.
Here’s the scenario. Dreamhost, my webhost, is running MySQL Server v5.0.24a, released in August 2006. On my laptop I’m running MySQL Server v5.0.51a, released in January 2008. The difference between the two is a year and a half of bugfixes and performance improvements.
On each I’ve got a copy of the same database table, wp_posts, from my WordPress 2.5.1 install for Justinsomnia. And on each system I’ve got a copy of the giant SQL select statement generated by WordPress that returns the first 8 blog posts that should appear on my homepage. The unusual thing about this particular query is that it contains an insanely long NOT IN () list to filter out my neatlinks from the main column.
SELECT SQL_CALC_FOUND_ROWS wp_posts.*
FROM wp_posts
WHERE 1=1
AND wp_posts.ID NOT IN ('876', '877', '878', '879', '880'...'5456', '5458', '5460', '5461', '5462', '5463')
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 8
The problem is that running the same SQL statement on each server returns different results—and I wanted to figure out why.
So I prefixed the query with EXPLAIN, to see what each version of MySQL would tell me about how they were dealing with the same query. I expected the results to be the same. They turned out to be quite different.
MySQL 5.0.24a: +----+-------------+----------+-------+--------------------------------------+---------+---------+------+------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+-------+--------------------------------------+---------+---------+------+------+----------------------------------------------+ | 1 | SIMPLE | wp_posts | range | PRIMARY,post_status,type_status_date | PRIMARY | 4 | NULL | 611 | Using where; Using temporary; Using filesort | +----+-------------+----------+-------+--------------------------------------+---------+---------+------+------+----------------------------------------------+ MySQL 5.0.51a: +----+-------------+----------+------+--------------------------------------+------------------+---------+-------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+------+--------------------------------------+------------------+---------+-------------+------+-------------+ | 1 | SIMPLE | wp_posts | ref | PRIMARY,post_status,type_status_date | type_status_date | 25 | const,const | 5350 | Using where | +----+-------------+----------+------+--------------------------------------+------------------+---------+-------------+------+-------------+
As you scroll to the right, you can see that v5.0.24a chose the PRIMARY key to find the most recent posts, while v5.0.51a opted for type_status_date. I’m not quite sure what that means, except that v5.0.24a obviously made the wrong choice. Which gave me an idea for an interim solution (while I wait for Dreamhost to upgrade MySQL): index hints.
If I could force MySQL to ignore the PRIMARY key, maybe it would “fix” my blog. So I added IGNORE INDEX (PRIMARY) to the query that selects posts, and voila, my blog homepage started working again! Here’s the diff of the code change I made. Luckily I have WordPress “installed” via Subversion, so any changes I make to core files get carried over with each upgrade.
Index: wp-includes/query.php
===================================================================
--- wp-includes/query.php (revision 7987)
+++ wp-includes/query.php (working copy)
@@ -1424,7 +1424,7 @@
if ( !empty($limits) )
$found_rows = 'SQL_CALC_FOUND_ROWS';
- $request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
+ $request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts IGNORE INDEX (PRIMARY) $join WHERE 1=1 $where $groupby $orderby $limits";
$this->request = apply_filters('posts_request', $request);
$this->posts = $wpdb->get_results($this->request);
Hopefully I haven’t inadvertently broken some other aspect of my blog. If anyone sees anything out of order, please leave a comment, mmmk?
Update: for Nate, here’s the EXPLAIN on 5.0.24a with the IGNORE INDEX:
+----+-------------+----------+------+------------------------------+------------------+---------+-------------+------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+------+------------------------------+------------------+---------+-------------+------+----------------------------------------------+ | 1 | SIMPLE | wp_posts | ref | post_status,type_status_date | type_status_date | 25 | const,const | 5351 | Using where; Using temporary; Using filesort | +----+-------------+----------+------+------------------------------+------------------+---------+-------------+------+----------------------------------------------+
The WordPress SQL Executioner
If I had a dime for every time someone said “WordPress Suicide is great, but I only want to delete posts that are more than a year old,” I’d probably have 50¢. Which is about when I start to think about solving the problem with a new plugin.
The programmer/database jockey in me knows the request above is insanely easy. Just start up the MySQL command line client, connect to the WordPress database and fire off the following query:
delete from wp_posts where post_date < date_sub(curdate(), interval 1 year)
Of course knowing SQL takes experience, but the first barrier for most people is just getting command line access to their WordPress database (especially on shared hosts). I figured if it was easier for the average WordPress user to gain direct access to their database from within the admin interface, it’d be a whole lot easier for me to help them, by giving them custom one-off SQL queries to run. And oh by the way, this would be pretty awesome for the power user.
So that’s what I did, I built a stripped-down PHPMyAdmin in the form of a WordPress plugin. WPMyAdmin if you will, though I opted to call it the WordPress SQL Executioner. Actually it’s more of a web-based version of the mysql command line client. It performs both selects and describes for analysis, and inserts, updates, and alters for modification. In fact you can send it just about any SQL command MySQL accepts. Here’s a screenshot to give you an idea of what I’m talking about:

Simply enter your SQL query and click “Execute SQL”. If it’s a select, describe, show, or explain, an HTML table will be returned with your results. If it’s any other command that modifies data or structure, you’ll get a message about the number of rows affected. You’ll have one chance to confirm that you want to execute an insert, update, delete, or alter, but after that, your fate is in your own hands.
The tables listed above the SQL box are shortcut references to all the tables in your database. This makes it possible to write a generic SQL query with variables in place of the actual table names so that it’ll work on any WordPress install, regardless of the table prefix (it’s usually wp_). Of course the actual table names with prefixes are accepted. For example, the query above could be rewritten as:
delete from $posts where post_date < date_sub(curdate(), interval 1 year)
Finally one handy bonus feature, if you click on any of the table names in the list, it will automatically describe the table for you.
Instructions
- Download wp-sql-executioner-1.0.zip (v1.0)
- Unzip the file and upload wp-sql-executioner.php to your plugins directory:
/path/to/wordpress/wp-content/plugins - Activate the plugin (don’t forget!)
- Goto Manage > SQL Executioner and have fun!
As always, questions, comments, and suggestions are always welcome.
Host your own open source project on Ubuntu in just 3 easy steps!
This is a zero-commentary guide to getting Apache 2, Subversion, and Trac all up and running with SSL on Ubuntu.
If you’re looking for more explanation of what each command does, please skip down to the references at the end of the post. If, on the other hand, you’re looking to get your open source project up and running fast without having to think too hard, you’ve come to the right place.
Note: I’ve tested this process on Ubuntu’s Gutsy Gibbon, v7.10.
1) Install Apache 2 with SSL
sudo apt-get install apache2 ssl-cert
sudo a2enmod ssl
sudo mkdir /etc/apache2/ssl
sudo /usr/sbin/make-ssl-cert \
/usr/share/ssl-cert/ssleay.cnf \
/etc/apache2/ssl/apache.pem
sudo cp /etc/apache2/sites-available/default \
/etc/apache2/sites-available/ssl
Edit:
sudo vi /etc/apache2/sites-available/ssl
Replace:
NameVirtualHost * <VirtualHost *>
With:
NameVirtualHost *:443
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.pem
SSLProtocol all
SSLCipherSuite HIGH:MEDIUM
sudo a2ensite ssl
Edit:
sudo vi /etc/apache2/apache2.conf
Add:
ServerName servername
2) Install Subversion
sudo apt-get install subversion libapache2-svn sudo mkdir /var/svn cd /var/svn sudo mkdir project sudo svnadmin create /var/svn/project sudo svn mkdir file:///var/svn/project/trunk -m trunk sudo svn mkdir file:///var/svn/project/tags -m tags sudo svn mkdir file:///var/svn/project/branches -m branches sudo chown -R www-data.www-data project sudo chmod -R g+rws project sudo htpasswd -c /etc/subversion/passwd user_name
Edit:
sudo vi /etc/apache2/mods-available/dav_svn.conf
Add:
<Location /svn>
DAV svn
SVNParentPath /var/svn
AuthType Basic
AuthName "Subversion"
AuthUserFile /etc/subversion/passwd
SSLRequireSSL
<LimitExcept GET PROPFIND OPTIONS REPORT>
Require valid-user
</LimitExcept>
</Location>
3) Install Trac
sudo apt-get install trac \
libapache2-mod-python \
python-setuptools
sudo mkdir /var/trac
cd /var/trac
sudo trac-admin project initenv
sudo trac-admin project permission add user_name TRAC_ADMIN
sudo chown -R www-data.www-data /var/trac
Edit:
sudo vi /etc/apache2/sites-available/ssl
Add to bottom:
<LocationMatch "/trac/[[:alnum:]]+/login">
AuthType Basic
AuthName "trac"
AuthUserFile /etc/subversion/passwd
Require valid-user
SSLRequireSSL
</LocationMatch>
<Location /trac>
SetHandler mod_python
PythonInterpreter main_interpreter
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /var/trac
PythonOption TracUriRoot /trac
SSLRequireSSL
</Location>
sudo /etc/init.d/apache2 restart
References
- Viktor Zigo’s Installation of Subversion on Ubuntu, with Apache, SSL, and BasicAuth.
- Ariejan de Vroom’s How to setup a Ubuntu development server – Part 1 and How to setup a Ubuntu development server – Part 2
- Ubuntu’s Subversion documentation
- Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato’s Version Control with Subversion online book




