katello 3.17.0.rc2.1 → 3.17.3

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/api_controller.rb +1 -2
  3. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +9 -1
  4. data/app/controllers/katello/api/v2/host_tracer_controller.rb +16 -36
  5. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +12 -1
  6. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +23 -0
  7. data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +6 -2
  8. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +6 -2
  9. data/app/lib/actions/katello/content_view/promote.rb +2 -2
  10. data/app/lib/actions/katello/content_view/promote_to_environment.rb +12 -3
  11. data/app/lib/actions/katello/content_view/publish.rb +18 -2
  12. data/app/lib/actions/katello/content_view_version/import.rb +36 -0
  13. data/app/lib/actions/katello/content_view_version/incremental_update.rb +1 -1
  14. data/app/lib/actions/katello/host/hypervisors_update.rb +18 -0
  15. data/app/lib/actions/katello/organization/create.rb +1 -1
  16. data/app/lib/actions/katello/organization/simple_content_access/disable.rb +8 -0
  17. data/app/lib/actions/katello/organization/simple_content_access/enable.rb +8 -0
  18. data/app/lib/actions/katello/organization/simple_content_access/toggle.rb +16 -2
  19. data/app/lib/actions/katello/repository/multi_clone_contents.rb +8 -6
  20. data/app/lib/actions/pulp3/abstract_async_task.rb +1 -0
  21. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +1 -1
  22. data/app/lib/actions/pulp3/content_view_version/create_importer.rb +20 -0
  23. data/app/lib/actions/pulp3/content_view_version/destroy_importer.rb +16 -0
  24. data/app/lib/actions/pulp3/content_view_version/import.rb +21 -0
  25. data/app/lib/actions/pulp3/orchestration/content_view_version/copy_version_units_to_library.rb +25 -0
  26. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +9 -1
  27. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +41 -0
  28. data/app/lib/actions/pulp3/repository/copy_content.rb +6 -1
  29. data/app/lib/actions/pulp3/repository/delete.rb +1 -1
  30. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +1 -1
  31. data/app/lib/katello/resources/cdn.rb +3 -2
  32. data/app/lib/katello/util/cdn_var_substitutor.rb +9 -7
  33. data/app/models/katello/concerns/redhat_extensions.rb +2 -2
  34. data/app/models/katello/concerns/smart_proxy_extensions.rb +3 -1
  35. data/app/models/katello/content_view.rb +6 -0
  36. data/app/models/katello/content_view_version.rb +10 -1
  37. data/app/models/katello/glue/pulp/repo.rb +1 -1
  38. data/app/models/katello/root_repository.rb +5 -1
  39. data/app/overrides/add_organization_attributes.rb +12 -0
  40. data/app/services/katello/applicability/applicable_content_helper.rb +12 -1
  41. data/app/services/katello/host_trace_manager.rb +38 -0
  42. data/app/services/katello/pulp3/content_view_version/export.rb +25 -29
  43. data/app/services/katello/pulp3/content_view_version/import.rb +87 -0
  44. data/app/services/katello/pulp3/content_view_version/import_export_common.rb +44 -0
  45. data/app/services/katello/pulp3/erratum.rb +2 -1
  46. data/app/services/katello/pulp3/repository.rb +8 -4
  47. data/app/services/katello/pulp3/repository/yum.rb +71 -4
  48. data/app/services/katello/pulp3/task.rb +4 -4
  49. data/app/services/katello/pulp3/task_group.rb +6 -0
  50. data/app/services/katello/ui_notifications/subscriptions/sca_disable_error.rb +13 -0
  51. data/app/services/katello/ui_notifications/subscriptions/sca_disable_success.rb +13 -0
  52. data/app/services/katello/ui_notifications/subscriptions/sca_enable_error.rb +13 -0
  53. data/app/services/katello/ui_notifications/subscriptions/sca_enable_success.rb +13 -0
  54. data/app/views/overrides/organizations/_edit_override.html.erb +10 -1
  55. data/app/views/overrides/organizations/_index_header_override.html.erb +3 -0
  56. data/app/views/overrides/organizations/_index_row_override.html.erb +3 -0
  57. data/config/routes/api/v2.rb +1 -6
  58. data/config/routes/overrides.rb +4 -0
  59. data/db/migrate/20150930183738_migrate_content_hosts.rb +1 -1
  60. data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +5 -2
  61. data/db/seeds.d/109-katello-notification-blueprints.rb +24 -0
  62. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-associations.controller.js +2 -5
  63. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-repository-sets.controller.js +4 -3
  64. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-subscriptions.controller.js +2 -4
  65. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-repository-sets.html +1 -1
  66. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html +1 -1
  67. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-traces-modal.controller.js +3 -4
  68. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details-info.controller.js +2 -4
  69. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-repository-sets.controller.js +4 -3
  70. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-subscriptions.controller.js +2 -4
  71. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-repository-sets.html +1 -1
  72. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register-client.html +1 -1
  73. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-bulk-action.factory.js +2 -1
  74. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +1 -1
  75. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +1 -1
  76. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +2 -2
  77. data/lib/katello/permission_creator.rb +1 -1
  78. data/lib/katello/permissions/host_permissions.rb +1 -0
  79. data/lib/katello/tasks/pulp3_content_switchover.rake +3 -1
  80. data/lib/katello/tasks/pulp3_post_migration_check.rake +2 -1
  81. data/lib/katello/tasks/reimport.rake +1 -1
  82. data/lib/katello/tasks/reports.rake +4 -1
  83. data/lib/katello/version.rb +1 -1
  84. data/webpack/index.js +0 -1
  85. metadata +34 -14
  86. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-traces-resolve.factory.js +0 -18
@@ -0,0 +1,38 @@
1
+ module Katello
2
+ class HostTraceManager
3
+ def self.resolve_traces(traces)
4
+ traces.each do |trace|
5
+ if trace.reboot_required?
6
+ trace.helper = 'reboot'
7
+ end
8
+ end
9
+
10
+ traces_by_host_id = traces.group_by(&:host_id)
11
+ traces_by_helper = traces.group_by(&:helper)
12
+
13
+ composers = []
14
+
15
+ if traces_by_host_id.size < traces_by_helper.size
16
+ traces_by_host_id.each do |host_id, trace|
17
+ needed_traces = trace.map(&:helper).join(',')
18
+ joined_helpers = { :helper => needed_traces }
19
+ composers << ::JobInvocationComposer.for_feature(:katello_service_restart, [host_id], joined_helpers)
20
+ end
21
+ else
22
+ traces_by_helper.each do |helper, trace|
23
+ helpers = { :helper => helper }
24
+ composers << ::JobInvocationComposer.for_feature(:katello_service_restart, trace.map(&:host_id), helpers)
25
+ end
26
+ end
27
+
28
+ job_invocations = []
29
+
30
+ composers.each do |composer|
31
+ composer.trigger
32
+ job_invocations << composer.job_invocation
33
+ end
34
+
35
+ job_invocations
36
+ end
37
+ end
38
+ end
@@ -2,20 +2,15 @@ module Katello
2
2
  module Pulp3
3
3
  module ContentViewVersion
4
4
  class Export
5
+ include ImportExportCommon
6
+ METADATA_FILE = "metadata.json".freeze
7
+
5
8
  def initialize(smart_proxy:, content_view_version: nil, destination_server: nil)
6
9
  @smart_proxy = smart_proxy
7
10
  @content_view_version = content_view_version
8
11
  @destination_server = destination_server
9
12
  end
10
13
 
11
- def exporter_name
12
- @content_view_version.name.gsub(/\s/, '_')
13
- end
14
-
15
- def generate_exporter_id
16
- "#{@content_view_version.organization.label}_#{exporter_name}"
17
- end
18
-
19
14
  def generate_exporter_path
20
15
  export_path = "#{@content_view_version.content_view}/#{@content_view_version.version}/#{@destination_server}/#{date_dir}".gsub(/\s/, '_')
21
16
  "#{@content_view_version.organization.label}/#{export_path}"
@@ -25,28 +20,8 @@ module Katello
25
20
  DateTime.now.to_s.gsub(/\W/, '-')
26
21
  end
27
22
 
28
- def api
29
- ::Katello::Pulp3::Api::Core.new(@smart_proxy)
30
- end
31
-
32
- def repository_hrefs
33
- version_hrefs.map { |href| version_href_to_repository_href(href) }.uniq
34
- end
35
-
36
- def version_hrefs
37
- if @content_view_version.default?
38
- @content_view_version.repositories.yum_type.pluck(:version_href).compact
39
- else
40
- @content_view_version.archived_repos.yum_type.pluck(:version_href).compact
41
- end
42
- end
43
-
44
- def version_href_to_repository_href(version_href)
45
- version_href.split("/")[0..-3].join("/") + "/"
46
- end
47
-
48
23
  def create_exporter(export_base_dir: Setting['pulpcore_export_destination'])
49
- api.exporter_api.create(name: generate_exporter_id,
24
+ api.exporter_api.create(name: generate_id,
50
25
  path: "#{export_base_dir}/#{generate_exporter_path}",
51
26
  repositories: repository_hrefs)
52
27
  end
@@ -65,6 +40,27 @@ module Katello
65
40
  api.export_api.delete(export_data.pulp_href) unless export_data.blank?
66
41
  api.exporter_api.delete(exporter_href)
67
42
  end
43
+
44
+ def generate_metadata
45
+ ret = { organization: @content_view_version.organization.name,
46
+ repository_mapping: {},
47
+ content_view: @content_view_version.content_view.name,
48
+ content_view_version: {
49
+ major: @content_view_version.major,
50
+ minor: @content_view_version.minor
51
+ }
52
+ }
53
+ repositories.each do |repo|
54
+ next if repo.version_href.blank?
55
+ pulp3_repo = fetch_repository_info(repo.version_href).name
56
+ ret[:repository_mapping][pulp3_repo] = {
57
+ repository: repo.root.name,
58
+ product: repo.root.product.name,
59
+ redhat: repo.redhat?
60
+ }
61
+ end
62
+ ret
63
+ end
68
64
  end
69
65
  end
70
66
  end
@@ -0,0 +1,87 @@
1
+ module Katello
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class Import
5
+ include ImportExportCommon
6
+ BASEDIR = '/var/lib/pulp'.freeze
7
+
8
+ def initialize(smart_proxy:, content_view_version: nil, path: nil)
9
+ @smart_proxy = smart_proxy
10
+ @content_view_version = content_view_version
11
+ @path = path
12
+ end
13
+
14
+ def repository_mapping
15
+ mapping = {}
16
+ metadata[:repository_mapping].each do |key, value|
17
+ repo = @content_view_version.importable_repositories.joins(:root, :product).
18
+ where("#{::Katello::Product.table_name}" => {:name => value[:product]},
19
+ "#{::Katello::RootRepository.table_name}" => {:name => value[:repository]}).first
20
+ next unless repo&.version_href
21
+ repo_info = fetch_repository_info(repo.version_href)
22
+ mapping[key] = repo_info.name
23
+ end
24
+ mapping
25
+ end
26
+
27
+ def create_importer
28
+ api.importer_api.create(name: generate_id,
29
+ repo_mapping: repository_mapping)
30
+ end
31
+
32
+ def create_import(importer_href)
33
+ [api.import_api.create(importer_href, toc: "#{@path}/#{metadata[:toc]}")]
34
+ end
35
+
36
+ def fetch_import(importer_href)
37
+ api.import_api.list(importer_href).results.first
38
+ end
39
+
40
+ def destroy_importer(importer_href)
41
+ import_data = fetch_import(importer_href)
42
+ api.import_api.delete(import_data.pulp_href) unless import_data.blank?
43
+ api.importer_api.delete(importer_href)
44
+ end
45
+
46
+ def metadata
47
+ @metadata ||= self.class.metadata(@path)
48
+ end
49
+
50
+ class << self
51
+ def metadata(path)
52
+ JSON.parse(File.read("#{path}/#{Export::METADATA_FILE}")).with_indifferent_access
53
+ end
54
+
55
+ def check_permissions!(path)
56
+ fail _("Invalid path specified.") if path.blank? || !File.directory?(path)
57
+ fail _("The import path must be in a subdirectory under '%s'." % BASEDIR) unless path.starts_with?(BASEDIR)
58
+ metadata_file = "#{path}/#{::Katello::Pulp3::ContentViewVersion::Export::METADATA_FILE}"
59
+ fail _("Could not find metadata.json at '%s'." % metadata_file) unless File.exist?(metadata_file)
60
+ fail _("Unable to read the metadata.json at '%s'." % metadata_file) unless File.readable?(metadata_file)
61
+ fail _("Pulp user or group unable to read content in '%s'." % path) unless pulp_user_accessible?(path)
62
+ Dir.glob("#{path}/*").each do |file|
63
+ next if file == metadata_file
64
+ fail _("Pulp user or group unable to read '%s'." % file) unless pulp_user_accessible?(file)
65
+ end
66
+ end
67
+
68
+ def pulp_user_accessible?(path)
69
+ pulp_info = fetch_pulp_user_info
70
+ return false if pulp_info.blank?
71
+
72
+ stat = File.stat(path)
73
+ stat.gid.to_s == pulp_info.gid ||
74
+ stat.uid.to_s == pulp_info.uid ||
75
+ stat.mode.to_s(8)[-1].to_i >= 4
76
+ end
77
+
78
+ def fetch_pulp_user_info
79
+ pulp_user = nil
80
+ Etc.passwd { |u| pulp_user = u if u.name == 'pulp' }
81
+ pulp_user
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,44 @@
1
+ module Katello
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ module ImportExportCommon
5
+ def generate_name
6
+ @content_view_version.name.gsub(/\s/, '_')
7
+ end
8
+
9
+ def generate_id
10
+ "#{@content_view_version.organization.label}_#{generate_name}"
11
+ end
12
+
13
+ def api
14
+ ::Katello::Pulp3::Api::Core.new(@smart_proxy)
15
+ end
16
+
17
+ def fetch_repository_info(version_href)
18
+ repo_api = ::Katello::Pulp3::Api::Yum.new(@smart_proxy).repositories_api
19
+ repo_api.read(version_href_to_repository_href(version_href))
20
+ end
21
+
22
+ def repository_hrefs
23
+ version_hrefs.map { |href| version_href_to_repository_href(href) }.uniq
24
+ end
25
+
26
+ def version_hrefs
27
+ repositories.pluck(:version_href).compact
28
+ end
29
+
30
+ def repositories
31
+ if @content_view_version.default?
32
+ @content_view_version.repositories.yum_type
33
+ else
34
+ @content_view_version.archived_repos.yum_type
35
+ end
36
+ end
37
+
38
+ def version_href_to_repository_href(version_href)
39
+ version_href.split("/")[0..-3].join("/") + "/"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -35,7 +35,8 @@ module Katello
35
35
  custom_json["issued"] = convert_date_if_epoch(custom_json["issued"])
36
36
  custom_json["updated"] = convert_date_if_epoch(custom_json["updated"]) unless custom_json["updated"].blank?
37
37
 
38
- if model.updated.blank? || (custom_json['updated'].to_datetime != model.updated.to_datetime)
38
+ if model.updated.blank? ||
39
+ (custom_json['updated'] && (custom_json['updated'].to_datetime != model.updated.to_datetime))
39
40
  custom_json['errata_id'] = custom_json.delete('id')
40
41
  custom_json['errata_type'] = custom_json.delete('type')
41
42
  custom_json['updated'] = custom_json['updated'].blank? ? custom_json['issued'] : custom_json['updated']
@@ -1,5 +1,4 @@
1
1
  require "pulpcore_client"
2
-
3
2
  module Katello
4
3
  module Pulp3
5
4
  class Repository
@@ -188,8 +187,9 @@ module Katello
188
187
  api.repositories_api.read(repository_reference.try(:repository_href))
189
188
  end
190
189
 
191
- def delete(href = repository_reference.try(:repository_href))
192
- repository_reference.try(:destroy)
190
+ def delete_repository(repo_reference = repository_reference)
191
+ href = repo_reference.try(:repository_href)
192
+ repo_reference.try(:destroy)
193
193
  ignore_404_exception { api.repositories_api.delete(href) } if href
194
194
  end
195
195
 
@@ -251,8 +251,12 @@ module Katello
251
251
  create_version(:base_version => from_repository.version_href)
252
252
  end
253
253
 
254
+ def version_zero?
255
+ repo.version_href.ends_with?('/versions/0/')
256
+ end
257
+
254
258
  def delete_version
255
- ignore_404_exception { api.repository_versions_api.delete(repo.version_href) }
259
+ ignore_404_exception { api.repository_versions_api.delete(repo.version_href) } unless version_zero?
256
260
  end
257
261
 
258
262
  def create_version(options = {})
@@ -3,10 +3,13 @@ require 'pulp_rpm_client'
3
3
  module Katello
4
4
  module Pulp3
5
5
  class Repository
6
+ # rubocop:disable Metrics/ClassLength
6
7
  class Yum < ::Katello::Pulp3::Repository
7
8
  include Katello::Util::Errata
8
9
  include Katello::Util::PulpcoreContentFilters
9
10
 
11
+ UNIT_LIMIT = 10_000
12
+
10
13
  def remote_options
11
14
  url, sles_token = extract_sles_token
12
15
  options = common_remote_options
@@ -109,14 +112,70 @@ module Katello
109
112
  data.config << config
110
113
  end
111
114
  end
112
- # FIXME: data's content being [] causes all content to be copied back
113
- tasks << api.copy_api.copy_content(data)
115
+ tasks << copy_content_chunked(data)
114
116
  else
115
117
  tasks << remove_all_content_from_mapping(repo_id_map)
116
118
  end
117
119
  tasks.flatten
118
120
  end
119
121
 
122
+ def copy_api_data_dup(data)
123
+ data_dup = PulpRpmClient::Copy.new
124
+ data_dup.dependency_solving = data.dependency_solving
125
+ data_dup.config = []
126
+ data.config.each do |repo_config|
127
+ config_hash = {
128
+ source_repo_version: repo_config[:source_repo_version],
129
+ dest_repo: repo_config[:dest_repo],
130
+ content: []
131
+ }
132
+ config_hash[:dest_base_version] = repo_config[:dest_base_version] if repo_config[:dest_base_version]
133
+ data_dup.config << config_hash
134
+ end
135
+ data_dup
136
+ end
137
+
138
+ def copy_content_chunked(data)
139
+ tasks = []
140
+ # Don't chunk if there aren't enough content units
141
+ if data.config.sum { |repo_config| repo_config[:content].size } <= UNIT_LIMIT
142
+ return api.copy_api.copy_content(data)
143
+ end
144
+
145
+ unit_copy_counter = 0
146
+ i = 0
147
+ leftover_units = data.config.first[:content].deep_dup
148
+
149
+ # Copy data and clear its content fields
150
+ data_dup = copy_api_data_dup(data)
151
+
152
+ while i < data_dup.config.size
153
+ # Copy all units within repo or only some?
154
+ if leftover_units.length < UNIT_LIMIT - unit_copy_counter
155
+ copy_amount = leftover_units.length
156
+ else
157
+ copy_amount = UNIT_LIMIT - unit_copy_counter
158
+ end
159
+
160
+ data_dup.config[i][:content] = leftover_units.pop(copy_amount)
161
+ unit_copy_counter += copy_amount
162
+ if unit_copy_counter != 0
163
+ tasks << api.copy_api.copy_content(data_dup)
164
+ unit_copy_counter = 0
165
+ end
166
+
167
+ if leftover_units.empty?
168
+ # Nothing more to copy -- clear current config's content
169
+ data_dup.config[i][:content] = []
170
+ i += 1
171
+ # Fetch unit list for next data config
172
+ leftover_units = data.config[i][:content].deep_dup unless i == data_dup.config.size
173
+ end
174
+ end
175
+
176
+ tasks
177
+ end
178
+
120
179
  def remove_all_content_from_mapping(repo_id_map)
121
180
  tasks = []
122
181
  repo_id_map.each do |_source_repo_ids, dest_repo_id_map|
@@ -148,6 +207,16 @@ module Katello
148
207
  tasks
149
208
  end
150
209
 
210
+ def copy_all(source_repository)
211
+ data = PulpRpmClient::Copy.new
212
+ data.config = [{
213
+ source_repo_version: source_repository.version_href,
214
+ dest_repo: repository_reference.repository_href
215
+ }]
216
+
217
+ [api.copy_api.copy_content(data)]
218
+ end
219
+
151
220
  def remove_all_content_from_repo(repo_href)
152
221
  data = PulpRpmClient::RepositoryAddRemoveContent.new(
153
222
  remove_content_units: ['*'])
@@ -271,7 +340,6 @@ module Katello
271
340
  end
272
341
 
273
342
  filters.flatten!.compact!
274
-
275
343
  whitelist_ids = []
276
344
  blacklist_ids = []
277
345
  filters.each do |filter|
@@ -298,7 +366,6 @@ module Katello
298
366
  content_unit_hrefs += additional_content_hrefs(source_repository, content_unit_hrefs)
299
367
  end
300
368
  content_unit_hrefs += source_repository.srpms.pluck(:pulp_id)
301
-
302
369
  dependency_solving = options[:solve_dependencies] || false
303
370
  copy_units(source_repository, content_unit_hrefs.uniq, dependency_solving)
304
371
  end
@@ -61,7 +61,7 @@ module Katello
61
61
  end
62
62
 
63
63
  def task_group_href
64
- task_data[:task_group]
64
+ task_data[:task_group] || task_data[:created_resources].find { |href| href.starts_with?("/pulp/api/v3/task-groups/") }
65
65
  end
66
66
 
67
67
  def done?
@@ -79,7 +79,7 @@ module Katello
79
79
 
80
80
  def error
81
81
  if task_data[:state] == CANCELED
82
- self.new(_("Task canceled"))
82
+ _("Task canceled")
83
83
  elsif task_data[:state] == FAILED
84
84
  if task_data[:error][:description].blank?
85
85
  _("Pulp task error")
@@ -90,8 +90,8 @@ module Katello
90
90
  end
91
91
 
92
92
  def cancel
93
- data = PulpcoreClient::Task.new(state: 'canceled')
94
- tasks_api.tasks_cancel(pulp_task['pulp_href'], data)
93
+ data = PulpcoreClient::TaskResponse.new(state: 'canceled')
94
+ tasks_api.tasks_cancel(task_data['pulp_href'], data)
95
95
  #the main task may have completed, so cancel spawned tasks too
96
96
  task_data['spawned_tasks']&.each { |spawned| tasks_api.tasks_cancel(spawned['pulp_href'], data) }
97
97
  end
@@ -73,6 +73,12 @@ module Katello
73
73
  end
74
74
 
75
75
  def cancel
76
+ tasks_api = ::Katello::Pulp3::Api::Core.new(@smart_proxy).tasks_api
77
+ tasks_response = tasks_api.list(task_group: task_group_data['pulp_href'])
78
+ data = PulpcoreClient::TaskResponse.new(state: 'canceled')
79
+ tasks_response.results.collect do |result|
80
+ tasks_api.tasks_cancel(result.pulp_href, data)
81
+ end
76
82
  end
77
83
  end
78
84
  end