-
Notifications
You must be signed in to change notification settings - Fork 0
feat(installation): Add task to remove db migrations #89
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,159 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require 'rake/testtask' | ||
| require 'set' | ||
| require 'pulp_ansible_client' | ||
|
|
||
| module ForemanAnsibleDirector | ||
| module TaskHelpers | ||
| module_function | ||
|
|
||
| ANSIBLE_DIRECTOR_FEATURE = 'Ansible_Director' | ||
| PULP_PAGE_SIZE = 1000 | ||
| PULP_CLEANUP_RESOURCES = { | ||
| distribution: { | ||
| api_class: ::PulpAnsibleClient::DistributionsAnsibleApi, | ||
| action: 'ForemanAnsibleDirector::Actions::Pulp3::Ansible::Distribution::Destroy', | ||
| input_key: :distribution_href, | ||
| }, | ||
| repository: { | ||
| api_class: ::PulpAnsibleClient::RepositoriesAnsibleApi, | ||
| action: 'ForemanAnsibleDirector::Actions::Pulp3::Ansible::Repository::Destroy', | ||
| input_key: :repository_href, | ||
| }, | ||
| git_remote: { | ||
| api_class: ::PulpAnsibleClient::RemotesGitApi, | ||
| action: 'ForemanAnsibleDirector::Actions::Pulp3::Ansible::Remote::Git::Destroy', | ||
| input_key: :git_remote_href, | ||
| }, | ||
| collection_remote: { | ||
| api_class: ::PulpAnsibleClient::RemotesCollectionApi, | ||
| action: 'ForemanAnsibleDirector::Actions::Pulp3::Ansible::Remote::Collection::Destroy', | ||
| input_key: :collection_remote_href, | ||
| }, | ||
| role_remote: { | ||
| api_class: ::PulpAnsibleClient::RemotesRoleApi, | ||
| action: 'ForemanAnsibleDirector::Actions::Pulp3::Ansible::Remote::Role::Destroy', | ||
| input_key: :role_remote_href, | ||
| }, | ||
| }.freeze | ||
|
|
||
| def records_exist?(records) | ||
| records.respond_to?(:exists?) ? records.exists? : records.any? | ||
| end | ||
|
|
||
| def ansible_director_proxies | ||
| ::SmartProxy.unscoped.with_features(ANSIBLE_DIRECTOR_FEATURE) | ||
| end | ||
|
|
||
| def ensure_ansible_director_proxy! | ||
| proxies = ansible_director_proxies | ||
| missing_feature_message = | ||
| 'No Smart Proxy with the Ansible_Director feature is available for Foreman Ansible Director Pulp cleanup.' | ||
| raise Foreman::Exception, missing_feature_message unless records_exist?(proxies) | ||
|
|
||
| proxy = proxies.first | ||
| return if proxy&.url.present? | ||
|
|
||
| missing_url_message = | ||
| 'No Smart Proxy with a configured URL is available for Foreman Ansible Director Pulp cleanup.' | ||
| raise Foreman::Exception, missing_url_message | ||
| end | ||
|
Comment on lines
+49
to
+61
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know there is something similar in the proxy base client but I thought it might be a good idea to check on the proxy before even starting a task not when the task is running or whenever this is evaluated. |
||
|
|
||
| def destroy_pulp_object(deleted_hrefs, key, href, action, input_key) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it posible to re-use the introduced labels 1be49d4#diff-bc0ac4dcf2708e3d510050a532b88b8bde8d3e97af27d3b9bde58b62ea777005R13 to find and remove the pulp content / images?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean we could have a call to Pulp which simply removes everything with one specific label?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes. this should be possible - for each remote / distribution / publication / etc. |
||
| return if href.blank? || deleted_hrefs[key].include?(href) | ||
|
|
||
| ForemanTasks.sync_task(action, input_key => href) | ||
| deleted_hrefs[key] << href | ||
| end | ||
|
|
||
| def cleanup_pulp_objects(deleted_hrefs) | ||
| PULP_CLEANUP_RESOURCES.each do |resource_type, resource_config| | ||
| cleanup_resource_hrefs(resource_type, resource_config, deleted_hrefs) | ||
| end | ||
| end | ||
|
|
||
| def cleanup_resource_hrefs(resource_type, resource_config, deleted_hrefs) | ||
| action_class = resource_config[:action].constantize | ||
|
|
||
| fetch_pulp_hrefs(resource_config).each do |href| | ||
| destroy_pulp_object( | ||
| deleted_hrefs, | ||
| resource_type, | ||
| href, | ||
| action_class, | ||
| resource_config[:input_key] | ||
| ) | ||
| end | ||
| end | ||
|
|
||
| def fetch_pulp_hrefs(resource_config) | ||
| api_client = resource_config[:api_class].new(::ForemanAnsibleDirector::Pulp3::BaseClient.ansible_api_client) | ||
| offset = 0 | ||
| hrefs = [] | ||
|
|
||
| loop do | ||
| response = api_client.list( | ||
| limit: PULP_PAGE_SIZE, | ||
| offset: offset, | ||
| pulp_label_select: pulp_label_select | ||
| ) | ||
|
|
||
| hrefs.concat(response.results.map(&:pulp_href)) | ||
|
|
||
| offset += PULP_PAGE_SIZE | ||
| break if response.results.empty? || offset >= response.count | ||
| end | ||
|
|
||
| hrefs | ||
| end | ||
|
|
||
| def pulp_label_select | ||
| ::ForemanAnsibleDirector::Constants::PULP_OBJECT_LABELS.map do |key, value| | ||
| "#{key}=#{value}" | ||
| end.join(',') | ||
| end | ||
|
|
||
| def build_deleted_hrefs | ||
| PULP_CLEANUP_RESOURCES.each_key.with_object({}) do |resource_type, deleted_hrefs| | ||
| deleted_hrefs[resource_type] = Set.new | ||
| end | ||
| end | ||
| end | ||
| end | ||
|
|
||
| # Tasks | ||
| namespace :foreman_ansible_director do | ||
| desc 'Delete all Pulp objects associated with imported content unit versions' | ||
| task cleanup_pulp_objects: ['environment', 'dynflow:client'] do | ||
| ::ForemanAnsibleDirector::TaskHelpers.ensure_ansible_director_proxy! | ||
|
|
||
| previous_value = Rails.application.config.x.ansible_director.running_in_rake | ||
| Rails.application.config.x.ansible_director.running_in_rake = true | ||
|
|
||
| begin | ||
| # Track Pulp hrefs that have already been deleted so each labeled resource | ||
| # is destroyed only once, even if Pulp returns duplicates across pages. | ||
| deleted_hrefs = ::ForemanAnsibleDirector::TaskHelpers.build_deleted_hrefs | ||
|
|
||
| ::ForemanAnsibleDirector::TaskHelpers.cleanup_pulp_objects(deleted_hrefs) | ||
| ensure | ||
| Rails.application.config.x.ansible_director.running_in_rake = previous_value | ||
| end | ||
| end | ||
|
|
||
| desc 'Run all Foreman Ansible Director cleanup tasks' | ||
| task cleanup_all: :environment do | ||
| Rake::Task['foreman_ansible_director:cleanup_pulp_objects'].invoke | ||
| Rake::Task['foreman_ansible_director:revert_db_migrations'].invoke | ||
| end | ||
|
|
||
| desc 'Revert all database migrations of this plugin, preparing plugin uninstall' | ||
| task revert_db_migrations: :environment do | ||
| plugin = Foreman::Plugin.find ForemanAnsibleDirector.name.underscore | ||
| ActiveRecord::MigrationContext.new(plugin.migrations_paths, ActiveRecord::SchemaMigration).down | ||
| end | ||
| end | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this will cut it.
I intend to add a consistency check in general, which will do a mix of both, so this problem may already be solved in the future. |
||
|
|
||
| # Tests | ||
| namespace :test do | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like this. But it does not seem to work otherwise, even if I add a Rails flag. Maybe because the task is created in rake env but then scheduled from the Rails application. Not sure what exactly happens here. However, something similar seems to exist in Katello:
https://github.com/Katello/katello/blob/master/app/models/katello/concerns/smart_proxy_extensions.rb#L88