katello 3.18.1.1 → 3.18.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/katello/katello.scss +0 -72
  3. data/app/controllers/katello/api/v2/api_controller.rb +1 -2
  4. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +1 -1
  5. data/app/controllers/katello/concerns/api/v2/authorization.rb +14 -1
  6. data/app/lib/actions/katello/host/update_system_purpose.rb +1 -1
  7. data/app/lib/actions/pulp3/content_migration_reset.rb +22 -0
  8. data/app/models/katello/concerns/pulp_database_unit.rb +12 -0
  9. data/app/models/katello/concerns/redhat_extensions.rb +2 -2
  10. data/app/models/katello/concerns/smart_proxy_extensions.rb +3 -1
  11. data/app/models/katello/file_unit.rb +4 -0
  12. data/app/services/katello/applicability/applicable_content_helper.rb +32 -14
  13. data/app/services/katello/pulp3/erratum.rb +2 -1
  14. data/app/services/katello/pulp3/migration.rb +51 -3
  15. data/app/services/katello/pulp3/migration_plan.rb +2 -2
  16. data/app/services/katello/pulp3/migration_switchover.rb +21 -5
  17. data/app/services/katello/pulp3/repository.rb +7 -2
  18. data/app/services/katello/pulp3/repository/yum.rb +10 -1
  19. data/app/views/katello/sync_management/_products.html.erb +1 -1
  20. data/db/migrate/20150930183738_migrate_content_hosts.rb +1 -1
  21. data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +5 -2
  22. data/db/migrate/20210201165835_add_migration_missing_content.rb +12 -0
  23. data/engines/bastion/app/assets/javascripts/bastion/auth/authorization.service.js +1 -1
  24. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html +1 -1
  25. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-system-purpose-modal.html +35 -40
  26. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/register-client.html +1 -1
  27. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +1 -1
  28. data/lib/katello/tasks/delete_orphaned_content.rake +1 -3
  29. data/lib/katello/tasks/pulp3_content_switchover.rake +3 -1
  30. data/lib/katello/tasks/pulp3_migration.rake +8 -3
  31. data/lib/katello/tasks/pulp3_migration_abort.rake +1 -1
  32. data/lib/katello/tasks/pulp3_migration_approve_corrupted.rake +16 -0
  33. data/lib/katello/tasks/pulp3_migration_reset.rake +26 -0
  34. data/lib/katello/tasks/pulp3_migration_stats.rake +35 -2
  35. data/lib/katello/tasks/pulp3_post_migration_check.rake +1 -3
  36. data/lib/katello/tasks/reports.rake +4 -1
  37. data/lib/katello/tasks/repository.rake +3 -5
  38. data/lib/katello/version.rb +1 -1
  39. data/webpack/components/TypeAhead/TypeAhead.js +2 -1
  40. data/webpack/components/TypeAhead/pf3Search/TypeAheadSearch.js +2 -1
  41. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +7 -2
  42. data/webpack/scenes/Subscriptions/Manifest/index.js +1 -0
  43. metadata +17 -8
  44. data/lib/katello/tasks/common.rake +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66b5a21f5447c3d2ba6f03aa43a1ddbd958e9c13676b51798229ffeedf6e6b9e
4
- data.tar.gz: 0c188e13dc68b845e3d5fdaa5c2a52a370c7d976f0542d624e07a7676d630b61
3
+ metadata.gz: cb532cdaf1e25293105ac236fca987d75fb73d336c9a7c48f6d9d5e196b3eee6
4
+ data.tar.gz: 71581e670f4b0bd9811aaa529ef8fe515a958e9bd9d7a558b6bbda8aa6efdeba
5
5
  SHA512:
6
- metadata.gz: df5a80b234e5ab2f39a6ef6ac3aa2afc8859e77e4c1719c9dd4e958e75c0dd5c475c9f81ae7867ee65d6c6fc17eaae20fa90b9e025bae14b9ac278fbe1dafb30
7
- data.tar.gz: b2d252a12334713a3ce551a7de3b32f1bcdde818707f602b3bfa7779b8493adce51274b70e6acaa90807be0e8cca4ba4fa725b4f3e8c30f307e2075508963c7b
6
+ metadata.gz: 0630ee6e3a5e8c5ee653a499611bd1e647b62d6d291619c398cd32af95bdf3ef4e2b3b3097f13d53cfc35313d56e1e1a6cd64db1b040ed7775824bc199bbadc7
7
+ data.tar.gz: 1c6b2912fd5438dcbbcff04c152f45e2cc003535a3ebc8c84fbca5574b5b2e2ccc32684f9a4e61048f9c6f81432eb882a31faf54aba3b7512b5df3bfede1f37c
@@ -163,78 +163,6 @@ input:focus {
163
163
  @extend .status_exclamation_icon;
164
164
  }
165
165
 
166
- /* BUTTONS */
167
- input[type='submit'], button, .button {
168
- font-size: 10px;
169
- display: inline-block;
170
- vertical-align: bottom;
171
- background: -moz-linear-gradient(top, #f9f9f9, #f0f0f0, #e5e5e5, #e9e9e9);
172
- background: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), color-stop(0.9, #e5e5e5), to(#e9e9e9));
173
- box-shadow: none;
174
- border: 1px solid darken($stroke_color, 20%);
175
- color: #221e1f;
176
- cursor: pointer;
177
- padding: 4px 8px;
178
- border-radius: 5px;
179
- text-shadow: 0 1px 0 rgba($white_color, 1);
180
- min-height: 14px;
181
- .nomargin {
182
- margin: 0;
183
- }
184
- &:hover {
185
- background: -moz-linear-gradient(top, $white_color, $white_color, #cfcfcf);
186
- background: -webkit-gradient(linear, left top, left bottom, from($white_color), color-stop(0.6, $white_color), to(#cfcfcf));
187
- box-shadow: 0 1px 2px rgba(0,0,0,0.5);
188
- text-decoration: none;
189
- color: black;
190
- }
191
- &:active {
192
- background: -moz-linear-gradient(top, #c2c3c0, #e4e5e4);
193
- background: -webkit-gradient(linear, left top, left bottom, from(#c2c3c0), to(#e4e5e4));
194
- box-shadow: none;
195
- text-decoration: none;
196
- }
197
- &:focus {
198
- text-decoration: none;
199
- color: #000;
200
- border-width: 2px;
201
- }
202
- &.dialogbutton {
203
- float: right;
204
- margin-left: 3px;
205
- margin: 40px 4px 4px;
206
- }
207
- &.formbutton {
208
- display: inline-block;
209
- margin-left: 3px;
210
- margin: 40px 4px 4px;
211
- }
212
- &.actionlink {
213
- margin: 40px 0 0;
214
- }
215
- &.disabled, &[disabled] {
216
- cursor: default;
217
- background: transparent;
218
- opacity: 0.4;
219
-
220
- &:hover {
221
- background: transparent;
222
- box-shadow: none;
223
- }
224
- }
225
- &.iconbutton {
226
- display: inline-block;
227
- }
228
- &.tiny {
229
- padding: 4px;
230
- margin: 0;
231
- &:active, &:focus {
232
- margin: 0;
233
- padding: 3px;
234
- }
235
- }
236
- }
237
-
238
166
  table {
239
167
  border-collapse: collapse;
240
168
  border: 1px solid $stroke_color;
@@ -39,8 +39,7 @@ module Katello
39
39
  end
40
40
 
41
41
  def deprecate_katello_agent
42
- ::Foreman::Deprecation.api_deprecation_warning("Remote actions using katello-agent are deprecated and will be removed in Katello 4.0. " \
43
- "You may consider switching to Remote Execution.")
42
+ ::Foreman::Deprecation.api_deprecation_warning("Katello-agent is deprecated and will be removed in a future release.")
44
43
  end
45
44
 
46
45
  def full_result_response(collection)
@@ -73,7 +73,7 @@ module Katello
73
73
  respond :resource => @filter
74
74
  end
75
75
 
76
- api :delefind_filterte, "/content_views/:content_view_id/filters/:id", N_("delete a filter")
76
+ api :delete, "/content_views/:content_view_id/filters/:id", N_("delete a filter")
77
77
  api :delete, "/content_view_filters/:id", N_("delete a filter")
78
78
  param :content_view_id, :number, :desc => N_("content view identifier")
79
79
  param :id, :number, :desc => N_("filter identifier"), :required => true
@@ -39,7 +39,20 @@ module Katello
39
39
  end
40
40
 
41
41
  def throw_resource_not_found(name: resource_name, id: params[:id])
42
- fail HttpErrors::NotFound, _("Could not find %{name} resource with id %{id}") % {id: id, name: name}
42
+ perms_message = "Potential missing permissions: " +
43
+ missing_permissions.map(&:name).join(', ')
44
+ fail HttpErrors::NotFound, _("Could not find %{name} resource with id %{id}. %{perms_message}") % {id: id, name: name, perms_message: perms_message}
45
+ end
46
+
47
+ def missing_permissions
48
+ missing_perms = ::Foreman::AccessControl.permissions_for_controller_action(path_to_authenticate)
49
+
50
+ # promote_or_remove_content_views_to_environments has a special relationship to promote_or_remove_content_views
51
+ if path_to_authenticate["controller"] == "katello/api/v2/content_view_versions" &&
52
+ path_to_authenticate["action"].in?(["promote", "remove_from_environment", "remove", "republish_repositories"])
53
+ missing_perms << ::Permission.find_by(name: "promote_or_remove_content_views_to_environments")
54
+ end
55
+ missing_perms
43
56
  end
44
57
 
45
58
  def throw_resources_not_found(name:, expected_ids: [])
@@ -14,7 +14,7 @@ module Actions
14
14
  host.subscription_facet.purpose_addons = purpose_addon_objects
15
15
  end
16
16
 
17
- host.subscription_facet.save!
17
+ host.save!
18
18
  plan_self(:hostname => host.name)
19
19
  end
20
20
 
@@ -0,0 +1,22 @@
1
+ module Actions
2
+ module Pulp3
3
+ class ContentMigrationReset < Pulp3::AbstractAsyncTask
4
+ def plan(smart_proxy)
5
+ plan_self(smart_proxy_id: smart_proxy.id)
6
+ end
7
+
8
+ def invoke_external_task
9
+ migration_service = ::Katello::Pulp3::Migration.new(smart_proxy)
10
+ migration_service.reset
11
+ end
12
+
13
+ def humanized_name
14
+ _("Content Migration Reset")
15
+ end
16
+
17
+ def rescue_strategy
18
+ Dynflow::Action::Rescue::Skip
19
+ end
20
+ end
21
+ end
22
+ end
@@ -218,6 +218,18 @@ module Katello
218
218
  def db_values(new_ids, pulp_id_href_map, repository)
219
219
  new_ids.map { |unit_id| [unit_id.to_i, pulp_id_href_map.dig(unit_id), repository.id.to_i, Time.now.utc.to_s(:db), Time.now.utc.to_s(:db)].compact }
220
220
  end
221
+
222
+ def unmigrated_content
223
+ self.where(migrated_pulp3_href: nil, ignore_missing_from_migration: false)
224
+ end
225
+
226
+ def missing_migrated_content #missing or corrupted content that could not be migrated
227
+ self.where(migrated_pulp3_href: nil, missing_from_migration: true, ignore_missing_from_migration: false)
228
+ end
229
+
230
+ def ignored_missing_migrated_content
231
+ self.where(migrated_pulp3_href: nil, missing_from_migration: true, ignore_missing_from_migration: true)
232
+ end
221
233
  end
222
234
  end
223
235
  end
@@ -44,8 +44,8 @@ module Katello
44
44
 
45
45
  def kickstart_repos(host)
46
46
  distros = distribution_repositories(host).where(distribution_bootable: true)
47
- if distros && host.content_source
48
- distros.map { |distro| distro.to_hash(host.content_source) }
47
+ if distros && host&.content_facet&.content_source
48
+ distros.map { |distro| distro.to_hash(host.content_facet.content_source) }
49
49
  else
50
50
  []
51
51
  end
@@ -179,7 +179,9 @@ module Katello
179
179
  end
180
180
 
181
181
  def fix_pulp3_capabilities(type)
182
- if missing_pulp3_capabilities? && !pulp2_preferred_for_type?(type)
182
+ repository_type_obj = type.is_a?(String) || type.is_a?(Symbol) ? Katello::RepositoryTypeManager.repository_types[type] : type
183
+
184
+ if missing_pulp3_capabilities? && repository_type_obj.pulp3_plugin && !pulp2_preferred_for_type?(repository_type_obj.id)
183
185
  self.refresh
184
186
  if self.capabilities(::SmartProxy::PULP3_FEATURE).empty?
185
187
  fail Katello::Errors::PulpcoreMissingCapabilities
@@ -13,6 +13,10 @@ module Katello
13
13
  order(:name)
14
14
  end
15
15
 
16
+ def filename
17
+ path
18
+ end
19
+
16
20
  def self.total_for_repositories(repos)
17
21
  self.in_repositories(repos).count
18
22
  end
@@ -60,17 +60,7 @@ module Katello
60
60
  end
61
61
 
62
62
  def fetch_rpm_content_ids
63
- # Query for applicable RPM ids
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 is null or
92
- katello_module_stream_rpms.module_stream_id in (:enabled_module_streams)",
93
- :enabled_module_streams => enabled_module_stream_ids).pluck(:id).uniq
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
@@ -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? || (custom_json['updated'].to_datetime != model.updated.to_datetime)
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']
@@ -15,6 +15,10 @@ module Katello
15
15
  Katello::Erratum
16
16
  ].freeze
17
17
 
18
+ CORRUPTABLE_CONTENT_TYPES = [
19
+ Katello::Rpm, Katello::FileUnit
20
+ ].freeze
21
+
18
22
  def self.repository_types_for_migration
19
23
  #we can migrate types that pulp3 supports, but are overridden to pulp2. These are in 'migration mode'
20
24
  overridden = (SETTINGS[:katello][:use_pulp_2_for_content_type] || {}).keys.select { |key| SETTINGS[:katello][:use_pulp_2_for_content_type][key] }
@@ -104,6 +108,7 @@ module Katello
104
108
  Katello::RepositoryTypeManager.repository_types[repository_type_label].content_types_to_index.each do |content_type|
105
109
  Katello::Logging.time("CONTENT_MIGRATION - Importing Content", data: {type: content_type.label}) do
106
110
  import_content_type(content_type)
111
+ mark_missing_content(content_type)
107
112
  end
108
113
  end
109
114
  end
@@ -114,6 +119,44 @@ module Katello
114
119
  Katello::Pulp3::MigrationPlan.new(@repository_types).generate.as_json
115
120
  end
116
121
 
122
+ def reset
123
+ if @repository_types.empty?
124
+ fail ::Katello::Errors::Pulp3MigrationError, 'There are no Pulp 3 content types to reset'
125
+ end
126
+
127
+ plugins = @repository_types.sort.map do |repository_type|
128
+ {
129
+ type: ::Katello::Pulp3::MigrationPlan.pulp2_repository_type(repository_type)
130
+ }
131
+ end
132
+ plan = { plugins: plugins }
133
+
134
+ # TODO: Don't provide the plan as a string once this is resolved: https://pulp.plan.io/issues/8211
135
+ migration_plan_api.reset(migration_plan_api.create(plan: plan).pulp_href, plan.to_json)
136
+
137
+ content_types_for_migration.each do |content_type|
138
+ if content_type.model_class == ::Katello::Erratum
139
+ ::Katello::RepositoryErratum.update_all(erratum_pulp3_href: nil)
140
+ else
141
+ content_type.model_class.update_all(migrated_pulp3_href: nil)
142
+ end
143
+ end
144
+
145
+ @repository_types.each do |repo_type|
146
+ if repo_type == "file"
147
+ ::Katello::Repository.file_type.update(remote_href: nil, publication_href: nil, version_href: nil)
148
+ elsif repo_type == "docker"
149
+ ::Katello::Repository.docker_type.update(remote_href: nil, publication_href: nil, version_href: nil)
150
+ elsif repo_type == "yum"
151
+ ::Katello::Repository.yum_type.update(remote_href: nil, publication_href: nil, version_href: nil)
152
+ end
153
+ end
154
+
155
+ ::Katello::Pulp3::RepositoryReference.destroy_all
156
+ ::Katello::Pulp3::DistributionReference.destroy_all
157
+ ::Katello::Pulp3::ContentGuard.destroy_all
158
+ end
159
+
117
160
  def create_migrations
118
161
  plan = migration_plan
119
162
  Rails.logger.info("Migration Plan: #{plan}")
@@ -127,7 +170,7 @@ module Katello
127
170
  end
128
171
 
129
172
  def start_migration(plan_href)
130
- migration_plan_api.run(plan_href, dry_run: false, validate: true)
173
+ migration_plan_api.run(plan_href, dry_run: false, validate: true, skip_corrupted: true)
131
174
  end
132
175
 
133
176
  def import_repositories(repository_type_label)
@@ -261,6 +304,12 @@ module Katello
261
304
  on_duplicate_key_update: {conflict_target: [:erratum_id, :repository_id], columns: [:erratum_pulp3_href]})
262
305
  end
263
306
 
307
+ def mark_missing_content(content_type)
308
+ unless [Katello::DockerTag, Katello::DockerManifest, Katello::Erratum].include?(content_type.model_class)
309
+ content_type.model_class.where(:migrated_pulp3_href => nil).update_all(:missing_from_migration => true)
310
+ end
311
+ end
312
+
264
313
  def import_content_type(content_type)
265
314
  if content_type.model_class == Katello::Erratum
266
315
  import_errata
@@ -280,8 +329,7 @@ module Katello
280
329
  update_import_status("Importing migrated content type #{content_type.label}: #{current_count}/#{total_count}")
281
330
  migrated_units = pulp2_content_api.list(pulp2_id__in: needing_hrefs.map { |unit| unit.pulp_id }.join(','))
282
331
  migrated_units.results.each do |migrated_unit|
283
- matching_record = needing_hrefs.find { |db_unit| db_unit.pulp_id == migrated_unit.pulp2_id }
284
- matching_record&.update_column(:migrated_pulp3_href, migrated_unit.pulp3_content)
332
+ content_type.model_class.where(pulp_id: migrated_unit.pulp2_id).update_all(migrated_pulp3_href: migrated_unit.pulp3_content)
285
333
  end
286
334
  end
287
335
  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,7 @@ 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 }
24
25
  end
25
26
  end
26
27
 
@@ -106,12 +107,27 @@ module Katello
106
107
  end
107
108
  end
108
109
 
109
- def migrated_content_type_check
110
+ def remove_missing_content
110
111
  content_types.each do |content_type|
111
- if content_type.model_class == Katello::Erratum
112
- migrated_errata_check
113
- elsif content_type.model_class.where(migrated_pulp3_href: nil).any?
114
- fail SwitchOverError, "ERROR: at least one #{content_type.model_class.table_name} record has migrated_pulp3_href NULL value\n"
112
+ if Migration::CORRUPTABLE_CONTENT_TYPES.include?(content_type.model_class)
113
+ content_type.model_class.ignored_missing_migrated_content.destroy_all
114
+ else
115
+ content_type.model_class.unmigrated_content.destroy_all
116
+ end
117
+ end
118
+ end
119
+
120
+ def migrated_content_type_check
121
+ content_classes = content_types.map(&:model_class)
122
+ migrated_errata_check if content_classes.include?(Katello::Erratum)
123
+
124
+ (content_classes & Migration::CORRUPTABLE_CONTENT_TYPES).each do |content_type|
125
+ if content_type.missing_migrated_content.any?
126
+ 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"
127
+ end
128
+
129
+ if content_type.unmigrated_content.any?
130
+ fail SwitchOverError, "ERROR: at least one #{content_type.table_name} record was not able to be migrated\n"
115
131
  end
116
132
  end
117
133
  end
@@ -1,6 +1,7 @@
1
1
  require "pulpcore_client"
2
2
  module Katello
3
3
  module Pulp3
4
+ # rubocop:disable Metrics/ClassLength
4
5
  class Repository
5
6
  include Katello::Util::HttpProxy
6
7
  attr_accessor :repo
@@ -257,8 +258,12 @@ module Katello
257
258
  create_version(:base_version => from_repository.version_href)
258
259
  end
259
260
 
261
+ def version_zero?
262
+ repo.version_href.ends_with?('/versions/0/')
263
+ end
264
+
260
265
  def delete_version
261
- ignore_404_exception { api.repository_versions_api.delete(repo.version_href) }
266
+ ignore_404_exception { api.repository_versions_api.delete(repo.version_href) } unless version_zero?
262
267
  end
263
268
 
264
269
  def create_version(options = {})
@@ -300,7 +305,7 @@ module Katello
300
305
  }
301
306
  remote_options[:url] = root.url unless root.url.blank?
302
307
  remote_options[:download_concurrency] = root.download_concurrency unless root.download_concurrency.blank?
303
- if root.upstream_username && root.upstream_password
308
+ if !root.upstream_username.blank? && !root.upstream_password.blank?
304
309
  remote_options.merge!(username: root.upstream_username,
305
310
  password: root.upstream_password)
306
311
  end
@@ -14,7 +14,16 @@ module Katello
14
14
  url, sles_token = extract_sles_token
15
15
  options = common_remote_options
16
16
  options.merge!(sles_auth_token: sles_token) if sles_token
17
- options.merge!(url: url, policy: root.download_policy)
17
+
18
+ options.merge!(url: url, policy: translated_download_policy)
19
+ end
20
+
21
+ def translated_download_policy
22
+ if root.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_BACKGROUND
23
+ ::Runcible::Models::YumImporter::DOWNLOAD_IMMEDIATE
24
+ else
25
+ root.download_policy
26
+ end
18
27
  end
19
28
 
20
29
  def extract_sles_token
@@ -42,5 +42,5 @@
42
42
  </tbody>
43
43
  </table>
44
44
 
45
- <%= submit_tag _('Synchronize Now'), :class => 'button fr', :id => 'sync_button' %>
45
+ <%= submit_tag _('Synchronize Now'), :class => 'btn btn-default fr', :id => 'sync_button' %>
46
46
  <% end %>
@@ -329,7 +329,7 @@ class MigrateContentHosts < ActiveRecord::Migration[4.2]
329
329
  # rubocop:disable Metrics/MethodLength
330
330
  # rubocop:disable Metrics/AbcSize
331
331
  def up
332
- if User.where(:login => User::ANONYMOUS_API_ADMIN).first.nil?
332
+ unless User.unscoped.where(:login => User::ANONYMOUS_API_ADMIN).exists?
333
333
  logger.warn("Foreman anonymous admin does not exist, skipping content host migration.")
334
334
  return
335
335
  end
@@ -1,6 +1,6 @@
1
1
  class MoveKatelloFieldsFromHostgroups < ActiveRecord::Migration[6.0]
2
2
  def up
3
- if User.where(login: User::ANONYMOUS_ADMIN).exists?
3
+ if User.unscoped.where(login: User::ANONYMOUS_ADMIN).exists?
4
4
  User.as_anonymous_admin do
5
5
  copy_data_from_hostgroup
6
6
  end
@@ -46,7 +46,10 @@ class MoveKatelloFieldsFromHostgroups < ActiveRecord::Migration[6.0]
46
46
  content_facet.kickstart_repository_id = kickstart_repository_id
47
47
  content_facet.content_view_id = content_view_id
48
48
  content_facet.lifecycle_environment_id = lifecycle_environment_id
49
- content_facet.save!
49
+ unless content_facet.save
50
+ Rails.logger.warn("Unable to save content facet hostgroup for #{content_facet.inspect} ")
51
+ Rails.logger.warn(content_facet.errors.full_messages.join("\n"))
52
+ end
50
53
  end
51
54
  end
52
55
  end
@@ -0,0 +1,12 @@
1
+ class AddMigrationMissingContent < ActiveRecord::Migration[6.0]
2
+ def change
3
+ content_models = [Katello::Rpm, Katello::ModuleStream, Katello::Erratum, Katello::PackageGroup, Katello::YumMetadataFile,
4
+ Katello::Srpm, Katello::FileUnit, Katello::DockerManifestList, Katello::DockerManifest, Katello::DockerTag,
5
+ Katello::Deb]
6
+
7
+ content_models.each do |model|
8
+ add_column model.table_name, :missing_from_migration, :bool, :default => false, :null => false
9
+ add_column model.table_name, :ignore_missing_from_migration, :bool, :default => false, :null => false
10
+ end
11
+ end
12
+ end
@@ -20,7 +20,7 @@ angular.module('Bastion.auth').service('Authorization', ['CurrentUser', 'Permiss
20
20
  allowedTo = model.permissions[permissionName];
21
21
  } else {
22
22
  angular.forEach(Permissions, function (permission) {
23
- if (permission.permission.name === permissionName) {
23
+ if (permission.name === permissionName) {
24
24
  allowedTo = true;
25
25
  }
26
26
  });
@@ -1,7 +1,7 @@
1
1
  <section>
2
2
  <p bst-alert="warning" >
3
3
  <span translate>
4
- Katello-agent is deprecated and will be removed in Katello 4.0. Consider migrating to Remote Execution.
4
+ Katello-agent is deprecated and will be removed in a future release.
5
5
  </span>
6
6
  </p>
7
7
  </section>
@@ -1,8 +1,7 @@
1
1
  <div data-extend-template="components/views/bst-modal.html">
2
- <h4 data-block="modal-header" translate>Content Host System Purpose</h4>
2
+ <h2 data-block="modal-header" translate>Assign System Purpose</h2>
3
3
 
4
4
  <div data-block="modal-body">
5
- <h4 translate>Assign System Purpose:</h4>
6
5
 
7
6
  <div class="row">
8
7
  <div class="col-sm-12">
@@ -10,67 +9,63 @@
10
9
  </div>
11
10
  </div>
12
11
 
12
+ <div bst-alert="info">
13
+ <span translate>
14
+ This change will be applied to <b>{{ hostCount }} systems.</b>
15
+ </span>
16
+ </div>
17
+ <br />
18
+
13
19
  <form name="contentHostContentForm" class="form" ng-hide="content.workingMode">
14
- <div>
15
- <label translate>Service Level:</label>
20
+ <div><b>
21
+ <dl class="dl-horizontal dl-horizontal-left">
22
+ <dt><label translate>Service Level (SLA):</label></dt>
16
23
 
17
- <select type="select"
18
- ng-options="item for item in defaultServiceLevels"
19
- ng-model="selectedServiceLevels">
20
- </select>
21
- <br /><br />
24
+ <dd><select type="select"
25
+ ng-options="item for item in defaultServiceLevels"
26
+ ng-model="selectedServiceLevels">
27
+ </select></dd>
28
+ <br /><br />
22
29
 
23
- <label translate>Usage Type:</label>
30
+ <dt style="margin-left: -50px;"><label translate>Usage Type:</label></dt>
24
31
 
25
- <select type="select"
32
+ <dd><select type="select"
26
33
  ng-options="item for item in defaultUsages"
27
34
  ng-model="selectedRoles">
28
- </select>
35
+ </select></dd>
29
36
  <br /><br />
30
37
 
31
- <label translate>Role:</label>
38
+ <dt style="margin-left: -98px;"><label translate>Role:</label></dt>
32
39
 
33
- <select type="select"
40
+ <dd><select type="select"
34
41
  ng-options="item for item in defaultRoles"
35
42
  ng-model="selectedUsages">
36
- </select>
43
+ </select></dd>
37
44
  <br /><br />
38
45
 
39
- <label ng-hide="!purposeAddonsList().length" translate>Add ons:</label>
40
- <div class="help-block" style="text-align:left;">
41
- <p translate>ctrl-click or shift-click to select multiple Add ons</p>
42
- </div>
46
+ <dt style="margin-left: -75px;"><label ng-hide="!purposeAddonsList().length" translate>Add ons:</label></dt>
43
47
 
44
- <select multiple ng-multiple="true"
48
+ <dd><select multiple ng-multiple="true"
45
49
  ng-hide="!purposeAddonsList().length"
46
50
  ng-options="item for item in purposeAddonsList()"
47
51
  ng-model="selectedAddons">
48
- </select>
49
- <br /><br />
50
-
51
- </div>
52
-
53
- <div bst-alert="info" ng-show="showConfirm">
54
- <span translate>
55
- Set System Purpose values on {{ hostCount }} selected content hosts?
56
- </span>
57
- <div>
58
- <br />
59
- <button type="button" class="btn btn-primary" ng-click="showConfirm = false; performAction()" translate>Assign</button>
52
+ </select></dd>
53
+ <div class="help-block" style="text-align:center; margin-left: -180px;">
54
+ <p translate>ctrl-click or shift-click to select multiple Add ons</p>
60
55
  </div>
56
+ <br /><br />
57
+ </dl></b>
61
58
  </div>
62
-
63
- <button class="btn btn-primary"
64
- type="button"
65
- ng-hide="showConfirm"
66
- ng-click="showConfirm = true;">
67
- <span translate>Assign</span>
68
- </button>
69
-
70
59
  </form>
71
60
  </div>
72
61
 
73
62
  <div data-block="modal-footer">
63
+ <button class="btn btn-primary"
64
+ type="button"
65
+ ng-click="performAction()">
66
+ <span translate>Assign</span>
67
+ </button>
68
+
74
69
  <button type="button" class="btn btn-default" ng-click="cancel()" translate>
75
70
  Cancel
76
71
  </button>
@@ -12,7 +12,7 @@
12
12
  <section>
13
13
  <p bst-alert="warning" >
14
14
  <span translate>
15
- Katello-agent is deprecated and will be removed in Katello 4.0. Consider migrating to Remote Execution.
15
+ Katello-agent is deprecated and will be removed in a future release.
16
16
  </span>
17
17
  </p>
18
18
  </section>
@@ -2778,7 +2778,7 @@ msgstr ""
2778
2778
 
2779
2779
  #: app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html
2780
2780
  #: app/assets/javascripts/bastion_katello/content-hosts/views/register-client.html
2781
- msgid "Katello-agent is deprecated and will be removed in Katello 4.0. Consider migrating to Remote Execution."
2781
+ msgid "Katello-agent is deprecated and will be removed in a future release."
2782
2782
  msgstr ""
2783
2783
 
2784
2784
  #: app/assets/javascripts/bastion_katello/content-views/details/views/content-view-info.html
@@ -1,9 +1,7 @@
1
- load "#{Katello::Engine.root}/lib/katello/tasks/common.rake"
2
-
3
1
  namespace :katello do
4
2
  desc "Remove orphaned and unneeded content/repos from a smart proxy.\
5
3
  Run with SMART_PROXY_ID=1 to run for a single smart proxy."
6
- task :delete_orphaned_content => ["environment", "disable_dynflow"] do
4
+ task :delete_orphaned_content => ["dynflow:client"] do
7
5
  User.current = User.anonymous_admin
8
6
  smart_proxy_id = ENV['SMART_PROXY_ID']
9
7
  if smart_proxy_id
@@ -3,13 +3,15 @@ require "#{Katello::Engine.root}/app/services/katello/pulp3/migration_switchover
3
3
 
4
4
  namespace :katello do
5
5
  desc "Runs a Pulp 3 migration of pulp3 hrefs to pulp ids for supported content types."
6
- task :pulp3_content_switchover => :environment do
6
+ task :pulp3_content_switchover => ["dynflow:client"] do
7
+ dryrun = ENV['DRYRUN']
7
8
  begin
8
9
  User.current = User.anonymous_admin
9
10
 
10
11
  ActiveRecord::Base.transaction do
11
12
  switchover_service = Katello::Pulp3::MigrationSwitchover.new(SmartProxy.pulp_primary)
12
13
  switchover_service.run
14
+ fail "Dryrun completed without error, aborting and rolling back" if dryrun
13
15
  end
14
16
  rescue Katello::Pulp3::SwitchOverError => e
15
17
  $stderr.print(e.message)
@@ -1,8 +1,6 @@
1
- load "#{Katello::Engine.root}/lib/katello/tasks/common.rake"
2
-
3
1
  namespace :katello do
4
2
  desc "Runs a Pulp 2 to 3 Content Migration for supported types. May be run multiple times. Use wait=false to immediately return with a task url."
5
- task :pulp3_migration => ["environment", "disable_dynflow", "check_ping"] do
3
+ task :pulp3_migration => ["dynflow:client", "check_ping"] do
6
4
  puts "Starting task."
7
5
  SmartProxy.pulp_primary.refresh
8
6
 
@@ -30,6 +28,13 @@ namespace :katello do
30
28
  $stderr.print(msg)
31
29
  fail ForemanTasks::TaskError, task
32
30
  else
31
+ puts
32
+ Katello::Pulp3::Migration::CORRUPTABLE_CONTENT_TYPES.each do |type|
33
+ if type.missing_migrated_content.any?
34
+ puts "Some corrupted or missing content found, run 'foreman-maintain content migration-stats' for more information."
35
+ exit(-1)
36
+ end
37
+ end
33
38
  puts _("Content Migration completed successfully")
34
39
  end
35
40
  else
@@ -1,6 +1,6 @@
1
1
  namespace :katello do
2
2
  desc "Cancels all running Pulp 2 to 3 migration tasks."
3
- task :pulp3_migration_abort => ["environment", "disable_dynflow"] do
3
+ task :pulp3_migration_abort => ["dynflow:client"] do
4
4
  migration_tasks = ForemanTasks::Task::DynflowTask.where(:label => "Actions::Pulp3::ContentMigration").where.not(:state => ["stopped", "paused"])
5
5
  cancelled_tasks_count = 0
6
6
  migration_tasks.each do |task|
@@ -0,0 +1,16 @@
1
+ namespace :katello do
2
+ desc "Marks corrupted or missing content as approved to be ignored during the migration"
3
+ task :approve_corrupted_migration_content => ["dynflow:client", "check_ping"] do
4
+ Katello::Pulp3::Migration::CORRUPTABLE_CONTENT_TYPES.each do |type|
5
+ type.missing_migrated_content.update_all(:ignore_missing_from_migration => true)
6
+ end
7
+ puts "Any missing or corrupt content will be ignored on migration to Pulp 3. This can be undone with 'foreman-rake katello:unapprove_corrupted_migration_content'"
8
+ end
9
+
10
+ task :unapprove_corrupted_migration_content => ["dynflow:client", "check_ping"] do
11
+ Katello::Pulp3::Migration::CORRUPTABLE_CONTENT_TYPES.each do |type|
12
+ type.ignored_missing_migrated_content.update_all(:ignore_missing_from_migration => false)
13
+ end
14
+ puts "Resetting approval on any corrupted or missing content, you may want to re-run the 'foreman-maintain content prepare' step to attempt re-migration."
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ namespace :katello do
2
+ desc "Reset the Pulp 2 -> Pulp 3 migration for content types that haven't been fully switched over"
3
+ task :pulp3_migration_reset => ["dynflow:client", "check_ping"] do
4
+ puts "Starting Content Migration Reset."
5
+ SmartProxy.pulp_primary.refresh
6
+
7
+ task = ForemanTasks.async_task(Actions::Pulp3::ContentMigrationReset, SmartProxy.pulp_primary)
8
+
9
+ if ENV['wait'].nil? || ::Foreman::Cast.to_bool(ENV['wait'])
10
+ until !task.pending? || task.paused?
11
+ sleep(20)
12
+ task = ForemanTasks::Task.find(task.id)
13
+ end
14
+
15
+ if task.result == 'warning' || task.result == 'pending'
16
+ msg = _("Content Migration Reset failed, You will want to investigate: https://#{Socket.gethostname}/foreman_tasks/tasks/#{task.id}\n")
17
+ $stderr.print(msg)
18
+ fail ForemanTasks::TaskError, task
19
+ else
20
+ puts _("Content Migration Reset completed successfully")
21
+ end
22
+ else
23
+ puts "Content Migration Reset started, you may monitor it at: https://#{Socket.gethostname}/foreman_tasks/tasks/#{task.id}"
24
+ end
25
+ end
26
+ end
@@ -23,7 +23,7 @@ namespace :katello do
23
23
  hours = (migration_minutes / 60) % 60
24
24
  minutes = migration_minutes % 60
25
25
 
26
- puts
26
+ puts "============Migration Summary================"
27
27
  puts "Migrated/Total RPMs: #{migrated_rpm_count}/#{::Katello::Rpm.count}"
28
28
  puts "Migrated/Total errata: #{migrated_erratum_count}/#{::Katello::RepositoryErratum.count}"
29
29
  puts "Migrated/Total repositories: #{migrated_repo_count}/#{migratable_repo_count}"
@@ -34,8 +34,41 @@ namespace :katello do
34
34
  else
35
35
  puts "Estimated migration time based on yum content: fewer than 5 minutes"
36
36
  end
37
+
37
38
  puts
38
- puts "\e[33mNote:\e[0m ensure there is sufficient storage space for /var/lib/pulp/published to double in size before starting the migration process."
39
+ puts "\e[33mNote:\e[0m ensure there is sufficient storage space for /var/lib/pulp/published to triple in size before starting the migration process."
39
40
  puts "Check the size of /var/lib/pulp/published with 'du -sh /var/lib/pulp/published/'"
41
+
42
+ displayed_warning = false
43
+ found_missing = false
44
+ path = Dir.mktmpdir('unmigratable_content-')
45
+ Katello::Pulp3::Migration::CORRUPTABLE_CONTENT_TYPES.each do |type|
46
+ if type.missing_migrated_content.any?
47
+ unless displayed_warning
48
+ displayed_warning = true
49
+ puts
50
+ puts "============Missing/Corrupted Content Summary================"
51
+ puts "WARNING: MISSING OR CORRUPTED CONTENT DETECTED"
52
+ end
53
+
54
+ found_missing = true
55
+ name = type.name.demodulize
56
+ puts "Corrupted or Missing #{name}: #{type.missing_migrated_content.count}/#{type.count}"
57
+
58
+ File.open(File.join(path, name), 'w') do |file|
59
+ text = type.missing_migrated_content.map(&:filename).join("\n") + "\n"
60
+ file.write(text)
61
+ end
62
+ end
63
+ end
64
+
65
+ if found_missing
66
+ puts "Corrupted or missing content has been detected, you can examine the list of content in #{path} and take action by either:"
67
+ puts "1. Performing a 'Verify Checksum' sync under Advanced Sync Options, let it complete, and re-running the migration"
68
+ puts "2. Deleting/disabling the affected repositories and running orphan cleanup (foreman-rake katello:delete_orphaned_content) and re-running the migration"
69
+ puts "3. Manually correcting files on the filesystem in /var/lib/pulp/content/ and re-running the migration"
70
+ puts "4. Mark currently corrupted or missing content as skipped (foreman-rake katello:approve_corrupted_migration_content). This will skip migration of missing or corrupted content."
71
+ puts
72
+ end
40
73
  end
41
74
  end
@@ -1,9 +1,7 @@
1
1
  require File.expand_path("../engine", File.dirname(__FILE__))
2
- load "#{Katello::Engine.root}/lib/katello/tasks/common.rake"
3
-
4
2
  namespace :katello do
5
3
  desc "Runs a post Pulp3 migration check for supported content types."
6
- task :pulp3_post_migration_check => [:environment, :disable_dynflow] do
4
+ task :pulp3_post_migration_check => ["dynflow:client"] do
7
5
  User.current = User.anonymous_admin
8
6
  repository_types = Katello::Pulp3::Migration.repository_types_for_migration
9
7
 
@@ -1,4 +1,7 @@
1
1
  load "#{Rails.root}/lib/tasks/reports.rake"
2
2
 
3
3
  #Katello reports can generate a foreman task, so mark the task as a dynflow client
4
- ["reports:daily", "reports:weekly", "reports:monthly"].each { |task| Rake::Task[task].enhance ["dynflow:client"] }
4
+ ["reports:daily", "reports:weekly", "reports:monthly"].each do |task|
5
+ Rake::Task[task].clear
6
+ Rake::Task[task].enhance ["dynflow:client"]
7
+ end
@@ -1,12 +1,10 @@
1
- load "#{Katello::Engine.root}/lib/katello/tasks/common.rake"
2
-
3
1
  namespace :katello do
4
2
  def commit?
5
3
  ENV['COMMIT'] == 'true' || ENV['FOREMAN_UPGRADE'] == '1'
6
4
  end
7
5
 
8
6
  desc "Check for repositories that have not been published since their last sync, and republish if they have."
9
- task :publish_unpublished_repositories => ["environment", "disable_dynflow", "check_ping"] do
7
+ task :publish_unpublished_repositories => ["dynflow:client", "check_ping"] do
10
8
  needing_publish = []
11
9
  Organization.find_each do |org|
12
10
  if org.default_content_view && !org.default_content_view.versions.empty?
@@ -27,7 +25,7 @@ namespace :katello do
27
25
  end
28
26
 
29
27
  desc "Regnerate metadata for all repositories. Specify CONTENT_VIEW=name and LIFECYCLE_ENVIRONMENT=name to narrow repositories."
30
- task :regenerate_repo_metadata => ["environment", "disable_dynflow", "check_ping"] do
28
+ task :regenerate_repo_metadata => ["dynflow:client", "check_ping"] do
31
29
  User.current = User.anonymous_api_admin
32
30
  repos = lookup_repositories
33
31
 
@@ -40,7 +38,7 @@ namespace :katello do
40
38
  end
41
39
 
42
40
  desc "Refresh repository metadata for all repositories. Specify CONTENT_VIEW=name and LIFECYCLE_ENVIRONMENT=name to narrow repositories."
43
- task :refresh_pulp_repo_details => ["environment", "disable_dynflow", "check_ping"] do
41
+ task :refresh_pulp_repo_details => ["dynflow:client", "check_ping"] do
44
42
  User.current = User.anonymous_api_admin
45
43
  repos = lookup_repositories
46
44
 
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "3.18.1.1".freeze
2
+ VERSION = "3.18.2".freeze
3
3
  end
@@ -1,6 +1,7 @@
1
1
  import React, { Component } from 'react';
2
2
  import Downshift from 'downshift';
3
3
  import PropTypes from 'prop-types';
4
+ import { translate as __ } from 'foremanReact/common/I18n';
4
5
 
5
6
  import TypeAheadSearch from './pf3Search/TypeAheadSearch';
6
7
  // eslint-disable-next-line import/no-named-default
@@ -101,7 +102,7 @@ TypeAhead.propTypes = {
101
102
  };
102
103
 
103
104
  TypeAhead.defaultProps = {
104
- actionText: 'Search',
105
+ actionText: __('Search'),
105
106
  initialInputValue: '',
106
107
  patternfly4: false,
107
108
  };
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { InputGroup, Button, Icon } from 'patternfly-react';
3
3
  import PropTypes from 'prop-types';
4
+ import { translate as __ } from 'foremanReact/common/I18n';
4
5
 
5
6
  import TypeAheadInput from './TypeAheadInput';
6
7
  import TypeAheadItems from './TypeAheadItems';
@@ -46,7 +47,7 @@ TypeAheadSearch.propTypes = {
46
47
  };
47
48
 
48
49
  TypeAheadSearch.defaultProps = {
49
- actionText: 'Search',
50
+ actionText: __('Search'),
50
51
  };
51
52
 
52
53
  export default TypeAheadSearch;
@@ -51,8 +51,11 @@ class ManageManifestModal extends Component {
51
51
  showDeleteManifestModal = () =>
52
52
  this.props.setModalOpen({ id: DELETE_MANIFEST_MODAL_ID });
53
53
 
54
- hideDeleteManifestModal = () =>
55
- this.props.setModalClosed({ id: DELETE_MANIFEST_MODAL_ID });
54
+ hideDeleteManifestModal = () => {
55
+ if (this.props.deleteManifestModalExists) {
56
+ this.props.setModalClosed({ id: DELETE_MANIFEST_MODAL_ID });
57
+ }
58
+ };
56
59
 
57
60
  updateRepositoryUrl = (event) => {
58
61
  this.setState({ redhat_repository_url: event.target.value });
@@ -326,6 +329,7 @@ ManageManifestModal.propTypes = {
326
329
  canImportManifest: PropTypes.bool,
327
330
  canDeleteManifest: PropTypes.bool,
328
331
  isManifestImported: PropTypes.bool,
332
+ deleteManifestModalExists: PropTypes.bool,
329
333
  canEditOrganizations: PropTypes.bool,
330
334
  disableManifestActions: PropTypes.bool,
331
335
  disabledReason: PropTypes.string,
@@ -351,6 +355,7 @@ ManageManifestModal.defaultProps = {
351
355
  canImportManifest: false,
352
356
  canDeleteManifest: false,
353
357
  isManifestImported: false,
358
+ deleteManifestModalExists: false,
354
359
  canEditOrganizations: false,
355
360
  simpleContentAccess: false,
356
361
  simpleContentAccessEligible: undefined,
@@ -20,6 +20,7 @@ const mapStateToProps = state => ({
20
20
  simpleContentAccess: selectSimpleContentAccessEnabled(state),
21
21
  isManifestImported: selectIsManifestImported(state),
22
22
  modalOpenState: state.foremanModals.ManageManifestModal,
23
+ deleteManifestModalExists: !!state.foremanModals.deleteManifestModal,
23
24
  manifestActionStarted: selectManifestActionStarted(state),
24
25
  simpleContentAccessEligible: selectSimpleContentAccessEligible(state),
25
26
  });
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katello
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.18.1.1
4
+ version: 3.18.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - N/A
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-17 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -87,6 +87,9 @@ dependencies:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: 0.14.1
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '4.0'
90
93
  type: :runtime
91
94
  prerelease: false
92
95
  version_requirements: !ruby/object:Gem::Requirement
@@ -94,6 +97,9 @@ dependencies:
94
97
  - - ">="
95
98
  - !ruby/object:Gem::Version
96
99
  version: 0.14.1
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '4.0'
97
103
  - !ruby/object:Gem::Dependency
98
104
  name: foreman_remote_execution
99
105
  requirement: !ruby/object:Gem::Requirement
@@ -360,20 +366,20 @@ dependencies:
360
366
  requirements:
361
367
  - - ">="
362
368
  - !ruby/object:Gem::Version
363
- version: 3.6.2
369
+ version: 3.9.0
364
370
  - - "<"
365
371
  - !ruby/object:Gem::Version
366
- version: 3.8.0
372
+ version: 3.10.0
367
373
  type: :runtime
368
374
  prerelease: false
369
375
  version_requirements: !ruby/object:Gem::Requirement
370
376
  requirements:
371
377
  - - ">="
372
378
  - !ruby/object:Gem::Version
373
- version: 3.6.2
379
+ version: 3.9.0
374
380
  - - "<"
375
381
  - !ruby/object:Gem::Version
376
- version: 3.8.0
382
+ version: 3.10.0
377
383
  - !ruby/object:Gem::Dependency
378
384
  name: pulp_2to3_migration_client
379
385
  requirement: !ruby/object:Gem::Requirement
@@ -1066,6 +1072,7 @@ files:
1066
1072
  - app/lib/actions/pulp3/content_guard/refresh_all_distributions.rb
1067
1073
  - app/lib/actions/pulp3/content_migration.rb
1068
1074
  - app/lib/actions/pulp3/content_migration_presenter.rb
1075
+ - app/lib/actions/pulp3/content_migration_reset.rb
1069
1076
  - app/lib/actions/pulp3/content_view/delete_repository_references.rb
1070
1077
  - app/lib/actions/pulp3/content_view_version/create_exporter.rb
1071
1078
  - app/lib/actions/pulp3/content_view_version/create_importer.rb
@@ -2134,6 +2141,7 @@ files:
2134
2141
  - db/migrate/20201012192035_add_metadata_to_katello_content_view_version_export_history.rb
2135
2142
  - db/migrate/20201021150008_add_import_only_to_katello_content_view.rb
2136
2143
  - db/migrate/20201119211133_pulp3_migration_progress.rb
2144
+ - db/migrate/20210201165835_add_migration_missing_content.rb
2137
2145
  - db/seeds.d/101-locations.rb
2138
2146
  - db/seeds.d/102-organizations.rb
2139
2147
  - db/seeds.d/104-proxy.rb
@@ -4479,7 +4487,6 @@ files:
4479
4487
  - lib/katello/tasks/clean_backend_objects.rake
4480
4488
  - lib/katello/tasks/clean_old_file_repos.rake
4481
4489
  - lib/katello/tasks/clean_published_repo_directories.rake
4482
- - lib/katello/tasks/common.rake
4483
4490
  - lib/katello/tasks/delete_orphaned_content.rake
4484
4491
  - lib/katello/tasks/import_applicability.rake
4485
4492
  - lib/katello/tasks/import_subscriptions.rake
@@ -4488,6 +4495,8 @@ files:
4488
4495
  - lib/katello/tasks/pulp3_content_switchover.rake
4489
4496
  - lib/katello/tasks/pulp3_migration.rake
4490
4497
  - lib/katello/tasks/pulp3_migration_abort.rake
4498
+ - lib/katello/tasks/pulp3_migration_approve_corrupted.rake
4499
+ - lib/katello/tasks/pulp3_migration_reset.rake
4491
4500
  - lib/katello/tasks/pulp3_migration_stats.rake
4492
4501
  - lib/katello/tasks/pulp3_post_migration_check.rake
4493
4502
  - lib/katello/tasks/receptor/extract_orgs.rake
@@ -5068,7 +5077,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
5068
5077
  - !ruby/object:Gem::Version
5069
5078
  version: '0'
5070
5079
  requirements: []
5071
- rubygems_version: 3.0.3
5080
+ rubygems_version: 3.1.4
5072
5081
  signing_key:
5073
5082
  specification_version: 4
5074
5083
  summary: Content and Subscription Management plugin for Foreman
@@ -1,7 +0,0 @@
1
- namespace :katello do
2
- task :disable_dynflow do
3
- #Ensures that we run as a dynflow 'client'
4
- ::Rails.application.dynflow.initialize!
5
- ForemanTasks.dynflow.config.remote = true
6
- end
7
- end