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

Fixes #33620 - Command for upgrading foreman-maintain to major version #546

Merged
merged 5 commits into from
Nov 24, 2021

Conversation

upadhyeammit
Copy link
Contributor

No description provided.

@theforeman-bot
Copy link
Member

Issues: #33620

@upadhyeammit
Copy link
Contributor Author

This covers below use cases:

  1. Does not limit users to upgrade foreman-maintain package from just next major version. This is considering administrator knows what he is doing and in future if skipped version upgrade is possible?
  2. Does not allow user to upgrade package from current version of Satellite as that should be handled by already available upgrade mechanism followed by the upgrade.
  3. Disables the new maintenance repository on successful upgrade and re-enables repositories which were configured on the system.
  4. Failure in package upgrade rescued, it does not rescue the failure of enabling the repository using yum-config-manager. The rescue steps disables the new maintenance repository and re-enables repos which were configured on system.
  5. Takes cares of situation when trying to enable different major version repos can dump enabled_repos.yml file with multiple maintenance repositories. Allows only one maintenance repository on system as per the version.
  6. Introduces a procedure to dump the enabled repo ids on disk.
  7. Does not allow to enable N-1 version maintenance repository.
  8. While doing the upgrade only specific maintenance repository is enabled and no other repositories are enabled.

@upadhyeammit
Copy link
Contributor Author

@evgeni @ekohl this is not urgent, whenever time permits request to review.

Comment on lines 29 to 33
@stored_enabled_repos_ids = []
backup_dir = File.expand_path(ForemanMaintain.config.backup_dir)
File.open(File.join(backup_dir, 'enabled_repos.yml'), 'r') do |repos_file|
@stored_enabled_repos_ids = YAML.load(repos_file.read)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file doesn't have to exist. BackupEnabledRepos only writes it if it's non-empty. I think this would fail then. It also won't be in older backups. You probably need to deal with that to prevent exceptions. You could also use File.read instead of File.open + .read, but that's a small nit.

Suggested change
@stored_enabled_repos_ids = []
backup_dir = File.expand_path(ForemanMaintain.config.backup_dir)
File.open(File.join(backup_dir, 'enabled_repos.yml'), 'r') do |repos_file|
@stored_enabled_repos_ids = YAML.load(repos_file.read)
end
path = File.expand_path('enabled_repos.yml', ForemanMaintain.config.backup_dir)
@stored_enabled_repos_ids = File.file?(path) ? YAML.load(File.read(path)) : []

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, what I am expecting,

If system is not having any repositories enabled then not having the yml dump is fine. However this also let me thought the situation where yml file has old repositories which are not relevant to current state of the system and hence I feel I should clean up this file after successfully executing enable_repos(repos_ids_to_reenable).

definitions/scenarios/self_upgrade.rb Outdated Show resolved Hide resolved
lib/foreman_maintain/cli/self_upgrade_command.rb Outdated Show resolved Hide resolved
@ehelms
Copy link
Member

ehelms commented Oct 20, 2021

Is there a mechanism by which, for testing purposes, the repository handling could be skipped or configured to test this without first having to have the new maintenance repository in existence?

@upadhyeammit
Copy link
Contributor Author

Is there a mechanism by which, for testing purposes, the repository handling could be skipped or configured to test this without first having to have the new maintenance repository in existence?

I am pushing a new change which has additional flag to skip enabling repository

@ehelms
Copy link
Member

ehelms commented Oct 21, 2021

Thinking on testing, and ahead towards Foreman use case, if the repository could be made configurable either via a foreman-maintain configuration file or an ENV variable then the code becomes more usable and able to test by pointing it at whatever repository you want to get updates. Generally, trying to split the mechanism from the configuration (details) will allow flexibility.

@upadhyeammit
Copy link
Contributor Author

@ekohl @ehelms wish to know your thoughts on below use cases,

  1. The BackupEnabledRepos only does the backup when there are some repositories enabled. This exposes to the situation where we are having enabled_repos.yml file which has the stale repo details and we end up enabling those.
  2. I added the rescue scenario as I was under impression that we serialize and de serialize every scenario kind but that's not the case, I can see its implemented for upgrade scenario only. This means the self upgrade wont resume if we terminate the process in between.
  3. So without rescue scenario as we always want to re-enable repositories we have on system I can skip the storing part, however if user terminates the process before reenabling the repositories then we wont be able to restore the state of the repositories. This brings me to the first point of actually saving repos in yml and not writing anything to enabled_repos.yml if repolist is empty.

Technically I can just go and enable whatever the required repositories for the X.Y version of Satellite but then that wont work for disconnected setups and there can still be some repositories user has configured which we want to reenable.

backup_dir = File.expand_path(ForemanMaintain.config.backup_dir)
unless enabled_repos_ids.empty?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can only expand the path if there are any repos:

Suggested change
backup_dir = File.expand_path(ForemanMaintain.config.backup_dir)
unless enabled_repos_ids.empty?
unless enabled_repos_ids.empty?
backup_dir = File.expand_path(ForemanMaintain.config.backup_dir)

class SelfUpgradeRescue < SelfUpgradeBase
metadata do
label :rescue_self_upgrade
description 'Disables all version specific maintenance repo and,'\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description 'Disables all version specific maintenance repo and,'\
description 'Disables all version specific maintenance repos and,'\

Comment on lines 4 to 5
option ['--target-version'], 'TARGET_VERSION', 'Major version of the Satellite or Capsule'\
', e.g 7.0', :required => true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is allowed coding style wise, but it avoids breaking up the string which I think makes it easier to read.

Suggested change
option ['--target-version'], 'TARGET_VERSION', 'Major version of the Satellite or Capsule'\
', e.g 7.0', :required => true
option ['--target-version'], 'TARGET_VERSION',
'Major version of the Satellite or Capsule, e.g 7.0', :required => true

definitions/scenarios/self_upgrade.rb Outdated Show resolved Hide resolved
definitions/scenarios/self_upgrade.rb Outdated Show resolved Hide resolved
definitions/scenarios/self_upgrade.rb Outdated Show resolved Hide resolved
definitions/scenarios/self_upgrade.rb Outdated Show resolved Hide resolved
@upadhyeammit
Copy link
Contributor Author

Thinking on testing, and ahead towards Foreman use case, if the repository could be made configurable either via a foreman-maintain configuration file or an ENV variable then the code becomes more usable and able to test by pointing it at whatever repository you want to get updates. Generally, trying to split the mechanism from the configuration (details) will allow flexibility.

Now you can export the maintenance_repo env var and it will try to enable that repo to update package. I did not disable this repo considering it can be foreman repo itself.
Removed the option which I had introduced to skip repo enablement.

Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure about the inline comment. Overall I think this looks good from reading it, though I didn't test it.

end

def maintenance_repo_version
return '6' if current_version == '6.10'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering: would it technically be 6 for 6.*? Do you want compatibility with that or is it irrelevant? So:

Suggested change
return '6' if current_version == '6.10'
return '6' if current_version.start_with?('6.')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought to keep it 6.10 as new package wont be available for older versions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will we already have a separate repo for 6.10 then? Or is this procedure in some other way guarded to be unavailable on 6.9 and older?

@@ -29,6 +33,10 @@ def disable_repos(repo_ids)
execute!("yum-config-manager --disable #{repo_ids.join(',')}")
end

def enable_repos(repo_ids)
execute!("yum-config-manager --enable #{repo_ids.join(',')}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least on EL8 this is not present by default.

given this is also used in disable_repos which is old code, I guess we should add this to "EL8" todos, as it's not strictly related to this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, this won't be a factor until upgrades to 7.1 or upstream makes use of this. I'm fine with leaving as is and tackling later if we have a EL8 tracker somewhere to add this to?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ekohl
Copy link
Member

ekohl commented Oct 26, 2021

3\. This brings me to the first point of actually saving repos in yml and not writing anything to `enabled_repos.yml` if repolist is empty.

I do think this is a good idea. This allows you to distinguish offline setups from setups. That said, you should still deal with the file missing in a way that it doesn't hard crash foreman_maintain.

Copy link
Member

@ehelms ehelms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a few comments to address or resolve, so I will leave those to also be tackled. I think this looks good at the moment and is good to merge until we have all the repositories in place to test.

@ehelms
Copy link
Member

ehelms commented Nov 18, 2021

@upadhyeammit looks good! I think this can be squashed and merged.

@upadhyeammit
Copy link
Contributor Author

@ehelms there were few things I have handled in latest commit. The confine block is not working for the scenario out of the box, need to check what is missing for that. Accordingly as of now this scenario is limited using if condition in compose. And I will raise another pr to change it for PuppetDisable command as well.

@upadhyeammit
Copy link
Contributor Author

@ehelms changes have been pushed, if there are no more comments then I will squash and merge.

@upadhyeammit upadhyeammit merged commit 894e362 into theforeman:master Nov 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants