MediaWiki – Preformatted Text within Lists

As I discovered this morning, with MediaWiki 1.5.7+, if you attempt to put a <pre> wraped block of code within a numbered list, the indentation breaks and the numbering starts over after the <pre> block. This was pretty annoying, as I was trying to document a procedure including the commands to be run and their explanation. It took a few minutes, but I found the solution in the wikimedia Help:Editing FAQ page, thanks to Ulf Rompe:

# one
# two
#:<code lang="text">
#:here are a couple lines
#:of preformatted text
#:</code>
# and the numbering
# continues

The code lines are indented a bit more than what looks right, but it works.

Nagios / Icinga Configuration Highlighting with GeSHi

As you may know from former posts, this blog (WordPress-powered) and a few MediaWiki sites that I have use the excellent PHP-based GeSHi syntax highlighter. Today I was writing a post that includes some Icinga (Nagios) configuration snippets. After a quick search, I found a Nagios language file for GeSHi on GitHub. Thanks very much to Albéric de Pertat (adepertat) for writing this and providing it to the public.

Using Templates to Track Outdated Content in a Documentation MediaWiki

Both my last and current jobs use MediaWiki for internal documentation. As always happens, some of this documentation will inevitably get out-of-date, or totally deprecated. As is also the case, many times when we’re looking for docs in the middle of an incident, we don’t have the time to go back and fix what’s wrong. So, I devised the following template/category system to help keep track of these problem pages.

First, create some templates that you will apply to the problem pages. I use three – one for totally deprecated pages, one for pages that need updating, and one for pages that just need cleanup. For the cleanup template, in the MediaWiki search box, enter “Template:Cleanup” and click “go”. You should be told that the page doesn’t exist, and given a link to create the page. Create it, and enter the following content:

<table class="metadata plainlinks mbox mbox-caution" style="">
<tr>
<td class="mbox-image">
[[Image:Cleanup.png]]
</td>
<td class="mbox-text" style="">'''This page needs to be cleaned up or reorganized.'''</td>
</tr>
</table>
 
<includeonly>[[Category:Pages Needing Cleanup]]</includeonly>

Now we create a category page for it, “Category:Pages Needing Cleanup”, with the content:

__HIDDENCAT__
 
This category is for pages that are mostly correct and just need minor corrections or reorganization.
 
'''To add pages to this category''', include the following at the '''TOP''' of the page:<br />
 
<code><nowiki><!-- REMOVE THIS TEMPLATE WHEN PAGE IS UPDATED-->
{{cleanup}}</nowiki></code>

and save the page.

Now there’s a few other changes we need to make. First, upload the Cleanup.png graphic, which I got from wikimedia.org here and uploaded as Cleanup.png.

If you refresh the Template:Cleanup page, you should now see the image. On a side note, “__HIDDENCAT__” on the category page prevents that category from showing up in the category list at the bottom of the pages we add to it, but this only works in MediaWiki 1.13 and up.

The last step is to add the MediaWiki mbox template and its dependencies. While I did this once before, I didn’t really remember the steps, but I found a post on Glynor’s blog that details them rather nicely:

  1. Enable the ParserFunctions extension. There are download and install instructions on the extension page, but you’ll want to enable string functions. To do this, include the extension in LocalSettings.php like:
    require_once( "$IP/extensions/ParserFunctions/ParserFunctions.php" );
    $wgPFEnableStringFunctions = true;
  2. Create a new page in your wiki called “Mediawiki:Common.css”, and paste in the content from MediaWiki.org MediaWiki:Common.css.
  3. Go to Wikipedia’s Special:Export page, and enter “Template:Ambox” in the box, check off “Include templates”, and export the template (and all dependencies) to a local XML file.
  4. Go to the “Special:Import” page of your wiki, and upload the XML file you just grabbed from Wikipedia. This will import the Ambox and mbox templates, as well as their dependencies.
  5. Now, if you go back and refresh the Template:Cleanup page you created, you should see the icon and a nice message box:

cleanup message box

Finally, add the template and category pages for update and deprecated:
Template:Update

<table class="metadata plainlinks mbox mbox-caution" style="">
<tr>
<td class="mbox-image">
[[Image:Warning.png]]
</td>
<td class="mbox-text" style="">'''This page is in need of updating. Some information on it may be out of date, and should not be relied on.'''</td>
</tr>
</table>
 
<includeonly>[[Category:Pages Needing Updates]]</includeonly>

Category:Pages Needing Updates

__HIDDENCAT__
 
This category keeps track of pages that need changes or updates.
 
'''To add pages to this category''', include the following at the '''TOP''' of the page:<br />
 
<code><nowiki><!-- REMOVE THIS TEMPLATE WHEN PAGE IS UPDATED-->
{{update}}</nowiki></code>

Template:Deprecated

<table class="metadata plainlinks mbox mbox-caution" style="">
<tr>
<td class="mbox-image">
[[Image:Critical.png]]
</td>
<td class="mbox-text" style="">'''The information on this page is badly out-of-date.''' It describes a system that is no longer in production or has drastically changed, and '''needs to be updated or rewritten'''.</td>
</tr>
</table>
 
<includeonly>[[Category:Deprecated Content]]</includeonly>

Category:Deprecated Content

 __HIDDENCAT__
 
This category keeps track of pages that are '''seriously old''' or otherwise describe systems/hosts/etc. that have seriously changed from what is described in the page.
 
 
'''To add pages to this category''', include the following at the '''TOP''' of the page:<br />
 
<code><nowiki><!-- REMOVE THIS TEMPLATE WHEN PAGE IS UPDATED-->
{{deprecated}}</nowiki></code>

And the download the two images – http://upload.wikimedia.org/wikipedia/commons/9/98/Ambox_deletion.png gets uploaded as Critical.png and http://upload.wikimedia.org/wikipedia/en/f/f4/Ambox_content.png gets uploaded as Warning.png.

That’s it. To use this, just add {{cleanup}}, {{deprecated}} or {{update}} to the top of a wiki article (adding the HTML comment before it is also recommended), and it will add the page to the appropriate category and show a nice message box at the top of the page:

Cleanup:
cleanup message box
Update:
update message box
Deprecated:
deprecated message box

I also add a link to the top of the main wiki page:

Things that need to be done: [[:Category:Pages Needing Updates|Pages Needing Updates]], [[:Category:Deprecated Content|Pages with Largely Deprecated Content]], [[:Category:Pages Needing Cleanup|Pages Needing Cleanup]], [[Special:WantedPages|Links to Nonexistent Pages]]

Puppet Syntax Highlighting with GeSHi

This blog is run on wordpress, and I also do quite a bit in PHP, so I’m familiar with the GeSHi syntax highlighter. It’s PHP-based, and can run both as a WordPress plugin (WP-Syntax) and as a PHP module. It also works quite well with the MediaWiki SyntaxHighlight GeSHi extension.

Today I was documenting some Puppet code in a wiki, and realized that I didn’t have syntax highlighting. Well, fellow Linux sysadmin and puppetmaster Jason Hancock was nice enough to post on his blog (Puppet Syntax Highlighting with GeSHi) that he’s developed a GeSHi language file for Puppet, available from GitHub. Many thanks!

Custom MediaWiki Sidebar; New Blog?

As you may have noticed, some Firefox 3 buttons have popped up not only here on my blog, but also on my wiki. While adding the buttons to Blogger was a simple addition to the template, getting them in the sidebar of MediaWiki wasn’t exactly as easy (yeah, I’m considering the arduous project of moving my whole 102+ page wiki to Drupal or another good F/OSS CMS).

After some serious grepping through the source, and adding HTML comments to see where they appeared, I finally found a solution to add the button to the MediaWiki sidebar – though I’d really like it to appear below the search box (I guess that’s something for my to-do list). I’m using the MonoBook skin (though somewhat modified). I’m using “MonoBook nouveau”, and it should be the version that shipped with MW 1.10.1. In this version, I added the code around line 166. Specifically, this was added before the <div id="p-search" class="portlet"> line, and after the end of the foreach ($this->data['sidebar'] as $bar => $cont) loop. This threw the button in a box directly above the search box, and below all of my sidebar links.

The code looked something like:

      <?php } ?>      <!-- firefox link added to MonoBook.php by jantman 2008-06-18 -->      <div class='portlet' id='p-logos'>          <h5>Cool Stuff</h5>          <div class='pBody'>              <ul>                  <li><a href="http://www.spreadfirefox.com/node&id=238326&t=305" target="_blank"><img border="0" alt="Firefox 3" title="Firefox 3" src="http://sfx-images.mozilla.org/affiliates/Buttons/firefox3/110x32_best-yet.png"/></a></li>              </ul>           </div>      </div>      <!-- end firefox link -->      <div id="p-search" class="portlet">

In other news, I’m taking a Data Driven Websites class this summer (PHP/MySQL, but for some reason they switched to a Windows server… endless problems, and I can’t even edit with Nano on the server, let alone emacs). Our first project was to build a blog engine, which I’m working on right now. Anyway, it got me thinking… the one thing that Blogger is missing is the ability to post to a given category, and allow users to view or subscribe to a specific category (or everything). So I think I may look into writing something like that myself, if I can’t find a good alternative that’s already done and is F/OSS. Regardless, I’ll probably be keeping the Blogger template as well as (ugh) moving over all of my current posts, which Blogger chose to store in raw HTML. So there’s going to be a lot of parsing on my future…

PS – When I get a new blog engine, I’m also going to go for a slightly modified template that uses relative widths and placement – so that code, like the snippet here, fits the screen correctly.

SunSPOT; CarPC; MediaWiki Logging

Well, finals season is upon me. That’s probably why I haven’t been posting much lately (I haven’t even been checking Google Reader – I’ll have to delete a few thousand entries when I get back into the swing of things). I’ve been pretty busy, between studying, projects, and work. I’ll be working 4 days a week through June 20th, as well as taking night classes 4 nigths a week (unfortunately not the same 4 days) through July 3, in an effort to graduate Rutgers on time (after transferring in and also switching majors). Work after June 20th is up in the air – who knows how hard the budget cuts will hit.

My internship as the Sun Microsystems Campus Ambassador to Rutgers is over on May 12th. I got a chance to do the Rutgers IT Vendor Fair with Sun, and met a few cool people – especially including Matt McGrath of Continental Resources, a Sun Strategic iForce Partner, who’s doing some wonderful things with the Sun Education Essentials Matching Grant Program, and Skip Paul, a Linux Systems Engineer for Novell’s Open Platform Solutions group. I also finally cracked open my demo set of SunSPOTs. Wonderful little devices, radio, run Java on the bare metal, and have temperature sensors, accelerometers, and liberal I/O. My first development exereice will probably be making a temperature and acceleration data logger for my truck, but there’s surely more to come. They’re great!

My newest project – which I’m hoping to spend nearly the whole summer on – is the TuxTruck. I’ve been frustrated with the lack of “smartness” in my truck (an 06 Ford F-250), not to mention having to remember my MP3 player so I can listen to podcasts on the way to work, and having so many gadgets in my truck. So, the solution is obvious: a Linux-based CarPC. A nice little Mini-ATX box under a seat, with a 7″ pull-out touchscreen in the dash (replacing the factory radio). It’s a big, complicated, and expensive project – but I want one, and I could use some experience with smaller systems.
The major features I have planned:

  1. Realtime GPS navigation
  2. Hands-free bluetooth calls from my cell, with address book, routing to contact address, possibly voice dialing.
  3. Realtime weather
  4. OBD-II interface, for vehicle diagnostics and fuel efficiency/performance profiling
  5. Audio – at a minimum searching and playing MP3s, and automatically downloading podcasts and throwing them in a playlist. Perhaps also an AM/FM tuner

It’s not an easy project. So far, the major challenges seem to be:

  • No full-featured GPS navigation package available. The ones that are available don’t seem to be too easy to integrate into my planned GUI, which will allot them 800×420 pixels (on an 800×480 screen) and requre the bottom toolbar to be always available.
  • How to handle processing of multiple data streams that require near-real-time processing – specifically, GPS with text-to-speech, turn-by-turn directions, plus playing audio, plus responding to an incoming phone call in a timely manner, pausing the audio, and stopping GPS audio but continuing navigation.
  • Whether to install a smaller stereo and use aux input for audio, or totally rip out the stereo, use an amp with the computer as its only input, and then how to control volume?

There will be more to come in the future. For now, take a look at the TuxTruck github.


Update Saturday, March 2, 2013 – I’m in the process of migrating my legacy CVS and Subversion repositories to github.com. The forgotten SVN repository for TuxTruck has been migrated there, and the CVS repository will soon be moved there as well. Tuxtruck.org has been permanently taken offline and redirected to the GitHub repository.


Mediawiki Logging – I recently had a situation where I had to confirm how much work someone had done on a MediaWiki-based project. The Recent Changes page only goes back 30 days, and walking through the History of each page is a pain. After looking around in the database a bit, I found a few tables of interest:
  • Table “users” includes fields “user_touched” (last time the user was updated) and “user_editcount” (a really simple count of the users’ number of edits).
  • Table “recentchanges” holds a lot of data… seemingly the entire life of the wiki

Website, Blog, Bacula

Website – In personal news, I’ve finished migrating all of the information content of JasonAntman.com to a wiki, based on MediaWiki. I’m still getting some kinks ironed out, and working on customization, but it seems to be coming along very well. It’s wonderfully easy to update information and to link between articles. Most of the content is more like notes than articles, but I’m trying to put most of my SysAdmin and programming notes up there, both for my own future reference and that of anyone who happens by the site. As always, though, some content will just live its’ life as a blog entry, so I encourage searching of my blog as well. This is my fourth instance of MeidaWiki, and while I haven’t set them up to play together, they all run wonderfully – and share a lot of common configuration (though I have separate instances of the code). Hopefully I’ll do a bunch of reorganization of the wiki sometime, and keep adding new content. Some of the newer pages include pages on DenyHosts and HPASM (from my blog post).

Blog – I know the template is awful. It’s on my list of things to do, and should be at the top of the queue in approximately 2056.

Bacula – Up to now, my backups have been a total kludge. The mere explanation of this elicits a feeling of nausea. A shell script on my backup storage server executes via cron. Each of the four important servers on my network (mail, web, monitoring, and development) have shell scripts that handle local backups – tar’ing up a list of directories, MySQL dumps, etc. – then tar gzip the whole thing and plop it in a local directory. The backup server executes these scripts and then copies the temporary files to its own disk via SCP. All of this is handled through an expect script, that runs each server consecutively. By morning, I end up with a 6+ hour job that’s finished, and dumped gigs of files on the backup server. Before finishing each machine, it deletes any backups on the backup server that are older than 10 days. After copying everything, it deletes the client’s local copy. The bottom line is that if a machine goes down, I can re-install the OS and all packages, and then have the backups of just /etc and user data. Not beautiful. Even worse, my backup storage server doesn’t have a tape drive. When I get around to it, I run a script on my development/storage box that copies the latest backups from each machine, located on the backup server, to a tempdir and then writes them to tape. To top it all off, I have only one network, so all of these gigs of data are crawling across my ancient 10/100 switch, along with all other connectivity to the outside world.

Unfortunately, it doesn’t look like I’ll have the money to upgrade to Gig-E any time soon, even just for the 5 machines involved. More to the point, there’s no way that I’ll have the money to buy a manageable Gig-E switch that can come anywhere close to my BayStack 450-24T. So, it’s time to invest… well… time… in a good backup infrastructure. After doing a lot of research, I came to two findings:

  1. The two main options seem to be AMANDA and Bacula.
  2. I don’t like how AMANDA works.

So, I’m going to give Bacula a shot. I did consult the SAGE mailing list for advice, and got some recommendations for BackupPC, but Bacula seems to be more my type of thing. Well, I did an install, and spent about 8 hours hacking around with the config files. No luck. Bacula is designed to be highly modular and scalable, but to be honest, I find the config files to be *very* complicated. Furthermore, I wasn’t able to find any good example configurations with documentation. After brainstorming for a while (laying in bed watching Law & Order and reading the Bacula docs on dead trees) I decided to give in – despite my continued efforts to stop using it, I checked Webmin and, surely enough, they have a Bacula module. After starting with fresh config files, I was able to get Bacula up and running on my development/storage server (a fresh install of openSuSE 10.1) as the director. I got a file daemon installed on the web server. Everything looked wonderful.

The current status: My backup storage server does only that – storage of backups. Nothing else. It’s still running SuSE 9.3. The Bacula RPMs for 9.3 are from the 1.x tree, and all of my other machines are running openSuSE 10.x, with Bacula 2.x. I gave it a shot but, sure enough, a Bacula 2.x director won’t jive with a 1.x storage daemon. And I’m in dependency hell – Bacula 2.x requires upgrades of everything from the C libs all the way up. So, I’m going to give a shot at an upgrade of the storage machine via YaST, and see where I get.