lib/chef/knife/solo_cook.rb in knife-solo-0.3.0 vs lib/chef/knife/solo_cook.rb in knife-solo-0.4.0

- old
+ new

@@ -39,10 +39,14 @@ option :sync_only, :long => '--sync-only', :description => 'Only sync the cookbook - do not run Chef' + option :sync, + :long => '--no-sync', + :description => 'Do not sync kitchen - only run Chef' + option :berkshelf, :long => '--no-berkshelf', :description => 'Skip berks install' option :librarian, @@ -74,15 +78,18 @@ validate! ui.msg "Running Chef on #{host}..." check_chef_version if config[:chef_check] - generate_node_config - berkshelf_install if config_value(:berkshelf, true) - librarian_install if config_value(:librarian, true) - sync_kitchen - generate_solorb + if config_value(:sync, true) + generate_node_config + berkshelf_install if config_value(:berkshelf, true) + librarian_install if config_value(:librarian, true) + patch_cookbooks_install + sync_kitchen + generate_solorb + end cook unless config[:sync_only] end end def validate! @@ -102,17 +109,18 @@ def sync_kitchen ui.msg "Uploading the kitchen..." run_portable_mkdir_p(provisioning_path, '0700') cookbook_paths.each_with_index do |path, i| - upload_to_provision_path(path, "/cookbooks-#{i + 1}", 'cookbook_path') + upload_to_provision_path(path.to_s, "/cookbooks-#{i + 1}", 'cookbook_path') end - upload_to_provision_path(node_config, 'dna.json') + upload_to_provision_path(node_config.to_s, 'dna.json') upload_to_provision_path(nodes_path, 'nodes') upload_to_provision_path(:role_path, 'roles') upload_to_provision_path(:data_bag_path, 'data_bags') upload_to_provision_path(:encrypted_data_bag_secret, 'data_bag_key') + upload_to_provision_path(:environment_path, 'environments') end def expand_path(path) Pathname.new(path).expand_path end @@ -120,11 +128,11 @@ def expanded_config_paths(key) Array(Chef::Config[key]).map { |path| expand_path path } end def cookbook_paths - @cookbook_paths ||= expanded_config_paths(:cookbook_path) + [patch_cookbooks_path] + @cookbook_paths ||= expanded_config_paths(:cookbook_path) end def proxy_setting_keys [:http_proxy, :https_proxy, :http_proxy_user, :http_proxy_pass, :no_proxy] end @@ -217,10 +225,12 @@ src = Chef::Config[src] end if src.nil? Chef::Log.debug "'#{key_name}' not set" + elsif !src.is_a?(String) + ui.error "#{key_name} is not a String: #{src.inspect}" elsif !File.exist?(src) ui.warn "Local #{key_name} '#{src}' does not exist" else upload("#{src}#{'/' if File.directory?(src)}", File.join(provisioning_path, dest)) end @@ -235,28 +245,40 @@ ensure file.unlink end def rsync(source_path, target_path, extra_opts = '--delete') - cmd = %Q{rsync -rl #{rsync_debug} #{rsync_permissions} --rsh="ssh #{ssh_args}" #{extra_opts}} - cmd << rsync_excludes.map { |ignore| " --exclude '#{ignore}'" }.join - cmd << %Q{ #{adjust_rsync_path_on_client(source_path)} :#{adjust_rsync_path_on_node(target_path)}} - Chef::Log.debug cmd - system! cmd + cmd = ['rsync', '-rL', rsync_debug, rsync_permissions, %Q{--rsh=ssh #{ssh_args}}, extra_opts] + cmd += rsync_excludes.map { |ignore| "--exclude=#{ignore}" } + cmd << adjust_rsync_path_on_client(source_path) + cmd << %Q{:#{adjust_rsync_path_on_node(target_path)}} + cmd = cmd.flatten.compact + Chef::Log.debug cmd.inspect + system!(*cmd) end def check_chef_version ui.msg "Checking Chef version..." - unless Gem::Requirement.new(CHEF_VERSION_CONSTRAINT).satisfied_by? Gem::Version.new(chef_version) + unless chef_version_satisfies? CHEF_VERSION_CONSTRAINT raise "Couldn't find Chef #{CHEF_VERSION_CONSTRAINT} on #{host}. Please run `knife solo prepare #{ssh_args}` to ensure Chef is installed and up to date." end + if node_environment != '_default' && chef_version_satisfies?('<11.6.0') + ui.warn "Chef version #{chef_version} does not support environments. Environment '#{node_environment}' will be ignored." + end end + def chef_version_satisfies?(requirement) + Gem::Requirement.new(requirement).satisfied_by? Gem::Version.new(chef_version) + end + # Parses "Chef: x.y.z" from the chef-solo version output def chef_version - cmd = %q{sudo chef-solo --version 2>/dev/null | awk '$1 == "Chef:" {print $2}'} - run_command(cmd).stdout.strip + # Memoize the version to avoid multiple SSH calls + @chef_version ||= lambda do + cmd = %q{sudo chef-solo --version 2>/dev/null | awk '$1 == "Chef:" {print $2}'} + run_command(cmd).stdout.strip + end.call end def cook ui.msg "Running Chef..." cmd = "sudo chef-solo -c #{provisioning_path}/solo.rb -j #{provisioning_path}/dna.json" @@ -265,9 +287,15 @@ cmd << " -W" if config[:why_run] cmd << " -o #{config[:override_runlist]}" if config[:override_runlist] result = stream_command cmd raise "chef-solo failed. See output above." unless result.success? + end + + protected + + def patch_cookbooks_install + add_cookbook_path(patch_cookbooks_path) end end end end