diff --git a/.gitignore b/.gitignore index 873839586..0b6c1978e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,27 @@ .rspec results tags .*.sw[op] ext/packaging pkg test.pp # YARD generated documentation .yardoc /doc # Now that there is a gemfile, RVM ignores rvmrc in parent directories, so a local one is required # to work around that. Which we don't want committed, so we can ignore it here. /.rvmrc .bundle/ ext/packaging/ pkg/ Gemfile.lock Gemfile.local .bundle/ puppet-acceptance/ /.project .idea/ .ruby-version .ruby-gemset +acceptance/junit +acceptance/log +acceptance/.bundle diff --git a/acceptance/Gemfile b/acceptance/Gemfile index 248f77dad..bb5aa6183 100644 --- a/acceptance/Gemfile +++ b/acceptance/Gemfile @@ -1,17 +1,17 @@ # Specifies a gem mirror; duplicated in acceptance setup # to ensure a similar environment on acceptance hosts. source ENV['GEM_SOURCE'] || 'https://rubygems.org' -gem (ENV['BEAKER_GEM'] || "beaker"), "~> 1.17" +gem (ENV['BEAKER_GEM'] || "beaker"), "~> 2.2" gem "rake", "~> 10.1" gem "httparty", :require => false gem 'uuidtools', :require => false group(:test) do gem "rspec", "~> 2.14.0", :require => false gem "mocha", "~> 0.10.5", :require => false end if File.exists? "#{__FILE__}.local" eval(File.read("#{__FILE__}.local"), binding) end diff --git a/acceptance/Rakefile b/acceptance/Rakefile index 87e15c20a..5fb29fae5 100644 --- a/acceptance/Rakefile +++ b/acceptance/Rakefile @@ -1,356 +1,364 @@ require 'rake/clean' require 'pp' require 'yaml' $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'lib')) require 'puppet/acceptance/git_utils' extend Puppet::Acceptance::GitUtils ONE_DAY_IN_SECS = 24 * 60 * 60 REPO_CONFIGS_DIR = "repo-configs" CLEAN.include('*.tar', REPO_CONFIGS_DIR, 'merged_options.rb') module HarnessOptions DEFAULTS = { :type => 'git', :helper => ['lib/helper.rb'], :tests => ['tests'], :log_level => 'debug', :color => false, :root_keys => true, :ssh => { :keys => ["id_rsa_acceptance", "#{ENV['HOME']}/.ssh/id_rsa-acceptance"], }, :xml => true, :timesync => false, :repo_proxy => true, :add_el_extras => true, :preserve_hosts => 'onfail', :forge_host => 'forge-aio01-petest.puppetlabs.com', :'master-start-curl-retries' => 30, } class Aggregator attr_reader :mode def initialize(mode) @mode = mode end def get_options(file_path) puts file_path if File.exists? file_path options = eval(File.read(file_path), binding) else puts "No options file found at #{File.expand_path(file_path)}" end options || {} end def get_mode_options get_options("./config/#{mode}/options.rb") end def get_local_options get_options("./local_options.rb") end def final_options(intermediary_options = {}) mode_options = get_mode_options local_overrides = get_local_options final_options = DEFAULTS.merge(mode_options) final_options.merge!(intermediary_options) final_options.merge!(local_overrides) return final_options end end def self.options(mode, options) final_options = Aggregator.new(mode).final_options(options) final_options end end def beaker_test(mode = :packages, options = {}) delete_options = options.delete(:__delete_options__) || [] final_options = HarnessOptions.options(mode, options) preserve_config = final_options.delete(:__preserve_config__) if mode == :git # Build up project git urls based on git server and fork env variables or defaults final_options[:install].map! do |install| raise(ArgumentError, "Missing Git URL within options hash. Install URL is nil.") if install.nil? if md = /^(\w+)#(\w+)$/.match(install) project, project_sha = md.captures "#{build_giturl(project)}##{project_sha}" elsif md = /^(\w+)$/.match(install) project = md[1] "#{build_giturl(project)}##{sha}" else install end end end delete_options.each do |delete_me| final_options.delete(delete_me) end options_file = 'merged_options.rb' File.open(options_file, 'w') do |merged| merged.puts <<-EOS # Copy this file to local_options.rb and adjust as needed if you wish to run # with some local overrides. EOS merged.puts(final_options.pretty_inspect) end tests = ENV['TESTS'] || ENV['TEST'] tests_opt = "--tests=#{tests}" if tests config_opt = "--hosts=#{config}" if config overriding_options = ENV['OPTIONS'] args = ["--options-file", options_file, config_opt, tests_opt, overriding_options].compact begin sh("beaker", *args) ensure preserve_configuration(final_options, options_file) if preserve_config end end def preserve_configuration(final_options, options_file) if (hosts_file = config || final_options[:hosts_file]) && hosts_file !~ /preserved_config/ cp(hosts_file, "log/latest/config.yml") generate_config_for_latest_hosts end mv(options_file, "log/latest") end def generate_config_for_latest_hosts preserved_config_hash = { 'HOSTS' => {} } puts "\nPreserving configuration so that any preserved nodes can be tested again locally..." config_hash = YAML.load_file('log/latest/config.yml') if !config_hash || !config_hash.include?('HOSTS') puts "Warning: No HOSTS configuration found in log/latest/config.yml" return else nodes = config_hash['HOSTS'].map do |node_label,hash| { :node_label => node_label, :roles => hash['roles'], :platform => hash['platform'] } end pre_suite_log = File.read('log/latest/pre_suite-run.log') nodes.each do |node_info| host_regex = /^([\w.]+) \(#{node_info[:node_label]}\)/ if matched = host_regex.match(pre_suite_log) hostname = matched[1] fqdn = (hostname =~ /\./) ? hostname : "#{hostname}.delivery.puppetlabs.net" elsif /^#{node_info[:node_label]} /.match(pre_suite_log) fqdn = "#{node_info[:node_label]}" puts "* Couldn't find any log lines for #{host_regex}, assuming #{fqdn} is the fqdn" end if fqdn preserved_config_hash['HOSTS'][fqdn] = { 'roles' => node_info[:roles], 'platform' => node_info[:platform], } else puts "* Couldn't match #{node_info[:node_label]} in pre_suite-run.log" end end pp preserved_config_hash File.open('log/latest/preserved_config.yaml', 'w') do |config_file| YAML.dump(preserved_config_hash, config_file) end end rescue Errno::ENOENT => e puts "Warning: Couldn't generate preserved_config.yaml #{e}" end def list_preserved_configurations(secs_ago = ONE_DAY_IN_SECS) preserved = {} Dir.glob('log/*_*').each do |dir| preserved_config_path = "#{dir}/preserved_config.yaml" yesterday = Time.now - secs_ago.to_i if preserved_config = File.exists?(preserved_config_path) directory = File.new(dir) if directory.ctime > yesterday hosts = [] preserved_config = YAML.load_file(preserved_config_path).to_hash preserved_config['HOSTS'].each do |hostname,values| hosts << "#{hostname}: #{values['platform']}, #{values['roles']}" end preserved[hosts] = directory.to_path end end end preserved.map { |k,v| [v,k] }.sort { |a,b| a[0] <=> b[0] }.reverse end def list_preserved_hosts(secs_ago = ONE_DAY_IN_SECS) hosts = Set.new Dir.glob('log/**/pre*suite*run.log').each do |log| yesterday = Time.now - secs_ago.to_i File.open(log, 'r') do |file| if file.ctime > yesterday file.each_line do |line| matchdata = /^(\w+)(?:\.[\w.]+)? \(.*?\) \d\d:\d\d:\d\d\$/.match(line.encode!('UTF-8', 'UTF-8', :invalid => :replace)) hosts.add(matchdata[1]) if matchdata end end end end hosts end def release_hosts(hosts = nil, secs_ago = ONE_DAY_IN_SECS) secs_ago ||= ONE_DAY_IN_SECS hosts ||= list_preserved_hosts(secs_ago) hosts.each do |h| hostname = h.split('.').first puts "Releaseing '#{hostname}'" puts `curl -X DELETE --url http://vcloud.delivery.puppetlabs.net/vm/#{hostname}` end end def print_preserved(preserved) preserved.each_with_index do |entry,i| puts "##{i}: #{entry[0]}" entry[1].each { |h| puts " #{h}" } end end def beaker_run_type type = ENV['TYPE'] || :packages type = type.to_sym end def sha ENV['SHA'] end def config ENV['CONFIG'] end namespace :ci do task :check_env do raise(USAGE) unless sha end namespace :test do USAGE = <<-EOS Requires commit SHA to be put under test as environment variable: SHA=''. Also must set CONFIG=config/nodes/foo.yaml or include it in an options.rb for Beaker. You may set TESTS=path/to/test,and/more/tests. You may set additional Beaker OPTIONS='--more --options' If testing from git checkouts, you may optionally set the github fork to checkout from using PUPPET_FORK='some-other-puppet-fork' (you may change the HIERA_FORK and FACTER_FORK as well if you wish). You may also optionally set the git server to checkout repos from using GIT_SERVER='some.git.mirror'. Or you may set PUPPET_GIT_SERVER='my.host.with.git.daemon', specifically, if you have set up a `git daemon` to pull local commits from. (You will need to allow the git daemon to serve the repo (see `git help daemon` and the docs/acceptance_tests.md for more details)). If there is a Beaker options hash in a ./local_options.rb, it will be included. Commandline options set through the above environment variables will override settings in this file. EOS desc <<-EOS Run the acceptance tests through Beaker and install packages on the configuration targets. #{USAGE} EOS task :packages => 'ci:check_env' do beaker_test end + desc <<-EOS +Run the acceptance tests through Beaker and install packages as part of the AIO puppet-agent installation. +#{USAGE} +EOS + task :aio => 'ci:check_env' do + beaker_test(:aio) + end + desc <<-EOS Run the acceptance tests through Beaker and install from git on the configuration targets. #{USAGE} EOS task :git => 'ci:check_env' do beaker_test(:git) end end desc "Capture the master and agent hostname from the latest log and construct a preserved_config.yaml for re-running against preserved hosts without provisioning." task :extract_preserved_config do generate_config_for_latest_hosts end desc <<-EOS Run an acceptance test for a given node configuration and preserve the hosts. Defaults to a packages run, but you can set it to 'git' with TYPE='git'. #{USAGE} EOS task :test_and_preserve_hosts => 'ci:check_env' do beaker_test(beaker_run_type, :preserve_hosts => 'always', :__preserve_config__ => true) end desc "List acceptance runs from the past day which had hosts preserved." task :list_preserved do preserved = list_preserved_configurations print_preserved(preserved) end desc <<-EOS Shutdown and destroy any hosts that we have preserved for testing. These should be reaped daily by scripts, but this will free up resources immediately. Specify a list of comma separated HOST_NAMES if you have a set of dynamic vcloud host names you want to purge outside of what can be grepped from the logs. You can go back through the last SECS_AGO logs. Default is one day ago in secs. EOS task :release_hosts do host_names = ENV['HOST_NAMES'].split(',') if ENV['HOST_NAMES'] secs_ago = ENV['SECS_AGO'] release_hosts(host_names, secs_ago) end task :destroy_preserved_hosts => 'ci:release_hosts' do puts "Note: we are now releasing hosts back to the vcloud pooling api rather than destroying them directly. The rake task for this is ci:release_hosts" end desc <<-EOS Rerun an acceptance test using the last captured preserved_config.yaml to skip provisioning. Or specify a CONFIG_NUMBER from `rake ci:list_preserved`. Defaults to a packages run, but you can set it to 'git' with TYPE='git'. EOS task :test_against_preserved_hosts do config_number = (ENV['CONFIG_NUMBER'] || 0).to_i preserved = list_preserved_configurations print_preserved(preserved) config_path = preserved[config_number][0] puts "Using ##{config_number}: #{config_path}" options = { :hosts_file => "#{config_path}/preserved_config.yaml", :no_provision => true, :preserve_hosts => 'always', } run_type = beaker_run_type if run_type == :packages options.merge!(:pre_suite => [ 'setup/packages/pre-suite/015_PackageHostsPresets.rb', 'setup/packages/pre-suite/045_EnsureMasterStartedOnPassenger.rb', ]) else options.merge!(:__delete_options__ => [:pre_suite]) end beaker_test(beaker_run_type, options) end end task :default do sh('rake -T') end task :spec do sh('rspec lib') end diff --git a/acceptance/config/aio/options.rb b/acceptance/config/aio/options.rb new file mode 100644 index 000000000..47f840960 --- /dev/null +++ b/acceptance/config/aio/options.rb @@ -0,0 +1,12 @@ +{ + :type => 'aio', + :pre_suite => [ + 'setup/common/pre-suite/001_PkgBuildSetup.rb', + 'setup/aio/pre-suite/010_Install.rb', + 'setup/aio/pre-suite/015_PackageHostsPresets.rb', + 'setup/common/pre-suite/025_StopFirewall.rb', + 'setup/common/pre-suite/040_ValidateSignCert.rb', + 'setup/aio/pre-suite/045_EnsureMasterStartedOnPassenger.rb', + 'setup/common/pre-suite/070_InstallCACerts.rb', + ], +} diff --git a/acceptance/lib/puppet/acceptance/install_utils.rb b/acceptance/lib/puppet/acceptance/install_utils.rb index 7b0f7324e..0ae48ced0 100644 --- a/acceptance/lib/puppet/acceptance/install_utils.rb +++ b/acceptance/lib/puppet/acceptance/install_utils.rb @@ -1,222 +1,237 @@ require 'open-uri' require 'open3' require 'uri' module Puppet module Acceptance module InstallUtils PLATFORM_PATTERNS = { :redhat => /fedora|el|centos/, :debian => /debian|ubuntu/, :debian_ruby18 => /debian|ubuntu-lucid|ubuntu-precise/, :solaris_10 => /solaris-10/, :solaris_11 => /solaris-11/, :windows => /windows/, }.freeze # Installs packages on the hosts. # # @param hosts [Array] Array of hosts to install packages to. # @param package_hash [Hash{Symbol=>Array>}] # Keys should be a symbol for a platform in PLATFORM_PATTERNS. Values # should be an array of package names to install, or of two element # arrays where a[0] is the command we expect to find on the platform # and a[1] is the package name (when they are different). # @param options [Hash{Symbol=>Boolean}] # @option options [Boolean] :check_if_exists First check to see if # command is present before installing package. (Default false) # @return true def install_packages_on(hosts, package_hash, options = {}) check_if_exists = options[:check_if_exists] hosts = [hosts] unless hosts.kind_of?(Array) hosts.each do |host| package_hash.each do |platform_key,package_list| if pattern = PLATFORM_PATTERNS[platform_key] if pattern.match(host['platform']) package_list.each do |cmd_pkg| if cmd_pkg.kind_of?(Array) command, package = cmd_pkg else command = package = cmd_pkg end if !check_if_exists || !host.check_for_package(command) host.logger.notify("Installing #{package}") additional_switches = '--allow-unauthenticated' if platform_key == :debian host.install_package(package, additional_switches) end end end else raise("Unknown platform '#{platform_key}' in package_hash") end end end return true end def fetch(base_url, file_name, dst_dir) FileUtils.makedirs(dst_dir) src = "#{base_url}/#{file_name}" dst = File.join(dst_dir, file_name) if File.exists?(dst) logger.notify "Already fetched #{dst}" else logger.notify "Fetching: #{src}" logger.notify " and saving to #{dst}" open(src) do |remote| File.open(dst, "w") do |file| FileUtils.copy_stream(remote, file) end end end return dst end def fetch_remote_dir(url, dst_dir) logger.notify "fetch_remote_dir (url: #{url}, dst_dir #{dst_dir})" if url[-1, 1] !~ /\// url += '/' end url = URI.parse(url) chunks = url.path.split('/') dst = File.join(dst_dir, chunks.last) #determine directory structure to cut #only want to keep the last directory, thus cut total number of dirs - 2 (hostname + last dir name) cut = chunks.length - 2 wget_command = "wget -nv -P #{dst_dir} --reject \"index.html*\",\"*.gif\" --cut-dirs=#{cut} -np -nH --no-check-certificate -r #{url}" logger.notify "Fetching remote directory: #{url}" logger.notify " and saving to #{dst}" logger.notify " using command: #{wget_command}" #in ruby 1.9+ we can upgrade this to popen3 to gain access to the subprocess pid result = `#{wget_command} 2>&1` result.each_line do |line| logger.debug(line) end if $?.to_i != 0 raise "Failed to fetch_remote_dir '#{url}' (exit code #{$?}" end dst end def stop_firewall_on(host) case host['platform'] when /debian/ on host, 'iptables -F' when /fedora|el-7/ on host, puppet('resource', 'service', 'firewalld', 'ensure=stopped') when /el|centos/ on host, puppet('resource', 'service', 'iptables', 'ensure=stopped') when /ubuntu/ on host, puppet('resource', 'service', 'ufw', 'ensure=stopped') else logger.notify("Not sure how to clear firewall on #{host['platform']}") end end - def install_repos_on(host, sha, repo_configs_dir) + def install_repos_on(host, project, sha, repo_configs_dir) platform = host['platform'].with_version_codename platform_configs_dir = File.join(repo_configs_dir,platform) case platform when /^(fedora|el|centos)-(\d+)-(.+)$/ variant = (($1 == 'centos') ? 'el' : $1) fedora_prefix = ((variant == 'fedora') ? 'f' : '') version = $2 arch = $3 rpm = fetch( "http://yum.puppetlabs.com", "puppetlabs-release-%s-%s.noarch.rpm" % [variant, version], platform_configs_dir ) - pattern = "pl-puppet-%s-%s-%s%s-%s.repo" + pattern = "pl-%s-%s-%s-%s%s-%s.repo" repo_filename = pattern % [ + project, sha, variant, fedora_prefix, version, arch ] repo = fetch( - "http://builds.puppetlabs.lan/puppet/%s/repo_configs/rpm/" % sha, + "http://builds.puppetlabs.lan/%s/%s/repo_configs/rpm/" % [project, sha], repo_filename, platform_configs_dir ) - link = "http://builds.puppetlabs.lan/puppet/%s/repos/%s/%s%s/products/%s/" % [sha, variant, fedora_prefix, version, arch] + link = "http://builds.puppetlabs.lan/%s/%s/repos/%s/%s%s/products/%s/" % [ + project, + sha, + variant, + fedora_prefix, + version, + arch + ] if not link_exists?(link) - link = "http://builds.puppetlabs.lan/puppet/%s/repos/%s/%s%s/devel/%s/" % [sha, variant, fedora_prefix, version, arch] + link = "http://builds.puppetlabs.lan/%s/%s/repos/%s/%s%s/devel/%s/" % [ + project, + sha, + variant, + fedora_prefix, + version, + arch + ] end if not link_exists?(link) raise "Unable to reach a repo directory at #{link}" end repo_dir = fetch_remote_dir(link, platform_configs_dir) on host, "rm -rf /root/*.repo; rm -rf /root/*.rpm; rm -rf /root/#{arch}" scp_to host, rpm, '/root' scp_to host, repo, '/root' scp_to host, repo_dir, '/root' on host, "mv /root/*.repo /etc/yum.repos.d" on host, "find /etc/yum.repos.d/ -name \"*.repo\" -exec sed -i \"s/baseurl\\s*=\\s*http:\\/\\/builds.puppetlabs.lan.*$/baseurl=file:\\/\\/\\/root\\/#{arch}/\" {} \\;" on host, "rpm -Uvh --force /root/*.rpm" when /^(debian|ubuntu)-([^-]+)-(.+)$/ variant = $1 version = $2 arch = $3 deb = fetch( "http://apt.puppetlabs.com/", "puppetlabs-release-%s.deb" % version, platform_configs_dir ) list = fetch( - "http://builds.puppetlabs.lan/puppet/%s/repo_configs/deb/" % sha, - "pl-puppet-%s-%s.list" % [sha, version], + "http://builds.puppetlabs.lan/%s/%s/repo_configs/deb/" % [project, sha], + "pl-%s-%s-%s.list" % [project, sha, version], platform_configs_dir ) - repo_dir = fetch_remote_dir("http://builds.puppetlabs.lan/puppet/%s/repos/apt/%s" % [sha, version], platform_configs_dir) + repo_dir = fetch_remote_dir("http://builds.puppetlabs.lan/%s/%s/repos/apt/%s" % [project, sha, version], platform_configs_dir) on host, "rm -rf /root/*.list; rm -rf /root/*.deb; rm -rf /root/#{version}" scp_to host, deb, '/root' scp_to host, list, '/root' scp_to host, repo_dir, '/root' on host, "mv /root/*.list /etc/apt/sources.list.d" on host, "find /etc/apt/sources.list.d/ -name \"*.list\" -exec sed -i \"s/deb\\s\\+http:\\/\\/builds.puppetlabs.lan.*$/deb file:\\/\\/\\/root\\/#{version} #{version} main/\" {} \\;" on host, "dpkg -i --force-all /root/*.deb" on host, "apt-get update" else host.logger.notify("No repository installation step for #{platform} yet...") end end # Configures gem sources on hosts to use a mirror, if specified # This is a duplicate of the Gemfile logic. def configure_gem_mirror(hosts) hosts = [hosts] unless hosts.kind_of?(Array) gem_source = ENV['GEM_SOURCE'] || 'https://rubygems.org' hosts.each do |host| case host['platform'] when /windows/ gem = 'cmd /c gem' else gem = 'gem' end on host, "#{gem} source --clear-all" on host, "#{gem} source --add #{gem_source}" end end end end end diff --git a/acceptance/setup/packages/pre-suite/010_Install.rb b/acceptance/setup/aio/pre-suite/010_Install.rb similarity index 87% copy from acceptance/setup/packages/pre-suite/010_Install.rb copy to acceptance/setup/aio/pre-suite/010_Install.rb index 2329b8014..9d355d631 100644 --- a/acceptance/setup/packages/pre-suite/010_Install.rb +++ b/acceptance/setup/aio/pre-suite/010_Install.rb @@ -1,52 +1,52 @@ require 'puppet/acceptance/install_utils' extend Puppet::Acceptance::InstallUtils test_name "Install Packages" step "Install repositories on target machines..." do sha = ENV['SHA'] repo_configs_dir = 'repo-configs' hosts.each do |host| - install_repos_on(host, sha, repo_configs_dir) + install_repos_on(host, 'puppet-agent', sha, repo_configs_dir) end end MASTER_PACKAGES = { :redhat => [ 'puppet-server', ], :debian => [ 'puppetmaster-passenger', ], # :solaris => [ # 'puppet-server', # ], # :windows => [ # 'puppet-server', # ], } AGENT_PACKAGES = { :redhat => [ - 'puppet', + 'puppet-agent', ], :debian => [ - 'puppet', + 'puppet-agent', ], # :solaris => [ # 'puppet', # ], # :windows => [ # 'puppet', # ], } install_packages_on(master, MASTER_PACKAGES) install_packages_on(agents, AGENT_PACKAGES) configure_gem_mirror(hosts) diff --git a/acceptance/setup/aio/pre-suite/015_PackageHostsPresets.rb b/acceptance/setup/aio/pre-suite/015_PackageHostsPresets.rb new file mode 100644 index 000000000..026c6985b --- /dev/null +++ b/acceptance/setup/aio/pre-suite/015_PackageHostsPresets.rb @@ -0,0 +1,5 @@ +if master['platform'] =~ /debian|ubuntu/ + master.uses_passenger! +elsif master['platform'] =~ /redhat|el|centos|scientific|fedora/ + master['use-service'] = true +end diff --git a/acceptance/setup/aio/pre-suite/045_EnsureMasterStartedOnPassenger.rb b/acceptance/setup/aio/pre-suite/045_EnsureMasterStartedOnPassenger.rb new file mode 100644 index 000000000..20f4fdfb5 --- /dev/null +++ b/acceptance/setup/aio/pre-suite/045_EnsureMasterStartedOnPassenger.rb @@ -0,0 +1,3 @@ +if master.graceful_restarts? + on(master, puppet('resource', 'service', master['puppetservice'], "ensure=running")) +end diff --git a/acceptance/setup/packages/pre-suite/010_Install.rb b/acceptance/setup/packages/pre-suite/010_Install.rb index 2329b8014..72f93b825 100644 --- a/acceptance/setup/packages/pre-suite/010_Install.rb +++ b/acceptance/setup/packages/pre-suite/010_Install.rb @@ -1,52 +1,52 @@ require 'puppet/acceptance/install_utils' extend Puppet::Acceptance::InstallUtils test_name "Install Packages" step "Install repositories on target machines..." do sha = ENV['SHA'] repo_configs_dir = 'repo-configs' hosts.each do |host| - install_repos_on(host, sha, repo_configs_dir) + install_repos_on(host, 'puppet', sha, repo_configs_dir) end end MASTER_PACKAGES = { :redhat => [ 'puppet-server', ], :debian => [ 'puppetmaster-passenger', ], # :solaris => [ # 'puppet-server', # ], # :windows => [ # 'puppet-server', # ], } AGENT_PACKAGES = { :redhat => [ 'puppet', ], :debian => [ 'puppet', ], # :solaris => [ # 'puppet', # ], # :windows => [ # 'puppet', # ], } install_packages_on(master, MASTER_PACKAGES) install_packages_on(agents, AGENT_PACKAGES) configure_gem_mirror(hosts)