AutomateIt screenshotsAutomateIt is an open source tool for automating the setup and maintenance of servers, applications and their dependencies. The screenshots below will show how to use AutomateIt to setup a Ruby on Rails application server on Linux. AutomateIt can also be used to fully automate entire systems and works well with a variety of OSes, frameworks and tools. The code in these screens is self-documenting and the accompanying text is deliberately brief. Please read the Tutorial for further information. You will need to install AutomateIt to run these examples. Let’s see some code!ProjectCreate a project, this will make a root@kagami> automateit --create demo Change into this new directory with TagsDescribe hosts and their roles in the project’s rails_servers: - kagami - tsukasa myapp_servers: - kagami FieldsDefine configuration constants in the project’s user: myapp_user
port: 9826
path: /tmp/myapp_server
Installer recipeWrite a recipe to set up a Rails application server, saving it as # Install dependencies on hosts with 'rails_servers' or 'myapp_servers' roles if tagged?("rails_servers | myapp_servers") # Install platform-specific packages if tagged?("ubuntu | debian") # Install the 'build-essential' package and others on Ubuntu or Debian package_manager.install("build-essential", "ruby1.8-dev", "libsqlite3-dev") elsif tagged?("fedoracore | fedora | centos") # Install equivalent packages on Fedora and similar OSes package_manager.install("gcc", "ruby-devel", "sqlite-devel") else # Fail if running on another platform raise NotImplementedError.new("no packages specified for this platform") end # Install Rails and supporting libraries with RubyGems package_manager.install("rails", "sqlite3-ruby", "mongrel", :with => :gem, :docs => false) end # ENDS: if tagged?("rails_servers | myapp_servers") # Setup the myapp server, a simple Rails server instance if tagged?(:myapp_servers) # Create user for the application account_manager.add_user(lookup(:user)) # Create a directory for the application and 'cd' into it mkdir_p(lookup(:path)) do # Run shell commands to create the app and database unless File.exists?("config/routes.rb") sh("rails --database=sqlite3 . > /dev/null") end # Create the database if it doesn't exist. if Dir["db/*.sqlite3"].empty? sh("rake db:migrate") end # Edit the homepage edit(:file => "public/index.html") do append("<!-- Edited by AutomateIt -->") replace("Welcome aboard", "This is MyAppServer") end # Set the ownership of the created files chperm(".", :user => lookup(:user), :recurse => true) # Generate a service startup file using a template render( :file => dist+"myapp_server.erb", :to => "/etc/init.d/myapp_server", :mode => 0555, :locals => { :path => lookup(:path), :user => lookup(:user), :port => lookup(:port), } ) # Start the server service_manager.start("myapp_server") end # ENDS: mkdir_p(lookup(:path)) do end # ENDS: if tagged?(:myapp_servers) TemplateCreate a template file to render, #!/usr/bin/env ruby user = "<%=user%>" port = "<%=port%>" path = "<%=path%>" pid = "mongrel.pid" ENV["PATH"] = "%s/bin:%s" % [`gem env gemdir`.strip, ENV["PATH"]] case ARGV.first when "start" Dir.chdir(path) puts "Starting MyAppServer at http://localhost:#{port}/" exit system("PATH=#{ENV["PATH"]} mongrel_rails start " \ "--user #{user} --group #{user} --pid #{pid} --daemonize " \ "--port #{port} 2>&1 | grep -v cgi_multipart_eof_fix") ? 0 : 1 when "stop" Dir.chdir(path) exit system("PATH=#{ENV["PATH"]} mongrel_rails stop " \ "--pid #{pid} 2>&1 | grep -v cgi_multipart_eof_fix") ? 0 : 1 when "status" begin Process.kill(0, File.read(File.join(path, pid)).to_i) exit 0 rescue Errno::ENOENT, Errno::ESRCH exit -1 # File or pid not found end else puts "ERROR: expected argument -- start, stop or status" end Preview and executionPreview the commands this recipe will execute, without actually executing them, by specifying the root@kagami> automateit --preview recipes/install.rb ** apt-get install -y -q ruby1.8-dev libsqlite3-dev < /dev/null 2>&1 ** gem install -y --no-ri --no-rdoc rails sqlite3-ruby mongrel 2>&1 ** useradd --create-home --shell /bin/bash myapp_user > /dev/null ** nscd --invalidate passwd ** mkdir -p /tmp/myapp_server ** pushd /tmp/myapp_server ** rails --database=sqlite3 . > /dev/null ** rake db:migrate => Edited 'public/index.html' ** chown -R myapp_user . => Rendering '/etc/init.d/myapp_server' because of it doesn't exist ** chmod 0555 /etc/init.d/myapp_server ** /etc/init.d/myapp_server start ** popd root@kagami> Run the recipe without the root@kagami> automateit recipes/install.rb ** apt-get install -y -q ruby1.8-dev libsqlite3-dev < /dev/null 2>&1 Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: [...] ** gem install -y --no-ri --no-rdoc rails sqlite3-ruby mongrel 2>&1 Select which gem to install for your platform (i486-linux) 1. mongrel 1.0.1 (mswin32) 2. mongrel 1.0.1 (ruby) 3. mongrel 1.0 (mswin32) 4. mongrel 1.0 (ruby) 5. Skip this gem 6. Cancel installation >=> Guessing: 2 [...] ** useradd --create-home --shell /bin/bash myapp_user > /dev/null ** nscd --invalidate passwd ** mkdir -p /tmp/myapp_server ** pushd /tmp/myapp_server ** rails --database=sqlite3 . > /dev/null ** rake db:migrate [...] => Edited 'public/index.html' ** chown -R myapp_user . => Rendering '/etc/init.d/myapp_server' because of it doesn't exist ** chmod 0555 /etc/init.d/myapp_server ** /etc/init.d/myapp_server start Starting MyAppServer at http://localhost:9826/ ** popd root@kagami> Run the recipe again — it will detect that everything is as it should be and won’t do anything: root@kagami> automateit recipes/install.rb root@kagami> Now stop the Rails server manually and re-run the recipe — it will figure out that the server isn’t running and start it: root@kagami> /etc/init.d/myapp_server stop Sending TERM to Mongrel at PID 32419...Done. root@kagami> automateit recipes/install.rb ** pushd /tmp/myapp_server ** /etc/init.d/myapp_server start Starting MyAppServer at http://localhost:9826/ ** popd root@kagami> Uninstaller recipeYou can uninstall the Rails server with this recipe, save it as if tagged? :myapp_servers service_manager.stop "myapp_server" rm "/etc/init.d/myapp_server" rm_rf lookup(:path) account_manager.remove_user lookup(:user) end Run the uninstaller: root@kagami> automateit recipes/uninstall.rb ** "/etc/init.d/myapp_server" "stop" Sending TERM to Mongrel at PID 29149...Done. ** rm /etc/init.d/myapp_server ** rm_rf /tmp/myapp_server ** userdel -r myapp_user ** nscd --invalidate passwd root@kagami> Re-run the uninstaller — it’ll detect that the files are gone and the server is stopped, and so it won’t do anything: root@kagami> automateit recipes/uninstall.rb root@kagami> EmbeddingAutomateIt can be easily embedded into other programs. For example, put the following require "automateit" # Create an Interpreter for project in current directory. @interpreter = AutomateIt.new(:project => ".") # Include Interpreter's 'invoke' and 'preview' methods into Rake. @interpreter.include_in(self, %w(invoke preview)) desc "Install myapp server" task :install do # The 'invoke' method was created by the 'include_in' call earlier, # as a convenient shortcut for: @interpreter.invoke("install") invoke "install" end desc "Uninstall myapp server" task :uninstall do invoke "uninstall" end desc "Preview action, e.g, 'rake preview install'" task :preview do preview true end Learn moreAutomateIt can do much more than this simple example shows. For more information, see the hands-on Tutorial and reference Documentation. |
Copyright © 2007-2009 Igal Koshevoy. Legal.