Ruby / Rails Continuous Integration w/ Cerberus + Git + SSH + OSX + ruby-switcher

datePosted on 16:31, June 15th, 2009 by Peter Fitzgibbons

I recently completed configuration of continuous-integration between two servers.

Here’s the steps and notes that I have for the move.

System Layout

The system of servers/services comes together like this :

Git / Redmine

Git and Redmine run on server ‘redmine-server’, which is a CentOS 5 Intel box.  OpenSSH is installed, Redmine runs on Ruby 1.8.7, yum package install.
User on this server is ‘git’

Cerberus continuous integration

Cerberus runs on an OSX box named ‘ci-server’, Leopard.
Ruby on this box is installed using ruby-switcher, with 1.8.7p173 and 1.9.1p129r23412.
My customization of that ruby-switcher is here ruby_switcher.sh.
User on this server is ‘cerberus’

SSH setup Git -> Cerberus

The Git repository lives on a different server, so SSH is employed to protect passwords-cleartext over the wire.

There is an additional constraint in that Git hooks are “non-interactive”, so ssh keys must be configured to not challenge.  There are [security implications] to this.  The option I have chosen is passwordless “backup keys” for specific purposes.

git@redmine-server $ ssh-keygen -t rsa -C git_ci_server@redmine_server
Generating public/private rsa key pair.
Enter file in which to save the key (/home/git/.ssh/id_rsa): \
  .ssh/id_rsa_git_ci_server
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in .ssh/id_rsa_git_ci_server.
Your public key has been saved in .ssh/id_rsa_git_ci_server.pub.
The key fingerprint is:
42:62:16:4c:00:74:7c:a9:96:90:5a:75:5d:08:c5:f9 git_ci_server@redmine_server

Move the key to the target server ci-server

[git@redmine-server]$ scp .ssh/id_rsa_git_ci_server.pub \
  cerberus@ci-server:id_rsa_git_ci_server.redmine-server
Password:
id_rsa_git_ci_server.pub                     100%  410     0.4KB/s   00:00
[git@redmine-server]$ ssh deployer@web-ci
Password:
Last login: Mon Jun 15 09:20:00 2009 from redmine-server

[cerberus@ci-server]$ cat id_rsa_git_ci_server.redmine-server
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtOVHRlhLmUI/9XglQs6u9F1reUwAq2U0clJI2l
j5kAX5XkVW7FoiiGo4BfAqP3j69ynMBnLx/eUtcYcxHUKZfikwQbXnUdAUd8mIXoNhOfVZ/gqr
i0yS0XHpkGU2lJve3soqEIyYu2gxf5QPP18ibJeyFZ5QRTPUATfi1c6Pb12tsr4O9H+b5T08cU
ejvQP5ISyYH3ysPZwLQ3d1Ods9ZItm7h9/eoZQxgXpVLxUkQ3NO+JoktKlruGajTRgm5xP7NBd
gUZsC2vs84/mW64RWSzbl8fA5oKUhKQIDt7QSOGx2UVGYAoarFGTsvps5g9WnXTJ37XRT+ORHI
cpmO90mQ== git_ci_server@redmine_server
[cerberus@ci-server]$ cat id_rsa_git_ci_server.redmine-server >> .ssh/authorized_keys
[cerberus@ci-server]$ exit

SSH Backup-Key

From ‘man ssh’ :

 -i identity_file
    Selects a file from which the identity (private key) for RSA or DSA authentication is read.  The default is
    ~/.ssh/identity for protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for protocol version 2.  Identity files
    may also be specified on a per-host basis in the configuration file.  It is possible to have multiple -i options
    (and multiple identities specified in configuration files).

This Git server does not have ssh-agent running, so using -i will cause the indicated file to be the only identity used in the ssh session.

Now test the login using the backup-key switch of ’ssh’

[git@redmine-server]$ ssh -i .ssh/id_rsa_git_ci_server cerberus@ci-server
Last login: Mon Jun 15 10:53:38 2009 from redmine-server
[cerberus@ci-server]$

The backup-key switch will be used in the Git post-receive hook for executing Cerberus build upon Git Push

Git Post-Receive

Simple.  Use ssh to call a build script on ci-server, which we’ll build after the break…

#!/bin/sh
#
# An example hook script for the post-receive event
#
# This script is run after receive-pack has accepted a pack and the
# repository has been updated.  It is passed arguments in through stdin
# in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
# see contrib/hooks/ for an sample, or uncomment the next line (on debian)
#

ssh -i ~/.ssh/id_rsa_git_ci_server cerberus@ci-server \
 bin/cerberus-build racc-webapp

NOTE: the use of the -i switch

This hook is applied to each repository that will be monitored by Cerberus Continuous Integration.  It must be made executable so Git will execute it!

[git@redmine-server]$ cp post-receieve repos/my_app/.git/hooks/post-receive
[git@redmine-server]$ chmod +x repos/my_app/.git/hooks/post-receive

Cerberus configuration

Using the ruby-switcher, install the ruby of your choice (’install_ruby_187p173′).  The use it (’use_ruby_187′).

Install cerberus gem (note we are using local gem storage to accomodate ruby-switcher):

[cerberus@ci-server]$ gem install cerberus

Configure cerberus globals, especially email server config (for SMTP send).

I also configured the builder/rake to handle new migrations (Rails 2.3) and Rspec (rake spec)

[cerberus@ci-server]$ cat .cerberus/config.yml
publisher:
#  active: mail jabber rss campfire
  mail:
    address: smtp.test.com
    port: 25
    domain: test.com
    authentication: :none
    sender: Cerberus CI <cerberus@test.com>
#    address: smtp.gmail.com
#    port: 587
#    domain: gmail.com
#    authentication: plain
#    user_name: someuser
#    password: somepassword
#    on_event: all
#  jabber:
#    jid: somemailbox@gmail.com/cerberus
#    password: somepassword
#  twitter:
#    login: twitter_username
#    password: twitter_password
#  irc:
#    nick: cerb
#    server: irc.freenode.net
#    channel: cerberus
#  campfire:
#    url: http://someemail:password@cerberustool.campfirenow.com/room/51660
#  rss:
#    file: /usr/www/rss.xml
builder:
  rake:
    task: db:migrate spec
#changeset_url: POINT_TO_YOUR_TRAC/changeset/
#hook:
#  rcov:
#    on_event: successful, setup #by default - run hook for any state
#    action: 'export CERBERUS_HOME=/home/anatol && sudo chown www-data -R /home/anatol/cerberus && rcov' #Add here any hook you want

Configure the cerberus project. Note how the config points back to the repository

[cerberus@ci-server]$ cerberus add git@redmine-server:my_app/.git \
  APPLICATION_NAME=my-app SCM=git

Edit the configuration of the project to add project-level mailing addresses.  The BUILD WILL FAIL WITHOUT THIS!!!

[cerberus@ci-server]$ cat .cerberus/config/my-app.yml
---
publisher:
  mail:
    recipients: someuser@test.com
scm:
  url: git@redmine-server:repos/my_app/.git
  type: git

An initial build ‘cerberus build my-app’ is required to set the sources.  This one will likely fail, as it is necessary to configure non-SCM files like ‘database.yml’.

You should receive email from “Cerberus CI” declaring your failure.

You have completed config.  Now FIX YOUR BROKEN CHECKIN FTW!!

categoryPosted in Uncategorized
Related Posts:

Leave a Reply

Name: (required)
Email: (required) (will not be published)
Website:
Comment: