Upgrading to Gutsy

It's that time again. Ubuntu 7.10, code named "Gutsy Gibbon" came out last week, and so it was time for me to upgrade all my systems. So here is my report.

In the past, Ubuntu upgrades have been a pretty hit and miss process. Earlier releases involved manually editing your sources.list file and running apt-get commands in a particular order. The last upgrade, however, was a much less painful procedure, and this one followed in its steps. However, it still wasn't nearly as seemless a process as I would have liked.

Currently I have 4 machines running Kubuntu Linux: my home desktop, Sarah's desktop, my laptop, and my work desktop. So far I have upgraded my home and work desktop and done a clean install on my laptop. Sarah's desktop will also be a clean install when I get around to it, because she's still on release 6.06, which can't be upgraded directly.

First, I'll start with the good news. I experienced no hardware problems whatsoever when upgrading. Everything "just worked" after the upgrade. This was no surprise on my home desktop, which is now using a wired LAN connection and has no exotic hardware. It wasn't a big surprise on my work desktop either, as the only weird hardware that has is the tri-head display setup, the configuration for which should have carried over from before the upgrade. With my laptop, however, I was pleased to discover that the integrated Broadcom card now works without NDISwrapper. Kubuntu's new restricted driver manager allowed me to automatically download and install the binary firmware the card needed to run, and after that it worked perfectly. The process was entirely graphical and consisted of just a few clicks. No fuss, no muss!

Now the bad news. While the laptop install was pretty smooth, the desktop upgrades weren't that great. My home desktop just had a slight hicough, as the installer bombed out after complaining that it couldn't verify the gutsy-security repository. This was easily fixed by commenting that repository out of my sources.list and re-running the upgrade. After that, the only problem was that the entire process was really slow and required sporadic user interaction. That part actually caused the upgrade to drag out over the entire day, as I would answer one prompt, go away for two hours, come back to another, and so forth. However, it wasn't as bad as the last upgrade.

My work desktop, on the other hand, was a huge pain. The system functioned properly once I was done, but it was way harder than it should have been. But on the up side, the dual-core processor, 2GB of RAM, and gigabit LAN with a fiber connection made things pretty fast.

Basically, my problem was that the upgrade tool just kept crashing and hanging. For instance, I had to kill it after it spent over half an hour configuring an OpenOffice package. This might have been due to our internet connection going down briefly, but it's hard to say for sure, as I the upgrade tool wouldn't give me any terminal output at that point. After that, I had another, similar, hang, followed by several crashes. The one crash which kept recurring turned out to be caused by the mono-xsp package. Apparently, when the install script tried to shut down the service, the xsp script in /etc/init.d was bombing out with an invalid file descriptor error. This, in turn, was killing Adept. To cut a long the story short, I forced the upgrade on xsp, ran dpkg --configure -a a few times, and everything was eventually fixed. But it was an ugly, command-line intensive process.

Going back to the brighter side, I'm liking Kubuntu Gutsy so far. It's not a radical departure from Feisty, but the changes I've seen so far are nice. I've already mentioned the restricted driver manager, which is great. The boot time seems to have dropped noticably as well. They've also switched from Konqueror to Dolphin as the default file manager. I didn't care for Dolphin when I had tried it in the past, but it's starting to grow on me. It has the features I use on a regular basis and is certainly less complicated than Konqueror.

Another little nicety is that they've moved to a KDM theme with a user list. I believe that, in the past, KDM themes didn't work correctly with user lists, but it seems that that's no longer a problem. I always liked that feature - it just makes the login a little more personal, I think, what with the little avatars and such. It will also be nice for when I migrate my mother's system from Xandros 3.0 (hey, it seemed like a good idea at the time) to Kubuntu. Having a list of usernames means one less thing to remember.

Lastly, I see that they've added Strigi as the default desktop search engine. I don't have any experience with Strigi, but I have had some not-so-great experiences with Beagle. In particular, it has a tendency to just hammer your system, sometimes causing serious drag. It also generates pretty large indexes. I've read that Strigi is supposed to fix both of those problems, but haven't used it long enough to say for sure.

The one problem I have with Strigi is the user interface. To call it "spartan" would be an understatement. It's a browser-based interface that makes Google's front page look lavish. Honestly, it feels like the UI is an afterthought. Compare this to Kerry Beagle, which is simple to use, but very pretty and very functional. Hopefully there's a Strigi front-end someplace that's comparable.

So, to summarize, Kubuntu keeps getting better. It's evolution is gradual, but visible. We'be certainly come a long way from release 5.10, which I thought was pretty good at the time. Now if only KDE 4 was done....

PHP IDE mini-review

Tomorrow marks my 2-month anniversary at my new job doing LAMP. And for most of that two months, I've been going back and forth on what editor or IDE to use.

My requirements for a PHP IDE are, I think, not unreasonable. In addition to syntax highlighting (which should be a given for any code editor), I need to following:

  1. Support for editing remote files over SSH. This is non-negotiable.
  2. A PHP parser, preferably with intellisense and code completion.
  3. A file tree browser that supports SSH.
  4. Syntax highlighting, and perferably parsers, for (X)HTML and JavaScript.
  5. Search and replace that supports regular expressions.
  6. Support for an ad hoc, per-file workflow. In other words, I don't want something that is extremely project-centric.
  7. It should be free - preferably as-in-speech, but I'll take as-in-beer if it's really good.

So far, my preferred IDE has been Quanta Plus. It has all of the features I need and also integrates nicely with KDE. It also has a few other nice features, including context-sensitive help (once you install the documentation in the right place). However, the build of Quanta 3.5.6 that came with Kubuntu Feisty is kind of unstable. It crashes on me every few days, and for one project, I actually had to switch to something else because I was making heavy use of regex search and replace, which was consistently crashing Quanta. Also, while Quanta has a PHP parser with some intellisense, it's pretty weak and not in any way comparable to, say, Visual Studio.

My second heavier-weight choice is ActiveState's free KomodoEdit. This is a very nice, XUL-based editor. It's stongest feature is undoubtedly the PHP parser. It's really outstanding. For instance, it can scan pre-determined paths for PHP files and do intellisense for them. It even understands PHPDoc syntax and can add the documentation to the intellisense.

The down side is that, while Komodo does speak SFTP, the file browser tree only does local files. There is a Remote Drive Tree extension that adds this feature, but while it's better than nothing, it still isn't that good. I also don't much care for the look of Komodo or for the keyboard shortcuts. Those things are much easier to customize in Quanta.

After Quanta, my other old stand-by is jEdit. After installing the PHPParser, XML, and FTP plugins, this meets my needs. On the down side, the PHP parser doesn't do any intellisense (although it does detect syntax errors). The interface also feels a littly clunky at times, although it's much better than the average Java application and not really any worse than Quanta in that regard.

I took a brief look at a couple of Eclipse setups, but wasn't initially impressed by them. It might be worth looking at them again some time, but the whole process of getting and installing the appropriate plugins just seemed like a lot of trouble. Same goes for Vim. I'm sure I could get it to do most, if not all, of what I want, but it seems like an awful lot of trouble. And then, of course, there's the Zend IDE, which I don't really want to pay for. And besides, my one of my co-workers told me that, while it's a decent IDE, the real selling point is the integrated debugging and profiling, which won't work on our setup.

And so my intermitent search goes on. I'm hoping that the upgrade to Kubuntu Gutsy will fix the stability problems in Quanta, which is my biggest problem with it. I'm also hoping for some nice new features when KDE 4 comes along. But I guess I'll keep looking in the meantime.

Multi-monitor goodness

Remember how I said I had dual monitors at my new job? Well, that's not quite true anymore.
new_desk-tn.jpg

That's right: I now have three, count 'em, THREE monitors. This was not by design, but actually came about because one of the other programmers left for a new job. His last day was Wednesday, so we divided up his stuff on Thursday morning. Edwin, our lead developer, moved over to his desk and took his PC and one monitor, while I took the other monitor and moved to Edwin's old desk. So I now have three monitors, a bigger desk, more light, and a more comfortable chair. What I don't have, as you can see from the picture, is real monitor stands. But I'm not complaining.

Setting up three monitors on Kubuntu was a little complicated. Fortunately, Edwin has some experience with tri-monitor setup, so he helped me through it.

The first hurdle was the BIOS. I'm using a dual-port nVidia card for two of them and the integrated Intel card on my motherboard for the third. By default, the BIOS disables the onboard video when it detects an external card, so I had to set the onboard video to always be active. I also had to set the onboard card to be the primary video device. Failing to do that actually caused a kernel panic on boot.

Once both cards were detected, it was just a matter of X configuration. I was able to set up the two monitors on the nVidia card using the nvidia-settings utility. That let me set the relative position and resolution of those two screens and enable Xinerama.

The integrated card had to be added by hand. The final configuration wasn't too hard, though. I added another "Monitor" section (which was actually identical to the other two), another "Device" section using the "vesa" driver and had the integrated card's bus ID, and another "Screen" section for them with the appropriate resolution. After that, I just added this line to the "ServerLayout" section.
Screen 2 "Screen2" LeftOf "Screen0"
The last step was to restart the X server and watch all three screens come to life.

There's only one problem with this: now I'm going to want three monitors at home, but I don't have $500 to drop on that project. Maybe if I can get some used....

Time matters too

Debugging tip: When debugging code that is in any way time-sensitive, make sure that the time on the computer you're working on is correct.

This particular nugget-o-wisdom would have come in handy for me last week.

You see, I had recently been working on the advertising module for our site, integrating the old stand-alone ad system with our new CMS. I got a but report, so I made some changes to the code. But after I started testing my changes, I realized that orders for new ad campaigns were being accepted, but kept randomly disappearing. It made no sense. I would place a test order and it would go through. When I opened up a MySQL console, I could see the record in the database. But when I went into the administration portion of our CMS, it wasn't there. And when I checked the database directly after that, the record had just disappeared. Gone without a trace.

How could this happen?

The answer is simple: timing. When the administrative interface is loaded, it does some cleanup to the data base. In particular, it cleans out any "stale" orders that have been placed - ads that customers entered, but never paid for. So if an ad is left unpaid for more than a day, it will get deleted.

But the ads I was entering were no more than a couple of minutes old. So why were they getting deleted? The logic in the database-cleaning code was correct. The "stale record" time in the configuration table was correct. So the records shouldn't have been deleted.

The problem was, I forgot about two things:
1) None of the clocks on our test servers (which are VMWare Server virtual machines) are right.
2) The public portion of our site and the management portion run on different servers.

The short version is that I ordering ads on one server and trying to view them in the admin interface running on another server. However, the system clocks of those two servers weren't even remotely close - the content server where I created the orders was a day or so slow and the admin server was several days fast. So as soon as the admin server saw the newly created ads, it immediately thought they were "stale" and deleted them.

That particular "bug" actually came back and bit me again today. I guess I'm going to have to talk to the guys and see if we can set up the test servers to run a periodic ntpdate so that I don't have to worry about that sort of thing again.

Versions matter

I ran into an interesting PHP bug at work the other day. Actually, it was a bug in PDO in a particular version of PHP.

Here's the situation. I needed to write a script to do some fairly extensive data massaging for a database integration. Since we have PHP installed on pretty much all of the production and development servers, I wrote it in PHP. It worked perfectly on the test server, so I figured it was safe to use it in production. And I was right, to a certain extent: it was safe in the sense that it didn't break anything - it's just that the script didn't work.

I won't get too much into the details of the script, as it's kind of long and not particularly interesting, but here's some sample code with the key points: while ($rec = $data_stmt->fetch()) { $db->beginTransaction(); $get_id_statement->execute(array($rec['something'])); $id = $get_id_statement->fetchColumn(); $update_statement->execute(array($somevar, $id)); $db->commit(); } The upshot here is that I was looping through the result set from a query and performing other select and update queries based on the current record. Simple enough, right?

The error message I received when I tried to run the script on our production database server was this:

PDO::prepare(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.

The wierd thing about this is that, as I said, the script worked perfectly on the development server. And the development servers are supposed to be configured the same as the production servers. Of course, that obviously wasn't the case, so we ended up spending the next hour or so messing around with various code configurations with regard to transactions, prepared statements, and all that good stuff.

To make a long story short, it turned out that the explanation was simply that the development database server was running PHP 5.2.x and the production database server was running 5.1.x. The version on the production server still has an experimental version of PDO which, as it turns out, didn't work quite right. If I had just adjusted the IP address in the PDO connection string and run the script from our production staging server, which has PHP 5.2, it would have worked perfectly the first time. Unfortunately, I didn't discover that until I had already wasted an hour bug-hunting and messing with the script until I got it to work on PHP 5.1 (by moving all the fetch and fetchColumn method calls to fetchAll). Live and learn.