katello 3.18.1 → 3.18.3.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/assets/stylesheets/katello/katello.scss +0 -72
- data/app/controllers/katello/api/registry/registry_proxies_controller.rb +4 -6
- data/app/controllers/katello/api/v2/api_controller.rb +1 -2
- data/app/controllers/katello/api/v2/content_view_filters_controller.rb +1 -1
- data/app/controllers/katello/concerns/api/v2/authorization.rb +14 -1
- data/app/lib/actions/katello/host/update_system_purpose.rb +1 -1
- data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +1 -1
- data/app/lib/actions/katello/repository/sync.rb +5 -1
- data/app/lib/actions/pulp3/content_migration_reset.rb +22 -0
- data/app/lib/katello/util/hostgroup_facets_helper.rb +126 -0
- data/app/lib/katello/util/pulpcore_content_filters.rb +1 -1
- data/app/models/katello/concerns/hostgroup_extensions.rb +4 -2
- data/app/models/katello/concerns/pulp_database_unit.rb +12 -0
- data/app/models/katello/concerns/redhat_extensions.rb +9 -8
- data/app/models/katello/concerns/smart_proxy_extensions.rb +3 -1
- data/app/models/katello/file_unit.rb +4 -0
- data/app/models/katello/host/content_facet.rb +9 -31
- data/app/models/katello/ping.rb +35 -15
- data/app/services/katello/applicability/applicable_content_helper.rb +40 -20
- data/app/services/katello/pulp3/api/core.rb +14 -0
- data/app/services/katello/pulp3/erratum.rb +2 -1
- data/app/services/katello/pulp3/migration.rb +63 -7
- data/app/services/katello/pulp3/migration_plan.rb +2 -2
- data/app/services/katello/pulp3/migration_switchover.rb +36 -5
- data/app/services/katello/pulp3/repository.rb +40 -10
- data/app/services/katello/pulp3/repository/apt.rb +1 -2
- data/app/services/katello/pulp3/repository/yum.rb +10 -1
- data/app/services/katello/pulp3/rpm.rb +5 -1
- data/app/services/katello/pulp3/task.rb +8 -5
- data/app/services/katello/pulp3/task_group.rb +13 -5
- data/app/views/katello/sync_management/_products.html.erb +1 -1
- data/db/migrate/20150930183738_migrate_content_hosts.rb +1 -1
- data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +5 -2
- data/db/migrate/20210201165835_add_migration_missing_content.rb +12 -0
- data/db/migrate/20210420140050_add_pulp3_hrefs_to_content_types_deb.rb +5 -0
- data/engines/bastion/app/assets/javascripts/bastion/auth/authorization.service.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-system-purpose-modal.html +35 -40
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register-client.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +1 -1
- data/lib/katello/engine.rb +1 -1
- data/lib/katello/tasks/check_config.rake +18 -0
- data/lib/katello/tasks/delete_orphaned_content.rake +1 -3
- data/lib/katello/tasks/fix_hostgroup_facets.rake +8 -0
- data/lib/katello/tasks/pulp3_content_switchover.rake +7 -3
- data/lib/katello/tasks/pulp3_migration.rake +12 -3
- data/lib/katello/tasks/pulp3_migration_abort.rake +1 -1
- data/lib/katello/tasks/pulp3_migration_approve_corrupted.rake +16 -0
- data/lib/katello/tasks/pulp3_migration_reset.rake +26 -0
- data/lib/katello/tasks/pulp3_migration_stats.rake +37 -3
- data/lib/katello/tasks/pulp3_post_migration_check.rake +1 -3
- data/lib/katello/tasks/reimport.rake +1 -1
- data/lib/katello/tasks/reports.rake +4 -1
- data/lib/katello/tasks/repository.rake +3 -5
- data/lib/katello/version.rb +1 -1
- data/webpack/components/TypeAhead/TypeAhead.js +2 -1
- data/webpack/components/TypeAhead/pf3Search/TypeAheadSearch.js +2 -1
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +7 -2
- data/webpack/scenes/Subscriptions/Manifest/index.js +1 -0
- metadata +28 -21
- data/lib/katello/tasks/common.rake +0 -7
|
@@ -31,43 +31,21 @@ module Katello
|
|
|
31
31
|
validates :host, :presence => true, :allow_blank => false
|
|
32
32
|
validates_with Validators::ContentViewEnvironmentValidator
|
|
33
33
|
|
|
34
|
-
def bindable_types
|
|
35
|
-
[
|
|
36
|
-
{
|
|
37
|
-
type: Repository::DEB_TYPE,
|
|
38
|
-
matcher: '/pulp/deb/',
|
|
39
|
-
paths: []
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
type: Repository::YUM_TYPE,
|
|
43
|
-
matcher: '/pulp/repos/',
|
|
44
|
-
paths: []
|
|
45
|
-
}
|
|
46
|
-
]
|
|
47
|
-
end
|
|
48
|
-
|
|
49
34
|
def update_repositories_by_paths(paths)
|
|
50
|
-
|
|
35
|
+
prefixes = %w(/pulp/deb/ /pulp/repos/ /pulp/content/)
|
|
51
36
|
relative_paths = []
|
|
52
37
|
|
|
53
|
-
# paths == ["/pulp/repos/Default_Organization/Library/custom/Test_product/test2"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if absolute_path.starts_with?(supported[:matcher])
|
|
60
|
-
supported[:paths] << relative_path
|
|
61
|
-
break
|
|
62
|
-
end
|
|
38
|
+
# paths == ["/pulp/repos/Default_Organization/Library/custom/Test_product/test2"]
|
|
39
|
+
paths.each do |path|
|
|
40
|
+
if (prefix = prefixes.find { |pre| path.start_with?(pre) })
|
|
41
|
+
relative_paths << path.gsub(prefix, '')
|
|
42
|
+
else
|
|
43
|
+
Rails.logger.warn("System #{self.host.name} (#{self.host.id}) requested binding to repo with unknown prefix. #{path}")
|
|
63
44
|
end
|
|
64
45
|
end
|
|
65
46
|
|
|
66
|
-
repos =
|
|
67
|
-
|
|
68
|
-
relative_paths -= repos.pluck(:relative_path) # remove relative paths that match our repos
|
|
69
|
-
repos
|
|
70
|
-
end
|
|
47
|
+
repos = Repository.where(relative_path: relative_paths)
|
|
48
|
+
relative_paths -= repos.pluck(:relative_path) # remove relative paths that match our repos
|
|
71
49
|
|
|
72
50
|
# Any leftover relative paths do not match the repos we've just retrieved from the db,
|
|
73
51
|
# so we should log warnings about them.
|
data/app/models/katello/ping.rb
CHANGED
|
@@ -23,25 +23,18 @@ module Katello
|
|
|
23
23
|
services
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# Calls "status" services in all backend engines.
|
|
27
26
|
def ping(services: nil, capsule_id: nil)
|
|
28
|
-
services
|
|
29
|
-
|
|
30
|
-
services.each { |service| result[service] = {} }
|
|
27
|
+
ping_services_for_capsule(services, capsule_id)
|
|
28
|
+
end
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
ping_candlepin_without_auth(result[:candlepin]) if result.include?(:candlepin)
|
|
30
|
+
def ping!(services: nil, capsule_id: nil)
|
|
31
|
+
result = ping_services_for_capsule(services, capsule_id)
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
ping_candlepin_events(result[:candlepin_events]) if result.include?(:candlepin_events)
|
|
33
|
+
if result[:status] != OK_RETURN_CODE
|
|
34
|
+
failed_names = failed_services(result).keys
|
|
35
|
+
fail("The following services have not been started or are reporting errors: #{failed_names.join(', ')}")
|
|
36
|
+
end
|
|
41
37
|
|
|
42
|
-
# set overall status result code
|
|
43
|
-
result = {:services => result}
|
|
44
|
-
result[:status] = result[:services].each_value.any? { |v| v[:status] == FAIL_RETURN_CODE } ? FAIL_RETURN_CODE : OK_RETURN_CODE
|
|
45
38
|
result
|
|
46
39
|
end
|
|
47
40
|
|
|
@@ -221,6 +214,33 @@ module Katello
|
|
|
221
214
|
|
|
222
215
|
private
|
|
223
216
|
|
|
217
|
+
def failed_services(result)
|
|
218
|
+
result[:services].reject do |_name, details|
|
|
219
|
+
details[:status] != OK_RETURN_CODE
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def ping_services_for_capsule(services, capsule_id)
|
|
224
|
+
services ||= self.services(capsule_id)
|
|
225
|
+
result = {}
|
|
226
|
+
services.each { |service| result[service] = {} }
|
|
227
|
+
|
|
228
|
+
ping_pulp3_without_auth(result[:pulp3], capsule_id) if result.include?(:pulp3)
|
|
229
|
+
ping_pulp_without_auth(result[:pulp], capsule_id) if result.include?(:pulp)
|
|
230
|
+
ping_candlepin_without_auth(result[:candlepin]) if result.include?(:candlepin)
|
|
231
|
+
|
|
232
|
+
ping_pulp_with_auth(result[:pulp_auth], result[:pulp][:status]) if result.include?(:pulp_auth)
|
|
233
|
+
ping_candlepin_with_auth(result[:candlepin_auth]) if result.include?(:candlepin_auth)
|
|
234
|
+
ping_foreman_tasks(result[:foreman_tasks]) if result.include?(:foreman_tasks)
|
|
235
|
+
ping_katello_events(result[:katello_events]) if result.include?(:katello_events)
|
|
236
|
+
ping_candlepin_events(result[:candlepin_events]) if result.include?(:candlepin_events)
|
|
237
|
+
|
|
238
|
+
# set overall status result code
|
|
239
|
+
result = {:services => result}
|
|
240
|
+
result[:status] = result[:services].each_value.any? { |v| v[:status] == FAIL_RETURN_CODE } ? FAIL_RETURN_CODE : OK_RETURN_CODE
|
|
241
|
+
result
|
|
242
|
+
end
|
|
243
|
+
|
|
224
244
|
def fetch_proxy(capsule_id)
|
|
225
245
|
capsule_id ? SmartProxy.unscoped.find(capsule_id) : SmartProxy.pulp_primary
|
|
226
246
|
end
|
|
@@ -60,17 +60,7 @@ module Katello
|
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def fetch_rpm_content_ids
|
|
63
|
-
|
|
64
|
-
# -> Include all non-modular rpms or rpms that exist within installed module streams
|
|
65
|
-
enabled_module_stream_ids = ::Katello::ModuleStream.
|
|
66
|
-
joins("inner join katello_available_module_streams on
|
|
67
|
-
katello_module_streams.name = katello_available_module_streams.name and
|
|
68
|
-
katello_module_streams.stream = katello_available_module_streams.stream").
|
|
69
|
-
joins("inner join katello_host_available_module_streams on
|
|
70
|
-
katello_available_module_streams.id = katello_host_available_module_streams.available_module_stream_id").
|
|
71
|
-
where("katello_host_available_module_streams.host_id = :content_facet_id and
|
|
72
|
-
katello_host_available_module_streams.status = 'enabled'",
|
|
73
|
-
:content_facet_id => self.content_facet.host.id).select(:id)
|
|
63
|
+
enabled_module_stream_ids = fetch_enabled_module_stream_ids
|
|
74
64
|
|
|
75
65
|
::Katello::Rpm.
|
|
76
66
|
joins("INNER JOIN katello_repository_rpms ON
|
|
@@ -88,9 +78,37 @@ module Katello
|
|
|
88
78
|
:bound_library_repos => self.bound_library_instance_repos).
|
|
89
79
|
where("katello_host_installed_packages.host_id = :content_facet_id",
|
|
90
80
|
:content_facet_id => self.content_facet.host.id).
|
|
91
|
-
where("katello_module_stream_rpms.module_stream_id
|
|
92
|
-
|
|
93
|
-
|
|
81
|
+
where("(katello_module_stream_rpms.module_stream_id IS NULL AND
|
|
82
|
+
katello_installed_packages.id NOT IN (:locked_modular_installed_packages)) OR
|
|
83
|
+
(katello_module_stream_rpms.module_stream_id IN (:enabled_module_streams)
|
|
84
|
+
AND katello_installed_packages.id IN (:locked_modular_installed_packages))",
|
|
85
|
+
:enabled_module_streams => enabled_module_stream_ids,
|
|
86
|
+
:locked_modular_installed_packages => locked_modular_installed_packages(enabled_module_stream_ids)).pluck(:id).uniq
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def fetch_enabled_module_stream_ids
|
|
90
|
+
# Query for applicable RPM ids
|
|
91
|
+
# -> Include all non-modular rpms or rpms that exist within installed module streams
|
|
92
|
+
::Katello::ModuleStream.
|
|
93
|
+
joins("inner join katello_available_module_streams on
|
|
94
|
+
katello_module_streams.name = katello_available_module_streams.name and
|
|
95
|
+
katello_module_streams.stream = katello_available_module_streams.stream").
|
|
96
|
+
joins("inner join katello_host_available_module_streams on
|
|
97
|
+
katello_available_module_streams.id = katello_host_available_module_streams.available_module_stream_id").
|
|
98
|
+
where("katello_host_available_module_streams.host_id = :content_facet_id and
|
|
99
|
+
katello_host_available_module_streams.status = 'enabled'",
|
|
100
|
+
:content_facet_id => self.content_facet.host.id).select(:id)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Installed packages that are locked for the host due to enabled module stream membership
|
|
104
|
+
def locked_modular_installed_packages(enabled_module_streams)
|
|
105
|
+
rpms_in_enabled_module_streams = ::Katello::Rpm.
|
|
106
|
+
joins("INNER JOIN katello_module_stream_rpms ON katello_rpms.id = katello_module_stream_rpms.rpm_id").
|
|
107
|
+
where("katello_module_stream_rpms.module_stream_id IN (:enabled_module_streams)",
|
|
108
|
+
:enabled_module_streams => enabled_module_streams).select(:nvra, :epoch)
|
|
109
|
+
|
|
110
|
+
::Katello::InstalledPackage.where(nvra: rpms_in_enabled_module_streams.map(&:nvra),
|
|
111
|
+
epoch: rpms_in_enabled_module_streams.map(&:epoch)).select(:id)
|
|
94
112
|
end
|
|
95
113
|
|
|
96
114
|
def newest_distinct_installed_packages_query
|
|
@@ -104,20 +122,22 @@ module Katello
|
|
|
104
122
|
end
|
|
105
123
|
|
|
106
124
|
def applicable_differences
|
|
107
|
-
|
|
108
|
-
|
|
125
|
+
ActiveRecord::Base.connection.uncached do
|
|
126
|
+
consumer_ids = content_facet.send(applicable_units).pluck("#{content_unit_class.table_name}.id")
|
|
127
|
+
content_ids = fetch_content_ids
|
|
109
128
|
|
|
110
|
-
|
|
111
|
-
|
|
129
|
+
to_remove = consumer_ids - content_ids
|
|
130
|
+
to_add = content_ids - consumer_ids
|
|
112
131
|
|
|
113
|
-
|
|
132
|
+
[to_add, to_remove]
|
|
133
|
+
end
|
|
114
134
|
end
|
|
115
135
|
|
|
116
136
|
def insert(applicable_ids)
|
|
117
137
|
unless applicable_ids.empty?
|
|
118
138
|
inserts = applicable_ids.map { |applicable_id| "(#{applicable_id.to_i}, #{content_facet.id.to_i})" }
|
|
119
139
|
sql = "INSERT INTO #{content_facet_association_class.table_name} (#{content_unit_association_id}, content_facet_id) VALUES #{inserts.join(', ')}"
|
|
120
|
-
ActiveRecord::Base.connection.
|
|
140
|
+
ActiveRecord::Base.connection.exec_insert(sql)
|
|
121
141
|
end
|
|
122
142
|
end
|
|
123
143
|
|
|
@@ -58,6 +58,20 @@ module Katello
|
|
|
58
58
|
fail NotImplementedError
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
def self.ignore_409_exception(*)
|
|
62
|
+
yield
|
|
63
|
+
rescue => e
|
|
64
|
+
raise e unless e&.code == 409
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def cancel_task(task_href)
|
|
69
|
+
data = PulpcoreClient::TaskResponse.new(state: 'canceled')
|
|
70
|
+
self.class.ignore_409_exception do
|
|
71
|
+
tasks_api.tasks_cancel(task_href, data)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
61
75
|
def exporter_api
|
|
62
76
|
PulpcoreClient::ExportersPulpApi.new(core_api_client)
|
|
63
77
|
end
|
|
@@ -35,7 +35,8 @@ module Katello
|
|
|
35
35
|
custom_json["issued"] = convert_date_if_epoch(custom_json["issued"])
|
|
36
36
|
custom_json["updated"] = convert_date_if_epoch(custom_json["updated"]) unless custom_json["updated"].blank?
|
|
37
37
|
|
|
38
|
-
if model.updated.blank? ||
|
|
38
|
+
if model.updated.blank? ||
|
|
39
|
+
(custom_json['updated'] && (custom_json['updated'].to_datetime != model.updated.to_datetime))
|
|
39
40
|
custom_json['errata_id'] = custom_json.delete('id')
|
|
40
41
|
custom_json['errata_type'] = custom_json.delete('type')
|
|
41
42
|
custom_json['updated'] = custom_json['updated'].blank? ? custom_json['issued'] : custom_json['updated']
|
|
@@ -4,6 +4,8 @@ module Katello
|
|
|
4
4
|
module Pulp3
|
|
5
5
|
class Migration
|
|
6
6
|
attr_accessor :smart_proxy, :reimport_all, :task_id
|
|
7
|
+
attr_reader :repository_types
|
|
8
|
+
|
|
7
9
|
GET_QUERY_ID_LENGTH = 90
|
|
8
10
|
|
|
9
11
|
MUTABLE_CONTENT_TYPES = [
|
|
@@ -15,6 +17,12 @@ module Katello
|
|
|
15
17
|
Katello::Erratum
|
|
16
18
|
].freeze
|
|
17
19
|
|
|
20
|
+
CORRUPTABLE_CONTENT_TYPES = [
|
|
21
|
+
Katello::Rpm,
|
|
22
|
+
Katello::FileUnit,
|
|
23
|
+
Katello::Deb
|
|
24
|
+
].freeze
|
|
25
|
+
|
|
18
26
|
def self.repository_types_for_migration
|
|
19
27
|
#we can migrate types that pulp3 supports, but are overridden to pulp2. These are in 'migration mode'
|
|
20
28
|
overridden = (SETTINGS[:katello][:use_pulp_2_for_content_type] || {}).keys.select { |key| SETTINGS[:katello][:use_pulp_2_for_content_type][key] }
|
|
@@ -66,7 +74,9 @@ module Katello
|
|
|
66
74
|
|
|
67
75
|
def last_successful_migration_time
|
|
68
76
|
task = ForemanTasks::Task.where(:label => Actions::Pulp3::ContentMigration.to_s, :result => 'success').order("started_at desc").first
|
|
69
|
-
|
|
77
|
+
reset_task = ForemanTasks::Task.where(:label => Actions::Pulp3::ContentMigrationReset.to_s).order("started_at desc").first
|
|
78
|
+
reset_more_recent = reset_task && task && reset_task.started_at > task.started_at
|
|
79
|
+
if reimport_all || task.nil? || reset_more_recent
|
|
70
80
|
0
|
|
71
81
|
else
|
|
72
82
|
task.started_at.to_i
|
|
@@ -104,6 +114,7 @@ module Katello
|
|
|
104
114
|
Katello::RepositoryTypeManager.repository_types[repository_type_label].content_types_to_index.each do |content_type|
|
|
105
115
|
Katello::Logging.time("CONTENT_MIGRATION - Importing Content", data: {type: content_type.label}) do
|
|
106
116
|
import_content_type(content_type)
|
|
117
|
+
mark_missing_content(content_type)
|
|
107
118
|
end
|
|
108
119
|
end
|
|
109
120
|
end
|
|
@@ -114,6 +125,45 @@ module Katello
|
|
|
114
125
|
Katello::Pulp3::MigrationPlan.new(@repository_types).generate.as_json
|
|
115
126
|
end
|
|
116
127
|
|
|
128
|
+
def reset
|
|
129
|
+
if @repository_types.empty?
|
|
130
|
+
fail ::Katello::Errors::Pulp3MigrationError, 'There are no Pulp 3 content types to reset'
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
plugins = @repository_types.sort.map do |repository_type|
|
|
134
|
+
{
|
|
135
|
+
type: ::Katello::Pulp3::MigrationPlan.pulp2_repository_type(repository_type)
|
|
136
|
+
}
|
|
137
|
+
end
|
|
138
|
+
plan = { plugins: plugins }
|
|
139
|
+
|
|
140
|
+
pulp3_task = migration_plan_api.reset(migration_plan_api.create(plan: plan).pulp_href)
|
|
141
|
+
|
|
142
|
+
content_types_for_migration.each do |content_type|
|
|
143
|
+
if content_type.model_class == ::Katello::Erratum
|
|
144
|
+
::Katello::RepositoryErratum.update_all(erratum_pulp3_href: nil)
|
|
145
|
+
else
|
|
146
|
+
content_type.model_class.update_all(migrated_pulp3_href: nil, missing_from_migration: false, ignore_missing_from_migration: false)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
@repository_types.each do |repo_type|
|
|
151
|
+
if repo_type == "file"
|
|
152
|
+
::Katello::Repository.file_type.update_all(remote_href: nil, publication_href: nil, version_href: nil)
|
|
153
|
+
elsif repo_type == "docker"
|
|
154
|
+
::Katello::Repository.docker_type.update_all(remote_href: nil, publication_href: nil, version_href: nil)
|
|
155
|
+
elsif repo_type == "yum"
|
|
156
|
+
::Katello::Repository.yum_type.update_all(remote_href: nil, publication_href: nil, version_href: nil)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
::Katello::Pulp3::RepositoryReference.destroy_all
|
|
161
|
+
::Katello::Pulp3::DistributionReference.destroy_all
|
|
162
|
+
::Katello::Pulp3::ContentGuard.destroy_all
|
|
163
|
+
|
|
164
|
+
pulp3_task
|
|
165
|
+
end
|
|
166
|
+
|
|
117
167
|
def create_migrations
|
|
118
168
|
plan = migration_plan
|
|
119
169
|
Rails.logger.info("Migration Plan: #{plan}")
|
|
@@ -127,7 +177,7 @@ module Katello
|
|
|
127
177
|
end
|
|
128
178
|
|
|
129
179
|
def start_migration(plan_href)
|
|
130
|
-
migration_plan_api.run(plan_href, dry_run: false, validate: true)
|
|
180
|
+
migration_plan_api.run(plan_href, dry_run: false, validate: true, skip_corrupted: true)
|
|
131
181
|
end
|
|
132
182
|
|
|
133
183
|
def import_repositories(repository_type_label)
|
|
@@ -255,10 +305,17 @@ module Katello
|
|
|
255
305
|
to_import[[errata_id, repo_id]] ||= {erratum_id: errata_id, erratum_pulp3_href: pulp3_href, repository_id: repo_id}
|
|
256
306
|
end
|
|
257
307
|
end
|
|
308
|
+
|
|
309
|
+
Katello::RepositoryErratum.import([:erratum_id, :erratum_pulp3_href, :repository_id], to_import.values, :validate => false,
|
|
310
|
+
on_duplicate_key_update: {conflict_target: [:erratum_id, :repository_id], columns: [:erratum_pulp3_href]})
|
|
311
|
+
to_import = {}
|
|
258
312
|
end
|
|
313
|
+
end
|
|
259
314
|
|
|
260
|
-
|
|
261
|
-
|
|
315
|
+
def mark_missing_content(content_type)
|
|
316
|
+
unless [Katello::DockerTag, Katello::DockerManifest, Katello::Erratum].include?(content_type.model_class)
|
|
317
|
+
content_type.model_class.where(:migrated_pulp3_href => nil).update_all(:missing_from_migration => true)
|
|
318
|
+
end
|
|
262
319
|
end
|
|
263
320
|
|
|
264
321
|
def import_content_type(content_type)
|
|
@@ -278,10 +335,9 @@ module Katello
|
|
|
278
335
|
unmigrated_units.select(:id, :pulp_id).find_in_batches(batch_size: GET_QUERY_ID_LENGTH) do |needing_hrefs|
|
|
279
336
|
current_count += needing_hrefs.count
|
|
280
337
|
update_import_status("Importing migrated content type #{content_type.label}: #{current_count}/#{total_count}")
|
|
281
|
-
migrated_units = pulp2_content_api.list(pulp2_id__in: needing_hrefs.map
|
|
338
|
+
migrated_units = pulp2_content_api.list(pulp2_id__in: needing_hrefs.map(&:pulp_id))
|
|
282
339
|
migrated_units.results.each do |migrated_unit|
|
|
283
|
-
|
|
284
|
-
matching_record&.update_column(:migrated_pulp3_href, migrated_unit.pulp3_content)
|
|
340
|
+
content_type.model_class.where(pulp_id: migrated_unit.pulp2_id).update_all(migrated_pulp3_href: migrated_unit.pulp3_content)
|
|
285
341
|
end
|
|
286
342
|
end
|
|
287
343
|
end
|
|
@@ -21,13 +21,13 @@ module Katello
|
|
|
21
21
|
def generate_plugins
|
|
22
22
|
@repository_types.sort.map do |repository_type|
|
|
23
23
|
{
|
|
24
|
-
type: pulp2_repository_type(repository_type),
|
|
24
|
+
type: self.class.pulp2_repository_type(repository_type),
|
|
25
25
|
repositories: repository_migrations(repository_type)
|
|
26
26
|
}
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
def pulp2_repository_type(repository_type)
|
|
30
|
+
def self.pulp2_repository_type(repository_type)
|
|
31
31
|
if repository_type == 'yum'
|
|
32
32
|
return 'rpm' #migration plugin uses rpm
|
|
33
33
|
else
|
|
@@ -21,6 +21,20 @@ module Katello
|
|
|
21
21
|
Katello::Logging.time("CONTENT_SWITCHOVER - combine_duplicate_content_types") { combine_duplicate_content_types }
|
|
22
22
|
Katello::Logging.time("CONTENT_SWITCHOVER - combine_duplicate_docker_tags") { combine_duplicate_docker_tags } if docker_migration?
|
|
23
23
|
Katello::Logging.time("CONTENT_SWITCHOVER - migrate_pulp3_hrefs") { migrate_pulp3_hrefs }
|
|
24
|
+
Katello::Logging.time("CONTENT_SWITCHOVER - remove_missing_content") { remove_missing_content }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def remove_orphaned_content
|
|
29
|
+
models = []
|
|
30
|
+
@migration.repository_types.each do |repo_type_label|
|
|
31
|
+
repo_type = ::Katello::RepositoryTypeManager.repository_types[repo_type_label]
|
|
32
|
+
indexable_types = repo_type.content_types_to_index
|
|
33
|
+
models += indexable_types&.map(&:model_class)
|
|
34
|
+
models.select! { |model| model.many_repository_associations }
|
|
35
|
+
end
|
|
36
|
+
models.each do |model|
|
|
37
|
+
model.joins("left join katello_#{model.repository_association} on #{model.table_name}.id = katello_#{model.repository_association}.#{model.unit_id_field}").where("katello_#{model.repository_association}.#{model.unit_id_field} IS NULL").destroy_all
|
|
24
38
|
end
|
|
25
39
|
end
|
|
26
40
|
|
|
@@ -106,12 +120,29 @@ module Katello
|
|
|
106
120
|
end
|
|
107
121
|
end
|
|
108
122
|
|
|
109
|
-
def
|
|
123
|
+
def remove_missing_content
|
|
110
124
|
content_types.each do |content_type|
|
|
111
|
-
if content_type.model_class
|
|
112
|
-
|
|
113
|
-
elsif content_type.model_class
|
|
114
|
-
|
|
125
|
+
if Migration::CORRUPTABLE_CONTENT_TYPES.include?(content_type.model_class)
|
|
126
|
+
content_type.model_class.ignored_missing_migrated_content.destroy_all
|
|
127
|
+
elsif content_type.model_class == Katello::Erratum
|
|
128
|
+
Katello::RepositoryErratum.where(:erratum_pulp3_href => nil).delete_all
|
|
129
|
+
else
|
|
130
|
+
content_type.model_class.unmigrated_content.destroy_all
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def migrated_content_type_check
|
|
136
|
+
content_classes = content_types.map(&:model_class)
|
|
137
|
+
migrated_errata_check if content_classes.include?(Katello::Erratum)
|
|
138
|
+
|
|
139
|
+
(content_classes & Migration::CORRUPTABLE_CONTENT_TYPES).each do |content_type|
|
|
140
|
+
if content_type.missing_migrated_content.any?
|
|
141
|
+
fail SwitchOverError, "ERROR: at least one #{content_type.table_name} record has been detected as corrupt or missing. Run 'foreman-rake katello:pulp3_migration_stats' for more information.\n"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
if content_type.unmigrated_content.any?
|
|
145
|
+
fail SwitchOverError, "ERROR: at least one #{content_type.table_name} record was not able to be migrated\n"
|
|
115
146
|
end
|
|
116
147
|
end
|
|
117
148
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# rubocop:disable Metrics/ClassLength
|
|
1
2
|
require "pulpcore_client"
|
|
2
3
|
module Katello
|
|
3
4
|
module Pulp3
|
|
@@ -157,10 +158,7 @@ module Katello
|
|
|
157
158
|
end
|
|
158
159
|
|
|
159
160
|
def compute_remote_options(computed_options = remote_options)
|
|
160
|
-
|
|
161
|
-
computed_options[key] = Digest::SHA256.hexdigest(computed_options[key].chomp) if computed_options[key]
|
|
162
|
-
end
|
|
163
|
-
computed_options.except(:name)
|
|
161
|
+
computed_options.except(:name, :client_key)
|
|
164
162
|
end
|
|
165
163
|
|
|
166
164
|
def create
|
|
@@ -220,11 +218,38 @@ module Katello
|
|
|
220
218
|
end
|
|
221
219
|
|
|
222
220
|
def refresh_distributions
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
update_distribution
|
|
221
|
+
if repo.docker?
|
|
222
|
+
dist = lookup_distributions(base_path: repo.container_repository_name).first
|
|
226
223
|
else
|
|
224
|
+
dist = lookup_distributions(base_path: repo.relative_path).first
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# First check if the distribution exists
|
|
228
|
+
if dist
|
|
229
|
+
dist_ref = distribution_reference
|
|
230
|
+
# If we have a DistributionReference, update the distribution
|
|
231
|
+
if dist_ref
|
|
232
|
+
return update_distribution
|
|
233
|
+
# If no DistributionReference, create a DistributionReference and return
|
|
234
|
+
else
|
|
235
|
+
save_distribution_references([dist.pulp_href])
|
|
236
|
+
return []
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# So far, it looks like there is no distribution. Try to create one.
|
|
241
|
+
begin
|
|
227
242
|
create_distribution(relative_path)
|
|
243
|
+
rescue api.class.client_module::ApiError => e
|
|
244
|
+
# Now it seems there is a distribution. Fetch it and save the reference.
|
|
245
|
+
if e.message.include?("\"base_path\":[\"This field must be unique.\"]") ||
|
|
246
|
+
e.message.include?("\"base_path\":[\"Overlaps with existing distribution\"")
|
|
247
|
+
dist = lookup_distributions(base_path: repo.relative_path).first
|
|
248
|
+
save_distribution_references([dist.pulp_href])
|
|
249
|
+
return []
|
|
250
|
+
else
|
|
251
|
+
raise e
|
|
252
|
+
end
|
|
228
253
|
end
|
|
229
254
|
end
|
|
230
255
|
|
|
@@ -257,8 +282,12 @@ module Katello
|
|
|
257
282
|
create_version(:base_version => from_repository.version_href)
|
|
258
283
|
end
|
|
259
284
|
|
|
285
|
+
def version_zero?
|
|
286
|
+
repo.version_href.ends_with?('/versions/0/')
|
|
287
|
+
end
|
|
288
|
+
|
|
260
289
|
def delete_version
|
|
261
|
-
ignore_404_exception { api.repository_versions_api.delete(repo.version_href) }
|
|
290
|
+
ignore_404_exception { api.repository_versions_api.delete(repo.version_href) } unless version_zero?
|
|
262
291
|
end
|
|
263
292
|
|
|
264
293
|
def create_version(options = {})
|
|
@@ -270,7 +299,8 @@ module Katello
|
|
|
270
299
|
pulp3_distribution_data = api.get_distribution(href)
|
|
271
300
|
path, content_guard_href = pulp3_distribution_data&.base_path, pulp3_distribution_data&.content_guard
|
|
272
301
|
unless distribution_reference
|
|
273
|
-
|
|
302
|
+
# Ensure that duplicates won't be created in the case of a race condition
|
|
303
|
+
DistributionReference.where(path: path, href: href, repository_id: repo.id, content_guard_href: content_guard_href).first_or_create!
|
|
274
304
|
end
|
|
275
305
|
end
|
|
276
306
|
end
|
|
@@ -300,7 +330,7 @@ module Katello
|
|
|
300
330
|
}
|
|
301
331
|
remote_options[:url] = root.url unless root.url.blank?
|
|
302
332
|
remote_options[:download_concurrency] = root.download_concurrency unless root.download_concurrency.blank?
|
|
303
|
-
if root.upstream_username && root.upstream_password
|
|
333
|
+
if !root.upstream_username.blank? && !root.upstream_password.blank?
|
|
304
334
|
remote_options.merge!(username: root.upstream_username,
|
|
305
335
|
password: root.upstream_password)
|
|
306
336
|
end
|