Say hello to the OpenBlog project!

Yes! I've decided to put together a minimalistic Drupal 7 distro for blogging, OpenBlog! There are some awesome people working on it with me (shrop and thomas) and lots of great ideas going around.

There should be a release later this week after I implement a few more things.

Check out the OpenBlog project page and follow us on the twitter!

Installing postgres on OSX Lion with homebrew

1) Update homebrew and install it:

brew update
brew install postgresql

2) Create the postgres database

initdb /usr/local/var/postgres

3) Setup postgres to run on boot

cp /usr/local/Cellar/postgresql/9.1.3/homebrew.mxcl.postgresql.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

That's it. You can now use createuser and createdb to setup your database.

Some fun unix commands

Cleaning up old Aegir backups

If you use the Backup Scheduler built into Aegir you've already figured out that it's weird to configure and can start to eat up a lot of disk space if you have an agressive backup scheme or a lot of Drupal instances. We had about 40 or so when I noticed that our disk space started to resemble a J curve:

At the max we were using about 400GB of drive space in the backup directory. This amount of disk usage isn't going to be sustainable when there is 400 instances running on this box. So I needed to delete the tar archives of the backups that are older than 10 days.

find /var/aegir/backups -type f -mtime +10 -delete

Find has some awesome option like -mtime where you can tell find to only return files that are 10 days old. You can also use the -delete option instead of using -exec rm -rf {} \;. I feel safer using the -delete instead of -exec. So this command runs in an aegir job every day and we don't fill up our /var/aegir/backup disk.

Running drush cron on lots of sites at once

I use MAMP for local development and I tend to use Drush a lot when building sites. I needed a way to run drupal cron on all of my development instances without having to create a Jenkins job for each. With find you can use the -type option to tell find to only find specific types of files. I'm using d to tell find to only return directories. There are plenty of other options for finding files, symlinks, sockets, etc. I'm also using $() to substitute the output of the find command into the for. You can use the $() or ```` (backticks) to do this.

#!/bin/bash

DRUSH=/usr/local/bin/drush
PROJECTS=$HOME/projects/dev

for d in $(find $PROJECTS -type d -depth 1)
do
  if [ -f $d/sites/default/settings.php ]; then
    $DRUSH -r $d cron
  fi
done

I have a Jenkins job that runs this script periodically.

Create files with simular filenames but different extensions

When you're building modules or themes for Drupal you need start out by creating your info, module, install, or whatever other files you need that all have be simularly named. You can use {} to do this with touch:

zach@brains /tmp » mkdir module_name
zach@brains /tmp » touch module_name/module_name.{info,module,install}
zach@brains /tmp » ls -alh module_name 
total 0
drwxr-xr-x   5 zach  wheel   170B May  3 17:34 .
drwxrwxrwt  15 root  wheel   510B May  3 17:33 ..
-rw-r--r--   1 zach  wheel     0B May  3 17:34 module_name.info
-rw-r--r--   1 zach  wheel     0B May  3 17:34 module_name.install
-rw-r--r--   1 zach  wheel     0B May  3 17:34 module_name.module

This works with a few other commands. It doesn't play well with cp, but that's okay. We have regular expressions for cp.

Setting up aegir to host shibbolized drupal instances

We've spent the last few days working on getting Shibboleth authentication working with our Aegir hosted Drupal instances. It's turned out to be not that difficult to implement.

First add the Shibboloth authentication module to your platform.

Next, create a file called shib.conf in config/server_master/apache/pre.d and add this to it:

<Location />
  AuthType Shibboleth
  ShibRequireSession Off
  # the following single line is only valid for Shib2
  ShibUseHeaders On
  require shibboleth
</Location>

<LocationMatch /Shibboleth.sso(/*)>
  AuthType shibboleth
  ShibRequireSession On
  ShibUseHeaders On
  require valid-user
</LocationMatch>

Restart apache, enable and configure the module in every site you want to use Shibboleth on, and there you go. Every site has the capability to use Shibboleth along with the normal user model. You can add extra Locations to force the user to authentication to the site.

You can also add other config options in this folder. Learn more about Aegir's apache config by doing this:

$ more /var/aegir/config/server_master/apache.conf

Forcing Jenkins jobs that fail to be considered a success

So apparently my drupal-cron job in our Jenkins instance has been failing for around 5 days now, whatever. It's not doing anything it shouldn't, drush is just failing when it can't find a valid site. It really shouldn't be a failure, but Jenkins doesn't know that.

Jenkins decides on success/failure based on the exit code left by the last command ran. So if something ends with an exit 1 it will mark it as a failure, on the other hand if it ends with an exit 0 Jenkins will say that the job is a success.

So how do you fix this problem? Tell Jenkins that the script finished with a exit 0, duh. I went from this:

#!/bin/bash
DRUSH=/usr/local/bin/drush

for d in $(find $HOME/projects/dev -type d -depth 1)
do
  $DRUSH -r $d cron
done

The job's output is something like this:

Command core-cron needs a higher bootstrap level to run - you will       [error]
need invoke drush from a more functional Drupal environment to run
this command.
The drush command 'cron' could not be executed.                          [error]
The directory /Users/zach/projects/dev/mustache.appstate.edu does not    [error]
contain a valid Drupal installation
Cron run successfully.                                                 [success]
Cron run successfully.                                                 [success]
Command core-cron needs a higher bootstrap level to run - you will       [error]
need invoke drush from a more functional Drupal environment to run
this command.
The drush command 'cron' could not be executed.                          [error]
The directory /Users/zach/projects/dev/weathercams does not contain a    [error]
valid Drupal installation
Build step 'Execute shell' marked build as failure
Finished: FAILURE

If you add the exit 0 to the script and make it look like this: #!/bin/bash DRUSH=/usr/local/bin/drush

for d in $(find $HOME/projects/dev -type d -depth 1)
do
  $DRUSH -r $d cron
done
exit 0

Things look a bit better:

Command core-cron needs a higher bootstrap level to run - you will       [error]
need invoke drush from a more functional Drupal environment to run
this command.
The drush command 'cron' could not be executed.                          [error]
The directory /Users/zach/projects/dev/mustache.appstate.edu does not    [error]
contain a valid Drupal installation
Cron run successfully.                                                 [success]
Cron run successfully.                                                 [success]
Command core-cron needs a higher bootstrap level to run - you will       [error]
need invoke drush from a more functional Drupal environment to run
this command.
The drush command 'cron' could not be executed.                          [error]
The directory /Users/zach/projects/dev/weathercams does not contain a    [error]
valid Drupal installation
Finished: SUCCESS