A Series of Dependencies • Rails v2.2.2, v1.2.3, etc • Ruby/Ruby Enterprise • Apache/Nginx • Passenger/Thin/Mongrel • MySQL/PostgreSQL • system user Thursday, January 15, 2009
A Series of Dependencies • rmagick • libmagick10 libmagick9-dev • thinking-sphinx • compile by hand • memcached • libmemcached, rubygem, service Thursday, January 15, 2009
Answer some questions • application name • git repo • branch to deploy from • user to create • generates SSH key for git host • server ‘tags’ Thursday, January 15, 2009
Moonshine goes to work • clones your repo • parses and executes generated moonshine manifests • installs needed gems • install dependencies • migrates your db • deploys your app Thursday, January 15, 2009
Gem Dependencies gem_dependencies do |gem| #lots of dependencies are specified for you already #gem.packages 'mysql', %w(mysql‐dev libmysqlclient5‐dev) #gem.packages 'rmagick', %w(ruby‐dev libmagick9‐dev) #... #can specify a mini‐manifest to satisfy before #installation of this gem gem.custom 'urgem' do |puppet| puppet.file '/file/needed/by/ur/gem', :ensure => 'present', :content => 'foo' build_tarball('http://whatever.com/lib‐something.tgz') end end Thursday, January 15, 2009
On subsequent runs • updates your repo • parses and executes updated moonshine manifests • verifies needed gems • verifies dependencies • migrates your db • deploys your app Thursday, January 15, 2009
• Reproducible • Verified from top-bottom on each deploy • Versionable with your application • same commit can contain, for example, thinking sphinx and installation of the sphinx searchd daemon • DRY Deployment is now... Thursday, January 15, 2009
But Ruby class MysqlMain < Moonshine::Manifest puppet.file '/etc/my.cnf', :ensure => 'present', :content => ArbitraryKlass.arbitrary_function('foo') end Thursday, January 15, 2009
Modular UrClass < Moonshine::Manifest::Rails < Moonshine::Manifest •easy to create your own reusable server manifests •extend existing ones with modules Thursday, January 15, 2009
Sample ‘plugin’ module MoonshineOrderedPackages def packages(array_or_name, params = {}) package_array = array_or_name.to_a params = { :ensure => 'installed' }.merge(params) package_array.each_with_index do |name,index| #ensure packages are installed in order given package_params = params if package_array[index+1] package_params.merge({ :before => package(package_array[index+1]) }) end puppet.package name.to_s, package_params end end end Moonshine::Manifest::Rails.send(:extend, MoonshineOrderedPackages) Thursday, January 15, 2009