katello 4.5.0.rc2 → 4.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/content_exports_controller.rb +33 -3
  3. data/app/lib/actions/katello/content_view/promote_to_environment.rb +4 -2
  4. data/app/lib/actions/katello/content_view/publish.rb +5 -2
  5. data/app/lib/actions/katello/organization/environment_contents_refresh.rb +20 -0
  6. data/app/lib/actions/katello/organization/manifest_refresh.rb +2 -0
  7. data/app/lib/actions/pulp3/content_view_version/create_export_history.rb +3 -1
  8. data/app/lib/actions/pulp3/content_view_version/create_exporter.rb +9 -2
  9. data/app/lib/actions/pulp3/content_view_version/create_syncable_export_history.rb +45 -0
  10. data/app/lib/actions/pulp3/content_view_version/destroy_exporter.rb +6 -1
  11. data/app/lib/actions/pulp3/content_view_version/export.rb +8 -3
  12. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +28 -13
  13. data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +4 -2
  14. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +4 -2
  15. data/app/lib/actions/pulp3/orchestration/content_view_version/syncable_export.rb +82 -0
  16. data/app/lib/katello/concerns/base_template_scope_extensions.rb +24 -11
  17. data/app/models/katello/authorization/repository.rb +4 -2
  18. data/app/models/katello/content_view.rb +37 -29
  19. data/app/services/katello/content_unit_indexer.rb +1 -2
  20. data/app/services/katello/organization_creator.rb +14 -3
  21. data/app/services/katello/pulp3/api/core.rb +8 -0
  22. data/app/services/katello/pulp3/content_view_version/export.rb +38 -11
  23. data/app/services/katello/pulp3/content_view_version/import.rb +12 -5
  24. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +20 -5
  25. data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +3 -1
  26. data/app/services/katello/pulp3/content_view_version/syncable_format_export.rb +34 -0
  27. data/app/services/katello/pulp3/deb.rb +3 -1
  28. data/app/services/katello/pulp3/erratum.rb +4 -1
  29. data/app/services/katello/pulp3/pulp_content_unit.rb +2 -0
  30. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +4 -3
  31. data/db/migrate/20211220185935_clean_duplicate_content_units.rb +11 -9
  32. data/db/seeds.d/102-organizations.rb +1 -1
  33. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/activation-keys.routes.js +1 -1
  34. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-details.html +1 -1
  35. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages.controller.js +11 -3
  36. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -1
  37. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
  38. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +0 -3
  39. data/lib/katello/tasks/refresh_alternate_content_sources.rake +9 -4
  40. data/lib/katello/version.rb +1 -1
  41. data/locale/fr/katello.po +2 -2
  42. data/package.json +3 -0
  43. data/webpack/components/Table/TableHooks.js +2 -1
  44. data/webpack/components/Table/__test__/useBulkSelect.test.js +99 -0
  45. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +13 -1
  46. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +0 -6
  47. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +6 -9
  48. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +1 -1
  49. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +30 -3
  50. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +44 -19
  51. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +2 -2
  52. metadata +19 -59
  53. data/lib/katello/tasks/reset.rake.bak +0 -67
  54. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  55. data/locale/bn/katello.po.time_stamp +0 -0
  56. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  57. data/locale/cs/katello.po.time_stamp +0 -0
  58. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  59. data/locale/de/katello.po.time_stamp +0 -0
  60. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  61. data/locale/en/katello.po.time_stamp +0 -0
  62. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  63. data/locale/es/katello.po.time_stamp +0 -0
  64. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  65. data/locale/fr/katello.po.time_stamp +0 -0
  66. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  67. data/locale/gu/katello.po.time_stamp +0 -0
  68. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  69. data/locale/hi/katello.po.time_stamp +0 -0
  70. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  71. data/locale/it/katello.po.time_stamp +0 -0
  72. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  73. data/locale/ja/katello.po.time_stamp +0 -0
  74. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  75. data/locale/kn/katello.po.time_stamp +0 -0
  76. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  77. data/locale/ko/katello.po.time_stamp +0 -0
  78. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  79. data/locale/mr/katello.po.time_stamp +0 -0
  80. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  81. data/locale/or/katello.po.time_stamp +0 -0
  82. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  83. data/locale/pa/katello.po.time_stamp +0 -0
  84. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  85. data/locale/pt/katello.po.time_stamp +0 -0
  86. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  87. data/locale/pt_BR/katello.po.time_stamp +0 -0
  88. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  89. data/locale/ru/katello.po.time_stamp +0 -0
  90. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  91. data/locale/ta/katello.po.time_stamp +0 -0
  92. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  93. data/locale/te/katello.po.time_stamp +0 -0
  94. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  95. data/locale/zh_CN/katello.po.time_stamp +0 -0
  96. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  97. data/locale/zh_TW/katello.po.time_stamp +0 -0
@@ -33,49 +33,50 @@ module Katello
33
33
  has_many :content_view_repositories, :class_name => 'Katello::ContentViewRepository',
34
34
  :dependent => :destroy, :inverse_of => :content_view
35
35
  has_many :repositories, :through => :content_view_repositories, :class_name => "Katello::Repository",
36
- :after_remove => :remove_repository
36
+ :after_remove => :remove_repository
37
37
 
38
38
  has_many :filters, :dependent => :destroy, :class_name => "Katello::ContentViewFilter"
39
39
 
40
40
  has_many :activation_keys, :class_name => "Katello::ActivationKey", :dependent => :restrict_with_exception
41
41
 
42
42
  has_many :content_facets, :class_name => "Katello::Host::ContentFacet",
43
- :inverse_of => :content_view, :dependent => :restrict_with_exception
44
- has_many :hosts, :class_name => "::Host::Managed", :through => :content_facets,
45
- :inverse_of => :content_view
43
+ :inverse_of => :content_view, :dependent => :restrict_with_exception
44
+ has_many :hosts, :class_name => "::Host::Managed", :through => :content_facets,
45
+ :inverse_of => :content_view
46
46
  has_many :hostgroup_content_facets, :class_name => "Katello::Hostgroup::ContentFacet",
47
- :inverse_of => :content_view, :dependent => :nullify
47
+ :inverse_of => :content_view, :dependent => :nullify
48
48
  has_many :hostgroups, :class_name => "::Hostgroup", :through => :hostgroup_content_facets,
49
- :inverse_of => :content_view
49
+ :inverse_of => :content_view
50
50
 
51
51
  has_many :repository_references, :class_name => 'Katello::Pulp3::RepositoryReference',
52
52
  :dependent => :destroy, :inverse_of => :content_view
53
53
 
54
54
  validates_lengths_from_database :except => [:label]
55
- validates :label, :uniqueness => {:scope => :organization_id},
56
- :presence => true
57
- validates :name, :presence => true, :uniqueness => {:scope => :organization_id}
55
+ validates :label, :uniqueness => { :scope => :organization_id },
56
+ :presence => true
57
+ validates :name, :presence => true, :uniqueness => { :scope => :organization_id }
58
58
  validates :organization_id, :presence => true
59
59
  validate :check_non_composite_components
60
60
  validate :check_docker_conflicts
61
61
  validate :check_non_composite_auto_publish
62
+ validate :check_default_label_name, if: :default?
62
63
  validates :composite, :inclusion => [true, false]
63
64
  validates :composite,
64
- inclusion: { in: [false], message: "Composite Content Views can not solve dependencies"},
65
+ inclusion: { in: [false], message: "Composite Content Views can not solve dependencies" },
65
66
  if: :solve_dependencies
66
67
  validates :import_only, :inclusion => [true, false]
67
68
  validates :import_only,
68
- inclusion: { in: [false], message: "Import-only Content Views can not be Composite"},
69
+ inclusion: { in: [false], message: "Import-only Content Views can not be Composite" },
69
70
  if: :composite
70
71
  validates :import_only,
71
- inclusion: { in: [false], message: "Import-only Content Views can not solve dependencies"},
72
+ inclusion: { in: [false], message: "Import-only Content Views can not solve dependencies" },
72
73
  if: :solve_dependencies
73
74
  validate :import_only_immutable
74
75
  validates :generated_for,
75
- exclusion: { in: [:none], message: "Generated Content Views can not be Composite"},
76
+ exclusion: { in: [:none], message: "Generated Content Views can not be Composite" },
76
77
  if: :composite
77
78
  validates :generated_for,
78
- exclusion: { in: [:none], message: "Generated Content Views can not solve dependencies"},
79
+ exclusion: { in: [:none], message: "Generated Content Views can not solve dependencies" },
79
80
  if: :solve_dependencies
80
81
 
81
82
  validates_with Validators::KatelloNameFormatValidator, :attributes => :name
@@ -279,6 +280,7 @@ module Katello
279
280
  required :env, 'Katello::KTEnvironment', desc: 'a __Katello::KTEnvironment__ object for which we load the __Katello::ContentViewVersion__ object'
280
281
  returns 'Katello::ContentViewVersion'
281
282
  end
283
+
282
284
  def version(env)
283
285
  self.versions.in_environment(env).order("#{Katello::ContentViewVersion.table_name}.id ASC").readonly(false).last
284
286
  end
@@ -306,7 +308,7 @@ module Katello
306
308
 
307
309
  def history
308
310
  Katello::ContentViewHistory.joins(:content_view_version).where(
309
- "#{Katello::ContentViewVersion.table_name}.content_view_id" => self.id)
311
+ "#{Katello::ContentViewVersion.table_name}.content_view_id" => self.id)
310
312
  end
311
313
 
312
314
  def version_environment(env)
@@ -387,7 +389,7 @@ module Katello
387
389
  end
388
390
 
389
391
  def auto_publish_components
390
- component_composites.where(latest: true).joins(:composite_content_view).where(self.class.table_name => {auto_publish: true})
392
+ component_composites.where(latest: true).joins(:composite_content_view).where(self.class.table_name => { auto_publish: true })
391
393
  end
392
394
 
393
395
  def publish_repositories(override_components = nil)
@@ -446,8 +448,8 @@ module Katello
446
448
  def get_repo_clone(env, repo)
447
449
  lib_id = repo.library_instance_id || repo.id
448
450
  Repository.in_environment(env).where(:library_instance_id => lib_id).
449
- joins(:content_view_version).
450
- where("#{Katello::ContentViewVersion.table_name}.content_view_id" => self.id)
451
+ joins(:content_view_version).
452
+ where("#{Katello::ContentViewVersion.table_name}.content_view_id" => self.id)
451
453
  end
452
454
 
453
455
  def delete(from_env)
@@ -497,9 +499,15 @@ module Katello
497
499
  end
498
500
  end
499
501
 
502
+ def check_default_label_name
503
+ if default? && !(name == 'Default Organization View' && label == 'Default_Organization_View')
504
+ errors.add(:base, _("Name and label of default content view should not be changed"))
505
+ end
506
+ end
507
+
500
508
  def check_docker_conflicts
501
509
  duplicate_docker_repos.each do |repo|
502
- msg = _("Container Image repo '%{repo}' is present in multiple component content views.") % {repo: repo.name}
510
+ msg = _("Container Image repo '%{repo}' is present in multiple component content views.") % { repo: repo.name }
503
511
  errors.add(:base, msg)
504
512
  end
505
513
  end
@@ -526,7 +534,7 @@ module Katello
526
534
  :environment_id => env.id,
527
535
  :content_view => self,
528
536
  :content_view_version => version
529
- )
537
+ )
530
538
  end
531
539
  end
532
540
 
@@ -555,7 +563,7 @@ module Katello
555
563
  :minor => minor,
556
564
  :content_view => self,
557
565
  :components => components
558
- )
566
+ )
559
567
 
560
568
  update(:next_version => major.to_i + 1) unless major.to_i < next_version
561
569
  version
@@ -626,14 +634,14 @@ module Katello
626
634
  def check_remove_from_environment!(env)
627
635
  errors = []
628
636
 
629
- dependencies = {hosts: _("hosts"),
630
- activation_keys: _("activation keys")
637
+ dependencies = { hosts: _("hosts"),
638
+ activation_keys: _("activation keys")
631
639
  }
632
640
 
633
641
  dependencies.each do |key, name|
634
642
  if (models = self.association(key).scope.in_environment(env)).any?
635
643
  errors << _("Cannot remove '%{view}' from environment '%{env}' due to associated %{dependent}: %{names}.") %
636
- {view: self.name, env: env.name, dependent: name, names: models.map(&:name).join(", ")}
644
+ { view: self.name, env: env.name, dependent: name, names: models.map(&:name).join(", ") }
637
645
  end
638
646
  end
639
647
 
@@ -644,15 +652,15 @@ module Katello
644
652
  def check_ready_to_destroy!
645
653
  errors = []
646
654
 
647
- dependencies = {environments: _("environments"),
648
- hosts: _("hosts"),
649
- activation_keys: _("activation keys")
655
+ dependencies = { environments: _("environments"),
656
+ hosts: _("hosts"),
657
+ activation_keys: _("activation keys")
650
658
  }
651
659
 
652
660
  dependencies.each do |key, name|
653
661
  if (models = self.association(key).scope).any?
654
662
  errors << _("Cannot delete '%{view}' due to associated %{dependent}: %{names}.") %
655
- {view: self.name, dependent: name, names: models.map(&:name).join(", ")}
663
+ { view: self.name, dependent: name, names: models.map(&:name).join(", ") }
656
664
  end
657
665
  end
658
666
 
@@ -700,7 +708,7 @@ module Katello
700
708
  def remove_repository(repository)
701
709
  filters.each do |filter_item|
702
710
  repo_exists = Repository.unscoped.joins(:filters).where(
703
- ContentViewFilter.table_name => {:id => filter_item.id}, :id => repository.id).count
711
+ ContentViewFilter.table_name => { :id => filter_item.id }, :id => repository.id).count
704
712
  if repo_exists
705
713
  filter_item.repositories.delete(repository)
706
714
  filter_item.save!
@@ -22,7 +22,6 @@ module Katello
22
22
  end
23
23
 
24
24
  def import_all(filtered_indexing = false)
25
- additive = filtered_indexing || (@repository&.mirroring_policy == 'additive')
26
25
  association_tracker = RepoAssociationTracker.new(@content_type, @service_class, @repository)
27
26
  units_from_pulp.each do |units|
28
27
  units.each do |unit|
@@ -52,7 +51,7 @@ module Katello
52
51
  end
53
52
 
54
53
  if @model_class.many_repository_associations && @repository
55
- sync_repository_associations(association_tracker, additive: additive)
54
+ sync_repository_associations(association_tracker, additive: filtered_indexing)
56
55
  end
57
56
  end
58
57
 
@@ -101,12 +101,23 @@ module Katello
101
101
  end
102
102
 
103
103
  def create_library_view
104
- @library_view = Katello::ContentView.where(
104
+ cv_wrong_label = Katello::ContentView.where(
105
105
  default: true,
106
106
  name: DEFAULT_CONTENT_VIEW_NAME,
107
- label: DEFAULT_CONTENT_VIEW_LABEL,
108
107
  organization: @organization
109
- ).first_or_create!
108
+ ).where.not(label: DEFAULT_CONTENT_VIEW_LABEL)&.first
109
+
110
+ if cv_wrong_label
111
+ cv_wrong_label.update_attribute(:label, DEFAULT_CONTENT_VIEW_LABEL)
112
+ @library_view = cv_wrong_label
113
+ else
114
+ @library_view = Katello::ContentView.where(
115
+ default: true,
116
+ name: DEFAULT_CONTENT_VIEW_NAME,
117
+ label: DEFAULT_CONTENT_VIEW_LABEL,
118
+ organization: @organization
119
+ ).first_or_create!
120
+ end
110
121
  end
111
122
 
112
123
  def create_library_cvv
@@ -89,6 +89,10 @@ module Katello
89
89
  PulpcoreClient::RepositoriesReclaimSpaceApi.new(core_api_client)
90
90
  end
91
91
 
92
+ def yum_exporter_api
93
+ PulpcoreClient::ExportersFilesystemApi.new(core_api_client)
94
+ end
95
+
92
96
  def exporter_api
93
97
  PulpcoreClient::ExportersPulpApi.new(core_api_client)
94
98
  end
@@ -101,6 +105,10 @@ module Katello
101
105
  PulpcoreClient::ImportersPulpImportCheckApi.new(core_api_client)
102
106
  end
103
107
 
108
+ def yum_export_api
109
+ PulpcoreClient::ExportersFilesystemExportsApi.new(core_api_client)
110
+ end
111
+
104
112
  def export_api
105
113
  PulpcoreClient::ExportersPulpExportsApi.new(core_api_client)
106
114
  end
@@ -3,16 +3,31 @@ module Katello
3
3
  module ContentViewVersion
4
4
  class Export
5
5
  include ImportExportCommon
6
- attr_reader :smart_proxy, :content_view_version, :destination_server, :from_content_view_version
6
+ SYNCABLE = "syncable".freeze
7
+ IMPORTABLE = "importable".freeze
8
+ FORMATS = [SYNCABLE, IMPORTABLE].freeze
9
+
10
+ attr_reader :smart_proxy, :content_view_version, :destination_server, :from_content_view_version, :repository, :base_path
11
+ def self.create(options)
12
+ if options.delete(:format) == SYNCABLE
13
+ SyncableFormatExport.new(options)
14
+ else
15
+ self.new(options)
16
+ end
17
+ end
7
18
 
8
19
  def initialize(smart_proxy:,
9
20
  content_view_version: nil,
10
21
  destination_server: nil,
11
- from_content_view_version: nil)
22
+ from_content_view_version: nil,
23
+ repository: nil,
24
+ base_path: nil)
12
25
  @smart_proxy = smart_proxy
13
26
  @content_view_version = content_view_version
14
27
  @destination_server = destination_server
15
28
  @from_content_view_version = from_content_view_version
29
+ @repository = repository
30
+ @base_path = base_path
16
31
  end
17
32
 
18
33
  def repository_hrefs
@@ -37,21 +52,27 @@ module Katello
37
52
  end
38
53
 
39
54
  def generate_exporter_path
40
- export_path = "#{content_view_version.content_view}/#{content_view_version.version}/#{destination_server}/#{date_dir}".gsub(/\s/, '_')
41
- "#{content_view_version.organization.label}/#{export_path}"
55
+ return base_path if base_path
56
+ export_path = "#{content_view_version.content_view}/#{content_view_version.version}/"
57
+ export_path += "#{destination_server}/" unless destination_server.blank?
58
+ export_path += "#{date_dir}".gsub(/\s/, '_')
59
+ @base_path = "#{Setting['pulpcore_export_destination']}/#{content_view_version.organization.label}/#{export_path}"
42
60
  end
43
61
 
44
62
  def date_dir
45
63
  DateTime.now.to_s.gsub(/\W/, '-')
46
64
  end
47
65
 
48
- def create_exporter(export_base_dir: Setting['pulpcore_export_destination'])
49
- api.exporter_api.create(name: generate_id(content_view_version),
50
- path: "#{export_base_dir}/#{generate_exporter_path}",
51
- repositories: repository_hrefs)
66
+ def create_exporter
67
+ exporter_api = api.exporter_api
68
+ options = { name: generate_id(content_view_version), path: generate_exporter_path }
69
+ options[:repositories] = repository_hrefs
70
+
71
+ exporter_api.create(options)
52
72
  end
53
73
 
54
- def create_export(exporter_href, chunk_size: nil)
74
+ def create_export(exporter_data, chunk_size: nil)
75
+ exporter_href = exporter_data[:pulp_href]
55
76
  options = { versions: version_hrefs }
56
77
  options[:chunk_size] = "#{chunk_size}GB" if chunk_size
57
78
  if from_content_view_version
@@ -77,14 +98,16 @@ module Katello
77
98
  options[:start_versions] = start_versions
78
99
  options[:full] = 'false'
79
100
  end
80
- [api.export_api.create(exporter_href, options)]
101
+ export_api = api.export_api
102
+ [export_api.create(exporter_href, options)]
81
103
  end
82
104
 
83
105
  def fetch_export(exporter_href)
84
106
  api.export_api.list(exporter_href).results.first
85
107
  end
86
108
 
87
- def destroy_exporter(exporter_href)
109
+ def destroy_exporter(exporter_data)
110
+ exporter_href = exporter_data[:pulp_href]
88
111
  export_data = fetch_export(exporter_href)
89
112
  api.exporter_api.partial_update(exporter_href, :last_export => nil)
90
113
  api.export_api.delete(export_data.pulp_href) unless export_data.blank?
@@ -162,6 +185,10 @@ module Katello
162
185
  generated_for: generated_for).send(select_method)
163
186
  end
164
187
 
188
+ def format
189
+ is_a?(SyncableFormatExport) ? SYNCABLE : IMPORTABLE
190
+ end
191
+
165
192
  def self.find_library_export_view(create_by_default: false,
166
193
  destination_server:,
167
194
  organization:)
@@ -42,11 +42,14 @@ module Katello
42
42
  # In other words if metadata had repos {label:foo, product: bar}
43
43
  # this would match it to the repo with the label foo and product bar
44
44
  # in the library.
45
-
46
45
  queries = metadata_map.repositories.map do |repo|
47
- if repo.redhat && repo.product.cp_id
46
+ if repo.redhat && repo.product.cp_id && repo.content&.id
48
47
  library_repositories.where("#{Katello::Product.table_name}.cp_id": repo.product.cp_id,
49
- "#{Katello::RootRepository.table_name}.label": repo.label)
48
+ "#{::Katello::RootRepository.table_name}" => {
49
+ content_id: repo.content.id,
50
+ arch: repo.arch,
51
+ major: repo.major,
52
+ minor: repo.minor })
50
53
  else
51
54
  library_repositories.where("#{Katello::Product.table_name}.label": repo.product.label,
52
55
  "#{Katello::RootRepository.table_name}.label": repo.label)
@@ -84,9 +87,13 @@ module Katello
84
87
  relation = content_view_version.importable_repositories.joins(:root, :product)
85
88
 
86
89
  metadata_map.repositories.each do |metadata_repo|
87
- if metadata_repo.redhat && metadata_repo.product.cp_id
90
+ if metadata_repo.redhat && metadata_repo.product.cp_id && metadata_repo.content&.id
88
91
  repo = relation.where("#{::Katello::Product.table_name}" => {cp_id: metadata_repo.product.cp_id},
89
- "#{::Katello::RootRepository.table_name}" => {label: metadata_repo.label}).first
92
+ "#{::Katello::RootRepository.table_name}" => {
93
+ content_id: metadata_repo.content.id,
94
+ arch: metadata_repo.arch,
95
+ major: metadata_repo.major,
96
+ minor: metadata_repo.minor}).first
90
97
  else
91
98
  repo = relation.where("#{::Katello::Product.table_name}" => {label: metadata_repo.product.label},
92
99
  "#{::Katello::RootRepository.table_name}" => {label: metadata_repo.label}).first
@@ -22,12 +22,21 @@ module Katello
22
22
  product = product_for_metadata_repo(repo)
23
23
  fail _("Unable to find product '%s' in organization '%s'" % [repo.product.label, @organization.name]) if product.blank?
24
24
 
25
- root = product.root_repositories.find { |r| r.label == repo.label }
25
+ root = product.root_repositories.find do |r|
26
+ if repo.content&.id && repo.redhat
27
+ r.content.cp_content_id == repo.content.id &&
28
+ r.arch == repo.arch &&
29
+ r.major == repo.major &&
30
+ r.minor == repo.minor
31
+ else
32
+ r.label == repo.label
33
+ end
34
+ end
35
+
26
36
  if root
27
37
  updatable << { repository: root, options: update_repo_params(repo) }
28
38
  elsif repo.redhat
29
- content = repo.content
30
- product_content = product_content_by_label(content.label)
39
+ product_content = fetch_product_content(repo.content, product)
31
40
  substitutions = {
32
41
  basearch: repo.arch,
33
42
  releasever: repo.minor
@@ -49,8 +58,14 @@ module Katello
49
58
  end
50
59
  end
51
60
 
52
- def product_content_by_label(content_label)
53
- ::Katello::Content.find_by_label(content_label)
61
+ def fetch_product_content(content_metadata, product)
62
+ query = ::Katello::Content.joins(:product_contents).where("#{Katello::ProductContent.table_name}.product_id": product.id)
63
+ table_name = Katello::Content.table_name
64
+ if content_metadata&.id
65
+ query.find_by("#{table_name}.cp_content_id": content_metadata.id)
66
+ else
67
+ query.find_by("#{table_name}.label": content_metadata.label)
68
+ end
54
69
  end
55
70
 
56
71
  def gpg_key_id(metadata_repo)
@@ -16,10 +16,12 @@ module Katello
16
16
 
17
17
  def generate!
18
18
  ret = { organization: organization.name,
19
+ base_path: Setting['pulpcore_export_destination'],
19
20
  repositories: {},
20
21
  content_view: content_view.slice(:name, :label, :description, :generated_for),
21
22
  content_view_version: content_view_version.slice(:major, :minor, :description),
22
- incremental: from_content_view_version.present?
23
+ incremental: from_content_view_version.present?,
24
+ format: export_service.format
23
25
  }
24
26
 
25
27
  unless from_content_view_version.blank?
@@ -0,0 +1,34 @@
1
+ module Katello
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class SyncableFormatExport < Export
5
+ def create_exporter
6
+ api.yum_exporter_api.create(name: "#{generate_id(content_view_version)}-#{repository.id}",
7
+ path: generate_repository_exporter_path,
8
+ method: :hardlink)
9
+ end
10
+
11
+ def create_export(exporter_data, _options = {})
12
+ [api.yum_export_api.create(exporter_data[:pulp_href], publication: repository.publication_href)]
13
+ end
14
+
15
+ def fetch_export(exporter_href)
16
+ api.yum_export_api.list(exporter_href).results.first
17
+ end
18
+
19
+ def destroy_exporter(exporter_data)
20
+ exporter_href = exporter_data[:pulp_href]
21
+ export_data = fetch_export(exporter_href)
22
+ api.yum_export_api.delete(export_data.pulp_href)
23
+ api.yum_exporter_api.delete(exporter_href)
24
+ end
25
+
26
+ def generate_repository_exporter_path
27
+ _org, _content, content_path = repository.library_instance_or_self.relative_path.split("/", 3)
28
+ content_path = content_path.sub(%r|^/|, '')
29
+ "#{generate_exporter_path}/#{content_path}".gsub(/\s/, '_')
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -9,6 +9,7 @@ module Katello
9
9
  end
10
10
 
11
11
  def self.content_api_create(opts = {})
12
+ opts.delete(:relative_path) if opts.key?(:relative_path)
12
13
  self.content_api.create(opts)
13
14
  end
14
15
 
@@ -24,7 +25,8 @@ module Katello
24
25
  end
25
26
 
26
27
  def self.generate_model_row(unit)
27
- {
28
+ unit = unit.try(:with_indifferent_access)
29
+ return {
28
30
  pulp_id: unit[unit_identifier],
29
31
  checksum: unit[:sha256],
30
32
  filename: unit[:relative_path],
@@ -55,12 +55,15 @@ module Katello
55
55
  bugzillas += build_bugzillas(katello_id, unit['references'])
56
56
  cves += build_cves(katello_id, unit['references'])
57
57
  packages += build_packages(katello_id, unit['pkglist'])
58
- modules += build_modules(katello_id, unit['pkglist'])
59
58
  end
60
59
 
61
60
  Katello::ErratumBugzilla.insert_all(bugzillas, unique_by: [:erratum_id, :bug_id, :href]) if bugzillas.any?
62
61
  Katello::ErratumCve.insert_all(cves, unique_by: [:erratum_id, :cve_id, :href]) if cves.any?
63
62
  Katello::ErratumPackage.insert_all(packages, unique_by: [:erratum_id, :nvrea, :name, :filename]) if packages.any?
63
+ units.each do |unit|
64
+ katello_id = pulp_id_to_id[unit['id']]
65
+ modules += build_modules(katello_id, unit['pkglist'])
66
+ end
64
67
  ModuleStreamErratumPackage.insert_all(modules, unique_by: [:module_stream_id, :erratum_package_id]) if modules.any?
65
68
  nil
66
69
  end
@@ -146,6 +146,8 @@ module Katello
146
146
  elsif repository.generic?
147
147
  duplicate_sha_path_content_list = content_backend_service.content_api(repository.repository_type, unit_type_id).list(
148
148
  filter_label => checksum)
149
+ elsif unit_type_id == 'deb'
150
+ duplicate_sha_path_content_list = content_backend_service.content_api.list(filter_label => checksum)
149
151
  else
150
152
  duplicate_sha_path_content_list = content_backend_service.content_api.list(
151
153
  filter_label => checksum,
@@ -15,11 +15,12 @@ foreign_input_sets:
15
15
  exclude: action,package
16
16
  %>
17
17
 
18
+ <% advisory_ids = @host.advisory_ids(search: input("Errata search query")) %>
19
+ # RESOLVED_ERRATA_IDS=<%= advisory_ids.join(',') %>
20
+
18
21
  <% if @host.operatingsystem.family == 'Suse' -%>
19
- <% advisories = @host.advisory_ids(search: input("Errata search query")).join(' ') %>
20
- <%= render_template('Package Action - Script Default', :action => 'install -n -t patch', :package => advisories) %>
22
+ <%= render_template('Package Action - Script Default', :action => 'install -n -t patch', :package => advisory_ids.join(' ')) %>
21
23
  <% else %>
22
- <% advisory_ids = @host.advisory_ids(search: input("Errata search query")) %>
23
24
  <% raise "No errata matching given search query" if !input("Errata search query").blank? && advisory_ids.empty? %>
24
25
 
25
26
  <% advisories = advisory_ids.map { |e| "--advisory=#{e}" }.join(' ') %>
@@ -20,7 +20,7 @@ class CleanDuplicateContentUnits < ActiveRecord::Migration[6.0]
20
20
  to_delete = []
21
21
  to_update = []
22
22
  duplicate_models.each do |duplicate|
23
- query = {new_id_field => new_id}
23
+ query = { new_id_field => new_id }
24
24
  unique_fields.each do |field|
25
25
  query[field] = duplicate.send(field)
26
26
  end
@@ -52,28 +52,25 @@ class CleanDuplicateContentUnits < ActiveRecord::Migration[6.0]
52
52
  def up
53
53
  handle_null_pulp_ids
54
54
  add_foreign_keys
55
+ delete_deprecated_models
55
56
 
56
57
  handle_duplicate(Katello::ModuleStream,
57
58
  'module_stream_id',
58
59
  [:pulp_id],
59
- associated_models: {Katello::RepositoryModuleStream => :repository_id},
60
+ associated_models: { Katello::RepositoryModuleStream => :repository_id },
60
61
  child_models: [Katello::ContentViewModuleStreamFilterRule,
61
62
  Katello::ContentFacetApplicableModuleStream,
62
63
  Katello::ModuleProfile,
63
64
  Katello::ModuleStreamArtifact,
64
65
  Katello::ModuleStreamErratumPackage,
65
66
  Katello::ModuleStreamRpm])
66
- add_index :katello_module_streams, :pulp_id, :unique => true
67
67
 
68
- handle_duplicate(Katello::ModuleProfile, 'module_profile_id', [:module_stream_id, :name],
69
- child_models: [Katello::ModuleProfileRpm])
68
+ add_index :katello_module_streams, :pulp_id, :unique => true
70
69
  add_index :katello_module_profiles, [:module_stream_id, :name], :unique => true
71
-
72
- handle_duplicate(Katello::ModuleProfileRpm, 'module_profile_rpm_id', [:module_profile_id, :name])
73
70
  add_index :katello_module_profile_rpms, [:module_profile_id, :name], :unique => true
74
71
 
75
72
  handle_duplicate(Katello::AnsibleTag, 'ansible_tag_id', [:name],
76
- associated_models: {Katello::AnsibleCollectionTag => :ansible_collection_id})
73
+ associated_models: { Katello::AnsibleCollectionTag => :ansible_collection_id })
77
74
  add_index :katello_ansible_tags, [:name], :unique => true
78
75
 
79
76
  handle_duplicate(Katello::AnsibleCollectionTag, 'ansible_collection_tag_id', [:ansible_collection_id, :ansible_tag_id])
@@ -83,7 +80,7 @@ class CleanDuplicateContentUnits < ActiveRecord::Migration[6.0]
83
80
  handle_duplicate(Katello::GenericContentUnit,
84
81
  'generic_content_unit_id',
85
82
  [:pulp_id],
86
- associated_models: {Katello::RepositoryGenericContentUnit => :repository_id})
83
+ associated_models: { Katello::RepositoryGenericContentUnit => :repository_id })
87
84
  add_index :katello_generic_content_units, :pulp_id, :unique => true
88
85
 
89
86
  handle_duplicate(Katello::DockerManifestList, 'docker_manifest_list_id', [:pulp_id],
@@ -112,6 +109,11 @@ class CleanDuplicateContentUnits < ActiveRecord::Migration[6.0]
112
109
  change_column :katello_docker_manifests, :pulp_id, :string, :null => false
113
110
  end
114
111
 
112
+ def delete_deprecated_models
113
+ Katello::ModuleProfileRpm.delete_all
114
+ Katello::ModuleProfile.delete_all
115
+ end
116
+
115
117
  def add_foreign_keys
116
118
  Katello::DockerManifestListManifest.where.not(docker_manifest_list_id: Katello::DockerManifestList.pluck(:id)).delete_all
117
119
  add_foreign_key :katello_docker_manifest_list_manifests, :katello_docker_manifest_lists, column: :docker_manifest_list_id
@@ -1,7 +1,7 @@
1
1
  # This file should contain all the record creation needed to seed the database with its default values.
2
2
  # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
3
3
  #
4
- # !!! PLEASE KEEP THIS SCRIPT IDEMPOTENT !!!
4
+ # !! PLEASE KEEP THIS SCRIPT IDEMPOTENT !!
5
5
  #
6
6
 
7
7
  unless Rails.env.test?
@@ -115,7 +115,7 @@ angular.module('Bastion.activation-keys').config(['$stateProvider', function ($s
115
115
  })
116
116
  .state('activation-key.copy', {
117
117
  url: '/copy',
118
- permission: 'create_activation_key',
118
+ permission: 'create_activation_keys',
119
119
  controller: 'ActivationKeyCopyController',
120
120
  templateUrl: 'activation-keys/details/views/activation-key-copy.html',
121
121
  ncyBreadcrumb: {
@@ -8,7 +8,7 @@
8
8
  <div data-block="item-actions" bst-feature-flag="custom_products">
9
9
  <span select-action-dropdown>
10
10
  <ul class="dropdown-menu dropdown-menu-right" uib-dropdown-menu role="menu">
11
- <li role="menuitem" ng-hide="denied('create_activation_key')">
11
+ <li role="menuitem" ng-hide="denied('create_activation_keys')">
12
12
  <a ui-sref="activation-key.copy" translate>
13
13
  Copy Activation Key
14
14
  </a>