So as many of you know, I use Archlinux on a lot of my hardware - but you’ll have noticed that I always use Debian for my Foreman servers. What gives?

The Problem with Versions

Archlinux presents two major problems to Foreman. Firstly, the current version of Puppet in the AUR is 3.0.1. Admitedly, I made that problem for myself, since the AUR PKGBUILD of Puppet is owned by me… However, Arch is all about latest-and-greatest so it’s the right thing to do for Puppet.

Fortunately, the latest development code of Foreman supports Puppet 3, so we’re ready to go right?

No.

See, Arch also packages the latest and greatest Ruby as well (1.9.3p327). Foreman cannot (yet) deal with Ruby 1.9. So, we’re dead in the water. Or are we?

Community to the Rescue!

There is a pull request from the excellent user @witlessbirdproviding support for Ruby 1.9.3. It’s messy, as many of the problems stem from the gems we depend upon not being 1.9 compatible, but he’s forked them all and updated our Gemfile to point as his forks. So in theory it all works. He’s awesome :)

So I decided to set up Foreman on Arch. Just to see if it runs ;)

Getting Down and Dirty

So here we go. I’ll assume you have a freshly installed Archlinux box (assuming you’re playing along at home). I’ll also assume the ever-popular AUR helper ‘yaourt’ is installed, and with that you’ve installed Puppet 3.

Lets start by cloning the source. There’s no packages for Foreman on Arch yet, and we need to apply some 1.9 fixes anyway.  @witlessbird’s changes required some merge conflicts, so I’ve forked his repo so I could rebase the changes against. Get it this way:

cd /usr/share
git clone --recursive https://github.com/GregSutcliffe/foreman -b193

We also need bundler:

yaourt -S ruby-bundler

Now we set up run-time dependencies:

cd foreman
cp config/settings.yaml.example config/settings.yaml
cp config/database.yml.example config/database.yml
echo ":puppetconfdir: /etc/puppet" >> config/settings.yaml
yaourt -S libxml2 libxslt libmysqlclient postgresql-libs libvirt

Get the gems:

bundle install --path vendor/

Set up the db

bundle exec rake db:migrate

Start the server

bundle exec rails s

And lo! Foreman starts on port 3000. Wonderful. But we’re not done being awesome yet.

Enter the (e)ngin(e)

A better webserver needs to be added, since Webrick sucks. I decided to give Nginx a try. Nginx has the downside that modules have to be compiled in, but on Arch, Passenger has already been compiled in. So we just install it:

yaourt -S passenger nginx

In nginx.conf we have a basic passenger definition:

http {
passenger_root /usr/lib/passenger;
passenger_ruby /usr/bin/ruby;

server {
listen 80;
server_name topaz.elysium.emeraldreverie.org;
root /usr/share/foreman/public;
passenger_enabled on;
rails_env production;
}
}

So now we can start Nginx

systemctl start nginx
systemctl enable nginx

Yay! Foreman on port 80. Win!

Proxies, proxies, everywhere!

Of course, we’ll also need a foreman-proxy to manage puppet for us. We could just use my new foreman-proxy-git AUR package. But where’s the fun in that? Much more fun to run it in Nginx with Foreman! Lets clone the code:

cd /usr/share
git clone https://github.com/theforeman/smart-proxy.git foreman-proxy

Now to fix up the proxy…

yaourt -S ruby-sinatra sudo
server {
listen 8443;
server_name foreman-proxy;
root /usr/share/foreman-proxy/public;
passenger_enabled on;
rails_env production;
}

Of course, we still need to replicate a lot of what the installer would do on other distros:

echo -e "foreman-proxy ALL = NOPASSWD : /usr/bin/puppet
Defaults:foreman-proxy !requiretty" >> /etc/sudoers.d/foreman-proxy
groupadd -r foreman-proxy
useradd -r -g foreman-proxy -d /usr/share/foreman-proxy -s /sbin/nologin -c "Foreman Proxy deamon user" foreman-proxy
chown -R /usr/share/foreman-proxy

There are a few necessary gems for the foreman-proxy user as well:

su - foreman-proxy -s /bin/bash
gem install sinatra net-ping
exit

That’s it! Restart nginx to pick up the config, and try hitting the proxy for a request:

wget -q -O - http://localhost:8443/features

Final notes

Finally, a small dependency bug I discovered - Foreman requires Python to display the noVNC libvirt console. So we also need to do:

yaourt -S python

That’s it! However, just for fun, I decided to set Foreman up running on PostgreSQL 9.2, just for extra bleeding-edge-ness. I leave it as an excerise to the reader to do this, as it’s fairly standard database setup - Foreman has support Psql for quite a while.

Enjoy!