As a computer scientist and software developer, I have been conditioned to live in fear, or at least gross distaste, of legacy. That is to say, legacy code, legacy systems, legacy process/procedures, etc. As a self-proclaimed cowboy rock star egotastic developer, anytime I see code that wasn’t written by myself (or a select group of those whom I deem as “peers”), my first instinct is to proclaim that it’s horribly written and that I should redo it. Likewise, the same goes for legacy systems and process/procedures. “Oh gosh, we’d be so much more efficient without all this process in place!” … “Oh gosh, our server is running on an OS that’s 4 years old, we need to upgrade it!” … “Oh gosh, oh gosh!”
Sound familiar? It should if you’re a software developer on a project with more people assigned to it than you can count on two fingers. I’ve found that one important part of career and professional growth in software development is learning how to deal with legacy, and to reign back the instincts to immediately and bombastically proclaim it all as a bunch of crap. Sometimes dealing with legacy means refactoring utility code while you’re fixing a bug that is dependent on it (“I’m in this part of the code anyway, why not?”). Other times that means checking out half the source code tree to make a tiny change in every single file that has positive consequences in areas of performance, stability, maintainability, or whatever. On rare occasions it really does mean rewriting all the code, or redefining the process by which you’re doing development.
Oftentimes, however, I’ve learned that you should just leave it alone.
If you have something in place that works, and you don’t have plans to change it, then guess what … it’s probably ok to leave it alone! Even if the code is nasty, or the implementation uses 5 year old design patterns, or if there’s a new intern who really really wants to prove him or herself. For example, I would argue that Notepad works. It does its job, it does it well, and there’s really no need to rewrite it to use C# or WPF or sock puppets or anything. It’s a stable legacy system. (That’s not to say there isn’t a need or a market for something more, such as Notepad++ or Notepad2.)
Now, you might wonder what in the world this has to do with Paint.NET’s bug database. Well, before I start, you should first answer the following question: What do you think I’m using for Paint.NET defect/bug tracking?
Ok, seriously, ask yourself that question. Give yourself at least 10 seconds to come up with a few different possibilities, both low- and high-tech. Pieces of paper stapled to the wall? Sourceforge? A custom WinForms or ASP.NET app? Notepad? Excel? The back of my hand and a marker?
Here’s the answer and the story:
Paint.NET’s bug database is Bugzilla 2.16.3 running on Apache in Redhat Linux 8.0. It was originally hosted on a Pentium II named “elbonian3″ in some dark corner of the EECS department of Washington State University. It was set up by (I think) Chris Crosetto during Fall semester of 2003 (~August) for the Computer Science 422 class (“Software Testing”) that Jack Hagemeister was running. The purpose was to inspect the source code of some client software that Gene Apperson (Microsoft alumni, Diligent founder) was developing, and to then file bugs on it. I was in this class and filed many bugs on the code, although I don’t know if Gene ever fixed the bugs or if his project was ever finished. Paint.NET started the following semester, and version 1.0 was written from start to finish in 15 weeks without any official bug tracking system. I think Brandon had an Excel file but nobody else really had access. I do not recommend doing that, by the way, that’s just the way things went down.
For the Fall 2004 semester, I talked with Jack and we set up a senior design project to ramp Paint.NET up to version 2.0. We got three students to work on it: Tom Jackson, Michael Kelsey, and Craig Taylor. The first thing we did was to have me finish up my work on version 1.1, and have the three students do bug filing and write updated documentation (haha, suckers!). As part of this, they managed to get the new semester’s CS422 students to do a lot of testing. To do this they picked up and ran with the “elbonian3″ server that had been set up the year before. It worked great: students would file bugs, I would get e-mails from the server, and we could respond to each bug appropriately. The three students learned a lot about bug triaging, as well as release and defect management. Next up, they did their development work to push Paint.NET up to version 2.0 which was released right before Christmas. Then Paint.NET was Slashdotted. It was amazing, and comedic: the attention caused enough network traffic to bring down the entire EECS network for 2 days.
For about the next year and a half, I continued to use this server remotely from 300 miles away to do Paint.NET’s defect tracking. However, in early- to mid-2006 it was clear that it was no longer appropriate to house this software at EECS. The network administrator was overworked (as they always are!) and the server was often down (for whatever reason), and Paint.NET was not really a “WSU project” anymore. The admin wanted to retire the server, and said he could send me the contents of the hard drive as a VMWare virtual hard drive file. I said that would be great, and the next day I started downloading a 2 GB tarball over HTTP.
Once I had downloaded and extracted the file, my next job was to install the free Windows version of VMWare Player on my server box in a dark corner of my house. This was no problem; it booted right up and spat out a login screen. But, you see, there was a major problem: the server still thought it was in Pullman on the eecs.wsu.edu domain. I managed to figure out what IP address the server had obtained, but whenever I tried to access it Apache would respond with headers pointing my browser back to the old eecs.wsu.edu address. Argh! Try as I might, I couldn’t figure out how to reconfigure Apache not to do this.
I’m sure some magical combination of grep and sed and other 3-to-4 letter combinations could fix it quick, but I found a faster-for-me solution: I cheated. I edited my hosts file in Windows so that it would map elbonian3’s network name to the local IP address of the virtual machine. Then, when I typed in the IP address in to my browser, it would get redirected to elbonian3 which would then get redirected right back to the IP address in a way that was completely transparent to the browser. Success! I had a working bug server again!
On a quick side note, about a month after I set this up I found that my IP range was being blacklisted by spamhaus or something. The reason was that sendmail was still active on my virtual server. Bugzilla kept trying to blast e-mail notifications about bug changes through an EECS mail server, which for obvious reasons rejected them. I’m a dumb clumsy oaf when it comes to Linux administration so I had to find a clever way to disable sendmail … I think in the end I may have just removed execute permissions on the appropriate binary. Bugzilla still claims to be sending out e-mails in its UI, but none of them actually get sent.
Anyway. A few weeks ago I decided to retire that server, as it wasn’t really doing much other than hosting this virtual machine and a CVSNT server. Why pay for that electricity if I can get it to run on my main workstation anyway? These were two things I figured could be done much faster if I just ran them locally (CVSNT is slow for Paint.NET’s repository on a 100mbit connection). There was another problem though: I use VirtualPC so that I can host copies of Windows XP and Vista in various configurations (high DPI, weird visual themes, etc.) in order to do testing for Paint.NET. I had VMWare up and running successfully, but the moment I tried to run VirtualPC the whole system hung and my awesome techno music started skipping. Bleh!
I managed to find a utility to convert the VMWare “VMDK” hard drive file to a Virtual PC “VHD” file. It’s called, appropriately, Vmdk2Vhd. And now I have my Bugzilla running in Virtual PC on my desktop system.
So there you have it. I use an old version Bugzilla in a virtualized Linux installation which still thinks it’s sitting in a dusty corner of my old university that’s over 300 miles away.
And it works.
And past that, who cares? Right now, I sure don’t. Legacy isn’t all bad, as long as it works and you don’t have to maintain or reconfigure it all that often. I’m basically the sole developer on Paint.NET right now so my requirements are pretty slim for things like bug tracking and source code control (Linus thinks I’m “ugly and stupid” for using CVS … but hey, you gotta admire his passion).
By the way, the quote in the Bugzilla screenshot above reads: “Using exceptions for bounds checking is like driving a car … it’s cheaper to just do a little extra work and stay in-bounds than it is to crash off the side of the freeway and say, ‘Oh the insurance can pay for that.'”