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.
- checksums.yaml +4 -4
- data/app/controllers/katello/api/v2/content_exports_controller.rb +33 -3
- data/app/lib/actions/katello/content_view/promote_to_environment.rb +4 -2
- data/app/lib/actions/katello/content_view/publish.rb +5 -2
- data/app/lib/actions/katello/organization/environment_contents_refresh.rb +20 -0
- data/app/lib/actions/katello/organization/manifest_refresh.rb +2 -0
- data/app/lib/actions/pulp3/content_view_version/create_export_history.rb +3 -1
- data/app/lib/actions/pulp3/content_view_version/create_exporter.rb +9 -2
- data/app/lib/actions/pulp3/content_view_version/create_syncable_export_history.rb +45 -0
- data/app/lib/actions/pulp3/content_view_version/destroy_exporter.rb +6 -1
- data/app/lib/actions/pulp3/content_view_version/export.rb +8 -3
- data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +28 -13
- data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +4 -2
- data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +4 -2
- data/app/lib/actions/pulp3/orchestration/content_view_version/syncable_export.rb +82 -0
- data/app/lib/katello/concerns/base_template_scope_extensions.rb +24 -11
- data/app/models/katello/authorization/repository.rb +4 -2
- data/app/models/katello/content_view.rb +37 -29
- data/app/services/katello/content_unit_indexer.rb +1 -2
- data/app/services/katello/organization_creator.rb +14 -3
- data/app/services/katello/pulp3/api/core.rb +8 -0
- data/app/services/katello/pulp3/content_view_version/export.rb +38 -11
- data/app/services/katello/pulp3/content_view_version/import.rb +12 -5
- data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +20 -5
- data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +3 -1
- data/app/services/katello/pulp3/content_view_version/syncable_format_export.rb +34 -0
- data/app/services/katello/pulp3/deb.rb +3 -1
- data/app/services/katello/pulp3/erratum.rb +4 -1
- data/app/services/katello/pulp3/pulp_content_unit.rb +2 -0
- data/app/views/foreman/job_templates/install_errata_by_search_query.erb +4 -3
- data/db/migrate/20211220185935_clean_duplicate_content_units.rb +11 -9
- data/db/seeds.d/102-organizations.rb +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/activation-keys.routes.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-details.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages.controller.js +11 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +0 -3
- data/lib/katello/tasks/refresh_alternate_content_sources.rake +9 -4
- data/lib/katello/version.rb +1 -1
- data/locale/fr/katello.po +2 -2
- data/package.json +3 -0
- data/webpack/components/Table/TableHooks.js +2 -1
- data/webpack/components/Table/__test__/useBulkSelect.test.js +99 -0
- data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +13 -1
- data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +0 -6
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +6 -9
- data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +1 -1
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +30 -3
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +44 -19
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +2 -2
- metadata +19 -59
- data/lib/katello/tasks/reset.rake.bak +0 -67
- data/locale/bn/LC_MESSAGES/katello.mo +0 -0
- data/locale/bn/katello.po.time_stamp +0 -0
- data/locale/cs/LC_MESSAGES/katello.mo +0 -0
- data/locale/cs/katello.po.time_stamp +0 -0
- data/locale/de/LC_MESSAGES/katello.mo +0 -0
- data/locale/de/katello.po.time_stamp +0 -0
- data/locale/en/LC_MESSAGES/katello.mo +0 -0
- data/locale/en/katello.po.time_stamp +0 -0
- data/locale/es/LC_MESSAGES/katello.mo +0 -0
- data/locale/es/katello.po.time_stamp +0 -0
- data/locale/fr/LC_MESSAGES/katello.mo +0 -0
- data/locale/fr/katello.po.time_stamp +0 -0
- data/locale/gu/LC_MESSAGES/katello.mo +0 -0
- data/locale/gu/katello.po.time_stamp +0 -0
- data/locale/hi/LC_MESSAGES/katello.mo +0 -0
- data/locale/hi/katello.po.time_stamp +0 -0
- data/locale/it/LC_MESSAGES/katello.mo +0 -0
- data/locale/it/katello.po.time_stamp +0 -0
- data/locale/ja/LC_MESSAGES/katello.mo +0 -0
- data/locale/ja/katello.po.time_stamp +0 -0
- data/locale/kn/LC_MESSAGES/katello.mo +0 -0
- data/locale/kn/katello.po.time_stamp +0 -0
- data/locale/ko/LC_MESSAGES/katello.mo +0 -0
- data/locale/ko/katello.po.time_stamp +0 -0
- data/locale/mr/LC_MESSAGES/katello.mo +0 -0
- data/locale/mr/katello.po.time_stamp +0 -0
- data/locale/or/LC_MESSAGES/katello.mo +0 -0
- data/locale/or/katello.po.time_stamp +0 -0
- data/locale/pa/LC_MESSAGES/katello.mo +0 -0
- data/locale/pa/katello.po.time_stamp +0 -0
- data/locale/pt/LC_MESSAGES/katello.mo +0 -0
- data/locale/pt/katello.po.time_stamp +0 -0
- data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
- data/locale/pt_BR/katello.po.time_stamp +0 -0
- data/locale/ru/LC_MESSAGES/katello.mo +0 -0
- data/locale/ru/katello.po.time_stamp +0 -0
- data/locale/ta/LC_MESSAGES/katello.mo +0 -0
- data/locale/ta/katello.po.time_stamp +0 -0
- data/locale/te/LC_MESSAGES/katello.mo +0 -0
- data/locale/te/katello.po.time_stamp +0 -0
- data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
- data/locale/zh_CN/katello.po.time_stamp +0 -0
- data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
- 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
|
-
|
|
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
|
-
|
|
44
|
-
has_many :hosts,
|
|
45
|
-
|
|
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
|
-
|
|
47
|
+
:inverse_of => :content_view, :dependent => :nullify
|
|
48
48
|
has_many :hostgroups, :class_name => "::Hostgroup", :through => :hostgroup_content_facets,
|
|
49
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
450
|
-
|
|
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
|
-
|
|
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
|
-
|
|
649
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
).
|
|
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
|
-
|
|
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
|
-
|
|
41
|
-
"#{content_view_version.
|
|
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
|
|
49
|
-
api.exporter_api
|
|
50
|
-
|
|
51
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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}
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
53
|
-
::Katello::Content.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
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: '
|
|
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('
|
|
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>
|