From d8269d00df4dee11b6a23fe2fc0f53a0851bb7cf Mon Sep 17 00:00:00 2001 From: kevpl Date: Fri, 5 Aug 2016 10:23:40 -0700 Subject: [PATCH] (BKR-831) added dynamic puppet-agent version read from master --- lib/beaker-pe/install/pe_utils.rb | 30 +++++++- spec/beaker-pe/install/pe_utils_spec.rb | 94 ++++++++++++++++++++++--- 2 files changed, 115 insertions(+), 9 deletions(-) diff --git a/lib/beaker-pe/install/pe_utils.rb b/lib/beaker-pe/install/pe_utils.rb index b04fe90e..29dabfa4 100644 --- a/lib/beaker-pe/install/pe_utils.rb +++ b/lib/beaker-pe/install/pe_utils.rb @@ -416,7 +416,8 @@ def do_install hosts, opts = {} install_hosts.each do |host| if agent_only_check_needed && hosts_agent_only.include?(host) host['type'] = 'aio' - install_puppet_agent_pe_promoted_repo_on(host, { :puppet_agent_version => host[:puppet_agent_version] || opts[:puppet_agent_version], + puppet_agent_version = get_puppet_agent_version(host, opts) + install_puppet_agent_pe_promoted_repo_on(host, { :puppet_agent_version => puppet_agent_version, :puppet_agent_sha => host[:puppet_agent_sha] || opts[:puppet_agent_sha], :pe_ver => host[:pe_ver] || opts[:pe_ver], :puppet_collection => host[:puppet_collection] || opts[:puppet_collection] }) @@ -535,6 +536,33 @@ def do_install hosts, opts = {} end end + # Gets the puppet-agent version, hopefully from the host or local options. + # Will fall back to reading the `aio_agent_build` property on the master + # if neither of those two options are passed + # + # @note This method does have a side-effect: if it reads the + # `aio_agent_build` property from master, it will store it in the local + # options hash so that it won't have to do this more than once. + # + # @param [Beaker::Host] host Host to get puppet-agent for + # @param [Hash{Symbol=>String}] local_options local method options hash + # + # @return [String] puppet-agent version to install + def get_puppet_agent_version(host, local_options={}) + puppet_agent_version = host[:puppet_agent_version] || local_options[:puppet_agent_version] + return puppet_agent_version if puppet_agent_version + # we can query the master because do_install is called passing + # the {#sorted_hosts}, so we know the master will be installed + # before the agents + facts_result = on(master, 'puppet facts') + facts_hash = JSON.parse(facts_result.stdout.chomp) + puppet_agent_version = facts_hash['values']['aio_agent_build'] + logger.warn("No :puppet_agent_version in host #{host} or local options. Read puppet-agent version #{puppet_agent_version} from master") + # saving so that we don't have to query the master more than once + local_options[:puppet_agent_version] = puppet_agent_version + puppet_agent_version + end + # True if version is greater than or equal to MEEP_CUTOVER_VERSION (2016.2.0) def use_meep?(version) !version_is_less(version, MEEP_CUTOVER_VERSION) diff --git a/spec/beaker-pe/install/pe_utils_spec.rb b/spec/beaker-pe/install/pe_utils_spec.rb index 725de3fe..898c9e4b 100644 --- a/spec/beaker-pe/install/pe_utils_spec.rb +++ b/spec/beaker-pe/install/pe_utils_spec.rb @@ -772,15 +772,32 @@ def slice_installer_options(host) "puppet #{arg}" end + pa_version = 'rarified_air_9364' + allow( subject ).to receive( :get_puppet_agent_version ).and_return( pa_version ) + allow( subject ).to receive( :hosts ).and_return( hosts ) #create answers file per-host, except windows expect( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ).once #run installer on all hosts expect( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ).once - expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[1], - {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[1][:pe_ver], :puppet_collection=>nil} ).once - expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[2], - {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[2][:pe_ver], :puppet_collection=>nil} ).once + expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( + hosts[1], + { + :puppet_agent_version => pa_version, + :puppet_agent_sha => nil, + :pe_ver => hosts[1][:pe_ver], + :puppet_collection => nil + } + ).once + expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( + hosts[2], + { + :puppet_agent_version => pa_version, + :puppet_agent_sha => nil, + :pe_ver => hosts[2][:pe_ver], + :puppet_collection => nil + } + ).once hosts.each do |host| expect( subject ).to receive( :configure_type_defaults_on ).with( host ).once expect( subject ).to receive( :sign_certificate_for ).with( host ).once @@ -812,6 +829,9 @@ def slice_installer_options(host) hosts[2][:platform] = Beaker::Platform.new('el-6-x86_64') hosts[2][:pe_ver] = '3.8' + pa_version = 'rarified_air_1675' + allow( subject ).to receive( :get_puppet_agent_version ).and_return( pa_version ) + allow( subject ).to receive( :hosts ).and_return( hosts ) allow( subject ).to receive( :options ).and_return(Beaker::Options::Presets.new.presets) allow( subject ).to receive( :on ).and_return( Beaker::Result.new( {}, '' ) ) @@ -834,8 +854,15 @@ def slice_installer_options(host) expect( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ).once #run installer on all hosts expect( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ).once - expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[1], - {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[1][:pe_ver], :puppet_collection=>nil} ).once + expect( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( + hosts[1], + { + :puppet_agent_version => pa_version, + :puppet_agent_sha => nil, + :pe_ver => hosts[1][:pe_ver], + :puppet_collection => nil + } + ).once expect( subject ).to receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once hosts.each do |host| expect( subject ).to receive( :configure_type_defaults_on ).with( host ).once @@ -871,6 +898,9 @@ def slice_installer_options(host) opts[:HOSTS][host.name] = host end + pa_version = 'rarified_air_75699' + allow( subject ).to receive( :get_puppet_agent_version ).and_return( pa_version ) + allow( subject ).to receive( :hosts ).and_return( hosts ) allow( subject ).to receive( :options ).and_return(Beaker::Options::Presets.new.presets) allow( subject ).to receive( :on ).and_return( Beaker::Result.new( {}, '' ) ) @@ -893,8 +923,15 @@ def slice_installer_options(host) allow( subject ).to receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ) #run installer on all hosts allow( subject ).to receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ) - allow( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( hosts[1], - {:puppet_agent_version=>nil, :puppet_agent_sha=>nil, :pe_ver=>hosts[1][:pe_ver], :puppet_collection=>nil} ) + allow( subject ).to receive( :install_puppet_agent_pe_promoted_repo_on ).with( + hosts[1], + { + :puppet_agent_version => pa_version, + :puppet_agent_sha => nil, + :pe_ver => hosts[1][:pe_ver], + :puppet_collection => nil + } + ) # expect( subject ).to receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once hosts.each do |host| allow( subject ).to receive( :add_pe_defaults_on ).with( host ) unless subject.aio_version?(host) @@ -1202,4 +1239,45 @@ def slice_installer_options(host) end end + describe '#get_puppet_agent_version' do + + context 'when the puppet_agent version is set on an argument' do + + it 'uses host setting over all others' do + pa_version = 'pants of the dance' + host_arg = { :puppet_agent_version => pa_version } + expect( subject.get_puppet_agent_version( host_arg ) ).to be === pa_version + end + + it 'uses local options over all others (except host setting)' do + pa_version = 'who did it?' + local_options = { :puppet_agent_version => pa_version } + expect( subject.get_puppet_agent_version( {}, local_options ) ).to be === pa_version + end + end + + context 'when the puppet_agent version has to be read dynamically' do + + before :each do + allow( subject ).to receive( :master ).and_return( {} ) + @result_mock = Object.new + @pa_version = 'pa_version_' + @pa_version << rand(10 ** 5).to_s.rjust(5,'0') # 5 digit random number string + json_hash = "{ \"values\": { \"aio_agent_build\": \"#{@pa_version}\" }}" + allow( @result_mock ).to receive( :stdout ).and_return( json_hash ) + allow( subject ).to receive( :on ).and_return( @result_mock ) + end + + it 'parses and returns the command output correctly' do + expect( subject.get_puppet_agent_version( {} ) ).to be === @pa_version + end + + it 'saves the puppet_agent version in the local_options argument' do + local_options_hash = {} + subject.get_puppet_agent_version( {}, local_options_hash ) + expect( local_options_hash[:puppet_agent_version] ).to be === @pa_version + end + end + end + end