Running Clojure on OpenShift Origin

Over the weekend I've been playing with OpenShift Origin which is a collection of open source components that are used in the OpenShift Platform as a Service. Since they have a live CD I thought, I'll install it in VM assign a IP and start playing with it however all the docs on OpenShift's website assumes you will be running Origin on your LAN (at least thats the impression I got) so they omit couple of crucial points, such as changing the password for the admin account thats created during the installation or adding new users. If you are only interested in deploying Clojure to open OpenShift skip to Deploying a Clojure Application.

Deploying OpenShift

Mount/Insert ISO, boot the system open a terminal and start installation,

su
liveinst

Once installed login via SSH and disable graphical boot,

rm /etc/systemd/system/default.target
ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target

Disable Ruby updates,

sudo sed -i -e '/gpgkey=/aexclude=ruby ruby-devel ruby-irb ruby-libs ruby-rdoc' \
    /etc/yum.repos.d/fedora-updates.repo

Disable OpenShift live setup,

chkconfig --del livesys
chkconfig --del livesys-late
chkconfig --del livesys-late-openshift

Turn on OpenShift services,

chkconfig httpd on
service httpd start
chkconfig stickshift-broker on
service stickshift-broker start

Make sure hosts hostname is broker.example.com otherwise it won't work.

Here comes the annoying part that took me couple of hours to figure out, changing the admin password. You need to grab the salt from,

/var/www/stickshift/broker/config/environments/plugin-config/swingshift-mongo-plugin.rb

And calculate a hash just like mongoauthservice.rb calculates for your password using the following ruby snippet,

require 'digest/md5'

digest = Digest::MD5.hexdigest(Digest::MD5.hexdigest("super_secret_pass") + "salt")
puts digest

then run the following command replacing the hash with the hash generated.

mongo stickshift_broker_dev --eval 'db.auth_user.update({"_id":"admin"}, {"_id":"admin","user":"admin","password":"hash"}, true)'

Once that is done you can add new users by using,

ss-register-user

Deploying a Clojure Application

Create a Clojure webapp with the following snippets,

(defproject hello "0.1.0-SNAPSHOT"
  :plugins [[lein-ring "0.7.5"]]
  :dependencies [[org.clojure/clojure "1.3.0"]
                 [noir "1.2.2"]]
  :ring {:handler hello.core/handler})
(ns hello.core
  (:use noir.core hiccup.core)
  (:require [noir.server :as server]))

(defpage "/" []
  "Hey There!")

(def handler (server/gen-handler {:mode :dev
                                  :ns 'hello.core}))

Generate a war,

lein ring uberwar

Create ~/.openshift/express.conf with the following content,

default_rhlogin=admin
libra_server=openshift-server-ip

Create a domain for the application,

rhc domain create -n cloud

Create a jbossas-7 application (you can call your application whatever you want),

rhc app create -a hello -t jbossas-7

Wait for it to timeout (DNS won't resolve hello-cloud.example.com). Add,

openshift-server-ip     hello-cloud.example.com

to /etc/hosts and copy your ssh key.

rhc sshkey add -k ~/.ssh/id_rsa.pub -i nakkaya

Now you can clone the repo using the given URL. Remove files left over from the sample application,

git rm -rf pom.xml src/

Publish your application as ROOT.war into deployments folder making it take up the base URL (/).

cp hello-0.1.0-SNAPSHOT-standalone.war /hello/deployments/ROOT.war

Add an alias so other people can see the content,

rhc app add-alias -a hello --alias "domain.com"

If you restart the host for any reason OpenShift won't start the application you need to do it manually,

rhc app start -a hello