The Return of Gentoo

About nine months ago I wrote a post title The End of Gentoo. At the time, the article mostly echoed my growing frustrations with the lack of maintainer support for the vast collection of software in Portage, Gentoo’s repository and package management subsystem. Although the gentoo-server mailing list has all but dried up, gentoo-user has seen a marked increase in activity. Whether seasonal or otherwise, I think it’s a positive sign.

Another positive sign that comes to mind is the increased frequency and speed with which package maintainers have been pushing stable (and sometimes unstable) package versions out the door. For example, I was surprised to discover that MongoDB exists in Gentoo at version 1.8.2 as of this writing, which is conveniently the same version in FreeBSD’s ports collection. Ubuntu is decidedly behind the curve, holding in at around version 1.4.x. Of course, with sufficient digging, you can find prebuilt .debs of 1.8.3, or you can always fall back on building from source. Then again, I’m somewhat torn with regards to this: Sure, it brings back memories of earlier days when I often had to build packages by hand just to apply security fixes or obtain new versions, but I also wonder what the value is to it. After all, if I abandoned Gentoo to avoid the nightmare of compile-wait-restart, what’s the point if I leap over to another distribution that is forcing me to do exactly the same thing (except with less automation)?

Given the nature of work and my current projects, I’ve discovered that Gentoo suits my needs best. I can obtain fairly new versions of packages with some degree of customization without the need to manually run the ./configure && make && make install cycle by hand. Downgrading is also fairly easy, provided it doesn’t affect too many packages. However, I’ve found that eselect for those packages it supports can be an exceedingly welcome tool in the developer’s arsenal. I may not use it with any degree of regularity, but the option of setting the system default of a specific package to one version or another is appealing. I suspect this will be mostly useful for any Python-based tools I write in the near future, particularly given the split that is currently underway between 2.x and 3.x, but eselect also works with a handful of other systems that exhibit some degree of change between versions, including PostgreSQL and Boost.

But, I confess that none of this really influences my motivation for writing this post. Well, with the exception of V8 and MongoDB.

I think that much of my decision revolves around familiarity and maybe, if I were to make something of a stretch, annoyance. Ubuntu on the desktop looks absolutely beautiful. I love it. I really do. But the moment you dare to venture beyond the official packages it shipped with (think instant messengers), you begin to encounter various bits of weirdness that fester into a sore. Ubuntu has a great community of developers and supporters, but sometimes more peculiar problems are harder to find via search simply because of the noise level generated by its popularity. There’s nothing wrong with that–in fact, that’s an excellent problem for a distribution to have–but for unusual issues, it often makes finding the answer an uphill battle that is difficult to win without some patience. Add this to the abomination that is NetworkManager (installed and enabled by default), the excessively annoying network configuration borrowed from Debian, and whatever blasphemous modifications have been made to sysvinit, and one starts to see a pattern that makes this distribution more than a little tiring to those who simply wanted something that Just Worked.

It’s ironic in a way. I read an article a couple of weeks ago praising Linux Mint for many of these same reasons that Ubuntu seems deficient. Perhaps I should give it a try…

Yet time and again, I find myself drawn to Gentoo. It’s a rough distribution to maintain. It has many sharp edges. It’s not exceptionally good for use on a server where security updates may need to be applied from upstream regularly. It’s not even really that great for low powered desktops (try compiling Xorg and the desktop manager of your choice on a Netbook without distcc or cross-compilation on another system and then get back with me). Time and again, Gentoo lures me in. Why? Well, I’m starting to think that the answer is more complicated than simply “familiarity.” Perhaps I should take back what I said earlier.

About 8 or 9 years ago, I started toying around with a handful of Linux distributions. The only *nix-based systems I knew at the time were FreeBSD and OpenBSD; I had no idea what Linux really was, why there was such a significant chasm between the userland and kernel, or even really what the differences were between distributions. Superficially, I just assumed that the init systems were largely identical, and individual distributions simply customized various subsystems here and there. I had no idea that the world of Linux was vastly different from that of FreeBSD. In the latter, kernel and userland development is largely one and the same. FreeBSD is the kernel. It’s also the world. From init to various userland tools (yes, even ls) to device drivers (oh fxp0, how I miss you), development continued as a part of a single cohesive continuum. Little did I know, the Linux world is almost the polar opposite of that.

I was introduced to Gentoo by my friend John G. who suggested it as a more “BSD-like” distribution of Linux. He was right–everything about Gentoo seemed to be a GNU-derived analog of the BSD world with the one exception that it was decidedly Linux-flavored. But the most important lesson I took from Gentoo was that of how an operating system is put together–from scratch, but with training wheels. Sure, I knew all of the basic steps: There’s the file system, the kernel, the userland tools, and then there’s various odds and ends here and there that are glued in place to make life easier (or more miserable). In some ways, it’s almost a surprise any of this actually works as well as it does.

Yet I think it was that experience with Gentoo that won my heart. Not only do you have to partition the file systems yourself, but you have to effectively bootstrap the entire system from a live CD (or other Linux distribution), prepare it, and configure it, but you also have to build the kernel and all of the utilities yourself. To this end, I think Gentoo should be a required topic in any operating system course in every CS program at all universities. It’s like Linux From Scratch set to super-easy-mode. It’s no surprise then that any time I want to learn anything new, the best way for me is to pick it up under Gentoo and play with it.

And let’s be honest, Gentoo probably has one of the very best network configuration systems in the Linux world. It better–because it’s the kindred spirit of FreeBSD’s network configuration via rc.conf, except that it’s not. Well, not completely.

This isn’t to say that Gentoo is all sunshine and roses. It certainly does have more than its fair share of sharp edges. I recently reinstalled it on my desktop (no, I still have my Ubuntu install) only to discover that it still takes the better part of a weekend (and then some) to configure, build, and find everything you want, get things situated exactly right, and then discover that there’s one or two minor annoyances still eating away at you. For me, those annoyances are font-related, but I suppose nothing’s perfect. Ubuntu’s fonts are about as close to perfection as possible in the Linux world. Although, I admit that sound and sound support sucks badly in both. Oh, and don’t get me started on media players. I spent most of my free time this week messing around with the damned things only to discover that nearly every single one available is absolutely terrible. I miss Amarock 1.4. They had a good thing going…

The most important lesson I’ve taken from the time period between now and the time I wrote that fairly anti-Gentoo rant is something worth repeating: Nothing perfect. No distribution is perfect, no one distribution will do everything you want, and compromise is always a necessity. I still like Ubuntu for its aesthetics, but Gentoo is still the most appropriate solution for a general purpose workstation. I guess some things never really do change.

So, lesson learned: Rants are stupid. The future you is always the wisest. Sometimes you look back on what you wrote and wonder what the hell you were thinking. Long live Gentoo!

No comments.
***

How to Unclobber your Last Session in Google Chrome

Update, June 24th

It occurred to me that it is possible some of you may be reading this post in the hopes of discovering how to configure Chrome to automatically resume your previous session. Fortunately, that’s easy! Simply click on Configure (that’s the wrench icon in the upper right), then click on “options” and make certain that “reopen the pages that were open last” is selected under on startup in the “basics” configuration category.

The crux of this post doesn’t address what I have highlighted here; instead, it assumes that your browser is already resuming the last open session. Furthermore, the solution offered here 1) presumes that your typical use case includes having more than one browser window open with multiple tabs each and 2) is intended to recover your last session after you have inadvertently clobbered it, either by opening only one (1) window from your previous session–and then promptly closing it–or by closing so many tabs that Chrome’s new tab session selection no longer shows your previous windows.

I should also mention that this solution may or may not work for those of you who do not have Chrome configured to reopen your last session. There is a possibility that this fix works only in the circumstance that you do.

Unclobbering your Session

I’ve been using Chrome for quite some time because it’s markedly faster than Firefox. I still use Firefox regularly, but my tab addiction doesn’t seem to play nicely anymore with any browser I use. Unfortunately, there’s one glaring shortcoming with Chrome’s UI that drives me nuts: If you have dozens of tabs spread out across two or three Windows, you can recover your last session from Chrome’s default empty tab UI if and only if you haven’t recently closed enough new tabs that would otherwise overwrite your session history. Worse, extensions like FreshStart don’t always recover your previous browsing state–in fact, I’ve had very poor luck with FreshStart displaying empty sessions or not remembering all of my open windows! So what do you do?

Before you think “Crap, I just lost 200 tabs” and close Chrome again, don’t. Do copy Chrome’s user data (%APPDATA%/Local/Google/Chrome (Windows), ~/.config/chromium/Default (Chromium, Linux), ~/.config/google-chrome/Default/ (Chrome, Linux–thanks to Joe in the comments)) to a safe location before closing Chrome a second time. Or, optionally, copy Last Session and Last Tabs from %APPDATA%/Local/Google/Chrome to a safe location. Close Chrome once you’ve finished copying the appropriate files; if Windows complains that it can’t copy Current Session and Current Tabs, ignore it. We’ll be replacing these later. If you’ve already closed Chrome, be absolutely certain that you copy these files before you restart the browser. Upon restart, Chrome will wipe any and all chances you have to recover from this accident.

Next, examine the contents of %APPDATA%/Local/Google/Chrome/User Data/Default. Delete or rename the files Current Tabs and Current Session. Then, copy the Last Session and Last Tabs from the backup(s) you made, and rename those to Current Session and Current Tabs, but be mindful of the timestamps. They should match the date and time you last closed Chrome.

Restart Chrome, and it will magically be delivered back to the state it was in before you clobbered your previous session! The trick here, of course, is to not close Chrome a second time once you’ve realized your folly. Doing so will overwrite your previous session, giving you nothing to recover.

If you’re a taboholic like me, this will help you recover what you’ve lost, and it should work for most incidentals! If not, post here with your problems or offer your own unique solutions.

38 comments.
***

Annoyances: vBulletin 4 Template Hooks

I’ve been doing commercial software development for vBulletin 3.x (and, by extension, 4.x) off and on now for a couple of years. While there are some things that irritate the crap out of me about both of these products, vBulletin (both versions) have features that just aren’t found in other bulletin board packages. Admittedly, many of these exclusive features are provided by an extensive library of 3rd party software, but the point still stands–as much as I hate to admit it. Few other message boards have a plugin system that’s easy to develop for, and fewer still have the vast library of plugins available. phpBB doesn’t even come close. vBulletin still has its shortcomings for developers, but I’ll save my complaints for a later installment.

What I’m going to write about tonight is something that bit me, and I know it’s going to bite someone else out there: Template hooks have been the bane of my existence in vB4 for the majority of this weekend, and once you start adding a few yourself, you’ll grow to appreciate the manic schizophrenia that is the vBulletin 4.x template system in all its unadulterated glory. I hope to save you from the onset of severe insanity, so keep reading for my story and my solution.

Side note: You might also want to make this a summer project, because you’ll be bald by the time you’re finished, and I understand that bald heads get cold quite quickly. If you’re already bald, accept my apologies and tear something else out–like the upholstery stuffing in your desk chair. Don’t have a chair? Reach for the carpet. Don’t have carpet? Well, you’re on your own.

Template Hooks: They Work–But not When You Want Them To

I’ve written a couple of plugins that rely on the various forumhome_wgo_pos* template hooks for both vBulletin 3.x and 4.x. These hooks work perfectly for most use cases, regardless of when your plugin fires, and are almost foolproof. Don’t be lulled into a false sense of security, though. The moment you do anything unusual with template hooks in vBulletin 4.x, you’ll be bitten by the what-the-heck-happened-to-my-output surprise.

To reproduce the ailment that has been afflicting my sanity for the better part of this last Sunday, I direct you to a simple test:

  1. Create a new product, complete with its very own plugin.
  2. Set the plugin to fire on the global_start plugin hook.
  3. Add the following code to the plugin:
    $template_hook['footer_test_hook'] = '<b>Hi!</b>';
  4. Add the following code to your footer template:
    {vb:raw template_hook.footer_test_hook}
  5. Run it!

You should notice that you now have a nice, shiny string containing Hi! at the bottom of your page in the footer code. Now, let’s break it:

  1. Add a template, such as break_my_footer to your product XML (optional; you could use any other template if you like)
  2. Call this template from your plugin using something like:
    $tpl = vB_Template::create('mytemplate');

    Or, if you decided to use an existing (small) template:

    $tpl = vB_Template::create('option');
  3. Then modify your template hook code appropriately:
    $template_hook['footer_test_hook'] = htmlentities($tpl->render());
  4. Watch in horror as nothing appears in your footer.

Try as I might, I spent a good hour or two trawling various vBulletin support sites for answers. Rather than make a post somewhere and risk having one of their ill-tempered devs explain “Well, this is how it’s supposed to work, didn’t you use the search?” when the built in search generally sucks and Google doesn’t always pick up their help threads, I decided that this issue became personal. That is to say, this code insulted my mother, my father, my nonexistent siblings, and each of my ancestors going back 1,500 years.

After performing various blind tests I concluded that somehow the call to the vB_Template::create() factory method was effectively wiping the contents of $template_hook–or ignoring it, or purging it, or performing an exorcism on it with tremendous glee while I steamed with fury in front of my monitor. I then decided that I’d had enough, and so I searched for the footer template to determine where it was being called, prepared, and possibly rendered in the code. My hunch was that the footer was being generated separately from the forumhome cruft that so happily seemed to work no matter where I used it or what I did with it (and indeed it is generated separately). Yet my own template hook refused to work.

Then I came across this code in includes/class_bootstrap.php:

 $templater = vB_Template::create('footer');
                        $templater->register('admincpdir', $admincpdir);
                        $templater->register('ad_location', $ad_location);
                        $templater->register('cronimage', $cronimage);
                        $templater->register('languagechooserbits', $languagechooserbits);
                        $templater->register('modcpdir', $modcpdir);
                        $templater->register('quickchooserbits', $quickchooserbits);
                        $templater->register('template_hook', $template_hook);
                        $templater->register('facebook_footer', $facebook_footer);
                $footer = $templater->render();

Pay careful attention to the line $template->register('template_hook', $template_hook);. Clearly, the footer is processing the template hook here–so I thought to myself, perhaps there’s a nearby hook that I could attach my plugin to so I can guarantee I know that the content of $template_hook won’t be interfered with.

I scrolled up and found a hook that probably should have been fairly obvious to me from the start. But hey, it’s the weekend. What more can you expect?

($hook = vBulletinHook::fetch_hook('parse_templates')) ? eval($hook) : false;

Sheepishly, I changed my plugin to use the parse_templates plugin hook instead of global_start, and it worked! So the upshot is: If you’re going to try using custom template hooks and you discover that they won’t work the moment you load a template, try changing the plugin hook to parse_templates. It might just fix the problem.

Now, this was admittedly all my fault for not realizing that parse_templates may be the correct solution; I really should have examined the vBulletin sources more closely. Shame on me. In my defense, though, the vBulletin documentation is pretty poor, much of it is outdated, and even less of it focuses on issues specific to 4.x. However, I have one particular bone to pick: It’s puzzling to me that whatever is in $template_hook will work fine up until the moment you decide to call vB_Template::create(). There’s a comment under the create() method that indicates something to do with $template_hook and treating it as a special case for the purpose of various globals or some such, along with a reference to a bug tracker ID. I think that’s more coincidental than anything else, and certainly if I wanted to find out what was happening, I could run a trace with XDebug, but I’m not that desperate–or bored (yet). My guess is that, somehow, subsequent calls to vB_Template::create() clobber the contents of $template_hook by the time vBulletin gets around to rendering the footer; I may be wrong–I probably am–but this is an example of bizarre code suffering from manic schizophrenia.

Frankly, the vBulletin sources are so stupidly convoluted it’s a miracle the software works as well as it does. I’ll save that for another rant much later this week or next. In short, remember: If you’re toying with custom template hooks, you might just break your code. If you do, try changing the plugin you’re writing for template rendering purposes to hook into parse_templates. You’re almost guaranteed to have little to no interference with the contents of $template_hook and the parse_templates hook is nearest to the templates that are most likely to be affected.

Toodles for now. Expect to see a whiny rant soon!

3 comments.
***