Skip to content

Commit

Permalink
Capsule granular repair (Katello#10932)
Browse files Browse the repository at this point in the history
* Fixes #36803 - Add capsule repair tasks

* Fixes #37258 - Allow granular repair functionality for capsules
  • Loading branch information
sjha4 authored Apr 12, 2024
1 parent f3891b2 commit 03494ec
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 1 deletion.
24 changes: 24 additions & 0 deletions app/controllers/katello/api/v2/capsule_content_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,30 @@ def reclaim_space
respond_for_async :resource => task
end

api :POST, '/capsules/:id/content/verify_checksum', N_('Check for missing or corrupted artifacts, and attempt to redownload them.')
param :id, :number, :required => true, :desc => N_('Id of the smart proxy')
param :environment_id, Integer, :desc => N_('Id of the environment to limit verifying checksum on')
param :content_view_id, Integer, :desc => N_('Id of the content view to limit verifying checksum on')
param :repository_id, Integer, :desc => N_('Id of the repository to limit verifying checksum on')
def verify_checksum
find_capsule(false)
find_environment if params[:environment_id]
find_content_view if params[:content_view_id]
find_repository if params[:repository_id]

repair_options = {
:environment_id => @environment.try(:id),
:content_view_id => @content_view.try(:id),
:repository_id => @repository.try(:id)
}
repair_options[:environment_ids] = @capsule.lifecycle_environments&.pluck(:id) unless (@environment || @content_view || @repository)

task = async_task(::Actions::Katello::CapsuleContent::VerifyChecksum,
@capsule,
repair_options)
respond_for_async :resource => task
end

protected

def respond_for_lifecycle_environments_index(environments)
Expand Down
75 changes: 75 additions & 0 deletions app/lib/actions/katello/capsule_content/verify_checksum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
module Actions
module Katello
module CapsuleContent
class VerifyChecksum < ::Actions::EntryAction
def humanized_name
_("Verify checksum for content on smart proxy")
end

def plan(smart_proxy, options = {})
input[:options] = options
action_subject(smart_proxy)
fail _("Action not allowed for the default smart proxy.") if smart_proxy.pulp_primary?
subjects = subjects(options)
repair_options = options.merge(subjects)
environment = repair_options[:environment]
content_view = repair_options[:content_view]
check_cv_capsule_environments!(smart_proxy, content_view, environment)
repository = repair_options[:repository]
repos = repos_to_repair(smart_proxy, environment, content_view, repository)
repos.in_groups_of(Setting[:foreman_proxy_content_batch_size], false) do |repo_batch|
concurrence do
repo_batch.each do |repo|
if smart_proxy.pulp3_support?(repo)
plan_action(Actions::Pulp3::CapsuleContent::VerifyChecksum,
repo,
smart_proxy)
end
end
end
end
end

def repos_to_repair(smart_proxy, environment, content_view, repository)
smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
smart_proxy_helper.lifecycle_environment_check(environment, repository)
if repository
[repository]
else
repositories = smart_proxy_helper.repositories_available_to_capsule(environment, content_view).by_rpm_count
repositories
end
end

def check_cv_capsule_environments!(smart_proxy, content_view, environment)
cv_environments = content_view&.versions&.collect(&:environments)&.flatten
if cv_environments.present?
if environment.present? && !(cv_environments.pluck(:id).include? environment.id)
fail _("Content view '%{content_view}' is not attached to the environment.") % {content_view: content_view.name}
end
if (smart_proxy.lifecycle_environments.pluck(:id) & cv_environments.pluck(:id)).empty?
fail _("Content view '%{content_view}' is not attached to this capsule.") % {content_view: content_view.name}
end
end
end

def subjects(options = {})
environment_id = options.fetch(:environment_id, nil)
environment = ::Katello::KTEnvironment.find(environment_id) if environment_id

repository_id = options.fetch(:repository_id, nil)
repository = ::Katello::Repository.find(repository_id) if repository_id

content_view_id = options.fetch(:content_view_id, nil)
content_view = ::Katello::ContentView.find(content_view_id) if content_view_id

{content_view: content_view, environment: environment, repository: repository}
end

def rescue_strategy
Dynflow::Action::Rescue::Skip
end
end
end
end
end
27 changes: 27 additions & 0 deletions app/lib/actions/pulp3/capsule_content/verify_checksum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Actions
module Pulp3
module CapsuleContent
class VerifyChecksum < Pulp3::AbstractAsyncTask
def plan(repository, smart_proxy)
plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id)
end

def invoke_external_task
repo = ::Katello::Repository.find(input[:repository_id])
output[:pulp_tasks] = repo.backend_service(smart_proxy).with_mirror_adapter.repair
end

def repos_to_repair(smart_proxy, environment, content_view, repository)
smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
smart_proxy_helper.lifecycle_environment_check(environment, repository)
if repository
[repository]
else
repositories = smart_proxy_helper.repositories_available_to_capsule(environment, content_view).by_rpm_count
repositories
end
end
end
end
end
end
8 changes: 8 additions & 0 deletions app/services/katello/pulp3/api/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ def api_client_class(client)
client
end

def repair_api
PulpcoreClient::RepairApi.new(core_api_client)
end

def uploads_api
PulpcoreClient::UploadsApi.new(core_api_client)
end
Expand Down Expand Up @@ -230,6 +234,10 @@ def remotes_list_all(_smart_proxy, options = {})
end
end

def repair
repair_api.post(PulpcoreClient::Repair.new(verify_checksums: true))
end

def self.fetch_from_list
page_size = Setting[:bulk_load_size]
page_opts = { "offset" => 0, limit: page_size }
Expand Down
6 changes: 6 additions & 0 deletions app/services/katello/pulp3/repository_mirror.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ def create_distribution(path)
distribution_data = api.distribution_class.new(distribution_options(path))
repo_service.distributions_api.create(distribution_data)
end

def repair
data = api.repair_class.new
fail "Could not lookup a version_href for repo #{repo_service.repo.id}" if version_href.nil?
api.repository_versions_api.repair(version_href, data)
end
end
end
end
1 change: 1 addition & 0 deletions config/routes/api/v2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ActionDispatch::Routing::Mapper
get :sync, :action => :sync_status
delete :sync, :action => :cancel_sync
post :reclaim_space
post :verify_checksum
post '/lifecycle_environments' => 'capsule_content#add_lifecycle_environment'
delete '/lifecycle_environments/:environment_id' => 'capsule_content#remove_lifecycle_environment'
end
Expand Down
2 changes: 1 addition & 1 deletion lib/katello/permission_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def capsule_content_permissions
@plugin.permission :manage_capsule_content,
{
'katello/api/v2/capsule_content' => [:add_lifecycle_environment, :remove_lifecycle_environment,
:update_counts, :sync, :reclaim_space, :cancel_sync],
:update_counts, :sync, :reclaim_space, :verify_checksum, :cancel_sync],
'katello/api/v2/capsules' => [:index, :show]
},
:resource_type => 'SmartProxy'
Expand Down

0 comments on commit 03494ec

Please sign in to comment.