lib/beaker-pe/install/pe_utils.rb in beaker-pe-1.19.0 vs lib/beaker-pe/install/pe_utils.rb in beaker-pe-1.20.0

- old
+ new

@@ -79,10 +79,72 @@ real_agents = agents - special_nodes real_agents = real_agents.delete_if{ |host| !subset.include?(host) } special_nodes + real_agents end + # If host or opts has the :use_puppet_ca_cert flag set, then push the master's + # ca cert onto the given host at /etc/puppetlabs/puppet/ssl/certs/ca.pem. + # + # This in turn allows +frictionless_agent_installer_cmd+ to generate + # an install which references the cert to verify the master when downloading + # resources. + def install_ca_cert_on(host, opts) + if host[:use_puppet_ca_cert] || opts[:use_puppet_ca_cert] + @cert_cache_dir ||= Dir.mktmpdir("master_ca_cert") + local_cert_copy = "#{@cert_cache_dir}/ca.pem" + step "Copying master ca.pem to agent for secure frictionless install" do + ca_pem_dir = '/etc/puppetlabs/puppet/ssl/certs' + ca_pem_path = "#{ca_pem_dir}/ca.pem" + scp_from(master, ca_pem_path , @cert_cache_dir) unless File.exist?(local_cert_copy) + on(host, "mkdir -p #{ca_pem_dir}") + scp_to(host, local_cert_copy, ca_pem_dir) + end + end + end + + # Generate the command line string needed to from a frictionless puppet-agent + # install on this host in a PE environment. + # + # @param [Host] host The host to install puppet-agent onto + # @param [Hash] opts The full beaker options + # @option opts [Boolean] :use_puppet_ca_cert (false) if true the + # command will reference the local puppet ca cert to verify the master + # when obtaining the installation script + # @param [String] pe_version The PE version string for capabilities testing + # @return [String] of the commands to be executed for the install + def frictionless_agent_installer_cmd(host, opts, pe_version) + # PE 3.4 introduced the ability to pass in config options to the bash + # script in the form of <section>:<key>=<value> + frictionless_install_opts = [] + if host.has_key?('frictionless_options') and ! version_is_less(pe_version, '3.4.0') + # since we have options to pass in, we need to tell the bash script + host['frictionless_options'].each do |section, settings| + settings.each do |key, value| + frictionless_install_opts << "#{section}:#{key}=#{value}" + end + end + end + + pe_debug = host[:pe_debug] || opts[:pe_debug] ? ' -x' : '' + use_puppet_ca_cert = host[:use_puppet_ca_cert] || opts[:use_puppet_ca_cert] + + if host['platform'] =~ /windows/ then + cmd = %Q{powershell -c "cd #{host['working_dir']};[Net.ServicePointManager]::ServerCertificateValidationCallback = {\\$true};\\$webClient = New-Object System.Net.WebClient;\\$webClient.DownloadFile('https://#{master}:8140/packages/current/install.ps1', '#{host['working_dir']}/install.ps1');#{host['working_dir']}/install.ps1 -verbose #{frictionless_install_opts.join(' ')}"} + else + curl_opts = %w{--tlsv1 -O} + if use_puppet_ca_cert + curl_opts << '--cacert /etc/puppetlabs/puppet/ssl/certs/ca.pem' + elsif host['platform'] !~ /aix/ + curl_opts << '-k' + end + + cmd = "export FRICTIONLESS_TRACE=true; cd #{host['working_dir']} && curl #{curl_opts.join(' ')} https://#{master}:8140/packages/current/install.bash && bash#{pe_debug} install.bash #{frictionless_install_opts.join(' ')}".strip + end + + return cmd + end + #Create the PE install command string based upon the host and options settings # @param [Host] host The host that PE is to be installed on # For UNIX machines using the full PE installer, the host object must have the 'pe_installer' field set correctly. # @param [Hash{Symbol=>String}] opts The options # @option opts [String] :pe_ver Default PE version to install or upgrade to @@ -94,32 +156,11 @@ def installer_cmd(host, opts) version = host['pe_ver'] || opts[:pe_ver] # Frictionless install didn't exist pre-3.2.0, so in that case we fall # through and do a regular install. if host['roles'].include? 'frictionless' and ! version_is_less(version, '3.2.0') - # PE 3.4 introduced the ability to pass in config options to the bash script in the form - # of <section>:<key>=<value> - frictionless_install_opts = [] - if host.has_key?('frictionless_options') and ! version_is_less(version, '3.4.0') - # since we have options to pass in, we need to tell the bash script - host['frictionless_options'].each do |section, settings| - settings.each do |key, value| - frictionless_install_opts << "#{section}:#{key}=#{value}" - end - end - end - - pe_debug = host[:pe_debug] || opts[:pe_debug] ? ' -x' : '' - if host['platform'] =~ /windows/ then - "powershell -c \"cd #{host['working_dir']};[Net.ServicePointManager]::ServerCertificateValidationCallback = {\\$true};\\$webClient = New-Object System.Net.WebClient;\\$webClient.DownloadFile('https://#{master}:8140/packages/current/install.ps1', '#{host['working_dir']}/install.ps1');#{host['working_dir']}/install.ps1 -verbose #{frictionless_install_opts.join(' ')}\"" - elsif host['platform'] =~ /aix/ then - curl_opts = '--tlsv1 -O' - "cd #{host['working_dir']} && curl #{curl_opts} https://#{master}:8140/packages/current/install.bash && bash#{pe_debug} install.bash #{frictionless_install_opts.join(' ')}".strip - else - curl_opts = '--tlsv1 -kO' - "cd #{host['working_dir']} && curl #{curl_opts} https://#{master}:8140/packages/current/install.bash && bash#{pe_debug} install.bash #{frictionless_install_opts.join(' ')}".strip - end + frictionless_agent_installer_cmd(host, opts, version) elsif host['platform'] =~ /osx/ version = host['pe_ver'] || opts[:pe_ver] pe_debug = host[:pe_debug] || opts[:pe_debug] ? ' -verboseR' : '' "cd #{host['working_dir']} && hdiutil attach #{host['dist']}.dmg && installer#{pe_debug} -pkg /Volumes/puppet-enterprise-#{version}/puppet-enterprise-installer-#{version}.pkg -target /" elsif host['platform'] =~ /eos/ @@ -293,11 +334,11 @@ fetch_pe_on_unix(host, opts) end end end - #Classify the master so that it can deploy frictionless packages for a given host. + #Classify the master so that it can deploy frictionless packages for a given host. #This function does nothing when using meep for classification. # @param [Host] host The host to install pacakges for # @api private def deploy_frictionless_to_master(host) return if use_meep_for_classification?(master[:pe_ver], options) @@ -343,11 +384,20 @@ # add the pe_repo platform class if it's not already present if ! node_group['classes'].include?(klass) node_group['classes'][klass] = {} _console_dispatcher.create_new_node_group_model(node_group) - on master, puppet("agent -t"), :acceptable_exit_codes => [0,2] + # The puppet agent run that will download the agent tarballs to the master can sometimes fail with + # curl errors if there is a network hiccup. Use beakers `retry_on` method to retry up to + # three times to avoid failing the entire test pipeline due to a network blip + retry_opts = { + :desired_exit_codes => [0,2], + :max_retries => 3, + # Beakers retry_on method wants the verbose value to be a string, not a bool. + :verbose => 'true' + } + retry_on(master, puppet("agent -t"), retry_opts) end end end #Perform a Puppet Enterprise upgrade or install @@ -469,10 +519,11 @@ end end step "Install agents" do block_on(agents, {:run_in_parallel => true}) do |host| + install_ca_cert_on(host, opts) on(host, installer_cmd(host, opts)) end end step "Sign agent certificates" do @@ -569,9 +620,10 @@ # If We're *not* running the classic installer, we want # to make sure the master has packages for us. if host['platform'] != master['platform'] # only need to do this if platform differs deploy_frictionless_to_master(host) end + install_ca_cert_on(host, opts) on host, installer_cmd(host, opts) configure_type_defaults_on(host) elsif host['platform'] =~ /osx|eos/ # If we're not frictionless, we need to run the OSX special-case on host, installer_cmd(host, opts)