lib/jamie.rb in jamie-0.1.0.alpha12 vs lib/jamie.rb in jamie-0.1.0.alpha13

- old
+ new

@@ -553,10 +553,63 @@ def test_root DEFAULT_TEST_ROOT end end + # Stateless utility methods used in different contexts. Essentially a mini + # PassiveSupport library. + module Util + + def self.to_camel_case(str) + str.split('_').map { |w| w.capitalize }.join + end + + def self.to_snake_case(str) + str.split('::'). + last. + gsub(/([A-Z+])([A-Z][a-z])/, '\1_\2'). + gsub(/([a-z\d])([A-Z])/, '\1_\2'). + downcase + end + end + + # Mixin that wraps a command shell out invocation, providing a #run_command + # method. + module ShellOut + + # Wrapped exception for any interally raised shell out commands. + class ShellCommandFailed < StandardError ; end + + # Executes a command in a subshell on the local running system. + # + # @param cmd [String] command to be executed locally + # @param use_sudo [TrueClass, FalseClass] whether or not to use sudo + # @param log_subject [String] used in the output or log header for clarity + # and context + def run_command(cmd, use_sudo = false, log_subject = "local") + cmd = "sudo #{cmd}" if use_sudo + subject = " [#{log_subject} command]" + + $stdout.puts "#{subject} (#{display_cmd(cmd)})" + sh = Mixlib::ShellOut.new(cmd, :live_stream => $stdout, :timeout => 60000) + sh.run_command + puts "#{subject} ran in #{sh.execution_time} seconds." + sh.error! + rescue Mixlib::ShellOut::ShellCommandFailed => ex + raise ShellCommandFailed, ex.message + end + + private + + def display_cmd(cmd) + first_line, newline, rest = cmd.partition("\n") + last_char = cmd[cmd.size - 1] + + newline == "\n" ? "#{first_line}\\n...#{last_char}" : cmd + end + end + module Driver # Wrapped exception for any internally raised driver exceptions. class ActionFailed < StandardError ; end @@ -565,19 +618,21 @@ # @param plugin [String] a driver plugin type, which will be constantized # @return [Driver::Base] a driver instance def self.for_plugin(plugin, config) require "jamie/driver/#{plugin}" - klass = self.const_get(plugin.split('_').map { |w| w.capitalize }.join) + klass = self.const_get(Util.to_camel_case(plugin)) klass.new(config) end # Base class for a driver. A driver is responsible for carrying out the # lifecycle activities of an instance, such as creating, converging, and # destroying an instance. class Base + include ShellOut + def initialize(config) @config = config self.class.defaults.each do |attr, value| @config[attr] = value unless @config[attr] end @@ -671,10 +726,17 @@ File.expand_path(File.join( config['jamie_root'], ".jamie", "#{instance.name}.yml" )) end + def run_command(cmd, use_sudo = nil, log_subject = nil) + use_sudo = config['use_sudo'] if use_sudo.nil? + log_subject = Util.to_snake_case(self.class.to_s) + + super(cmd, use_sudo, log_subject) + end + def self.defaults @defaults ||= Hash.new end def self.default_config(attr, value) @@ -808,10 +870,12 @@ # Uploads Chef asset files such as dna.json, data bags, and cookbooks to an # instance over SSH. class ChefDataUploader + include ShellOut + def initialize(instance, ssh_args, jamie_root, chef_home) @instance = instance @ssh_args = ssh_args @jamie_root = jamie_root @chef_home = chef_home @@ -889,32 +953,23 @@ end end def run_berks(tmpdir) begin - run "if ! command -v berks >/dev/null ; then exit 1 ; fi" + run_command "if ! command -v berks >/dev/null; then exit 1; fi" rescue Mixlib::ShellOut::ShellCommandFailed abort ">>>>>> Berkshelf must be installed, add it to your Gemfile." end - run "berks install --path #{tmpdir}" + run_command "berks install --path #{tmpdir}" end def run_librarian(tmpdir) begin - run "if ! command -v librarian-chef >/dev/null ; then exit 1 ; fi" + run_command "if ! command -v librarian-chef >/dev/null; then exit 1; fi" rescue Mixlib::ShellOut::ShellCommandFailed abort ">>>>>> Librarian must be installed, add it to your Gemfile." end - run "librarian-chef install --path #{tmpdir}" + run_command "librarian-chef install --path #{tmpdir}" end - - def run(cmd) - puts " [local command] '#{cmd}'" - sh = Mixlib::ShellOut.new(cmd, :live_stream => STDOUT) - sh.run_command - puts " [local command] ran in #{sh.execution_time} seconds." - sh.error! - rescue Mixlib::ShellOut::ShellCommandFailed => ex - raise ActionFailed, ex.message - end end + end