Last Updated: February 25, 2016
·
1.227K
· sawanoboly

Continuous convergence with the chef-solo on the joyent smartmachine and meta-data API.

Create cookbook for applications.

  1. write recipes.
  2. create role as appname which contains runlist for recipes.

Provision smartmachine with meta-data following.

  • user-script: Add cron job which fetch repository and execute chef-solo cyclically.
  • use-data: Json data for chef-solo to force override attributes. This is usually empty json like "{}".
  • app_repo: Git repository uri.
  • app_name: Role name to be passed to the Chef-solo.

The user-script works 3 steps.

  1. fetch and update user-script and user-data.
  2. initialize or update cookbooks from the git repository.
  3. execute the chef-solo with the role named by app_name.

User-Script example.

Gist

#!/usr/bin/bash

set appname and apprepo to metadata when provisioning.

set -e
set -x

export PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/usr/sbin

MDATAWRAPPER=001
MDATAUSERSCRIPT=/var/svc/mdata-user-script
MDATAUSERDATA=/var/svc/mdata-user-data
CHEFREPOS=/usr/local/user-application

add mdata-wapper script to cron

Notice: this block must keep on top to retry fetch cyclically.

if ! exists /opt/local/sbin/mdatawrapper${MDATAWRAPPER}.sh ; then
  cat <<"EOL" > /opt/local/sbin/mdatawrapper${MDATAWRAPPER}.sh

!/usr/bin/bash

export PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/usr/sbin
sleep expr $$ % 60
svcadm restart mdata:fetch
if svcs mdata:fetch | grep -q maintenance  ; then svcadm clear mdata:fetch ;fi
sleep 2
svcadm restart mdata:execute
if svcs mdata:execute | grep -q maintenance  ; then svcadm clear mdata:execute ;fi
EOL

chmod u+x /opt/local/sbin/mdatawrapper${MDATAWRAPPER}.sh
  ln -fs /opt/local/sbin/mdatawrapper${MDATAWRAPPER}.sh /opt/local/sbin/mdata_wrapper.sh
fi

if ! grep -q -x "## user-application" /var/spool/cron/crontabs/root
then
  cat << "EOL" >> /var/spool/cron/crontabs/root

user-application

0,10,20,30,40,50 * * * * /opt/local/sbin/mdata_wrapper.sh
EOL
svcadm restart cron
fi

install chef-solo

if [ ! -f /opt/local/bin/chef-solo ] ; then

pkgin -y install gcc47 scmgit-base gmake ruby193-base ruby193-yajl ruby193-nokogiri ruby193-readline pkg-config

for smf cookbook

pkgin -y install libxslt

install chef

gem update --system
  gem install --no-ri --no-rdoc bundler
  gem install --no-ri --no-rdoc ohai
  gem install --no-ri --no-rdoc json
  gem install --no-ri --no-rdoc chef
  gem install --no-ri --no-rdoc rb-readline
fi

get attribute from metadata-api

mdatacheck(){
  if ! mdata-get $1 ; then echo "ERROR_EXIT: missing metadata $1" ; exit 1 ; fi
  export $2="mdata-get $1"
}

mdatacheck appname APPNAME
mdatacheck apprepo APPREPO

clone or pull application repositoly to local

if [ ! -d ${CHEFREPOS} ] ; then
  git clone ${APPREPO} ${CHEFREPOS}
else
  cd ${CHEFREPOS}
  git pull
fi

execute chef-solo

chef-solo -j ${MDATAUSERDATA} -c ${CHEFREPOS}/solo.rb -o "role[${APP_NAME}]"</code></pre>

Modifications to the repository is automatically reflected in the machine.