Skip to content

Commit

Permalink
Fail self-upgrade if current and target version are different
Browse files Browse the repository at this point in the history
  • Loading branch information
ehelms committed Jun 4, 2024
1 parent 29abb20 commit 7dd0f55
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 28 deletions.
12 changes: 12 additions & 0 deletions definitions/features/foreman_install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,16 @@ class Features::ForemanInstall < ForemanMaintain::Feature
!feature(:instance).downstream && feature(:foreman_server)
end
end

def target_version
'3.11'
end

def current_version
@current_version ||= package_version(package_name)
end

def package_name
'foreman'
end
end
4 changes: 4 additions & 0 deletions definitions/features/satellite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class Features::Satellite < ForemanMaintain::Feature
end
end

def target_version
'6.16'
end

def current_version
@current_version ||= package_version(package_name) || version_from_source
end
Expand Down
44 changes: 35 additions & 9 deletions definitions/scenarios/self_upgrade.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@ class SelfUpgradeBase < ForemanMaintain::Scenario
include ForemanMaintain::Concerns::Versions

def target_version
@target_version ||= Gem::Version.new(current_version).bump.to_s
if feature(:instance).downstream
feature(:satellite).target_version
else
feature(:foreman_install).target_version
end
end

def current_version
feature(:instance).downstream.current_version.to_s[/^\d+\.\d+\.\d+/]
version = if feature(:instance).downstream
feature(:instance).downstream.current_version
else
feature(:instance).foreman_install.current_version
end

version.to_s[/^\d+\.\d+\.\d+/]
end

def maintenance_repo_label
Expand Down Expand Up @@ -47,12 +57,12 @@ def req_repos_to_update_pkgs
end
end

def upstream_target_version
if feature(:katello_install)
return foreman_version_by_katello(target_version)
else
target_version
end
def upgrade_allowed?
Gem::Version.new(current_version) == Gem::Version.new(target_version)
end

def version_difference
((Gem::Version.new(target_version).version.to_f - current_version.to_f).round(2) * 100).to_i
end
end

Expand All @@ -65,6 +75,22 @@ class SelfUpgrade < SelfUpgradeBase
end

def downstream_self_upgrade(pkgs_to_update)
unless upgrade_allowed?
if version_difference > 1
raise(
ForemanMaintain::Error::Warn,
"foreman-maintain is too many versions ahead, given the" \
"target version is #{target_version}. Please rollback " \
"foreman-maintain to the proper version."
)
else
raise(
ForemanMaintain::Error::Warn,
"self-upgrade has already been executed, and is ready to upgrade to #{target_version}"
)
end
end

ForemanMaintain.enable_maintenance_module

add_step(Procedures::Packages::Update.new(packages: pkgs_to_update, assumeyes: true,
Expand All @@ -77,7 +103,7 @@ def upstream_self_upgrade(pkgs_to_update)
# 2. Update the foreman-maintain packages from next major version repository
# 3. Rollback the repository to current major version

add_step(Procedures::Repositories::Setup.new(:version => upstream_target_version))
add_step(Procedures::Repositories::Setup.new(:version => target_version))
add_step(Procedures::Packages::Update.new(packages: pkgs_to_update, assumeyes: true))
ensure
rollback_repositories
Expand Down
116 changes: 97 additions & 19 deletions test/definitions/scenarios/self_upgrade_test.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,107 @@
require 'test_helper'
require_relative '../test_helper'
require_relative '../../../definitions/scenarios/self_upgrade'

module Scenarios
describe ForemanMaintain::Scenarios::SelfUpgradeBase do
include DefinitionsTestHelper
describe ForemanMaintain::Scenarios::SelfUpgradeBase do
include ::DefinitionsTestHelper

describe 'with default params' do
let(:scenario) do
ForemanMaintain::Scenarios::SelfUpgradeBase.new
end
before do
File.stubs(:exist?).with('/etc/redhat-release').returns(true)
end

let(:scenario) do
ForemanMaintain::Scenarios::SelfUpgradeBase.new
end

it 'computes the target version correctly for downstream' do
assume_satellite_present

assert_equal '6.16', scenario.target_version
end

it 'returns target version correctly for upstream' do
assume_feature_present(:foreman_install)

it 'computes the target version correctly coming from normal release 6.10.0' do
assume_satellite_present do |feature_class|
feature_class.any_instance.stubs(:current_version => version('6.10.0'))
end
assert_equal '3.11', scenario.target_version
end

it 'allow upgrade when versions are equal' do
assume_satellite_present
scenario.expects(:current_version).returns('6.16')
scenario.expects(:target_version).returns('6.16')

assert scenario.upgrade_allowed?
end

it 'does not allow upgrade when versions are off by 1' do
assume_satellite_present
scenario.expects(:current_version).returns('6.15')
scenario.expects(:target_version).returns('6.16')

refute scenario.upgrade_allowed?
end

assert_equal '6.11', scenario.target_version
end
it 'does not allow upgrade when versions are off by 2 or more' do
assume_satellite_present
scenario.expects(:current_version).returns('6.14')
scenario.expects(:target_version).returns('6.16')

refute scenario.upgrade_allowed?
end
end

describe ForemanMaintain::Scenarios::SelfUpgrade do
include ::DefinitionsTestHelper

before do
File.stubs(:exist?).with('/etc/redhat-release').returns(true)
end

it 'runs successfully for downstream' do
ForemanMaintain.
package_manager.
expects(:find_installed_package).
with('satellite', "%{VERSION}").
returns('6.16.0')
assume_feature_present(:satellite)
scenario = ForemanMaintain::Scenarios::SelfUpgrade.new
scenario.expects(:target_version).twice.returns('6.16')
scenario.compose

assert run_step(scenario)
end

it 'fails if versions are off 1' do
ForemanMaintain.
package_manager.
expects(:find_installed_package).
with('satellite', "%{VERSION}").
returns('6.15.0')
assume_feature_present(:satellite)

msg = "self-upgrade has already been executed, and is ready to upgrade to 6.16"
assert_raises(ForemanMaintain::Error::Warn, msg) do
scenario = ForemanMaintain::Scenarios::SelfUpgrade.new
scenario.expects(:target_version).twice.returns('6.16')
scenario.compose
end
end

it 'computes the target version correctly coming from an async release 6.11.1.1' do
assume_satellite_present do |feature_class|
feature_class.any_instance.stubs(:current_version => version('6.11.1.1'))
end
it 'fails if versions are off 2 or more' do
ForemanMaintain.
package_manager.
expects(:find_installed_package).
with('satellite', "%{VERSION}").
returns('6.14.0')
assume_feature_present(:satellite)

assert_equal '6.12', scenario.target_version
end
msg = "foreman-maintain is too many versions ahead, given the " \
"target version is 6.16. Please rollback foreman-maintain " \
"to the proper version."
assert_raises(ForemanMaintain::Error::Warn, msg) do
scenario = ForemanMaintain::Scenarios::SelfUpgrade.new
scenario.expects(:target_version).twice.returns('6.16')
scenario.compose
end
end
end
1 change: 1 addition & 0 deletions test/definitions/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require File.expand_path('../test_helper', File.dirname(__FILE__))
require File.expand_path('assume_feature_dependencies_helper', File.dirname(__FILE__))

module DefinitionsTestHelper
include ForemanMaintain::Concerns::Finders
include ForemanMaintain::Concerns::SystemService
Expand Down

0 comments on commit 7dd0f55

Please sign in to comment.