katello 3.16.0.rc5 → 3.16.1.2

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 (97) 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 +1 -1
  4. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +5 -1
  5. data/app/controllers/katello/api/v2/host_tracer_controller.rb +0 -5
  6. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +15 -0
  7. data/app/controllers/katello/api/v2/repositories_controller.rb +10 -1
  8. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -5
  9. data/app/helpers/katello/content_view_helper.rb +15 -0
  10. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +1 -1
  11. data/app/lib/actions/katello/capsule_content/sync.rb +3 -2
  12. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +17 -3
  13. data/app/lib/actions/katello/content_view/incremental_updates.rb +3 -1
  14. data/app/lib/actions/katello/content_view/publish.rb +55 -16
  15. data/app/lib/actions/katello/content_view_version/incremental_update.rb +84 -53
  16. data/app/lib/actions/katello/host/attach_subscriptions.rb +5 -1
  17. data/app/lib/actions/katello/product/destroy.rb +25 -4
  18. data/app/lib/actions/katello/repository/destroy.rb +5 -1
  19. data/app/lib/actions/katello/repository/multi_clone_contents.rb +62 -0
  20. data/app/lib/actions/katello/repository/multi_clone_to_version.rb +30 -0
  21. data/app/lib/actions/katello/repository/sync.rb +35 -25
  22. data/app/lib/actions/katello/repository/update.rb +11 -16
  23. data/app/lib/actions/katello/repository/verify_checksum.rb +28 -0
  24. data/app/lib/actions/katello/sync_plan/run.rb +1 -1
  25. data/app/lib/actions/pulp/orchestration/repository/sync.rb +2 -1
  26. data/app/lib/actions/pulp/repository/sync.rb +2 -1
  27. data/app/lib/actions/pulp3/abstract_async_task.rb +62 -58
  28. data/app/lib/actions/pulp3/capsule_content/refresh_content_guard.rb +17 -0
  29. data/app/lib/actions/pulp3/capsule_content/sync.rb +3 -1
  30. data/app/lib/actions/pulp3/{ContentGuard → content_guard}/refresh.rb +0 -0
  31. data/app/lib/actions/pulp3/content_migration.rb +4 -0
  32. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -4
  33. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +36 -0
  34. data/app/lib/actions/pulp3/orchestration/repository/sync.rb +3 -1
  35. data/app/lib/actions/pulp3/orchestration/repository/trigger_update_repo_cert_guard.rb +22 -0
  36. data/app/lib/actions/pulp3/repository/copy_content.rb +0 -1
  37. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +28 -0
  38. data/app/lib/actions/pulp3/repository/multi_copy_units.rb +14 -7
  39. data/app/lib/actions/pulp3/repository/presenters/content_unit_presenter.rb +1 -1
  40. data/app/lib/actions/pulp3/repository/presenters/repair_presenter.rb +85 -0
  41. data/app/lib/actions/pulp3/repository/repair.rb +29 -0
  42. data/app/lib/actions/pulp3/repository/save_version.rb +20 -8
  43. data/app/lib/actions/pulp3/repository/save_versions.rb +47 -13
  44. data/app/lib/actions/pulp3/repository/sync.rb +1 -1
  45. data/app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb +6 -2
  46. data/app/lib/actions/pulp3/repository/upload_file.rb +1 -1
  47. data/app/lib/katello/concerns/base_template_scope_extensions.rb +4 -0
  48. data/app/lib/katello/errors.rb +1 -15
  49. data/app/lib/katello/resources/cdn.rb +3 -2
  50. data/app/lib/katello/util/cdn_var_substitutor.rb +9 -6
  51. data/app/models/katello/concerns/smart_proxy_extensions.rb +14 -3
  52. data/app/models/katello/content_view.rb +18 -6
  53. data/app/models/katello/content_view_erratum_filter.rb +13 -0
  54. data/app/models/katello/content_view_filter.rb +4 -0
  55. data/app/models/katello/content_view_module_stream_filter.rb +30 -3
  56. data/app/models/katello/content_view_package_filter.rb +1 -1
  57. data/app/models/katello/host/content_facet.rb +1 -0
  58. data/app/models/katello/module_stream.rb +1 -1
  59. data/app/models/katello/ping.rb +1 -3
  60. data/app/models/katello/repository.rb +16 -0
  61. data/app/models/setting/content.rb +1 -1
  62. data/app/presenters/katello/sync_status_presenter.rb +4 -2
  63. data/app/services/cert/certs.rb +10 -2
  64. data/app/services/katello/pulp/repository/yum.rb +2 -1
  65. data/app/services/katello/pulp3/api/core.rb +4 -0
  66. data/app/services/katello/pulp3/erratum.rb +3 -1
  67. data/app/services/katello/pulp3/migration.rb +10 -5
  68. data/app/services/katello/pulp3/migration_plan.rb +6 -6
  69. data/app/services/katello/pulp3/repository.rb +13 -5
  70. data/app/services/katello/pulp3/repository/yum.rb +235 -35
  71. data/app/services/katello/pulp3/repository_mirror.rb +7 -2
  72. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  73. data/app/services/katello/pulp3/task.rb +100 -0
  74. data/app/services/katello/pulp3/task_group.rb +79 -0
  75. data/app/services/katello/smart_proxy_helper.rb +13 -16
  76. data/app/views/katello/api/v2/content_view_filters/base.json.rabl +4 -0
  77. data/config/routes/api/rhsm.rb +1 -0
  78. data/config/routes/api/v2.rb +2 -0
  79. data/db/migrate/20200709021250_add_original_modules_to_content_view_module_stream_filter.rb +5 -0
  80. data/db/migrate/20200721142707_remove_duplicate_katello_pools_index.rb +5 -0
  81. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.routes.js +1 -13
  82. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/filter-details.controller.js +17 -4
  83. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/views/module-stream-filter-details.html +17 -0
  84. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/product-bulk-action.factory.js +1 -0
  85. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +6 -0
  86. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +7 -1
  87. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -0
  88. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +15 -0
  89. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +6 -0
  90. data/lib/katello/permission_creator.rb +2 -2
  91. data/lib/katello/plugin.rb +0 -1
  92. data/lib/katello/tasks/pulp3_post_migration_check.rake +2 -1
  93. data/lib/katello/tasks/reports.rake +16 -0
  94. data/lib/katello/version.rb +1 -1
  95. data/webpack/redux/actions/RedHatRepositories/helpers.js +6 -6
  96. metadata +34 -14
  97. data/app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb +0 -17
@@ -289,9 +289,21 @@ module Katello
289
289
  where("#{Katello::ContentViewVersion.table_name}.content_view_id" => self.id)
290
290
  end
291
291
 
292
- def repositories_to_publish
292
+ def repositories_to_publish(override_components = nil)
293
293
  if composite?
294
- ids = components.flat_map { |version| version.repositories.archived }.map(&:id)
294
+ components_to_publish = []
295
+ components.each do |component|
296
+ override_component = override_components&.detect do |override_cvv|
297
+ override_cvv.content_view == component.content_view
298
+ end
299
+
300
+ if override_component
301
+ components_to_publish << override_component
302
+ else
303
+ components_to_publish << component
304
+ end
305
+ end
306
+ ids = components_to_publish.flat_map { |version| version.repositories.archived }.map(&:id)
295
307
  Repository.where(:id => ids)
296
308
  else
297
309
  repositories
@@ -302,11 +314,11 @@ module Katello
302
314
  composite? ? repositories_to_publish.pluck(&:id) : repository_ids
303
315
  end
304
316
 
305
- def repositories_to_publish_by_library_instance
317
+ def repositories_to_publish_by_library_instance(override_components = nil)
306
318
  # retrieve the list of repositories in a hash, where the key
307
319
  # is the library instance id, and the value is an array
308
320
  # of the repositories for that instance.
309
- repositories_to_publish.inject({}) do |result, repo|
321
+ repositories_to_publish(override_components).inject({}) do |result, repo|
310
322
  result[repo.library_instance] ||= []
311
323
  result[repo.library_instance] << repo
312
324
  result
@@ -326,8 +338,8 @@ module Katello
326
338
  component_composites.where(latest: true).joins(:composite_content_view).where(self.class.table_name => {auto_publish: true})
327
339
  end
328
340
 
329
- def publish_repositories
330
- repositories = composite? ? repositories_to_publish_by_library_instance.values : repositories_to_publish
341
+ def publish_repositories(override_components = nil)
342
+ repositories = composite? ? repositories_to_publish_by_library_instance(override_components).values : repositories_to_publish
331
343
  repositories.each do |repos|
332
344
  if repos.is_a? Array
333
345
  yield repos
@@ -30,6 +30,7 @@ module Katello
30
30
  if filter_by_id?
31
31
  errata_ids = erratum_rules.map(&:errata_id)
32
32
  errata_pulp_ids = errata_package_pulp_ids_from_errata_ids(repo, errata_ids)
33
+ errata_pulp_ids += errata_module_stream_pulp_ids_from_errata_ids(errata_ids)
33
34
  else
34
35
  clauses = []
35
36
  clauses << errata_from
@@ -37,7 +38,9 @@ module Katello
37
38
  clauses << types_clause
38
39
  package_filenames = Erratum.list_filenames_by_clauses(repo, clauses.compact)
39
40
  errata_pulp_ids = errata_package_pulp_ids_from_package_filenames(repo, package_filenames)
41
+ errata_pulp_ids += errata_module_stream_pulp_ids_from_clauses(repo, clauses.compact)
40
42
  end
43
+
41
44
  errata_pulp_ids
42
45
  end
43
46
 
@@ -48,10 +51,20 @@ module Katello
48
51
  repo.rpms.where("filename ILIKE ANY ( array[?] )", query_params)
49
52
  end
50
53
 
54
+ def errata_module_stream_pulp_ids_from_clauses(repo, clauses)
55
+ module_streams = Erratum.list_modular_streams_by_clauses(repo, clauses)
56
+ module_streams.pluck(:pulp_id)
57
+ end
58
+
51
59
  def errata_package_pulp_ids_from_package_filenames(repo, package_filenames)
52
60
  rpms_by_filename(repo, package_filenames).pluck(:pulp_id)
53
61
  end
54
62
 
63
+ def errata_module_stream_pulp_ids_from_errata_ids(errata_ids)
64
+ module_streams = Katello::Erratum.where(:errata_id => errata_ids).map(&:module_streams).compact.flatten
65
+ module_streams.pluck(:pulp_id)
66
+ end
67
+
55
68
  def errata_package_pulp_ids_from_errata_ids(repo, errata_ids)
56
69
  package_filenames = Katello::ErratumPackage.joins(:erratum).where("#{Erratum.table_name}.errata_id" => errata_ids).pluck(:filename)
57
70
  rpms_by_filename(repo, package_filenames).pluck(:pulp_id)
@@ -182,6 +182,10 @@ module Katello
182
182
  fail "setting original_packages not supported for #{self.class.name}"
183
183
  end
184
184
 
185
+ def original_module_streams=(_include_original)
186
+ fail "setting original_module_streams not supported for #{self.class.name}"
187
+ end
188
+
185
189
  protected
186
190
 
187
191
  def validate_repos
@@ -6,9 +6,36 @@ module Katello
6
6
 
7
7
  validates_lengths_from_database
8
8
 
9
- def generate_clauses(_repo)
10
- return if module_stream_rules.blank?
11
- module_stream_rules.map(&:module_stream_id)
9
+ def generate_clauses(repo)
10
+ rules = module_stream_rules || []
11
+ ids = rules.map(&:module_stream_id)
12
+ if self.original_module_streams
13
+ ids.concat(repo.module_streams_without_errata.map(&:id))
14
+ end
15
+ ids
16
+ end
17
+
18
+ def original_module_streams=(value)
19
+ self[:original_module_streams] = value
20
+ end
21
+
22
+ def content_unit_pulp_ids(repo, dependents = false)
23
+ content_unit_ids = []
24
+ module_ids = []
25
+
26
+ self.module_stream_rules.each do |rule|
27
+ module_ids << rule.module_stream_id
28
+ end
29
+ if self.original_module_streams
30
+ module_ids.concat(repo.module_streams_without_errata.map(&:id))
31
+ end
32
+ modules_streams = ModuleStream.where(id: module_ids).includes(:rpms)
33
+ content_unit_ids += modules_streams.pluck(:pulp_id).flatten.uniq
34
+ if dependents && !modules_streams.empty?
35
+ rpms = modules_streams.map(&:rpms).flatten
36
+ content_unit_ids += rpms.pluck(:pulp_id).flatten.uniq
37
+ end
38
+ content_unit_ids.uniq
12
39
  end
13
40
  end
14
41
  end
@@ -37,7 +37,7 @@ module Katello
37
37
  self.package_rules.each do |rule|
38
38
  package_filenames.concat(query_rpms(repo, rule))
39
39
  end
40
-
40
+ package_filenames.concat(repo.packages_without_errata.map(&:filename)) if self.original_packages
41
41
  rpms = Rpm.in_repositories(repo)
42
42
  rpms.where(filename: package_filenames).where(:modular => false).pluck(:pulp_id).flatten.uniq
43
43
  end
@@ -126,6 +126,7 @@ module Katello
126
126
  ::Katello::Applicability::ApplicableContentHelper.new(self, ::Katello::Erratum, bound_repos).calculate_and_import
127
127
  ::Katello::Applicability::ApplicableContentHelper.new(self, ::Katello::ModuleStream, bound_repos).calculate_and_import
128
128
  update_applicability_counts
129
+ self.update_errata_status
129
130
  end
130
131
 
131
132
  def import_applicability(partial = false)
@@ -65,7 +65,7 @@ module Katello
65
65
  end
66
66
 
67
67
  def module_spec_hash
68
- {:name => name, :stream => stream, :version => version, :context => context, :arch => arch, :id => id}.compact
68
+ {:name => name, :stream => stream, :version => version, :context => context, :arch => arch, :pulp_id => pulp_id, :id => id}.compact
69
69
  end
70
70
 
71
71
  def self.parse_module_spec(module_spec)
@@ -31,9 +31,7 @@ module Katello
31
31
 
32
32
  # set overall status result code
33
33
  result = {:services => result}
34
- result[:services].each_value do |v|
35
- result[:status] = v[:status] == OK_RETURN_CODE ? OK_RETURN_CODE : FAIL_RETURN_CODE
36
- end
34
+ result[:status] = result[:services].each_value.any? { |v| v[:status] == FAIL_RETURN_CODE } ? FAIL_RETURN_CODE : OK_RETURN_CODE
37
35
  result
38
36
  end
39
37
 
@@ -133,6 +133,7 @@ module Katello
133
133
  scope :in_published_environments, -> { in_content_views(Katello::ContentView.non_default).where.not(:environment_id => nil) }
134
134
  scope :order_by_root, ->(attr) { joins(:root).order("#{Katello::RootRepository.table_name}.#{attr}") }
135
135
  scope :with_content, ->(content) { joins(Katello::RepositoryTypeManager.find_content_type(content).model_class.repository_association_class.name.demodulize.underscore.pluralize.to_sym).distinct }
136
+ scope :by_rpm_count, -> { left_joins(:repository_rpms).group(:id).order("count(katello_repository_rpms.id) ASC") } # smallest count first
136
137
 
137
138
  scoped_search :on => :name, :relation => :root, :complete_value => true
138
139
  scoped_search :rename => :product, :on => :name, :relation => :product, :complete_value => true
@@ -469,6 +470,17 @@ module Katello
469
470
  end
470
471
  end
471
472
 
473
+ def module_streams_without_errata
474
+ module_stream_errata = Katello::ModuleStreamErratumPackage.joins(:erratum_package => {:erratum => :repository_errata})
475
+ .where("#{RepositoryErratum.table_name}.repository_id" => self.id)
476
+ .pluck("#{Katello::ModuleStreamErratumPackage.table_name}.module_stream_id")
477
+ if module_stream_errata.any?
478
+ self.module_streams.where("#{ModuleStream.table_name}.id NOT in (?)", module_stream_errata)
479
+ else
480
+ self.module_streams
481
+ end
482
+ end
483
+
472
484
  def self.with_errata(errata)
473
485
  joins(:repository_errata).where("#{Katello::RepositoryErratum.table_name}.erratum_id" => errata)
474
486
  end
@@ -581,6 +593,10 @@ module Katello
581
593
  environment
582
594
  end
583
595
 
596
+ def self.smart_proxy_syncable
597
+ where.not(:environment_id => nil)
598
+ end
599
+
584
600
  def exist_for_environment?(environment, content_view, attribute = nil)
585
601
  if environment.present? && content_view.in_environment?(environment)
586
602
  repos = content_view.version(environment).repos(environment)
@@ -92,7 +92,7 @@ class Setting::Content < Setting
92
92
  self.set('check_services_before_actions', N_("Whether or not to check the status of backend services such as pulp and candlepin prior to performing some actions."),
93
93
  true, N_('Check services before actions')),
94
94
  self.set('foreman_proxy_content_batch_size', N_("How many repositories should be synced concurrently on the capsule. A smaller number may lead to longer sync times. A larger number will increase dynflow load."),
95
- 25, N_('Batch size to sync repositories in.')),
95
+ 100, N_('Batch size to sync repositories in.')),
96
96
  self.set('foreman_proxy_content_auto_sync', N_("Whether or not to auto sync the Smart Proxies after a Content View promotion."),
97
97
  true, N_('Sync Smart Proxies after Content View promotion')),
98
98
  self.set('default_download_policy', N_("Default download policy for custom repositories (either 'immediate', 'on_demand', or 'background')"), "immediate",
@@ -19,6 +19,8 @@ module Katello
19
19
  def sync_progress
20
20
  return {:state => nil} unless @repo
21
21
  return empty_task(@repo) unless @task
22
+ display_output = @task.humanized[:output]
23
+ display_output = display_output.split("\n")[0] if (display_output && @repo.version_href)
22
24
  {
23
25
  :id => @repo.id,
24
26
  :product_id => @repo.product.id,
@@ -29,8 +31,8 @@ module Katello
29
31
  :start_time => format_date(@task.started_at),
30
32
  :finish_time => format_date(@task.ended_at),
31
33
  :duration => format_duration(@task.ended_at, @task.started_at),
32
- :display_size => @task.humanized[:output],
33
- :size => @task.humanized[:output],
34
+ :display_size => display_output,
35
+ :size => display_output,
34
36
  :is_running => @task.pending && @task.state != 'paused',
35
37
  :error_details => @task.errors
36
38
  }
@@ -9,11 +9,19 @@ module Cert
9
9
  end
10
10
 
11
11
  def self.ssl_client_cert
12
- @ssl_client_cert ||= OpenSSL::X509::Certificate.new(File.open(Setting['pulp_client_cert'], 'r').read)
12
+ @ssl_client_cert ||= OpenSSL::X509::Certificate.new(File.open(ssl_client_cert_filename, 'r').read)
13
+ end
14
+
15
+ def self.ssl_client_cert_filename
16
+ Setting['pulp_client_cert']
13
17
  end
14
18
 
15
19
  def self.ssl_client_key
16
- @ssl_client_key ||= OpenSSL::PKey::RSA.new(File.open(Setting['pulp_client_key'], 'r').read)
20
+ @ssl_client_key ||= OpenSSL::PKey::RSA.new(File.open(ssl_client_key_filename, 'r').read)
21
+ end
22
+
23
+ def self.ssl_client_key_filename
24
+ Setting['pulp_client_key']
17
25
  end
18
26
 
19
27
  def self.verify_ueber_cert(organization)
@@ -246,7 +246,8 @@ module Katello
246
246
  remove = clause_gen.remove_clause
247
247
  remove_clauses = {filters: {unit: remove}} if remove
248
248
  else
249
- copy_clauses = {}
249
+ non_modular_rpms = ::Katello::Rpm.in_repositories(repo).non_modular.pluck(:filename)
250
+ copy_clauses = non_modular_rpms.blank? ? nil : {filters: {unit: ContentViewPackageFilter.generate_rpm_clauses(non_modular_rpms)}}
250
251
  remove_clauses = nil
251
252
  end
252
253
 
@@ -74,6 +74,10 @@ module Katello
74
74
  PulpcoreClient::TasksApi.new(core_api_client)
75
75
  end
76
76
 
77
+ def task_groups_api
78
+ PulpcoreClient::TaskGroupsApi.new(core_api_client)
79
+ end
80
+
77
81
  def upload_class
78
82
  PulpcoreClient::Upload
79
83
  end
@@ -26,8 +26,10 @@ module Katello
26
26
  end
27
27
 
28
28
  def update_model(model)
29
- keys = %w(title id severity issued type description reboot_suggested solution updated summary)
29
+ keys = %w(title id severity issued_date type description reboot_suggested solution updated_date summary)
30
30
  custom_json = backend_data.slice(*keys)
31
+ custom_json["issued"] = custom_json.delete("issued_date")
32
+ custom_json["updated"] = custom_json.delete("updated_date")
31
33
 
32
34
  # handle SUSE epoch dates
33
35
  custom_json["issued"] = convert_date_if_epoch(custom_json["issued"])
@@ -35,11 +35,15 @@ module Katello
35
35
  end
36
36
 
37
37
  def pulp2_content_api
38
- Pulp2to3MigrationClient::Pulp2contentApi.new(api_client)
38
+ Pulp2to3MigrationClient::Pulp2ContentApi.new(api_client)
39
+ rescue NameError
40
+ Pulp2to3MigrationClient::Pulp2contentApi.new(api_client) #backwards compatible
39
41
  end
40
42
 
41
43
  def pulp2_repositories_api
42
- Pulp2to3MigrationClient::Pulp2repositoriesApi.new(api_client)
44
+ Pulp2to3MigrationClient::Pulp2RepositoriesApi.new(api_client)
45
+ rescue NameError
46
+ Pulp2to3MigrationClient::Pulp2repositoriesApi.new(api_client) #backwards compatible
43
47
  end
44
48
 
45
49
  def create_and_run_migrations
@@ -64,8 +68,9 @@ module Katello
64
68
  end
65
69
 
66
70
  def create_migrations
67
- migration_plans = @repository_types.map { |label| Katello::Pulp3::MigrationPlan.new(label) }
68
- migration_plans.map { |plan| migration_plan_api.create(plan: plan.generate.as_json).pulp_href }
71
+ plan = Katello::Pulp3::MigrationPlan.new(@repository_types)
72
+ Rails.logger.info(plan)
73
+ [migration_plan_api.create(plan: plan.generate.as_json).pulp_href]
69
74
  end
70
75
 
71
76
  def start_migration(plan_href)
@@ -112,7 +117,7 @@ module Katello
112
117
  relative_path = pulp3_api.distributions_api.read(href).base_path
113
118
 
114
119
  dist_ref = Katello::Pulp3::DistributionReference.find_or_initialize_by(:path => relative_path)
115
- if (distribution_repo = Katello::Repository.find_by(:relative_path => relative_path))
120
+ if (distribution_repo = Katello::Repository.find_by(:relative_path => relative_path) || Katello::Repository.find_by(:container_repository_name => relative_path))
116
121
  dist_ref.href = href
117
122
  dist_ref.repository_id = distribution_repo.id
118
123
  dist_ref.save!
@@ -1,8 +1,8 @@
1
1
  module Katello
2
2
  module Pulp3
3
3
  class MigrationPlan
4
- def initialize(repository_type_label)
5
- @repository_type = repository_type_label
4
+ def initialize(repository_type_labels)
5
+ @repository_types = repository_type_labels
6
6
  end
7
7
 
8
8
  def master_proxy
@@ -17,12 +17,12 @@ module Katello
17
17
  end
18
18
 
19
19
  def generate_plugins
20
- [
20
+ @repository_types.map do |repository_type|
21
21
  {
22
- type: pulp2_repository_type(@repository_type),
23
- repositories: repository_migrations(@repository_type)
22
+ type: pulp2_repository_type(repository_type),
23
+ repositories: repository_migrations(repository_type)
24
24
  }
25
- ]
25
+ end
26
26
  end
27
27
 
28
28
  def pulp2_repository_type(repository_type)
@@ -193,14 +193,17 @@ module Katello
193
193
  ignore_404_exception { api.repositories_api.delete(href) } if href
194
194
  end
195
195
 
196
- def sync
197
- sync_url_params = {remote: repo.remote_href, mirror: repo.root.mirror_on_sync}
198
- skip_type_param = skip_types
199
- sync_url_params[:skip_types] = skip_type_param if skip_type_param
200
- repository_sync_url_data = api.class.repository_sync_url_class.new(sync_url_params)
196
+ def sync(options = {})
197
+ repository_sync_url_data = api.class.repository_sync_url_class.new(sync_url_params(options))
201
198
  [api.repositories_api.sync(repository_reference.repository_href, repository_sync_url_data)]
202
199
  end
203
200
 
201
+ def sync_url_params(_sync_options)
202
+ params = {remote: repo.remote_href, mirror: repo.root.mirror_on_sync}
203
+ params[:skip_types] = skip_types if skip_types
204
+ params
205
+ end
206
+
204
207
  def create_publication
205
208
  publication_data = api.class.publication_class.new(repository_version: repo.version_href)
206
209
  api.publications_api.create(publication_data)
@@ -352,6 +355,11 @@ module Katello
352
355
  api.repositories_api.modify(repository_reference.repository_href, add_content_units: content_unit_href)
353
356
  end
354
357
 
358
+ def add_content_for_repo(repository_href, content_unit_href)
359
+ content_unit_href = [content_unit_href] unless content_unit_href.is_a?(Array)
360
+ api.repositories_api.modify(repository_href, add_content_units: content_unit_href)
361
+ end
362
+
355
363
  def unit_keys(uploads)
356
364
  uploads.map do |upload|
357
365
  upload.except('id')
@@ -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
  if root.url.blank?
12
15
  common_remote_options.merge(url: nil, policy: root.download_policy)
@@ -59,6 +62,12 @@ module Katello
59
62
  end
60
63
  end
61
64
 
65
+ def sync_url_params(sync_options)
66
+ params = super
67
+ params[:optimize] = sync_options[:optimize] if sync_options.key?(:optimize)
68
+ params
69
+ end
70
+
62
71
  def self.distribution_bootable?(distribution)
63
72
  file_paths = distribution.results.first.images.map(&:path)
64
73
  file_paths.any? do |path|
@@ -70,48 +79,141 @@ module Katello
70
79
  "/pulp/repos/#{repo.relative_path}/".sub('//', '/')
71
80
  end
72
81
 
73
- def copy_units(source_repository, content_unit_hrefs, dependency_solving, dest_base_version = 0,
74
- additional_repo_map = {})
82
+ def multi_copy_units(repo_id_map, dependency_solving)
75
83
  tasks = []
76
84
 
77
- content_unit_hrefs.sort!
78
- if content_unit_hrefs.any?
85
+ if repo_id_map.values.pluck(:content_unit_hrefs).flatten.any?
86
+ data = PulpRpmClient::Copy.new
87
+ data.dependency_solving = dependency_solving
88
+ data.config = []
89
+ repo_id_map.each do |source_repo_ids, dest_repo_id_map|
90
+ dest_repo = ::Katello::Repository.find(dest_repo_id_map[:dest_repo])
91
+ dest_repo_href = ::Katello::Pulp3::Repository::Yum.new(dest_repo, SmartProxy.pulp_master).repository_reference.repository_href
92
+ content_unit_hrefs = dest_repo_id_map[:content_unit_hrefs]
93
+ # Not needed during incremental update due to dest_base_version
94
+ unless dest_repo_id_map[:base_version]
95
+ source_repo_for_package_envs = ::Katello::Repository.find(source_repo_ids.first)
96
+ unless source_repo_for_package_envs.library_instance?
97
+ source_repo_for_package_envs = source_repo_for_package_envs.library_instance
98
+ end
99
+ package_env_hrefs = packageenvironments({ :repository_version => source_repo_for_package_envs.version_href }).map(&:pulp_href).sort
100
+ tasks << remove_all_content_from_repo(dest_repo_href)
101
+ tasks << add_content_for_repo(dest_repo_href, package_env_hrefs) unless package_env_hrefs.empty?
102
+ end
103
+ source_repo_ids.each do |source_repo_id|
104
+ source_repo_version = ::Katello::Repository.find(source_repo_id).version_href
105
+ config = { source_repo_version: source_repo_version, dest_repo: dest_repo_href, content: content_unit_hrefs }
106
+ config[:dest_base_version] = dest_repo_id_map[:base_version] if dest_repo_id_map[:base_version]
107
+ data.config << config
108
+ end
109
+ end
110
+ tasks << copy_content_chunked(data)
111
+ else
112
+ tasks << remove_all_content_from_mapping(repo_id_map)
113
+ end
114
+ tasks.flatten
115
+ end
116
+
117
+ def copy_api_data_dup(data)
118
+ data_dup = PulpRpmClient::Copy.new
119
+ data_dup.dependency_solving = data.dependency_solving
120
+ data_dup.config = []
121
+ data.config.each do |repo_config|
122
+ config_hash = {
123
+ source_repo_version: repo_config[:source_repo_version],
124
+ dest_repo: repo_config[:dest_repo],
125
+ content: []
126
+ }
127
+ config_hash[:dest_base_version] = repo_config[:dest_base_version] if repo_config[:dest_base_version]
128
+ data_dup.config << config_hash
129
+ end
130
+ data_dup
131
+ end
132
+
133
+ def copy_content_chunked(data)
134
+ tasks = []
135
+ # Don't chunk if there aren't enough content units
136
+ if data.config.sum { |repo_config| repo_config[:content].size } <= UNIT_LIMIT
137
+ return api.copy_api.copy_content(data)
138
+ end
139
+
140
+ unit_copy_counter = 0
141
+ i = 0
142
+ leftover_units = data.config.first[:content].deep_dup
143
+
144
+ # Copy data and clear its content fields
145
+ data_dup = copy_api_data_dup(data)
146
+
147
+ while i < data_dup.config.size
148
+ # Copy all units within repo or only some?
149
+ if leftover_units.length < UNIT_LIMIT - unit_copy_counter
150
+ copy_amount = leftover_units.length
151
+ else
152
+ copy_amount = UNIT_LIMIT - unit_copy_counter
153
+ end
154
+
155
+ data_dup.config[i][:content] = leftover_units.pop(copy_amount)
156
+ unit_copy_counter += copy_amount
157
+ # Do copy call if limit is reached or if we're under the limit but on the last repo config.
158
+ if unit_copy_counter >= UNIT_LIMIT || (i == data_dup.config.size - 1 && leftover_units.empty?)
159
+ tasks << api.copy_api.copy_content(data_dup)
160
+ unit_copy_counter = 0
161
+ end
162
+
163
+ if leftover_units.empty?
164
+ # Nothing more to copy -- clear current config's content
165
+ data_dup.config[i][:content] = []
166
+ i += 1
167
+ # Fetch unit list for next data config
168
+ leftover_units = data.config[i][:content].deep_dup unless i == data_dup.config.size
169
+ end
170
+ end
171
+
172
+ tasks
173
+ end
174
+
175
+ def remove_all_content_from_mapping(repo_id_map)
176
+ tasks = []
177
+ repo_id_map.each do |_source_repo_ids, dest_repo_id_map|
178
+ dest_repo = ::Katello::Repository.find(dest_repo_id_map[:dest_repo])
179
+ dest_repo_href = ::Katello::Pulp3::Repository::Yum.new(dest_repo, SmartProxy.pulp_master).repository_reference.repository_href
180
+ tasks << remove_all_content_from_repo(dest_repo_href)
181
+ end
182
+ tasks
183
+ end
184
+
185
+ def copy_units(source_repository, content_unit_hrefs, dependency_solving)
186
+ tasks = []
187
+
188
+ if content_unit_hrefs.sort!.any?
79
189
  data = PulpRpmClient::Copy.new
80
190
  data.config = [{
81
191
  source_repo_version: source_repository.version_href,
82
192
  dest_repo: repository_reference.repository_href,
83
- dest_base_version: dest_base_version,
193
+ dest_base_version: 0,
84
194
  content: content_unit_hrefs
85
195
  }]
86
196
  data.dependency_solving = dependency_solving
87
- if dependency_solving
88
- # repo_map example: {
89
- # <source_repo_id>: {
90
- # dest_repo: <dest_repo_id>,
91
- # base_version: <base_version>
92
- # }
93
- # }
94
- additional_repo_map.each do |source_repo, dest_repo_map|
95
- source_repo_version = ::Katello::Repository.find(source_repo).version_href
96
-
97
- dest_repo = ::Katello::Repository.find(dest_repo_map[:dest_repo])
98
- dest_repo_href = ::Katello::Pulp3::Repository::Yum.new(dest_repo, SmartProxy.pulp_master).repository_reference.repository_href
99
- data.config << {
100
- source_repo_version: source_repo_version,
101
- dest_repo: dest_repo_href,
102
- dest_base_version: dest_repo_map[:base_version],
103
- content: content_unit_hrefs
104
- }
105
- end
106
- end
197
+ package_env_hrefs = packageenvironments({ :repository_version => source_repository.version_href }).map(&:pulp_href).sort
107
198
  tasks << api.copy_api.copy_content(data)
199
+ tasks << add_content(package_env_hrefs) unless package_env_hrefs.empty?
108
200
  else
109
201
  tasks << remove_all_content
110
202
  end
111
-
112
203
  tasks
113
204
  end
114
205
 
206
+ def remove_all_content_from_repo(repo_href)
207
+ data = PulpRpmClient::RepositoryAddRemoveContent.new(
208
+ remove_content_units: ['*'])
209
+ api.repositories_api.modify(repo_href, data)
210
+ end
211
+
212
+ def repair(repository_version_href)
213
+ data = PulpRpmClient::RepositoryVersion.new
214
+ api.repository_versions_api.repair(repository_version_href, data)
215
+ end
216
+
115
217
  def remove_all_content
116
218
  data = PulpRpmClient::RepositoryAddRemoveContent.new(
117
219
  remove_content_units: ['*'])
@@ -119,7 +221,7 @@ module Katello
119
221
  end
120
222
 
121
223
  def packageenvironments(options = {})
122
- api.content_package_environments_api.list(options)
224
+ Katello::Pulp3::Api::Core.fetch_from_list { |page_opts| api.content_package_environments_api.list(page_opts.merge(options)) }
123
225
  end
124
226
 
125
227
  def metadatafiles(options = {})
@@ -130,6 +232,94 @@ module Katello
130
232
  api.content_distribution_trees_api.list(options)
131
233
  end
132
234
 
235
+ def add_filter_content(source_repo_ids, filters, filter_list_map)
236
+ filters.each do |filter|
237
+ if filter.inclusion
238
+ source_repo_ids.each do |repo_id|
239
+ filter_list_map[:whitelist_ids] += filter.content_unit_pulp_ids(::Katello::Repository.find(repo_id))
240
+ end
241
+ else
242
+ source_repo_ids.each do |repo_id|
243
+ filter_list_map[:blacklist_ids] += filter.content_unit_pulp_ids(::Katello::Repository.find(repo_id))
244
+ end
245
+ end
246
+ end
247
+ filter_list_map
248
+ end
249
+
250
+ def add_un_modular_rpms(source_repo_ids, filters, filter_list_map)
251
+ if (filter_list_map[:whitelist_ids].empty? && filters.select { |filter| filter.inclusion }.empty?)
252
+ filter_list_map[:whitelist_ids] += source_repo_ids.collect do |source_repo_id|
253
+ source_repo = ::Katello::Repository.find(source_repo_id)
254
+ source_repo.rpms.where(:modular => false).pluck(:pulp_id).sort
255
+ end
256
+ end
257
+ filter_list_map
258
+ end
259
+
260
+ def add_modular_content(source_repo_ids, filters, modular_filters, filter_list_map)
261
+ inclusion_modular_filters = modular_filters.select { |filter| filter.inclusion }
262
+ exclusion_modular_filters = modular_filters - inclusion_modular_filters
263
+ if inclusion_modular_filters.empty? &&
264
+ !(filters.any? { |filter| filter.class == ContentViewErratumFilter && filter.inclusion })
265
+ source_repo_ids.each do |source_repo_id|
266
+ source_repo = ::Katello::Repository.find(source_repo_id)
267
+ filter_list_map[:whitelist_ids] += source_repo.rpms.where(:modular => true).pluck(:pulp_id).sort
268
+ filter_list_map[:whitelist_ids] += source_repo.module_streams.pluck(:pulp_id).sort
269
+ end
270
+ end
271
+
272
+ unless inclusion_modular_filters.empty?
273
+ filter_list_map[:whitelist_ids] += source_repo_ids.collect do |source_repo_id|
274
+ source_repo = ::Katello::Repository.find(source_repo_id)
275
+ modular_packages(source_repo, inclusion_modular_filters)
276
+ end
277
+ end
278
+
279
+ unless exclusion_modular_filters.empty?
280
+ filter_list_map[:blacklist_ids] += source_repo_ids.collect do |source_repo_id|
281
+ source_repo = ::Katello::Repository.find(source_repo_id)
282
+ modular_packages(source_repo, exclusion_modular_filters)
283
+ end
284
+ end
285
+
286
+ filter_list_map
287
+ end
288
+
289
+ def copy_content_from_mapping(repo_id_map, options = {})
290
+ repo_id_map.each do |source_repo_ids, dest_repo_map|
291
+ filters = [ContentViewErratumFilter, ContentViewPackageGroupFilter, ContentViewPackageFilter].collect do |filter_class|
292
+ filter_class.where(:id => dest_repo_map[:filter_ids])
293
+ end
294
+ modular_filters = ContentViewModuleStreamFilter.where(:id => dest_repo_map[:filter_ids])
295
+ filters.flatten!.compact!
296
+
297
+ filter_list_map = { whitelist_ids: [], blacklist_ids: [] }
298
+ filter_list_map = add_filter_content(source_repo_ids, filters, filter_list_map)
299
+ filter_list_map = add_un_modular_rpms(source_repo_ids, filters, filter_list_map)
300
+ filter_list_map = add_modular_content(source_repo_ids, filters, modular_filters, filter_list_map)
301
+
302
+ whitelist_ids = filter_list_map[:whitelist_ids].flatten&.uniq
303
+ blacklist_ids = filter_list_map[:blacklist_ids].flatten&.uniq
304
+ content_unit_hrefs = whitelist_ids - blacklist_ids
305
+
306
+ if content_unit_hrefs.any?
307
+ source_repo_ids.each do |source_repo_id|
308
+ content_unit_hrefs += additional_content_hrefs(::Katello::Repository.find(source_repo_id), content_unit_hrefs)
309
+ end
310
+ end
311
+ source_repo_ids.each do |source_repo_id|
312
+ content_unit_hrefs += ::Katello::Repository.find(source_repo_id).srpms.pluck(:pulp_id)
313
+ end
314
+
315
+ dest_repo_map[:content_unit_hrefs] = content_unit_hrefs.uniq.sort
316
+ end
317
+
318
+ dependency_solving = options[:solve_dependencies] || false
319
+
320
+ multi_copy_units(repo_id_map, dependency_solving)
321
+ end
322
+
133
323
  def copy_content_for_source(source_repository, options = {})
134
324
  filters = [ContentViewErratumFilter, ContentViewPackageGroupFilter, ContentViewPackageFilter].collect do |filter_class|
135
325
  filter_class.where(:id => options[:filter_ids])
@@ -147,12 +337,18 @@ module Katello
147
337
  end
148
338
  end
149
339
 
150
- if whitelist_ids.empty? && filters.select { |filter| filter.inclusion }.empty?
151
- whitelist_ids = source_repository.rpms.where(:modular => false).pluck(:pulp_id).sort
152
- end
340
+ whitelist_ids = source_repository.rpms.where(:modular => false).pluck(:pulp_id).sort if (whitelist_ids.empty? && filters.select { |filter| filter.inclusion }.empty?)
153
341
 
342
+ modular_filters = ContentViewModuleStreamFilter.where(:id => options[:filter_ids])
343
+ inclusion_modular_filters = modular_filters.select { |filter| filter.inclusion }
344
+ exclusion_modular_filters = modular_filters - inclusion_modular_filters
345
+ if inclusion_modular_filters.empty? && !(filters.any? { |filter| filter.class == ContentViewErratumFilter && filter.inclusion })
346
+ whitelist_ids += source_repository.rpms.where(:modular => true).pluck(:pulp_id).sort
347
+ whitelist_ids += source_repository.module_streams.pluck(:pulp_id).sort
348
+ end
349
+ whitelist_ids += modular_packages(source_repository, inclusion_modular_filters) unless inclusion_modular_filters.empty?
350
+ blacklist_ids += modular_packages(source_repository, exclusion_modular_filters) unless exclusion_modular_filters.empty?
154
351
  content_unit_hrefs = whitelist_ids - blacklist_ids
155
-
156
352
  if content_unit_hrefs.any?
157
353
  content_unit_hrefs += additional_content_hrefs(source_repository, content_unit_hrefs)
158
354
  end
@@ -162,6 +358,14 @@ module Katello
162
358
  copy_units(source_repository, content_unit_hrefs.uniq, dependency_solving)
163
359
  end
164
360
 
361
+ def modular_packages(source_repository, filters)
362
+ list_ids = []
363
+ filters.each do |filter|
364
+ list_ids += filter.content_unit_pulp_ids(source_repository, true)
365
+ end
366
+ list_ids
367
+ end
368
+
165
369
  def additional_content_hrefs(source_repository, content_unit_hrefs)
166
370
  repo_service = source_repository.backend_service(SmartProxy.pulp_master)
167
371
  options = { :repository_version => source_repository.version_href }
@@ -172,10 +376,6 @@ module Katello
172
376
  package_groups_to_include = filter_package_groups_by_pulp_href(source_repository.package_groups, content_unit_hrefs)
173
377
  content_unit_hrefs += package_groups_to_include.pluck(:pulp_id)
174
378
 
175
- package_environment_hrefs_to_include = filter_package_environments_by_pulp_hrefs(
176
- repo_service.packageenvironments(options).results, package_groups_to_include.pluck(:pulp_id))
177
- content_unit_hrefs += package_environment_hrefs_to_include
178
-
179
379
  metadata_file_hrefs_to_include = filter_metadatafiles_by_pulp_hrefs(
180
380
  repo_service.metadatafiles(options).results, content_unit_hrefs)
181
381
  content_unit_hrefs += metadata_file_hrefs_to_include