After starting to use Drush, I wanted to switch my Drupal cron jobs over to it. I’d previously been running these jobs the standard way, loading a URL for each of my Drupal sites with curl. That curl command was run by the cron; Site5 allows editing of your crontab directly or through its Backstage Web interface.
I started with the basics. Drush was installed in my home directory, with an alias under ~/bin in my Site5 account. I replaced my curl command one-for-one with the following:
This didn’t work out well. I was getting a huge number of mail messages, indicating problems with the cron jobs. The messages typically contained “tput: No value for $TERM and no -T specified.” Needless to say, this was rather frustrating, so after some trial and error, I modified the command as follows, and that has been working better for me.
The biggest change is that I specify PHP, rather than Drush, directly. This was done so that I could increase the PHP memory limit for the cron job significantly, to 64M, while running Drush. I’m sure that this increase was needed partly due to the number of modules I have installed on my main site (which has an even larger default PHP memory limit in its php.ini). My research indicated that I needed to do this for Drush since it doesn’t access the Drupal sites in the same way loading a page does.
The other noticeable change is that I provide the path to the drush.php file rather than pointing to the Drush alias.
It should come as no surprise that Apple Installer installation packages can contain scripts. These scripts are supposed to conduct important operations during the course of the software installation.
However, when you are the system administrator of more than one Mac, you find that developers sometimes miss a good balance between what you think should be in the installer payload versus what should be in its scripts. The payload of a installer, by definition, are the files and links that should be installed, along with information on where they should be installed as well as how (i.e. ownership, permissions).
Therefore, developers should not need to run scripts that create or delete files — they should be created from the payload itself, and if a file must be deleted during the install then consider that perhaps you’re doing it wrong. Likewise, there should be little need move or copy files, because as many copies as desired can be installed from the paylod. Similarly, the need to change ownership or modify permissions should be taken care of in the payload.
Perhaps I’m being a purist here. I’m certainly accused of that, from time to time. However, this just makes sense to me and I happen to think that many developers are similarly logical people. They just aren’t the kind of logical people who happen to spend effort on software installation, especially the kind that results in a deployment-friendly installer package.
So how do we as administrators verify the quality of the scripts in installers? Is there a way we can quickly peer into them to decide if any of the scripts’ steps will be superfluous or even (gasp!) harmful?
Well, I have a quick suggestion for scanning packaged installers. The following one-liner shell command will search an installer package or metapackage for scripts that have the kinds of steps outlined above.
Note that this will only work for the traditional installer packages; it will not work with Leopard-style flat packages (which are documented so badly by Apple that the best description comes from reverse engineering by Iceberg's author). The one-liner will currently only find the defined install operations scripts: preflight, preinstall, preupgrade, postinstall, postupgrade, and postflight. (Any other scripts are likely to be called by one of those six.) It assumes those scripts will be shell scripts, currently, even though any of them could be written in other scripting languages installed with Mac OS X, like Python, Perl, or Ruby. It will also not work on the JavaScript-based system and volume requirements portions of the installation.
However, it’s a start. The output displays the offending file and line number, so you can conduct more careful examination of the matches it finds.
I haven’t run this on an exhaustive list of installation packages, but I have already seen at least one installer that produces worrisome output.
Update: I’ve changed the regex for the pre/postflight script so that it is more general that what I originally posted. I’m also having some problems with the snippet working with a certain installer whose scripts I know have cp and chmod commands. So, I may be back to the drawing board with this; comments are welcome.
I have been struggling with the issue of module availability in Python. While the “batteries included” nature of the standard library is great, there are occasionally times when I need to resort to a module that isn’t included with Python.
There are also times where I’m using modules whose status has changed. I expect that to happen more in the eventual transition to Python 2.6 and 3.0, because I’ve used modules that are being deprecated.
So I wondered how I could conditionally import a module if it was available, without stopping the flow of my scripts — and gracefully handle situations where it is missing. And here’s one basic answer: use a “try” block to catch the “ImportError” exception. For example, if I were concerned that DNSPython wasn’t going to be installed on my target system:
try:
import dns.resolver # Import DNSPython
dnspython_available = True
except ImportError:
dnspython_available = False
The “except ImportError” clause could specify a different module to load, or other workarounds entirely. You could map the namespaces in the “try” bock so the rest of your script doesn’t notice the change in module functions, if you have a way to work around the missing module. Perhaps, you could even try to obtain and install the module, at least for temporary use by your script.
Thanks to authors of the article Python modules – how do they work? for the assist. The information under heading 2.11, “Is my module available?” answered my question and has given me something to think about.
I recently took a trip to Seattle, and reminded myself of a useful practice I’d developed a while ago. When I’m traveling, I collect import URLs for that trip in my browser — URLs for my organization’s travel booking/information system, airlines, hotels, maps, conference information, etc. — and put them in Safari’s Bookmarks Bar.
It’s pretty easy to collect them:

The resulting bookmarks can be rearranged, if necessary, in Safari’s bookmarks editor. (It’s the “open book” icon in the Bookmarks Bar.)
The entire group of pages can be opened all at once by clicking-and-holding on the folder in the Bookmarks Bar. When the menu drops down for the folder, choose the last command: “Open in Tabs.” This opens all of the sites bookmarked in the folder in separate tabs in the Safari window. I find that it’s useful to have them all open while I’m traveling to my destination, since that way I can see them even if I can’t get an Internet connection — free Wi-Fi is not always available.
When I’m done with the trip, I can delete the entire folder or just some of the bookmarks it contains. To delete the folder quickly, right-click on its name in the Bookmarks Bar and choose “Delete” from the contextual menu.
I have occasion to write scripts for systems administration, and for years I've stored them in a shared CVS repository.
Lately, however, I've been interested in distributed version control systems (or DVCS). The concept of DVCSes resonates with me — even though I cannot say I totally grok them yet. Of the DVCSes I've read about, Mercurial (aka "Hg") has caught my eye, particularly because it is:
Anyway, just to put it through its paces, I created my first repository, added a script to it, and began managing. It's making sense to me and I'm pleased so far with the results, so I've got more repositories and more files under revision control already. Of course, I've actually revised some of them, so I've seen how changesets operate in real life.
I'm finding it simple to use, especially after having skimmed through the Hg tutorial and scanned some of the Distributed revision control with Mercurial on-line and printable book by Bryan O'Sullivan (who was in a good Google Tech Talk on Mercurial).
Overall, I believe that systems administrators — even those who focus on client systems — should become familiar with version control and be able to employ it for any scripts they write as well as configuration files they manage. It just makes sense to me, and after a day with Mercurial, I'm finding that it works well me.
The Sabres won 5-3 over the the Florida Panthers, but rightly overshadowing that was the Panthers’ Zednik, who suffered a cut to his neck. The serious injury and its aftermath stopped play for about twenty minutes until it was decided to continue the game to its conclusion.
I was only listening to the telecast in catches from the kitchen at that point, but a call from my parents at the game brought us back to the Tivo to see what was happening. The replays were unnerving — as another Florida player's right skate came up into Zednik's neck as he skated into the corner to Miller's left — but thankfully we didn't see much of the blood on the ice. I think my mom said, "It was more blood than I've ever seen." The down-the-ice angle we saw of it on television certainly made it look like a profuse amount.
Richard Zednik skated quickly off the ice holding his neck, looking very, very pale, and was practically caught by trainers at the bench; he looked as if he was on the verge of collapse. I don't know how he made it. They got him out of the bench area and later we were told he had been stabilized and taken to a Buffalo hospital. As of this writing, the postgame show indicated he was in surgery.
The Buffalo fans held a standing ovation when it was announced that Zednik was stable and on the way to the hospital, but up until that, there appeared to be little news in the arena itself. I had tried to let mom know what was going on from the telecast, but I probably called her during this ovation because I had to scrub through video on the Tivo and was still a little behind realtime. I haven't heard from Aaron and Missy yet; they were in the seventh row for today's game, but I don't know what section.
Anyway, the injury was extremely scary and we pray for Zednik's continued safety and recovery.
Well, the AMP Energy NHL Winter Classic game between the Buffalo Sabres and Pittsburgh Penguins is over. The Penguins won their second straight against the Sabres with a 2-1 shootout victory.
Rewinding a bit, the Sabres were doing really well before Christmas, with two really exciting games against Philadelphia and a nice win streak. The icing on the cake was the shootout win when Miller stuffed Briere. As much as I like Danny, hey, I’ll still root for the home team so it was great to see Miller stop that shot.
Now, the up-and-down Sabres have dropped several games straight, including the home-and-home series against Pittsburgh which culminated today in the Winter Classic. They also lost against the New Jersey Devils during this current streak.
The Winter Classic lived up to the billing in at least one sense: the wintry weather. While we’ve had some mild weather in Western New York of late, it did turn cold with some snowfall today. That was sort-of ideal if you want to televise the first outdoor NHL game in the United States, and have an obvious topic for your telecast. It resulted in some interesting camera views of the game, and a lot — I might say too much — of Zamboni work and ice repair. It certainly didn’t help the flow of the game on television.
On the plus side, the game was carried by NBC in high definition. We went over to Aaron and Missy’s house to watch it on their big set and it really does make a difference. (I’m sure it would have been much harder to figure out which was a puck and which was a snowflake here at home. Although my answer that is that the pucks are all the same and the snowflakes are all unique.) I call it ridiculous that Time Warner Rochester doesn’t carry the HD feed of the Sabres games, given that the team is all of an hour away and has been so popular of late.
Also rating up there on the ridiculousity scale:
All in all, it would have been more satisfying if the Sabres had just won. Sigh.
The Apple TV, for all intents and purposes, sounds as if it is an iPod that you put on your home network and connect to your TV. It shows up in the “Devices” list in iTunes.
The Apple TV is based on Mac OS X; that’s how people have done some hacking on it.
So why don’t the iPhone and iPod Touch — software for which is also derived from Mac OS X — have network-based synchronization? Are they merely one flashy keynote address away from having it? And why not have introduced it before the new Zunes came along with that feature?
(Of course, you could ask the same question about other technologies, including Bluetooth A2DP.)
Let’s summarize the week in Apple news so far:
Oh. My. Gosh. I heard about and installed the Taxonomy Manager module for Drupal 5 — which was a just-completed Google Summer of Code 2007 submission — and it is fantastic. It makes managing taxonomy in Drupal so much more fluid. No, it makes taxonomy management possible.
It’s not perfect, and there are little visual oddities in the version I installed, but Taxonomy Manager is so much better than the normal user interface for taxonomy in Drupal core that I can’t see using anything else now. I’ve been spoiled.
Hearing about stuff like this — even if it’s nearly a throwaway comment by Angie Byron, almost lost in all the other voices on episode 48 — is exactly why I listen to the Lullabot Drupal Podcast. Thank you.
Oh, and sometime, I will look into free tagging. Gotta do that. Love it on del.icio.us.