Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(MODULES-11113) Allow present and latest as package version #565

Merged
merged 4 commits into from
Jul 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ group :development do
gem "rake", '~> 12', require: false
gem "parallel_tests", '>= 2.14.1', '< 2.14.3', require: false
gem "metadata-json-lint", '>= 2.0.2', '< 3.0.0', require: false
gem "rspec-puppet-facts", '~> 1.10.0', require: false
gem "rspec-puppet-facts", '~> 2.0.1', require: false
gem "rspec_junit_formatter", '~> 0.2', require: false
gem "rubocop", '~> 0.49.0', require: false
gem "rubocop-rspec", '~> 1.16.0', require: false
gem "rubocop-i18n", '~> 1.2.0', require: false
gem "puppetlabs_spec_helper", '>= 2.9.0', '< 3.0.0', require: false
gem "puppet-module-posix-default-r#{minor_version}", require: false, platforms: "ruby"
gem "puppet-module-win-default-r#{minor_version}", require: false, platforms: ["mswin", "mingw", "x64_mingw"]
gem "rspec-puppet", require: true, git: "https://github.com/rodjek/rspec-puppet", tag: "v2.7.9"
gem "rspec-puppet", require: true
gem 'rspec-expectations', '~> 3.9.0', require: false
gem "json_pure", '<= 2.0.1', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
gem "fast_gettext", '1.1.0', require: false if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.1.0')
Expand Down
10 changes: 9 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Previous releases of this module, now unsupported, upgraded agents from later ve

The puppet_agent module installs the appropriate official Puppet package repository (on systems that support repositories); migrates configuration required by Puppet to new locations used by puppet-agent; and installs the puppet-agent package, removing the previous Puppet installation.

If a package_version parameter is provided, it will ensure that puppet-agent version is installed. The package_version parameter is required to perform upgrades starting from a puppet-agent package, also this parameter can be set to "auto", ensuring that agent version matches the version on the master without having to manually update package_version after upgrading the master(s).
If a package_version parameter is provided, it will ensure that puppet-agent version is installed. The package_version parameter is required to perform upgrades starting from a puppet-agent package, also this parameter can be set to "auto", ensuring that agent version matches the version on the master without having to manually update package_version after upgrading the master(s). On platforms that install packages through repos (EL, Fedora, Debian, Ubuntu, SLES), the parameter can be set to "latest" in order to install the latest available package. To only ensure the presence of the package, the parameter can be set to "present".

If a config parameter is provided, it will manage the defined agent configuration settings.

Expand Down Expand Up @@ -191,6 +191,14 @@ or
``` puppet
package_version => 'auto'
```
or
``` puppet
package_version => 'latest'
```
or
``` puppet
package_version => 'present'
```

##### `service_names`

Expand Down
8 changes: 7 additions & 1 deletion acceptance/tests/test_upgrade_puppet5_to_puppet6.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@
step "Create new site.pp with upgrade manifest" do
manifest = <<-PP
node default {
if $::osfamily =~ /^(?i:windows|solaris|aix|darwin)$/ {
$_package_version = '#{latest_version}'
} else {
$_package_version = 'latest'
}

class { puppet_agent:
package_version => '#{latest_version}',
package_version => $_package_version,
apt_source => 'http://nightlies.puppet.com/apt',
yum_source => 'http://nightlies.puppet.com/yum',
windows_source => 'http://nightlies.puppet.com/downloads',
Expand Down
8 changes: 7 additions & 1 deletion acceptance/tests/test_upgrade_puppet6_to_puppet7.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@
step "Create new site.pp with upgrade manifest" do
manifest = <<-PP
node default {
if $::osfamily =~ /^(?i:windows|solaris|aix|darwin)$/ {
$_package_version = '#{latest_version}'
} else {
$_package_version = 'latest'
}

class { puppet_agent:
package_version => '#{latest_version}',
package_version => $_package_version,
apt_source => 'http://nightlies.puppet.com/apt',
yum_source => 'http://nightlies.puppet.com/yum',
windows_source => 'http://nightlies.puppet.com/downloads',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ def needs_upgrade?
current_version = Facter.value('aio_agent_version')
desired_version = @resource.name

return false if desired_version == 'present'

if desired_version == 'latest'
latest_version = @resource.catalog.resource('package', 'puppet-agent').parameters[:ensure].latest
desired_version = latest_version.match(%r{^(?:[0-9]:)?(\d+\.\d+(\.\d+)?(?:\.\d+))?}).captures.first
end

Puppet::Util::Package.versioncmp(desired_version, current_version) != 0
end
end
25 changes: 18 additions & 7 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@
fail('The puppet_agent module does not support pre-Puppet 4 upgrades.')
}

if $package_version == 'latest' and $::osfamily =~ /^(?i:windows|solaris|aix|darwin)$/ {
fail("Setting package_version to 'latest' is not supported on ${::osfamily.capitalize()}")
}

if $source != undef and $absolute_source != undef {
fail('Only one of $source and $absolute_source can be set')
}
Expand Down Expand Up @@ -166,12 +170,11 @@
}

if $::osfamily == 'redhat' {
if $master_or_package_version !~ /^\d+\.\d+\.\d+.*$/ {
if $master_or_package_version !~ /^\d+\.\d+\.\d+.*$|^latest$|^present$/ {
fail("invalid version ${master_or_package_version} requested")
}
}
else {
if $master_or_package_version !~ /^\d+\.\d+\.\d+([.-]?\d*|\.\d+\.g[0-9a-f]+)$/ {
} else {
if $master_or_package_version !~ /^\d+\.\d+\.\d+([.-]?\d*|\.\d+\.g[0-9a-f]+)$|^latest$|^present$/ {
fail("invalid version ${master_or_package_version} requested")
}
}
Expand All @@ -180,13 +183,21 @@
if $master_or_package_version =~ /.g/ {
$_expected_package_version = split($master_or_package_version, /[.-]g.*/)[0]
} elsif $::osfamily == 'redhat' {
$_expected_package_version = $master_or_package_version.match(/^\d+\.\d+\.\d+/)[0]
$_expected_package_version = $master_or_package_version.match(/^\d+\.\d+\.\d+|^latest$|^present$/)[0]
} else {
$_expected_package_version = $master_or_package_version
}

$aio_upgrade_required = versioncmp($::aio_agent_version, $_expected_package_version) < 0
$aio_downgrade_required = versioncmp($::aio_agent_version, $_expected_package_version) > 0
if $_expected_package_version == 'latest' {
$aio_upgrade_required = true
$aio_downgrade_required = false
} elsif $_expected_package_version == 'present' {
$aio_upgrade_required = false
$aio_downgrade_required = false
} else {
$aio_upgrade_required = versioncmp($::aio_agent_version, $_expected_package_version) < 0
$aio_downgrade_required = versioncmp($::aio_agent_version, $_expected_package_version) > 0
}

if $aio_upgrade_required {
if any_resources_of_type('filebucket', { path => false }) {
Expand Down
6 changes: 3 additions & 3 deletions manifests/install.pp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
}
} elsif $::osfamily == 'suse' {
# Prevent re-running the batch install
if ($puppet_agent::aio_upgrade_required) or ($puppet_agent::aio_downgrade_required){
if ($package_version =~ /^latest$|^present$/) or ($puppet_agent::aio_upgrade_required) or ($puppet_agent::aio_downgrade_required){
class { 'puppet_agent::install::suse':
package_version => $package_version,
install_options => $install_options,
Expand All @@ -67,7 +67,7 @@
$_source = "${::puppet_agent::params::local_packages_dir}/${::puppet_agent::prepare::package::package_file_name}"
} else {
# any other type of source means we use apt with no 'source' defined in the package resource below
if $package_version == 'present' {
if $package_version =~ /^latest$|^present$/ {
$_package_version = $package_version
} else {
$_package_version = "${package_version}-1${::lsbdistcodename}"
Expand All @@ -91,7 +91,7 @@
$_source = undef
}
}
$_aio_package_version = $package_version.match(/^\d+\.\d+\.\d+(\.\d+)?/)[0]
$_aio_package_version = $package_version.match(/^\d+\.\d+\.\d+(\.\d+)?|^latest$|^present$/)[0]
package { $::puppet_agent::package_name:
ensure => $_package_version,
install_options => $_install_options,
Expand Down
2 changes: 1 addition & 1 deletion manifests/install/suse.pp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
$_source = undef
}

$_aio_package_version = $package_version.match(/^\d+\.\d+\.\d+(\.\d+)?/)[0]
$_aio_package_version = $package_version.match(/^\d+\.\d+\.\d+(\.\d+)?|^latest$|^present$/)[0]
package { $::puppet_agent::package_name:
ensure => $package_version,
install_options => $install_options,
Expand Down
39 changes: 27 additions & 12 deletions manifests/osfamily/suse.pp
Original file line number Diff line number Diff line change
Expand Up @@ -143,21 +143,36 @@
}

$repo_settings.each |String $setting, String $value| {
ini_setting { "zypper ${repo_name} ${setting}":
ensure => present,
path => $repo_file,
section => $repo_name,
setting => $setting,
value => $value,
before => Exec["refresh-${repo_name}"],
if $_package_version =~ /^present$|^latest$/ {
ini_setting { "zypper ${repo_name} ${setting}":
ensure => present,
path => $repo_file,
section => $repo_name,
setting => $setting,
value => $value,
}
} else {
ini_setting { "zypper ${repo_name} ${setting}":
ensure => present,
path => $repo_file,
section => $repo_name,
setting => $setting,
value => $value,
before => Exec["refresh-${repo_name}"],
}
}
}

exec { "refresh-${repo_name}":
path => '/bin:/usr/bin:/sbin:/usr/sbin',
unless => "zypper search -r ${repo_name} -s | grep puppet-agent | awk '{print \$7}' | grep \"^${_package_version}\"",
command => "zypper refresh ${repo_name}",
logoutput => 'on_failure',
# If the requested package is "latest" we don't know the exact version yet,
# so we can't reliably refresh the repo. If "present", the repo contents don't
# matter at all if a version is already installed.
unless $_package_version =~ /^present$|^latest$/ {
exec { "refresh-${repo_name}":
path => '/bin:/usr/bin:/sbin:/usr/sbin',
unless => "zypper search -r ${repo_name} -s | grep puppet-agent | awk '{print \$7}' | grep \"^${_package_version}\"",
command => "zypper refresh ${repo_name}",
logoutput => 'on_failure',
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion spec/classes/puppet_agent_osfamily_solaris_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def install_script(ver, arch)

# Ensure we get a versionable package provider
pkg = Puppet::Type.type(:package)
pkg.stubs(:defaultprovider).returns(pkg.provider(:pkg))
allow(pkg).to receive(:defaultprovider).and_return(pkg.provider(:pkg))
end

context "when Solaris 11 i386 and a custom source" do
Expand Down
28 changes: 27 additions & 1 deletion spec/classes/puppet_agent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def global_facts(facts, os)

context 'package version' do
context 'valid' do
['5.5.15-1.el7', '5.5.15.el7', '6.0.9.3.g886c5ab'].each do |version|
['5.5.15-1.el7', '5.5.15.el7', '6.0.9.3.g886c5ab', 'present', 'latest'].each do |version|

redhat_familly_supported_os.each do |os, facts|
let(:facts) { global_facts(facts, os) }
Expand Down Expand Up @@ -92,6 +92,32 @@ def global_facts(facts, os)
end
end
end

context 'latest' do
context 'on unsupported platform' do
on_supported_os.select { |platform, _| platform =~ /solaris|aix|windows|osx/ }.each do |os, facts|
let(:facts) { global_facts(facts, os) }
let(:params) { { package_version: 'latest' } }

context os do
it { is_expected.not_to compile }
it { expect { catalogue }.to raise_error(Puppet::Error, /Setting package_version to 'latest' is not supported/) }
end
end
end

context 'on supported platform' do
on_supported_os.reject { |platform, _| platform =~ /solaris|aix|windows|osx/ }.each do |os, facts|
let(:facts) { global_facts(facts, os) }
let(:params) { { package_version: 'latest' } }

context os do
it { is_expected.to compile.with_all_deps }
it { expect { catalogue }.not_to raise_error }
end
end
end
end
end

context 'supported_operating systems' do
Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
end

RSpec.configure do |c|
c.mock_with :rspec
c.before :each do
Puppet::Parser::Functions.newfunction(:pe_build_version, type: :rvalue, doc: '') do |args|
'2018.1.0'
Expand Down
112 changes: 112 additions & 0 deletions spec/unit/puppet/provider/puppet_agent_end_run_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
require 'spec_helper'

describe Puppet::Type.type(:puppet_agent_end_run).provider(:puppet_agent_end_run) do
let(:catalog) { Puppet::Resource::Catalog.new }

before do
allow(Facter).to receive(:value)
end

context 'when package_version is latest' do
let(:resource) do
Puppet::Type.type(:puppet_agent_end_run).new(:name => 'latest', :provider => :puppet_agent_end_run)
end

let(:agent_latest_package) do
Puppet::Type.type(:package).new(:name => 'puppet-agent', :ensure => 'latest', :provider => :yum)
end

before do
catalog.add_resource(agent_latest_package)
resource.catalog = catalog
end

context 'with dev versions' do
it 'does not stop the run if package is already latest' do
catalog.resource('package', 'puppet-agent').parameters[:ensure].latest = '0:7.8.0.64.g6670bf40b-1.el8'
allow(Facter).to receive(:value).with('aio_agent_version').and_return('7.8.0.64')
expect(Puppet::Application).not_to receive(:stop!)

resource.provider.stop
end

it 'stops the run if the current and desired versions differ' do
catalog.resource('package', 'puppet-agent').parameters[:ensure].latest = '0:7.8.0.64.g6670bf40b-1.el8'
allow(Facter).to receive(:value).with('aio_agent_version').and_return('7.8.0.32')
expect(Puppet::Application).to receive(:stop!)

resource.provider.stop
end
end

context 'with released versions' do
it 'does not stop the run if package is already latest' do
catalog.resource('package', 'puppet-agent').parameters[:ensure].latest = '7.8.0-1.el8'
allow(Facter).to receive(:value).with('aio_agent_version').and_return('7.8.0')
expect(Puppet::Application).not_to receive(:stop!)

resource.provider.stop
end


it 'stops the run if the current and desired versions differ' do
catalog.resource('package', 'puppet-agent').parameters[:ensure].latest = '7.9.0-1.el8'
allow(Facter).to receive(:value).with('aio_agent_version').and_return('7.8.0')
expect(Puppet::Application).to receive(:stop!)

resource.provider.stop
end
end
end

context 'when package_version is present' do
let(:resource) do
Puppet::Type.type(:puppet_agent_end_run).new(:name => 'present', :provider => :puppet_agent_end_run)
end

it 'never stops the run' do
expect(Puppet::Application).not_to receive(:stop!)
resource.provider.stop
end
end

context 'when package_version is a released version' do
let(:resource) do
Puppet::Type.type(:puppet_agent_end_run).new(:name => '7.8.0', :provider => :puppet_agent_end_run)
end

it 'does not stop the run if current and desired versions match' do
allow(Facter).to receive(:value).with('aio_agent_version').and_return('7.8.0')
expect(Puppet::Application).not_to receive(:stop!)

resource.provider.stop
end

it 'stops the run if current and desired versions do not match' do
allow(Facter).to receive(:value).with('aio_agent_version').and_return('7.7.0')
expect(Puppet::Application).to receive(:stop!)

resource.provider.stop
end
end

context 'when package_version is a nightly version' do
let(:resource) do
Puppet::Type.type(:puppet_agent_end_run).new(:name => '7.8.0.32', :provider => :puppet_agent_end_run)
end

it 'does not stop the run if current and desired versions match' do
allow(Facter).to receive(:value).with('aio_agent_version').and_return('7.8.0.32')
expect(Puppet::Application).not_to receive(:stop!)

resource.provider.stop
end

it 'stops the run if current and desired versions do not match' do
allow(Facter).to receive(:value).with('aio_agent_version').and_return('7.8.0')
expect(Puppet::Application).to receive(:stop!)

resource.provider.stop
end
end
end