Automating Drupal cron with OS X’s launchd

Found this great post on Configuring cron on Mac OS X Server 10.5.x in the Drupal documentation. I’d been wanting to do that with my original post on Building a Drupal Multi-Site development environment, but I hadn’t had time to figure it out.

The title of the page at Drupal says “Mac OS X Server“, but there’s nothing that says you can’t use this technique on OS X Client, and I believe it will work on everything 10.4.x and up.

So I’m going to show you how to tie it into the Multi-Site setup I created on my local machine for the previous blog post.  If you haven’t read that post, you might want to do so, because some of what we’re going to do here is specific to that installation.

Again, we’ll be using the Terminal a lot for this to make sure that everyone can play, with no special software necessary.

Step 1: Remove the crontab Installation

The first thing I’m going to do is remove the information that I put into the crontab previously. Obviously, if you did not follow the procedure for creating a crontab file described in Step 10 for building a Drupal Multi-Site development environment, then this step is not necessary.

The user crontab files are located in /var/cron/tabs/. The first thing you need to do is make sure that the cronall statement that we put in earlier is the only thing in the file. In your Terminal application do the following:

$ sudo cat /var/cron/tabs/www

If the only thing you see is the statement to execute http://drupal6.local/cronall.php, then it is safe to just delete this file.

$ sudo rm /var/cron/tabs/www

We’ll need to stop and start the cron process in order for our changes to take effect. You can either restart your computer, or a better way is to just use Activity Monitor to quit the cron process.

  • Open Finder and navigate into your Applications > Utilities folder
  • Launch the Activity Monitor
  • Select Administrator Processes in the pulldown at the top
  • In the Filter box at the top, type “cron
  • Highlight the process and select Quit Process at the top
  • You should see the process go away, and come right back again with a new Process ID

If you saw additional commands in the file when you executed the cat command, then it’s probably best just to edit the crontab file and remove the lines related to Drupal. If you need to do that then do the following:

$ export EDITOR=nano
$ sudo crontab -u www -e

Remove the line containing http://drupal6.local/cronall.php.

Step 2: Create a plist file

Again, we’re basically following the recommendations found in Configuring cron on Mac OS X Server 10.5.x, so if you want to tweek this installation, please read that article. Now we need to create a launchd daemon .plist file. We’ll call this file drupal6.local-cronall.plist, and place it in /Library/LaunchDaemons/. Open your Terminal application and do the following:

$ cd /Library/LaunchDaemons
$ sudo nano drupal6.local-cronall.plist

Enter the following into the file:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
         "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
  <dict> 
    <key>Label</key> 
      <string>drupal6.local-cronall</string> 
    <key>UserName</key> 
      <string>nobody</string> 
    <key>GroupName</key> 
      <string>www</string> 
    <key>ProgramArguments</key> 
      <array> 
        <string>/usr/bin/curl</string>
        <string>-s</string> 
        <string>http://drupal6.local/cronall.php</string> 
      </array> 
    <key>RunAtLoad</key>
      <true/> 
    <key>StartInterval</key> 
      <integer>3600</integer> 
  </dict>
</plist>

Save the file.

Important!!! Note that we changed the GroupName from _www as described in the documentation to simply www. Not sure if this is a variation between the OS X Server and the Client version, or it could be a difference between 10.4 and 10.5+. In any case, for me on 10.4.x Client, it wouldn’t work until I got this value correct.

As you can see, we’ve used the StartInterval approach described in the article. I think this approach is more appropriate for our development environment, because it won’t care if you laptop or desktop is asleep at a specific time.

Step 3: Start the process

Ok, so now let’s load the agent into launchd.

$ sudo launchtl load /Library/LaunchDaemons/drupal6.local-cronall.plist

When I ran this, I got an error about “Workaround Bonjour: ….“, but the script seems to be executing ok, so I think you can ignore it.

Now let’s do a little testing.

Step 4: Testing

There are a couple of ways to test out what we’ve just done. The main thing is to open the Drupal status report (http://drupal6.local/admin/reports/status), and check how long it’s been since your cronall process ran. If you want to alter the interval while testing, change StartInterval. I used 120 to make the process run every 2 minutes. To get your changes to take effect, do the following:

$ sudo launchtl unload /Library/LaunchDaemons/drupal6.local-cronall.plist

This is important, you don’t want to alter things in the .plist file until you unload it, or you’ll lose access to the service. Now change the value of StartInterval:

$ sudo nano /Library/LaunchDaemons/drupal6.local-cronall.plist

And then restart the service:

$ sudo launchtl load /Library/LaunchDaemons/drupal6.local-cronall.plist

Just make sure that you reset the StartInterval to something like 3600 (1 hr), so that your computer isn’t constantly banging on your network connection.

That’s it for this article. I hope you’ve found it useful. If you got into this article from Step 10 of Building a Drupal development environment for Mac, then continue back to that article at Step 11.

3 comments

Leave a Reply

Your email address will not be published. Required fields are marked *