katello 3.18.0.rc1 → 3.18.0.rc2

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +17 -8
  3. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +5 -2
  4. data/app/controllers/katello/api/v2/content_views_controller.rb +10 -1
  5. data/app/controllers/katello/api/v2/host_debs_controller.rb +1 -0
  6. data/app/controllers/katello/api/v2/host_errata_controller.rb +2 -2
  7. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +18 -6
  8. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +1 -1
  9. data/app/controllers/katello/api/v2/products_controller.rb +9 -9
  10. data/app/controllers/katello/api/v2/repository_sets_controller.rb +24 -14
  11. data/app/controllers/katello/concerns/api/v2/authorization.rb +10 -0
  12. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +22 -18
  13. data/app/controllers/katello/concerns/registration_controller_extensions.rb +16 -0
  14. data/app/lib/actions/helpers/smart_proxy_sync_history_helper.rb +24 -0
  15. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +16 -7
  16. data/app/lib/actions/katello/content_view/publish.rb +5 -4
  17. data/app/lib/actions/katello/content_view_version/import.rb +3 -10
  18. data/app/lib/actions/katello/host/upload_package_profile.rb +3 -1
  19. data/app/lib/actions/katello/host/upload_profiles.rb +8 -6
  20. data/app/lib/actions/katello/repository/import_upload.rb +2 -0
  21. data/app/lib/actions/katello/repository/remove_content.rb +1 -1
  22. data/app/lib/actions/katello/repository/sync.rb +3 -1
  23. data/app/lib/actions/katello/repository/update.rb +1 -0
  24. data/app/lib/actions/katello/repository/upload_files.rb +1 -0
  25. data/app/lib/actions/middleware/record_smart_proxy_sync_history.rb +15 -0
  26. data/app/lib/actions/pulp/consumer/sync_capsule.rb +4 -2
  27. data/app/lib/actions/pulp/repository/distributor_publish.rb +1 -1
  28. data/app/lib/actions/pulp3/abstract_async_task.rb +1 -0
  29. data/app/lib/actions/pulp3/capsule_content/sync.rb +1 -0
  30. data/app/lib/actions/pulp3/content_view_version/export.rb +5 -1
  31. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +23 -6
  32. data/app/lib/actions/pulp3/orchestration/repository/generate_metadata.rb +4 -1
  33. data/app/models/katello/authorization/content_view_filter.rb +15 -0
  34. data/app/models/katello/concerns/smart_proxy_extensions.rb +2 -0
  35. data/app/models/katello/content_view.rb +25 -4
  36. data/app/models/katello/content_view_filter.rb +5 -0
  37. data/app/models/katello/content_view_puppet_module.rb +8 -0
  38. data/app/models/katello/content_view_repository.rb +13 -1
  39. data/app/models/katello/ping.rb +8 -3
  40. data/app/models/katello/repository.rb +26 -0
  41. data/app/models/katello/smart_proxy_sync_history.rb +8 -0
  42. data/app/services/katello/pulp3/content_view_version/export.rb +64 -6
  43. data/app/services/katello/pulp3/content_view_version/import.rb +2 -27
  44. data/app/services/katello/pulp3/content_view_version/import_export_common.rb +6 -0
  45. data/app/services/katello/pulp3/content_view_version/import_validator.rb +107 -0
  46. data/app/services/katello/pulp3/migration.rb +7 -1
  47. data/app/services/katello/pulp3/repository/yum.rb +1 -2
  48. data/app/services/katello/pulp3/task.rb +3 -3
  49. data/app/services/katello/pulp3/task_group.rb +6 -0
  50. data/app/services/katello/repository_type.rb +2 -1
  51. data/app/services/katello/smart_proxy_helper.rb +9 -0
  52. data/app/views/foreman/hosts/_registration.html.erb +12 -0
  53. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  54. data/db/migrate/20200929200357_create_katello_smart_proxy_sync_history.rb +13 -0
  55. data/db/migrate/20201021150008_add_import_only_to_katello_content_view.rb +5 -0
  56. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/content-views.controller.js +6 -2
  57. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-details.controller.js +12 -0
  58. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-details.html +7 -7
  59. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-info.html +7 -1
  60. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/content-view-new.controller.js +17 -3
  61. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/new/views/content-view-new.html +16 -2
  62. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/views/content-views.html +5 -0
  63. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository-types.service.js +8 -1
  64. data/lib/katello/engine.rb +1 -0
  65. data/lib/katello/permission_creator.rb +11 -11
  66. data/lib/katello/plugin.rb +6 -1
  67. data/lib/katello/tasks/pulp3_migration_abort.rake +17 -0
  68. data/lib/katello/version.rb +1 -1
  69. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +13 -11
  70. data/webpack/test-utils/react-testing-lib-wrapper.js +3 -0
  71. metadata +12 -3
  72. data/webpack/__mocks__/foremanReact/components/common/Fill/GlobalFill.js +0 -3
@@ -1,5 +1,6 @@
1
1
  module Katello
2
2
  class ContentViewFilter < Katello::Model
3
+ include Authorization::ContentViewFilter
3
4
  audited :associations => [:repositories]
4
5
  DOCKER = 'docker'.freeze
5
6
  RPM = Rpm::CONTENT_TYPE
@@ -157,6 +158,10 @@ module Katello
157
158
  if self.content_view.composite?
158
159
  errors.add(:base, _("cannot contain filters if composite view"))
159
160
  end
161
+
162
+ if self.content_view.import_only?
163
+ errors.add(:base, _("cannot add filter to import-only view"))
164
+ end
160
165
  end
161
166
 
162
167
  def validate_filter_repos(errors, content_view)
@@ -17,6 +17,8 @@ module Katello
17
17
 
18
18
  before_validation :set_attributes
19
19
 
20
+ validate :import_only_content_view
21
+
20
22
  def puppet_module
21
23
  PuppetModule.find_by(:pulp_id => self.uuid)
22
24
  end
@@ -42,6 +44,12 @@ module Katello
42
44
 
43
45
  private
44
46
 
47
+ def import_only_content_view
48
+ if self.content_view.import_only?
49
+ errors.add(:base, "Cannot add puppet modules to an import-only content view.")
50
+ end
51
+ end
52
+
45
53
  def set_attributes
46
54
  if self.uuid.present?
47
55
  puppet_module = PuppetModule.with_identifiers(self.uuid).first
@@ -7,6 +7,10 @@ module Katello
7
7
  Repository::DEB_TYPE
8
8
  ].freeze
9
9
 
10
+ ALLOWED_IMPORT_REPOSITORY_TYPES = [
11
+ Repository::YUM_TYPE
12
+ ].freeze
13
+
10
14
  belongs_to :content_view, :inverse_of => :content_view_repositories,
11
15
  :class_name => "Katello::ContentView"
12
16
  belongs_to :repository, :inverse_of => :content_view_repositories,
@@ -27,7 +31,7 @@ module Katello
27
31
  end
28
32
 
29
33
  def ensure_repository_type
30
- unless ALLOWED_REPOSITORY_TYPES.include?(repository.content_type)
34
+ unless allowed_repository_types.include?(repository.content_type)
31
35
  errors.add(:base, _("Cannot add %s repositories to a content view.") % repository.content_type)
32
36
  end
33
37
  end
@@ -41,5 +45,13 @@ module Katello
41
45
  errors.add(:base, _("Repositories from published Content Views are not allowed."))
42
46
  end
43
47
  end
48
+
49
+ def allowed_repository_types
50
+ if self.content_view.import_only?
51
+ ALLOWED_IMPORT_REPOSITORY_TYPES
52
+ else
53
+ ALLOWED_REPOSITORY_TYPES
54
+ end
55
+ end
44
56
  end
45
57
  end
@@ -5,10 +5,17 @@ module Katello
5
5
  PACKAGES = %w(katello candlepin pulp qpid foreman tfm hammer).freeze
6
6
 
7
7
  class << self
8
+ def pulpcore_enabled # for downstream 6.9, remove in 6.10
9
+ SETTINGS[:katello][:use_pulp_2_for_content_type].nil? || (!SETTINGS[:katello][:use_pulp_2_for_content_type][:yum] &&
10
+ !SETTINGS[:katello][:use_pulp_2_for_content_type][:docker] &&
11
+ !SETTINGS[:katello][:use_pulp_2_for_content_type][:file]) ||
12
+ system('systemctl is-enabled pulpcore-api.service')
13
+ end
14
+
8
15
  def services(capsule_id = nil)
9
16
  proxy = fetch_proxy(capsule_id)
10
17
  services = [:candlepin, :candlepin_auth, :foreman_tasks, :katello_events, :candlepin_events]
11
- services += [:pulp3] if proxy&.pulp3_enabled?
18
+ services += [:pulp3] if proxy&.pulp3_enabled? && pulpcore_enabled
12
19
  if proxy.nil? || proxy.has_feature?(SmartProxy::PULP_NODE_FEATURE) || proxy.has_feature?(SmartProxy::PULP_FEATURE)
13
20
  services += [:pulp, :pulp_auth]
14
21
  end
@@ -16,9 +23,7 @@ module Katello
16
23
  services
17
24
  end
18
25
 
19
- #
20
26
  # Calls "status" services in all backend engines.
21
- #
22
27
  def ping(services: nil, capsule_id: nil)
23
28
  services ||= self.services(capsule_id)
24
29
  result = {}
@@ -109,6 +109,8 @@ module Katello
109
109
  has_many :distribution_references, :class_name => 'Katello::Pulp3::DistributionReference', :foreign_key => :repository_id,
110
110
  :dependent => :destroy, :inverse_of => :repository
111
111
 
112
+ has_many :smart_proxy_sync_histories, :class_name => "::Katello::SmartProxySyncHistory", :inverse_of => :repository, :dependent => :delete_all
113
+
112
114
  validates_with Validators::ContainerImageNameValidator, :attributes => :container_repository_name, :allow_blank => false, :if => :docker?
113
115
  validates :container_repository_name, :if => :docker?, :uniqueness => {message: ->(object, _data) do
114
116
  _("for repository '%{name}' is not unique and cannot be created in '%{env}'. Its Container Repository Name (%{container_name}) conflicts with an existing repository. Consider changing the Lifecycle Environment's Registry Name Pattern to something more specific.") %
@@ -531,6 +533,30 @@ module Katello
531
533
  clone
532
534
  end
533
535
 
536
+ def self.synced_on_capsule(smart_proxy)
537
+ smart_proxy.smart_proxy_sync_histories.map { |sph| sph.repository unless sph.finished_at.nil? }
538
+ end
539
+
540
+ def clear_smart_proxy_sync_histories(smart_proxy = nil)
541
+ if smart_proxy
542
+ self.smart_proxy_sync_histories.where(:smart_proxy_id => smart_proxy.id).try(:delete_all)
543
+ else
544
+ self.smart_proxy_sync_histories.delete_all
545
+ end
546
+ end
547
+
548
+ def create_smart_proxy_sync_history(smart_proxy)
549
+ clear_smart_proxy_sync_histories(smart_proxy)
550
+ sp_history_args = {
551
+ :smart_proxy_id => smart_proxy.id,
552
+ :repository_id => self.id,
553
+ :started_at => Time.now
554
+ }
555
+ sp_history = ::Katello::SmartProxySyncHistory.create sp_history_args
556
+ sp_history.save!
557
+ sp_history.id
558
+ end
559
+
534
560
  def latest_sync_audit
535
561
  self.audits.where(:action => AUDIT_SYNC_ACTION).order(:created_at).last
536
562
  end
@@ -0,0 +1,8 @@
1
+ module Katello
2
+ class SmartProxySyncHistory < Katello::Model
3
+ self.table_name = 'katello_smart_proxy_sync_history'
4
+
5
+ belongs_to :smart_proxy, :class_name => "::SmartProxy", :inverse_of => :smart_proxy_sync_histories
6
+ belongs_to :repository, :class_name => "Katello::Repository", :inverse_of => :smart_proxy_sync_histories
7
+ end
8
+ end
@@ -4,10 +4,11 @@ module Katello
4
4
  class Export
5
5
  include ImportExportCommon
6
6
 
7
- def initialize(smart_proxy:, content_view_version: nil, destination_server: nil)
7
+ def initialize(smart_proxy:, content_view_version: nil, destination_server: nil, from_content_view_version: nil)
8
8
  @smart_proxy = smart_proxy
9
9
  @content_view_version = content_view_version
10
10
  @destination_server = destination_server
11
+ @from_content_view_version = from_content_view_version
11
12
  end
12
13
 
13
14
  def generate_exporter_path
@@ -25,9 +26,32 @@ module Katello
25
26
  repositories: repository_hrefs)
26
27
  end
27
28
 
28
- def create_export(exporter_href, chunk_size = nil)
29
+ def create_export(exporter_href, chunk_size: nil)
29
30
  options = { versions: version_hrefs }
30
31
  options[:chunk_size] = "#{chunk_size}MB" if chunk_size
32
+ if @from_content_view_version
33
+ from_exporter = Export.new(smart_proxy: @smart_proxy, content_view_version: @from_content_view_version)
34
+ start_versions = from_exporter.version_hrefs
35
+
36
+ # current_cvv - cvv_from , i.e. repos in current cvv that are not in from
37
+ # implying something got added to the current cvv
38
+ # make sure you set the start_versions as 0
39
+ added_repo_hrefs = repository_hrefs - from_exporter.repository_hrefs
40
+ added_repo_hrefs.each do |added_repo_href|
41
+ start_versions << zero_version_href(added_repo_href)
42
+ end
43
+
44
+ # cvv_from - current_cvv , i.e. repos in from cvv that are not in current
45
+ # implying something got removed the current cvv
46
+ # make sure the start_versions doesn't contain those
47
+ deleted_repo_hrefs = from_exporter.repository_hrefs - repository_hrefs
48
+ start_versions.select! do |href|
49
+ !deleted_repo_hrefs.include?(version_href_to_repository_href(href))
50
+ end
51
+
52
+ options[:start_versions] = start_versions
53
+ options[:full] = 'false'
54
+ end
31
55
  [api.export_api.create(exporter_href, options)]
32
56
  end
33
57
 
@@ -42,15 +66,49 @@ module Katello
42
66
  api.exporter_api.delete(exporter_href)
43
67
  end
44
68
 
69
+ def validate_incremental_export!
70
+ return if @from_content_view_version.blank?
71
+ from_exporter = Export.new(smart_proxy: @smart_proxy, content_view_version: @from_content_view_version)
72
+
73
+ from_exporter_repos = generate_repo_mapping(from_exporter.repositories)
74
+ to_exporter_repos = generate_repo_mapping(repositories)
75
+
76
+ invalid_repos_exist = (from_exporter_repos.keys & to_exporter_repos.keys).any? do |repo_id|
77
+ from_exporter_repos[repo_id] != to_exporter_repos[repo_id]
78
+ end
79
+
80
+ if invalid_repos_exist
81
+ fail _("The exported Content View Version '%{content_view} %{current}' cannot be incrementally updated from version '%{from}'."\
82
+ " Please do a full export." % { content_view: @content_view_version.content_view.name,
83
+ current: @content_view_version.version,
84
+ from: @from_content_view_version.version})
85
+ end
86
+ end
87
+
88
+ def generate_repo_mapping(repositories)
89
+ # return a repo mapping with key being the library_instance_id and value being the repostiory_href
90
+ # used by validate_incremental_export
91
+ repo_map = {}
92
+ repositories.each do |repo|
93
+ repo_map[repo.library_instance_id] = version_href_to_repository_href(repo.version_href)
94
+ end
95
+ repo_map
96
+ end
97
+
45
98
  def generate_metadata
46
99
  ret = { organization: @content_view_version.organization.name,
47
100
  repository_mapping: {},
48
101
  content_view: @content_view_version.content_view.name,
49
- content_view_version: {
50
- major: @content_view_version.major,
51
- minor: @content_view_version.minor
52
- }
102
+ content_view_version: @content_view_version.slice(:major, :minor)
53
103
  }
104
+
105
+ unless @from_content_view_version.blank?
106
+ ret[:from_content_view_version] = {
107
+ major: @from_content_view_version.major,
108
+ minor: @from_content_view_version.minor
109
+ }
110
+ end
111
+
54
112
  repositories.each do |repo|
55
113
  next if repo.version_href.blank?
56
114
  pulp3_repo = fetch_repository_info(repo.version_href).name
@@ -3,7 +3,6 @@ module Katello
3
3
  module ContentViewVersion
4
4
  class Import
5
5
  include ImportExportCommon
6
- BASEDIR = '/var/lib/pulp'.freeze
7
6
 
8
7
  def initialize(smart_proxy:, content_view_version: nil, path: nil, metadata: nil)
9
8
  @smart_proxy = smart_proxy
@@ -44,32 +43,8 @@ module Katello
44
43
  api.importer_api.delete(importer_href)
45
44
  end
46
45
 
47
- class << self
48
- def check_permissions!(path)
49
- fail _("Invalid path specified.") if path.blank? || !File.directory?(path)
50
- fail _("The import path must be in a subdirectory under '%s'." % BASEDIR) unless path.starts_with?(BASEDIR)
51
- fail _("Pulp user or group unable to read content in '%s'." % path) unless pulp_user_accessible?(path)
52
-
53
- Dir.glob("#{path}/*").each do |file|
54
- fail _("Pulp user or group unable to read '%s'." % file) unless pulp_user_accessible?(file)
55
- end
56
- end
57
-
58
- def pulp_user_accessible?(path)
59
- pulp_info = fetch_pulp_user_info
60
- return false if pulp_info.blank?
61
-
62
- stat = File.stat(path)
63
- stat.gid.to_s == pulp_info.gid ||
64
- stat.uid.to_s == pulp_info.uid ||
65
- stat.mode.to_s(8)[-1].to_i >= 4
66
- end
67
-
68
- def fetch_pulp_user_info
69
- pulp_user = nil
70
- Etc.passwd { |u| pulp_user = u if u.name == 'pulp' }
71
- pulp_user
72
- end
46
+ def self.check!(content_view:, metadata:, path:)
47
+ ImportValidator.new(content_view: content_view, metadata: metadata, path: path).check!
73
48
  end
74
49
  end
75
50
  end
@@ -38,6 +38,12 @@ module Katello
38
38
  def version_href_to_repository_href(version_href)
39
39
  version_href.split("/")[0..-3].join("/") + "/"
40
40
  end
41
+
42
+ def zero_version_href(repository_href)
43
+ # /pulp/api/v3/repositories/rpm/rpm/e59c4334-81d2-4d6b-a1a1-b61fa55ed664/versions/0/
44
+ repository_href += "/" unless repository_href.ends_with?('/')
45
+ "#{repository_href}versions/0/"
46
+ end
41
47
  end
42
48
  end
43
49
  end
@@ -0,0 +1,107 @@
1
+ module Katello
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class ImportValidator
5
+ BASEDIR = '/var/lib/pulp'.freeze
6
+ attr_accessor :metadata, :path, :content_view
7
+ def initialize(content_view:, path:, metadata:)
8
+ self.content_view = content_view
9
+ self.path = path
10
+ self.metadata = metadata
11
+ end
12
+
13
+ def check!
14
+ check_permissions!
15
+ ensure_importing_cvv_does_not_exist!
16
+ ensure_from_cvv_exists!
17
+ ensure_repositories_metadata_and_content_view_match!
18
+ end
19
+
20
+ def ensure_importing_cvv_does_not_exist!
21
+ major = metadata[:content_view_version][:major]
22
+ minor = metadata[:content_view_version][:minor]
23
+
24
+ if ::Katello::ContentViewVersion.where(major: major, minor: minor, content_view: content_view).exists?
25
+ fail _("Content View Version specified in the metadata - '%{name}' already exists. "\
26
+ "If you wish to replace the existing version, delete %{name} and try again. " % { name: "#{content_view.name} #{major}.#{minor}" })
27
+ end
28
+ end
29
+
30
+ def ensure_from_cvv_exists!
31
+ major = metadata[:content_view_version][:major]
32
+ minor = metadata[:content_view_version][:minor]
33
+
34
+ if metadata[:from_content_view_version].present?
35
+ from_major = metadata[:from_content_view_version][:major]
36
+ from_minor = metadata[:from_content_view_version][:minor]
37
+
38
+ unless ::Katello::ContentViewVersion.where(major: from_major, minor: from_minor, content_view: content_view).exists?
39
+ fail _("Prior Content View Version specified in the metadata - '%{name}' does not exist. "\
40
+ "Please import the metadata for '%{name}' before importing '%{current}' " % { name: "#{content_view.name} #{from_major}.#{from_minor}",
41
+ current: "#{content_view.name} #{major}.#{minor}"})
42
+ end
43
+ end
44
+ end
45
+
46
+ def ensure_repositories_metadata_and_content_view_match!
47
+ product_repos_in_content_view = content_view.repositories.yum_type.map { |repo| [repo.product.name, repo.name, repo.redhat?] }
48
+ product_repos_in_metadata = metadata[:repository_mapping].values.map { |repo| [repo[:product], repo[:repository], repo[:redhat]] }
49
+
50
+ product_repos_in_content_view.sort!
51
+ product_repos_in_metadata.sort!
52
+ # product_repos_in_content_view & product_repos_in_metadata look like [["prod1", "repo1", false], ["prod2", "repo2", false]]
53
+
54
+ if product_repos_in_content_view != product_repos_in_metadata
55
+ repos_in_content_view = generate_product_repo_i18n_string(product_repos_in_content_view)
56
+ repos_in_import = generate_product_repo_i18n_string(product_repos_in_metadata)
57
+
58
+ fail _("Repositories in the importing content view do not match the repositories provided in the import metadata.\n "\
59
+ "Repositories in Content View '%{content_view}': %{repos_in_content_view}\n "\
60
+ "Repositories in the Import Metadata: %{repos_in_import}" % { content_view: content_view.name,
61
+ repos_in_content_view: repos_in_content_view.join(""),
62
+ repos_in_import: repos_in_import.join("")}
63
+ )
64
+ end
65
+ end
66
+
67
+ def check_permissions!
68
+ fail _("Invalid path specified.") if path.blank? || !File.directory?(path)
69
+ fail _("The import path must be in a subdirectory under '%s'." % BASEDIR) unless path.starts_with?(BASEDIR)
70
+ fail _("Pulp user or group unable to read content in '%s'." % path) unless pulp_user_accessible?(path)
71
+
72
+ Dir.glob("#{path}/*").each do |file|
73
+ fail _("Pulp user or group unable to read '%s'." % file) unless pulp_user_accessible?(file)
74
+ end
75
+ toc_path = "#{path}/#{metadata[:toc]}"
76
+ fail _("The TOC file specified in the metadata does not exist. %s " % toc_path) unless File.exist?(toc_path)
77
+ end
78
+
79
+ def pulp_user_accessible?(path)
80
+ pulp_info = fetch_pulp_user_info
81
+ return false if pulp_info.blank?
82
+
83
+ stat = File.stat(path)
84
+ stat.gid.to_s == pulp_info.gid ||
85
+ stat.uid.to_s == pulp_info.uid ||
86
+ stat.mode.to_s(8)[-1].to_i >= 4
87
+ end
88
+
89
+ def fetch_pulp_user_info
90
+ pulp_user = nil
91
+ Etc.passwd { |u| pulp_user = u if u.name == 'pulp' }
92
+ pulp_user
93
+ end
94
+
95
+ def generate_product_repo_i18n_string(product_repos)
96
+ # product_repos look like [["prod1", "repo1", false], ["prod2", "repo2", false]]
97
+ product_repos.map do |product, repo, redhat|
98
+ repo_type = redhat ? _("Red Hat") : _("Custom")
99
+ _("\n* Product = '%{product}', Repository = '%{repository}', Repository Type = '%{repo_type}'" % { product: product,
100
+ repository: repo,
101
+ repo_type: repo_type})
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -165,10 +165,16 @@ module Katello
165
165
  process_distributions(pulp3_api, migrated_repo.pulp3_distribution_hrefs)
166
166
  end
167
167
 
168
+ def distribution_path_from_cache(href, pulp3_api)
169
+ @distribution_cache ||= {}
170
+ @distribution_cache[href] ||= pulp3_api.distributions_api.read(href).base_path
171
+ @distribution_cache[href]
172
+ end
173
+
168
174
  def process_distributions(pulp3_api, dist_hrefs_list)
169
175
  #distribution_path_hash(pulp3_api, dist_hrefs_list).each do |relative_path, href|
170
176
  dist_hrefs_list.each do |href|
171
- relative_path = pulp3_api.distributions_api.read(href).base_path
177
+ relative_path = distribution_path_from_cache(href, pulp3_api)
172
178
 
173
179
  dist_ref = Katello::Pulp3::DistributionReference.find_or_initialize_by(:path => relative_path)
174
180
  if (distribution_repo = Katello::Repository.find_by(:relative_path => relative_path) || Katello::Repository.find_by(:container_repository_name => relative_path))
@@ -159,8 +159,7 @@ module Katello
159
159
 
160
160
  data_dup.config[i][:content] = leftover_units.pop(copy_amount)
161
161
  unit_copy_counter += copy_amount
162
- # Do copy call if limit is reached or if we're under the limit but on the last repo config.
163
- if unit_copy_counter >= UNIT_LIMIT || (i == data_dup.config.size - 1 && leftover_units.empty?)
162
+ if unit_copy_counter != 0
164
163
  tasks << api.copy_api.copy_content(data_dup)
165
164
  unit_copy_counter = 0
166
165
  end
@@ -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