katello 3.16.0.rc4 → 3.16.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +39 -23
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +3 -3
  4. data/app/controllers/katello/api/v2/api_controller.rb +1 -0
  5. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +5 -1
  6. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +3 -0
  7. data/app/controllers/katello/api/v2/content_views_controller.rb +7 -0
  8. data/app/controllers/katello/api/v2/host_tracer_controller.rb +0 -5
  9. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +15 -0
  10. data/app/controllers/katello/api/v2/repositories_controller.rb +10 -1
  11. data/app/controllers/katello/concerns/api/v2/associations_permission_check.rb +67 -0
  12. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -5
  13. data/app/helpers/katello/content_view_helper.rb +15 -0
  14. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +5 -1
  15. data/app/lib/actions/katello/capsule_content/sync.rb +3 -6
  16. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +31 -17
  17. data/app/lib/actions/katello/content_view/incremental_updates.rb +8 -1
  18. data/app/lib/actions/katello/content_view/presenters/incremental_updates_presenter.rb +2 -1
  19. data/app/lib/actions/katello/content_view/publish.rb +55 -16
  20. data/app/lib/actions/katello/content_view_version/incremental_update.rb +120 -26
  21. data/app/lib/actions/katello/host/attach_subscriptions.rb +5 -1
  22. data/app/lib/actions/katello/product/destroy.rb +25 -4
  23. data/app/lib/actions/katello/repository/destroy.rb +5 -1
  24. data/app/lib/actions/katello/repository/multi_clone_contents.rb +62 -0
  25. data/app/lib/actions/katello/repository/multi_clone_to_version.rb +30 -0
  26. data/app/lib/actions/katello/repository/sync.rb +35 -25
  27. data/app/lib/actions/katello/repository/update.rb +11 -16
  28. data/app/lib/actions/katello/repository/verify_checksum.rb +28 -0
  29. data/app/lib/actions/katello/sync_plan/run.rb +1 -1
  30. data/app/lib/actions/pulp/abstract_async_task.rb +1 -0
  31. data/app/lib/actions/pulp/consumer/sync_capsule.rb +8 -0
  32. data/app/lib/actions/pulp/orchestration/repository/sync.rb +2 -1
  33. data/app/lib/actions/pulp/repository/presenters/deb_presenter.rb +2 -2
  34. data/app/lib/actions/pulp/repository/sync.rb +2 -1
  35. data/app/lib/actions/pulp3/abstract_async_task.rb +62 -58
  36. data/app/lib/actions/pulp3/capsule_content/refresh_content_guard.rb +17 -0
  37. data/app/lib/actions/pulp3/capsule_content/sync.rb +3 -1
  38. data/app/lib/actions/pulp3/{ContentGuard → content_guard}/refresh.rb +0 -0
  39. data/app/lib/actions/pulp3/content_migration.rb +4 -0
  40. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -4
  41. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +36 -0
  42. data/app/lib/actions/pulp3/orchestration/repository/sync.rb +3 -1
  43. data/app/lib/actions/pulp3/orchestration/repository/trigger_update_repo_cert_guard.rb +22 -0
  44. data/app/lib/actions/pulp3/repository/copy_content.rb +0 -1
  45. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +28 -0
  46. data/app/lib/actions/pulp3/repository/multi_copy_units.rb +55 -0
  47. data/app/lib/actions/pulp3/repository/presenters/content_unit_presenter.rb +1 -1
  48. data/app/lib/actions/pulp3/repository/presenters/repair_presenter.rb +85 -0
  49. data/app/lib/actions/pulp3/repository/repair.rb +29 -0
  50. data/app/lib/actions/pulp3/repository/save_version.rb +20 -8
  51. data/app/lib/actions/pulp3/repository/save_versions.rb +73 -0
  52. data/app/lib/actions/pulp3/repository/sync.rb +1 -1
  53. data/app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb +6 -2
  54. data/app/lib/actions/pulp3/repository/upload_file.rb +1 -1
  55. data/app/lib/katello/concerns/base_template_scope_extensions.rb +4 -14
  56. data/app/lib/katello/errors.rb +1 -15
  57. data/app/lib/katello/resources/cdn.rb +3 -2
  58. data/app/lib/katello/util/cdn_var_substitutor.rb +9 -6
  59. data/app/models/katello/concerns/smart_proxy_extensions.rb +14 -3
  60. data/app/models/katello/content_view.rb +18 -6
  61. data/app/models/katello/content_view_erratum_filter.rb +13 -0
  62. data/app/models/katello/content_view_filter.rb +4 -0
  63. data/app/models/katello/content_view_module_stream_filter.rb +30 -3
  64. data/app/models/katello/content_view_package_filter.rb +1 -1
  65. data/app/models/katello/glue/pulp/repo.rb +1 -0
  66. data/app/models/katello/host/content_facet.rb +11 -5
  67. data/app/models/katello/module_stream.rb +1 -1
  68. data/app/models/katello/ping.rb +1 -3
  69. data/app/models/katello/repository.rb +16 -0
  70. data/app/models/setting/content.rb +3 -1
  71. data/app/presenters/katello/sync_status_presenter.rb +4 -2
  72. data/app/services/cert/certs.rb +10 -2
  73. data/app/services/katello/pulp/repository/yum.rb +2 -1
  74. data/app/services/katello/pulp3/api/core.rb +4 -0
  75. data/app/services/katello/pulp3/erratum.rb +3 -1
  76. data/app/services/katello/pulp3/migration.rb +9 -4
  77. data/app/services/katello/pulp3/migration_plan.rb +6 -6
  78. data/app/services/katello/pulp3/repository.rb +13 -5
  79. data/app/services/katello/pulp3/repository/yum.rb +246 -25
  80. data/app/services/katello/pulp3/repository_mirror.rb +7 -2
  81. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  82. data/app/services/katello/pulp3/task.rb +100 -0
  83. data/app/services/katello/pulp3/task_group.rb +79 -0
  84. data/app/services/katello/smart_proxy_helper.rb +13 -16
  85. data/app/views/katello/api/v2/content_view_filters/base.json.rabl +4 -0
  86. data/config/routes/api/rhsm.rb +1 -0
  87. data/config/routes/api/v2.rb +2 -0
  88. data/db/migrate/20200709021250_add_original_modules_to_content_view_module_stream_filter.rb +5 -0
  89. data/db/migrate/20200721142707_remove_duplicate_katello_pools_index.rb +5 -0
  90. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.routes.js +1 -13
  91. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/filter-details.controller.js +17 -4
  92. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/views/module-stream-filter-details.html +17 -0
  93. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/errata.routes.js +1 -1
  94. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/product-bulk-action.factory.js +1 -0
  95. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +6 -0
  96. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +7 -1
  97. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -0
  98. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +15 -0
  99. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +6 -0
  100. data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +4 -0
  101. data/lib/katello/engine.rb +0 -1
  102. data/lib/katello/permission_creator.rb +2 -2
  103. data/lib/katello/plugin.rb +2 -1
  104. data/lib/katello/tasks/reports.rake +16 -0
  105. data/lib/katello/version.rb +1 -1
  106. data/webpack/redux/actions/RedHatRepositories/helpers.js +6 -6
  107. metadata +37 -14
  108. data/app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb +0 -17
@@ -0,0 +1,17 @@
1
+ module Actions
2
+ module Pulp3
3
+ module CapsuleContent
4
+ class RefreshContentGuard < Pulp3::AbstractAsyncTask
5
+ def plan(smart_proxy, options = {})
6
+ content_guard_api = ::Katello::Pulp3::Api::ContentGuard.new(smart_proxy)
7
+ content_guard_href = content_guard_api.list&.results&.first&.pulp_href
8
+ if content_guard_href && options.try(:[], :update)
9
+ content_guard_api.partial_update content_guard_href
10
+ else
11
+ content_guard_api.create
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -11,7 +11,9 @@ module Actions
11
11
 
12
12
  def invoke_external_task
13
13
  repo = ::Katello::Repository.find(input[:repository_id])
14
- output[:pulp_tasks] = repo.backend_service(smart_proxy).with_mirror_adapter.sync
14
+ sync_options = {}
15
+ sync_options[:optimize] = false if sync_options[:skip_metadata_check]
16
+ output[:pulp_tasks] = repo.backend_service(smart_proxy).with_mirror_adapter.sync(sync_options)
15
17
  end
16
18
 
17
19
  def rescue_strategy_for_self
@@ -12,6 +12,10 @@ module Actions
12
12
  migration_service = ::Katello::Pulp3::Migration.new(smart_proxy)
13
13
  migration_service.create_and_run_migrations
14
14
  end
15
+
16
+ def rescue_strategy
17
+ Dynflow::Action::Rescue::Skip
18
+ end
15
19
  end
16
20
  end
17
21
  end
@@ -16,13 +16,11 @@ module Actions
16
16
  copy_action = plan_action(Actions::Pulp3::Repository::CopyContent, source_repositories.first, smart_proxy, target_repo,
17
17
  filter_ids: filter_ids, solve_dependencies: solve_dependencies,
18
18
  rpm_filenames: rpm_filenames)
19
- plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo,
20
- repository_details: { latest_version_href: copy_action.output[:latest_version_href] }, tasks: copy_action.output[:pulp_tasks])
19
+ plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: copy_action.output[:pulp_tasks])
21
20
  else
22
21
  #if we are not filtering, copy the version to the cv repository, and the units for each additional repo
23
22
  action = plan_action(Actions::Pulp3::Repository::CopyVersion, source_repositories.first, smart_proxy, target_repo)
24
- plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo,
25
- repository_details: { latest_version_href: action.output[:latest_version_output] }, tasks: action.output[:pulp_tasks])
23
+ plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: action.output[:pulp_tasks])
26
24
  copy_actions = []
27
25
  #since we're creating a new version from the first repo, start copying at the 2nd
28
26
  source_repositories[1..-1].each do |source_repo|
@@ -0,0 +1,36 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Orchestration
4
+ module Repository
5
+ class MultiCopyAllUnits < Pulp3::Abstract
6
+ def plan(extended_repo_map, smart_proxy, options = {})
7
+ solve_dependencies = options.fetch(:solve_dependencies, false)
8
+ if extended_repo_map.values.pluck(:filters).flatten.present? ||
9
+ extended_repo_map.keys.detect { |source_repos| source_repos.length > 1 }
10
+ sequence do
11
+ copy_action = plan_action(Actions::Pulp3::Repository::MultiCopyContent, extended_repo_map, smart_proxy,
12
+ solve_dependencies: solve_dependencies)
13
+ plan_action(Actions::Pulp3::Repository::SaveVersions, extended_repo_map.values.pluck(:dest_repo),
14
+ tasks: copy_action.output[:pulp_tasks])
15
+ end
16
+ else
17
+ repo_id_map = {}
18
+ extended_repo_map.each do |source_repos, dest_repo_map|
19
+ repo_id_map[source_repos.first.id] = dest_repo_map[:dest_repo].id
20
+ end
21
+ plan_self(repo_id_map: repo_id_map)
22
+ end
23
+ end
24
+
25
+ def run
26
+ input[:repo_id_map].each do |source_repo_id, dest_repo_id|
27
+ dest_repo = ::Katello::Repository.find(dest_repo_id)
28
+ source_repo = ::Katello::Repository.find(source_repo_id)
29
+ dest_repo.update!(version_href: source_repo.version_href)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -7,7 +7,9 @@ module Actions
7
7
  def plan(repository, smart_proxy, options)
8
8
  sequence do
9
9
  action_output = plan_action(Actions::Pulp3::Repository::Sync, repository, smart_proxy, options).output
10
- version_output = plan_action(Pulp3::Repository::SaveVersion, repository, tasks: action_output[:pulp_tasks]).output
10
+
11
+ force_fetch_version = true if options[:optimize] == false
12
+ version_output = plan_action(Pulp3::Repository::SaveVersion, repository, tasks: action_output[:pulp_tasks], :force_fetch_version => force_fetch_version).output
11
13
  plan_action(Pulp3::Orchestration::Repository::GenerateMetadata, repository, smart_proxy, :contents_changed => version_output[:contents_changed])
12
14
  plan_self(:subaction_output => version_output)
13
15
  end
@@ -0,0 +1,22 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Orchestration
4
+ module Repository
5
+ class TriggerUpdateRepoCertGuard < Pulp3::Abstract
6
+ def plan(repository, smart_proxy)
7
+ plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id)
8
+ end
9
+
10
+ def run
11
+ repository = ::Katello::Repository.find(input[:repository_id])
12
+ ForemanTasks.async_task(::Actions::Pulp3::Repository::UpdateCVRepositoryCertGuard, repository, smart_proxy)
13
+ end
14
+
15
+ def humanized_name
16
+ _("Updating repository authentication configuration")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -11,7 +11,6 @@ module Actions
11
11
  def invoke_external_task
12
12
  source = ::Katello::Repository.find(input[:source_repository_id])
13
13
  target = ::Katello::Repository.find(input[:target_repository_id] || input[:target_repository])
14
- output[:latest_version_href] = target.backend_service(smart_proxy).read.latest_version_href
15
14
  output[:pulp_tasks] = target.backend_service(smart_proxy).copy_content_for_source(source, input)
16
15
  end
17
16
  end
@@ -0,0 +1,28 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ class MultiCopyContent < Pulp3::AbstractAsyncTask
5
+ def plan(extended_repo_map, smart_proxy, options)
6
+ repo_id_map = {}
7
+
8
+ extended_repo_map.each do |source_repos, dest_repo_map|
9
+ repo_id_map[source_repos&.map(&:id)] = { :dest_repo => dest_repo_map[:dest_repo].id,
10
+ :filter_ids => dest_repo_map[:filters]&.map(&:id) }
11
+ end
12
+
13
+ plan_self(options.merge(:repo_id_map => repo_id_map, :smart_proxy_id => smart_proxy.id))
14
+ end
15
+
16
+ def invoke_external_task
17
+ repo_id_map = {}
18
+
19
+ input[:repo_id_map].each do |source_repo_ids, dest_repo_map|
20
+ repo_id_map[JSON.parse(source_repo_ids)] = dest_repo_map.deep_dup
21
+ end
22
+
23
+ output[:pulp_tasks] = ::Katello::Repository.find(repo_id_map.values.first[:dest_repo]).backend_service(smart_proxy).copy_content_from_mapping(repo_id_map, input)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,55 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ class MultiCopyUnits < Pulp3::AbstractAsyncTask
5
+ # repo_map example: {
6
+ # [<source_repo_ids>]: {
7
+ # dest_repo: <dest_repo_id>,
8
+ # base_version: <base_version>
9
+ # }
10
+ # }
11
+ def plan(repo_map, unit_map, options = {})
12
+ if unit_map.values.flatten.any?
13
+ action_output = plan_self(repo_map: repo_map,
14
+ unit_map: unit_map,
15
+ dependency_solving: options[:dependency_solving],
16
+ incremental_update: options[:incremental_update],
17
+ smart_proxy_id: SmartProxy.pulp_master.id).output
18
+ plan_action(Pulp3::Repository::SaveVersions, repo_map.values.pluck(:dest_repo),
19
+ tasks: action_output[:pulp_tasks]).output
20
+ end
21
+ end
22
+
23
+ def invoke_external_task
24
+ unit_hrefs = []
25
+ repo_map = {}
26
+
27
+ input[:repo_map].each do |source_repo_ids, dest_repo_map|
28
+ repo_map[JSON.parse(source_repo_ids)] = dest_repo_map
29
+ end
30
+
31
+ if input[:unit_map][:errata].any?
32
+ unit_hrefs << ::Katello::RepositoryErratum.
33
+ joins("inner join katello_errata on katello_repository_errata.erratum_id = katello_errata.id").
34
+ where("katello_repository_errata.repository_id in (#{repo_map.keys.join(',')}) and
35
+ katello_errata.id in (#{input[:unit_map][:errata].join(",")})").map(&:erratum_pulp3_href)
36
+ end
37
+
38
+ if input[:unit_map][:rpms].any?
39
+ unit_hrefs << ::Katello::Rpm.where(:id => input[:unit_map][:rpms]).map(&:pulp_id)
40
+ end
41
+ unit_hrefs.flatten!
42
+
43
+ repo_map.each do |_source_repos, dest_repo_map|
44
+ dest_repo_map[:content_unit_hrefs] = unit_hrefs
45
+ end
46
+
47
+ target_repo = ::Katello::Repository.find(repo_map.values.first[:dest_repo])
48
+ unless unit_hrefs.flatten.empty?
49
+ output[:pulp_tasks] = target_repo.backend_service(SmartProxy.pulp_master).multi_copy_units(repo_map, input[:dependency_solving])
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -12,7 +12,7 @@ module Actions
12
12
  def humanized_details
13
13
  ret = []
14
14
  ret << _("Cancelled.") if cancelled?
15
- ret << _("Total tasks: ") + ": #{finished_units}/#{total_units}"
15
+ ret << _("Total steps: ") + "#{finished_units}/#{total_units}"
16
16
  ret << "--------------------------------"
17
17
  progress_reports = sync_task.try(:[], 'progress_reports') || []
18
18
  progress_reports = progress_reports.sort_by { |pr| pr.try(:[], 'message') }
@@ -0,0 +1,85 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ module Presenters
5
+ class RepairPresenter < Helpers::Presenter::Base
6
+ def humanized_output
7
+ if action.external_task
8
+ humanized_details
9
+ end
10
+ end
11
+
12
+ def progress
13
+ total_units == 0 ? 0.1 : finished_units.to_f / total_units
14
+ end
15
+
16
+ private
17
+
18
+ def repair_task
19
+ tasks = action.external_task.select do |task|
20
+ if task.key? 'name'
21
+ task['name'].include?("repair_version")
22
+ end
23
+ end
24
+ tasks.first
25
+ end
26
+
27
+ def cancelled?
28
+ repair_task && repair_task['state'] == 'cancelled'
29
+ end
30
+
31
+ def task_result
32
+ repair_task['result']
33
+ end
34
+
35
+ def task_result_details
36
+ task_result && task_result['details']
37
+ end
38
+
39
+ def humanized_details
40
+ ret = []
41
+ ret << _("Cancelled.") if cancelled?
42
+ ret << _("Total steps: ") + "#{finished_units}/#{total_units}"
43
+ ret << "--------------------------------"
44
+ progress_reports = repair_task.try(:[], 'progress_reports') || []
45
+ progress_reports = progress_reports.sort_by { |pr| pr.try(:[], 'message') }
46
+ progress_reports.each do |pr|
47
+ done = pr.try(:[], 'done')
48
+ total = pr.try(:[], 'total') || pr.try(:[], 'done')
49
+ unless done.nil? || total.nil?
50
+ ret << _(pr.try(:[], 'message') + ": #{done}/#{total}")
51
+ end
52
+ end
53
+
54
+ ret.join("\n")
55
+ end
56
+
57
+ def total_units
58
+ total_unit = 0
59
+ progress_reports = repair_task.try(:[], 'progress_reports') || []
60
+ progress_reports.each do |pr|
61
+ total = pr.try(:[], 'total')
62
+ total = pr.try(:[], 'done') if total.nil?
63
+ unless total.nil?
64
+ total_unit += total.to_i
65
+ end
66
+ end
67
+ total_unit
68
+ end
69
+
70
+ def finished_units
71
+ finished_unit = 0
72
+ progress_reports = repair_task.try(:[], 'progress_reports') || []
73
+ progress_reports.each do |pr|
74
+ done = pr.try(:[], 'done')
75
+ unless done.nil?
76
+ finished_unit += done.to_i
77
+ end
78
+ end
79
+ finished_unit
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,29 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ class Repair < Pulp3::AbstractAsyncTask
5
+ include Helpers::Presenter
6
+ def plan(repository_id, smart_proxy)
7
+ plan_self(:repository_id => repository_id, :smart_proxy_id => smart_proxy.id)
8
+ end
9
+
10
+ def invoke_external_task
11
+ repo = ::Katello::Repository.find(input[:repository_id])
12
+ output[:response] = repo.backend_service(smart_proxy).repair(repo.version_href)
13
+ end
14
+
15
+ def run_progress
16
+ presenter.progress
17
+ end
18
+
19
+ def run_progress_weight
20
+ 10
21
+ end
22
+
23
+ def presenter
24
+ Presenters::RepairPresenter.new(self)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,27 +3,39 @@ module Actions
3
3
  module Repository
4
4
  class SaveVersion < Pulp3::Abstract
5
5
  def plan(repository, options)
6
- plan_self(:repository_id => repository.id, :tasks => options[:tasks], :repository_details => options[:repository_details])
6
+ fail "Cannot accept tasks and repository_details into Save Version." if options[:tasks].present? && options[:repository_details].present?
7
+ plan_self(:repository_id => repository.id, :tasks => options[:tasks], :repository_details => options[:repository_details], :force_fetch_version => options.fetch(:force_fetch_version, false))
7
8
  end
8
9
 
9
10
  def run
10
11
  repo = ::Katello::Repository.find(input[:repository_id])
11
12
 
12
- if input[:tasks]
13
- version_href = input[:tasks].last[:created_resources].first
14
- end
15
-
16
- if !version_href && input[:repository_details]
13
+ if input[:force_fetch_version]
14
+ version_href = fetch_version_href(repo)
15
+ elsif input[:repository_details].present?
17
16
  version_href = input[:repository_details][:latest_version_href]
17
+ elsif input[:tasks].present?
18
+ version_href = input[:tasks].last[:created_resources].first
19
+ else
20
+ version_href = fetch_version_href(repo)
18
21
  end
19
22
 
20
23
  if version_href
21
- repo.update(:version_href => version_href)
22
- output[:contents_changed] = true
24
+ if repo.version_href != version_href || input[:force_fetch_version]
25
+ output[:contents_changed] = true
26
+ repo.update(:version_href => version_href)
27
+ end
23
28
  else
24
29
  output[:contents_changed] = false
25
30
  end
26
31
  end
32
+
33
+ def fetch_version_href(repo)
34
+ # Fetch latest Pulp 3 repo version
35
+ repo_backend_service = repo.backend_service(SmartProxy.pulp_master)
36
+ repo_href = repo_backend_service.repository_reference.repository_href
37
+ repo_backend_service.api.repositories_api.read(repo_href).latest_version_href
38
+ end
27
39
  end
28
40
  end
29
41
  end
@@ -0,0 +1,73 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ class SaveVersions < Pulp3::Abstract
5
+ def plan(repository_ids, options)
6
+ plan_self(:repository_ids => repository_ids, :tasks => options[:tasks])
7
+ end
8
+
9
+ def run
10
+ return if input[:tasks].empty?
11
+ version_hrefs = input[:tasks].last[:created_resources]
12
+ repositories = find_repositories(input[:repository_ids])
13
+
14
+ output.merge!(contents_changed: false, updated_repositories: [])
15
+ repositories.each do |repo|
16
+ repo_backend_service = repo.backend_service(SmartProxy.pulp_master)
17
+ if repo.version_href
18
+ # Chop off the version number to compare base repo strings
19
+ unversioned_href = repo.version_href[0..-2].rpartition('/').first
20
+ # Could have multiple version_hrefs for the same repo depending on the copy task
21
+ new_version_hrefs = version_hrefs.collect do |version_href|
22
+ version_href if unversioned_href == version_href[0..-2].rpartition('/').first
23
+ end
24
+
25
+ new_version_hrefs.compact!
26
+ if new_version_hrefs.size > 1
27
+ # Find latest version_href by its version number
28
+ new_version_href = version_map(new_version_hrefs).max_by { |_href, version| version }.first
29
+ else
30
+ new_version_href = new_version_hrefs.first
31
+ end
32
+
33
+ # Successive incremental updates won't generate a new repo version, so fetch the latest Pulp 3 repo version
34
+ new_version_href ||= latest_version_href(repo_backend_service)
35
+ else
36
+ new_version_href = latest_version_href(repo_backend_service)
37
+ end
38
+
39
+ unless new_version_href == repo.version_href
40
+ repo.update(version_href: new_version_href)
41
+ repo.index_content
42
+ output[:contents_changed] = true
43
+ output[:updated_repositories] << repo.id
44
+ end
45
+ end
46
+ end
47
+
48
+ def version_map(version_hrefs)
49
+ version_map = {}
50
+ version_hrefs.each do |href|
51
+ version_map[href] = href.split("/")[-1].to_i
52
+ end
53
+ version_map
54
+ end
55
+
56
+ def latest_version_href(repo_backend_service)
57
+ repo_backend_service.api.repositories_api.
58
+ read(repo_backend_service.repository_reference.repository_href).latest_version_href
59
+ end
60
+
61
+ def find_repositories(repository_ids)
62
+ repository_ids.collect do |repo_id|
63
+ if repo_id.is_a?(Hash)
64
+ ::Katello::Repository.find(repo_id.with_indifferent_access[:id])
65
+ else
66
+ ::Katello::Repository.find(repo_id)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end