Installing Foreman on Archlinux
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?
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:
git clone --recursive https://github.com/GregSutcliffe/foreman -b193
We also need bundler:
yaourt -S ruby-bundler
Now we set up run-time dependencies:
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:
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:
git clone https://github.com/theforeman/smart-proxy.git foreman-proxy
Now to fix up the proxy…
yaourt -S ruby-sinatra sudo
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
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
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.