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
@@ -7,9 +7,11 @@ module Actions
7
7
 
8
8
  # options:
9
9
  # skip_environment_update - defaults to false. skips updating the CP environment
10
+ # destroy_content - can be disabled to skip Candlepin remove_content
10
11
  def plan(repository, options = {})
11
12
  skip_environment_update = options.fetch(:skip_environment_update, false) ||
12
13
  options.fetch(:organization_destroy, false)
14
+ destroy_content = options.fetch(:destroy_content, true)
13
15
  action_subject(repository)
14
16
 
15
17
  unless repository.destroyable?
@@ -29,7 +31,9 @@ module Actions
29
31
  if repository.redhat?
30
32
  handle_redhat_content(repository) unless skip_environment_update
31
33
  else
32
- handle_custom_content(repository) unless skip_environment_update
34
+ if destroy_content && !skip_environment_update
35
+ handle_custom_content(repository)
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -0,0 +1,62 @@
1
+ module Actions
2
+ module Katello
3
+ module Repository
4
+ class MultiCloneContents < Actions::Base
5
+ include Actions::Katello::PulpSelector
6
+ def plan(extended_repo_mapping, options)
7
+ generate_metadata = options.fetch(:generate_metadata, true)
8
+ copy_contents = options.fetch(:copy_contents, true)
9
+ solve_dependencies = options.fetch(:solve_dependencies, false)
10
+
11
+ sequence do
12
+ if copy_contents
13
+ plan_action(Pulp3::Orchestration::Repository::MultiCopyAllUnits,
14
+ extended_repo_mapping,
15
+ SmartProxy.pulp_master,
16
+ solve_dependencies: solve_dependencies)
17
+ end
18
+
19
+ extended_repo_mapping.each do |source_repos, dest_repo_map|
20
+ if generate_metadata
21
+ metadata_generate(source_repos, dest_repo_map[:dest_repo], dest_repo_map[:filters])
22
+ end
23
+ end
24
+
25
+ extended_repo_mapping.values.each do |dest_repo_map|
26
+ plan_action(Katello::Repository::IndexContent, id: dest_repo_map[:dest_repo].id)
27
+ end
28
+ end
29
+ end
30
+
31
+ def metadata_generate(source_repositories, new_repository, filters)
32
+ metadata_options = {}
33
+
34
+ if source_repositories.count == 1 && filters.empty?
35
+ metadata_options[:source_repository] = source_repositories.first
36
+ end
37
+
38
+ check_matching_content = ::Katello::RepositoryTypeManager.find(new_repository.content_type).metadata_publish_matching_check
39
+ if new_repository.environment && source_repositories.count == 1 && check_matching_content
40
+ match_check_output = plan_action(Katello::Repository::CheckMatchingContent,
41
+ :source_repo_id => source_repositories.first.id,
42
+ :target_repo_id => new_repository.id).output
43
+
44
+ metadata_options[:matching_content] = match_check_output[:matching_content]
45
+ end
46
+
47
+ plan_action(Katello::Repository::MetadataGenerate, new_repository, metadata_options)
48
+ unless source_repositories.first.saved_checksum_type == new_repository.saved_checksum_type
49
+ plan_self(:source_checksum_type => source_repositories.first.saved_checksum_type,
50
+ :target_repo_id => new_repository.id)
51
+ end
52
+ end
53
+
54
+ def finalize
55
+ repository = ::Katello::Repository.find(input[:target_repo_id])
56
+ source_checksum_type = input[:source_checksum_type]
57
+ repository.update!(saved_checksum_type: source_checksum_type) if (repository && source_checksum_type)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,30 @@
1
+ module Actions
2
+ module Katello
3
+ module Repository
4
+ class MultiCloneToVersion < Actions::Base
5
+ def plan(repository_mapping, content_view_version, options = {})
6
+ incremental = options.fetch(:incremental, false)
7
+ content_view = content_view_version.content_view
8
+ extended_repo_map = extended_repo_mapping(repository_mapping, content_view, incremental)
9
+ sequence do
10
+ plan_action(::Actions::Katello::Repository::MultiCloneContents, extended_repo_map,
11
+ copy_contents: true,
12
+ solve_dependencies: content_view.solve_dependencies,
13
+ metadata_generate: !incremental)
14
+ end
15
+ end
16
+
17
+ def extended_repo_mapping(repo_map, content_view, incremental)
18
+ # Example: {[source_repos] => {dest_repo: dest_repo, filters: filters}}
19
+ extended_repo_map = {}
20
+ repo_map.each do |source_repos, dest_repo|
21
+ filters = incremental ? [] : content_view.filters.applicable(source_repos.first)
22
+ extended_repo_map[source_repos] = { :dest_repo => dest_repo,
23
+ :filters => filters }
24
+ end
25
+ extended_repo_map
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -34,38 +34,47 @@ module Actions
34
34
 
35
35
  pulp_sync_options = {}
36
36
  pulp_sync_options[:download_policy] = ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND if validate_contents && repo.yum?
37
+
38
+ #pulp2 options
37
39
  pulp_sync_options[:force_full] = true if skip_metadata_check && repo.yum?
38
40
  pulp_sync_options[:repair_sync] = true if validate_contents && repo.deb?
39
41
  pulp_sync_options[:remove_missing] = false if incremental
42
+ pulp_sync_options[:source_url] = source_url
43
+
44
+ #pulp3 options
45
+ pulp_sync_options[:optimize] = false if skip_metadata_check && repo.yum?
40
46
 
41
47
  sequence do
42
- plan_action(Pulp::Repository::RemoveUnits, :repo_id => repo.id, :content_unit_type => ::Katello::YumMetadataFile::CONTENT_TYPE) if validate_contents && repo.yum?
43
- sync_args = {:smart_proxy_id => SmartProxy.pulp_master.id, :repo_id => repo.id, :source_url => source_url, :options => pulp_sync_options}
44
- sync_action = plan_pulp_action([Actions::Pulp::Orchestration::Repository::Sync,
45
- Actions::Pulp3::Orchestration::Repository::Sync],
46
- repo,
47
- SmartProxy.pulp_master,
48
- sync_args)
49
- output = sync_action.output
50
-
51
- contents_changed = skip_metadata_check || output[:contents_changed]
52
-
53
- plan_action(Katello::Repository::IndexContent, :id => repo.id, :contents_changed => contents_changed)
54
- plan_action(Katello::Foreman::ContentUpdate, repo.environment, repo.content_view, repo)
55
- plan_action(Katello::Repository::FetchPxeFiles, :id => repo.id)
56
- plan_action(Katello::Repository::CorrectChecksum, repo)
57
- concurrence do
58
- plan_action(Pulp::Repository::Download, :pulp_id => repo.pulp_id, :options => {:verify_all_units => true}) if validate_contents && repo.yum?
59
- plan_action(Katello::Repository::MetadataGenerate, repo, :force => true) if skip_metadata_check && repo.yum?
60
- plan_action(Katello::Repository::ErrataMail, repo, nil, contents_changed)
61
- if generate_applicability
62
- regenerate_applicability(repo, contents_changed)
48
+ if SmartProxy.pulp_master.pulp3_support?(repo) && validate_contents
49
+ plan_action(Katello::Repository::VerifyChecksum, repo)
50
+ else
51
+ plan_action(Pulp::Repository::RemoveUnits, :repo_id => repo.id, :content_unit_type => ::Katello::YumMetadataFile::CONTENT_TYPE) if validate_contents && repo.yum?
52
+ sync_action = plan_pulp_action([Actions::Pulp::Orchestration::Repository::Sync,
53
+ Actions::Pulp3::Orchestration::Repository::Sync],
54
+ repo,
55
+ SmartProxy.pulp_master,
56
+ pulp_sync_options)
57
+ output = sync_action.output
58
+
59
+ contents_changed = skip_metadata_check || output[:contents_changed]
60
+
61
+ plan_action(Katello::Repository::IndexContent, :id => repo.id, :contents_changed => contents_changed)
62
+ plan_action(Katello::Foreman::ContentUpdate, repo.environment, repo.content_view, repo)
63
+ plan_action(Katello::Repository::FetchPxeFiles, :id => repo.id)
64
+ plan_action(Katello::Repository::CorrectChecksum, repo)
65
+ concurrence do
66
+ plan_action(Pulp::Repository::Download, :pulp_id => repo.pulp_id, :options => {:verify_all_units => true}) if validate_contents && repo.yum?
67
+ plan_action(Katello::Repository::MetadataGenerate, repo, :force => true) if skip_metadata_check && repo.yum?
68
+ plan_action(Katello::Repository::ErrataMail, repo, nil, contents_changed)
69
+ if generate_applicability
70
+ regenerate_applicability(repo, contents_changed)
71
+ end
63
72
  end
73
+ plan_self(:id => repo.id, :sync_result => output, :skip_metadata_check => skip_metadata_check, :validate_contents => validate_contents,
74
+ :contents_changed => contents_changed)
75
+ plan_action(Katello::Repository::ImportApplicability, :repo_id => repo.id, :contents_changed => contents_changed) if generate_applicability
76
+ plan_action(Katello::Repository::SyncHook, :id => repo.id)
64
77
  end
65
- plan_self(:id => repo.id, :sync_result => output, :skip_metadata_check => skip_metadata_check, :validate_contents => validate_contents,
66
- :contents_changed => contents_changed)
67
- plan_action(Katello::Repository::ImportApplicability, :repo_id => repo.id, :contents_changed => contents_changed) if generate_applicability
68
- plan_action(Katello::Repository::SyncHook, :id => repo.id)
69
78
  end
70
79
  end
71
80
 
@@ -91,6 +100,7 @@ module Actions
91
100
  def presenter
92
101
  found = all_planned_actions(Pulp::Repository::Sync)
93
102
  found = all_planned_actions(Pulp3::Repository::Sync) if found.empty?
103
+ found = all_planned_actions(Pulp3::Repository::Repair) if found.empty?
94
104
  Helpers::Presenter::Delegated.new(self, found)
95
105
  end
96
106
 
@@ -10,8 +10,7 @@ module Actions
10
10
  action_subject root.library_instance
11
11
 
12
12
  repo_params[:url] = nil if repo_params[:url] == ''
13
- update_cv_cert_protected = (repo_params[:unprotected] != repository.unprotected)
14
-
13
+ update_cv_cert_protected = repo_params.key?(:unprotected) && (repo_params[:unprotected] != repository.unprotected)
15
14
  root.update!(repo_params)
16
15
 
17
16
  if root.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_BACKGROUND
@@ -42,28 +41,24 @@ module Actions
42
41
  gpg_url: repository.yum_gpg_key_url)
43
42
  end
44
43
  if root.pulp_update_needed?
45
- plan_pulp_action([::Actions::Pulp::Orchestration::Repository::Refresh,
46
- ::Actions::Pulp3::Orchestration::Repository::Update],
47
- repository,
48
- SmartProxy.pulp_master)
49
- plan_self(:repository_id => root.library_instance.id, :update_cv_cert_protected => update_cv_cert_protected)
44
+ sequence do
45
+ plan_pulp_action([::Actions::Pulp::Orchestration::Repository::Refresh,
46
+ ::Actions::Pulp3::Orchestration::Repository::Update],
47
+ repository,
48
+ SmartProxy.pulp_master)
49
+ plan_self(:repository_id => root.library_instance.id)
50
+ if update_cv_cert_protected
51
+ plan_optional_pulp_action([::Actions::Pulp3::Orchestration::Repository::TriggerUpdateRepoCertGuard], repository, ::SmartProxy.pulp_master)
52
+ end
53
+ end
50
54
  end
51
55
  end
52
56
 
53
57
  def run
54
58
  repository = ::Katello::Repository.find(input[:repository_id])
55
- output[:repository_id] = input[:repository_id]
56
- output[:update_cv_cert_protected] = input[:update_cv_cert_protected]
57
59
  ForemanTasks.async_task(Katello::Repository::MetadataGenerate, repository)
58
60
  end
59
61
 
60
- def finalize
61
- repository = ::Katello::Repository.find(output[:repository_id])
62
- if output[:update_cv_cert_protected]
63
- ForemanTasks.async_task(::Actions::Katello::Repository::UpdateCVRepoCertGuard, repository, SmartProxy.pulp_master)
64
- end
65
- end
66
-
67
62
  private
68
63
 
69
64
  def update_content?(repository)
@@ -0,0 +1,28 @@
1
+ module Actions
2
+ module Katello
3
+ module Repository
4
+ class VerifyChecksum < Actions::EntryAction
5
+ include Helpers::Presenter
6
+ include Actions::Katello::PulpSelector
7
+
8
+ def plan(repo)
9
+ action_subject(repo)
10
+
11
+ if SmartProxy.pulp_master.pulp3_support?(repo)
12
+ plan_action(Actions::Pulp3::Repository::Repair, repo.id, SmartProxy.pulp_master)
13
+ else
14
+ options = {}
15
+ options[:validate_contents] = true
16
+ plan_action(Actions::Katello::Repository::Sync, repo, nil, options)
17
+ end
18
+ end
19
+
20
+ def presenter
21
+ found = all_planned_actions(Katello::Repository::Sync)
22
+ found = all_planned_actions(Pulp3::Repository::Repair) if found.empty?
23
+ Helpers::Presenter::Delegated.new(self, found)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -19,7 +19,7 @@ module Actions
19
19
  syncable_products = sync_plan.products.syncable
20
20
  syncable_roots = ::Katello::RootRepository.where(:product_id => syncable_products).has_url
21
21
 
22
- plan_action(::Actions::BulkAction, ::Actions::Katello::Repository::Sync, syncable_roots.map(&:library_instance)) unless syncable_roots.empty?
22
+ plan_action(::Actions::BulkAction, ::Actions::Katello::Repository::Sync, syncable_roots.map(&:library_instance).compact) unless syncable_roots.empty?
23
23
  plan_self(:sync_plan_name => sync_plan.name)
24
24
  end
25
25
  end
@@ -74,6 +74,7 @@ module Actions
74
74
  end
75
75
 
76
76
  def cancel!
77
+ output[:cancelled] = true
77
78
  cancel
78
79
  self.external_task = poll_external_task
79
80
  # We suspend the action and the polling will take care of finding
@@ -26,6 +26,14 @@ module Actions
26
26
  self.done? ? 1 : 0.1
27
27
  end
28
28
 
29
+ def rescue_strategy_for_self
30
+ if output[:cancelled]
31
+ Dynflow::Action::Rescue::Fail
32
+ else
33
+ Dynflow::Action::Rescue::Skip
34
+ end
35
+ end
36
+
29
37
  def run_progress_weight
30
38
  100
31
39
  end
@@ -4,8 +4,9 @@ module Actions
4
4
  module Repository
5
5
  class Sync < Pulp::Abstract
6
6
  include Actions::Helpers::OutputPropagator
7
- def plan(_repository, _smart_proxy, options)
7
+ def plan(repository, smart_proxy, options)
8
8
  sequence do
9
+ options.merge!(:repo_id => repository.id, :smart_proxy_id => smart_proxy.id)
9
10
  action_output = plan_action(Actions::Pulp::Repository::Sync, options).output
10
11
  plan_self(:subaction_output => action_output)
11
12
  end
@@ -54,11 +54,11 @@ module Actions
54
54
  end
55
55
 
56
56
  def items_done
57
- task_details&.inject(0) { |sum, details| sum + details[:num_success].to_i }
57
+ task_details&.inject(0) { |sum, details| sum + details[:num_success].to_i } || 0
58
58
  end
59
59
 
60
60
  def items_total
61
- task_details&.inject(0) { |sum, details| sum + details[:items_total].to_i }
61
+ task_details&.inject(0) { |sum, details| sum + details[:items_total].to_i } || 0
62
62
  end
63
63
 
64
64
  def size_done
@@ -14,8 +14,9 @@ module Actions
14
14
  overrides = {}
15
15
  overrides[:feed] = input[:source_url] if input[:source_url]
16
16
  overrides[:validate] = !(SETTINGS[:katello][:pulp][:skip_checksum_validation])
17
- overrides[:options] = input[:options] if input[:options]
17
+ overrides.merge(input[:options]) if input[:options]
18
18
  repo = ::Katello::Repository.find(input[:repo_id])
19
+
19
20
  output[:pulp_tasks] = repo.backend_service(::SmartProxy.pulp_master).sync(overrides)
20
21
  end
21
22
 
@@ -4,41 +4,6 @@ module Actions
4
4
  include Actions::Base::Polling
5
5
  include ::Dynflow::Action::Cancellable
6
6
 
7
- WAITING = ['waiting',
8
- SKIPPED = 'skipped'.freeze,
9
- RUNNING = 'running'.freeze,
10
- COMPLETED = 'completed'.freeze,
11
- FAILED = 'failed'.freeze,
12
- CANCELED = 'canceled'.freeze].freeze
13
-
14
- FINISHED_STATES = [COMPLETED, FAILED, CANCELED, SKIPPED].freeze
15
-
16
- # A call report Looks like: {"task":"/pulp/api/v3/tasks/5/"}
17
- # {
18
- # "pulp_href":"/pulp/api/v3/tasks/4/",
19
- # "pulp_created":"2019-02-21T19:50:40.476767Z",
20
- # "job_id":"d0359658-d926-47a2-b430-1b2092b3bd86",
21
- # "state":"completed",
22
- # "name":"pulp_file.app.tasks.publishing.publish",
23
- # "started_at":"2019-02-21T19:50:40.556002Z",
24
- # "finished_at":"2019-02-21T19:50:40.618397Z",
25
- # "non_fatal_errors":[
26
- #
27
- # ],
28
- # "error":null,
29
- # "worker":"/pulp/api/v3/workers/1/",
30
- # "parent":null,
31
- # "spawned_tasks":[
32
- #
33
- # ],
34
- # "progress_reports":[
35
- #
36
- # ],
37
- # "created_resources":[
38
- # "/pulp/api/v3/publications/1/"
39
- # ]
40
- # }
41
-
42
7
  def run(event = nil)
43
8
  # do nothing when the action is being skipped
44
9
  unless event == Dynflow::Action::Skip
@@ -49,16 +14,16 @@ module Actions
49
14
  def humanized_state
50
15
  case state
51
16
  when :running
52
- if self.external_task.nil?
17
+ if self.combined_tasks.empty?
53
18
  _("initiating Pulp task")
54
19
  else
55
20
  _("checking Pulp task status")
56
21
  end
57
22
  when :suspended
58
- if external_task&.all? { |task| task[:start_time].nil? }
59
- _("waiting for Pulp to start the task")
60
- else
23
+ if combined_tasks.any?(&:started?)
61
24
  _("waiting for Pulp to finish the task")
25
+ else
26
+ _("waiting for Pulp to start the task")
62
27
  end
63
28
  else
64
29
  super
@@ -66,28 +31,49 @@ module Actions
66
31
  end
67
32
 
68
33
  def done?
69
- external_task&.all? { |task| task[:finish_time] || FINISHED_STATES.include?(task[:state]) }
34
+ combined_tasks&.all? { |task| task.done? }
70
35
  end
71
36
 
72
37
  def external_task
73
- output[:pulp_tasks]
38
+ #this must return nil until external_task= is called
39
+ combined_tasks
40
+ end
41
+
42
+ def combined_tasks
43
+ return nil if pulp_tasks.nil? || task_groups.nil?
44
+ pulp_tasks + task_groups
45
+ end
46
+
47
+ def pulp_tasks
48
+ return nil if output[:pulp_tasks].nil?
49
+ output[:pulp_tasks] = new_or_existing_objects(::Katello::Pulp3::Task, output[:pulp_tasks])
50
+ end
51
+
52
+ def task_groups
53
+ return nil if output[:task_groups].nil?
54
+ output[:task_groups] = new_or_existing_objects(::Katello::Pulp3::TaskGroup, output[:task_groups])
55
+ end
56
+
57
+ def new_or_existing_objects(object_class, objects)
58
+ objects.map do |object|
59
+ if object.is_a?(object_class)
60
+ object
61
+ else
62
+ object_class.new(smart_proxy, object)
63
+ end
64
+ end
74
65
  end
75
66
 
76
67
  def cancel!
77
68
  cancel
78
- self.external_task = poll_external_task
69
+ poll_external_task
79
70
  # We suspend the action and the polling will take care of finding
80
71
  # out if the cancelling was successful
81
72
  suspend unless done?
82
73
  end
83
74
 
84
75
  def cancel
85
- output[:pulp_tasks].each do |pulp_task|
86
- data = PulpcoreClient::Task.new(state: 'canceled')
87
- tasks_api.tasks_cancel(pulp_task['pulp_href'], data)
88
- #the main task may have completed, so cancel spawned tasks too
89
- pulp_task['spawned_tasks']&.each { |spawned| tasks_api.tasks_cancel(spawned['pulp_href'], data) }
90
- end
76
+ pulp_tasks.each { |task| task.cancel }
91
77
  end
92
78
 
93
79
  def rescue_external_task(error)
@@ -109,24 +95,42 @@ module Actions
109
95
  response
110
96
  end
111
97
 
98
+ def check_for_errors
99
+ combined_tasks.each do |task|
100
+ if (message = task.error)
101
+ fail ::Katello::Errors::Pulp3Error, message
102
+ end
103
+ end
104
+ end
105
+
112
106
  def external_task=(external_task_data)
113
- output[:pulp_tasks] = transform_task_response(external_task_data)
114
- output[:pulp_tasks].each do |pulp_task|
115
- if (pulp_exception = ::Katello::Errors::Pulp3Error.from_task(pulp_task))
116
- fail pulp_exception
107
+ #currently we assume everything coming from invoke_external_task_methods are tasks
108
+ tasks = transform_task_response(external_task_data)
109
+ output[:pulp_tasks] = new_or_existing_objects(::Katello::Pulp3::Task, tasks)
110
+
111
+ add_task_groups
112
+ check_for_errors
113
+ end
114
+
115
+ def add_task_groups
116
+ output[:task_groups] ||= []
117
+ pulp_tasks.each do |task|
118
+ if task.task_group_href && !tracking_task_group?(task.task_group_href)
119
+ output[:task_groups] << ::Katello::Pulp3::TaskGroup.new_from_href(smart_proxy, task.task_group_href)
117
120
  end
118
121
  end
119
122
  end
120
123
 
121
- def tasks_api
122
- ::Katello::Pulp3::Api::Core.new(smart_proxy).tasks_api
124
+ def tracking_task_group?(href)
125
+ task_groups&.any? { |group| group.href == href }
123
126
  end
124
127
 
125
128
  def poll_external_task
126
- external_task.map do |task|
127
- task = tasks_api.read(task['pulp_href'] || task['task'])
128
- task.as_json
129
- end
129
+ pulp_tasks.each(&:poll)
130
+ output[:task_groups] = task_groups.each(&:poll) if task_groups
131
+ add_task_groups
132
+ check_for_errors
133
+ pulp_tasks
130
134
  end
131
135
  end
132
136
  end