katello 4.9.0.rc2 → 4.9.1

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/capsule_content_controller.rb +1 -1
  3. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +1 -4
  4. data/app/controllers/katello/api/v2/content_views_controller.rb +2 -1
  5. data/app/controllers/katello/api/v2/organizations_controller.rb +7 -4
  6. data/app/controllers/katello/api/v2/repositories_controller.rb +4 -4
  7. data/app/lib/actions/katello/content_view/promote_to_environment.rb +1 -1
  8. data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +2 -1
  9. data/app/lib/actions/katello/content_view_version/republish_repositories.rb +1 -1
  10. data/app/lib/actions/katello/orphan_cleanup/remove_orphaned_content_units.rb +22 -0
  11. data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +4 -15
  12. data/app/lib/actions/katello/repository/clone_to_version.rb +1 -1
  13. data/app/lib/actions/katello/repository/multi_clone_to_version.rb +1 -1
  14. data/app/lib/actions/katello/repository_set/enable_repository.rb +3 -1
  15. data/app/lib/katello/resources/cdn/katello_cdn.rb +8 -4
  16. data/app/models/katello/concerns/pulp_database_unit.rb +2 -2
  17. data/app/models/katello/content_view.rb +7 -0
  18. data/app/models/katello/repository.rb +0 -1
  19. data/app/models/katello/root_repository.rb +1 -1
  20. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +10 -6
  21. data/app/services/katello/pulp3/repository/docker.rb +1 -1
  22. data/app/services/katello/pulp3/repository.rb +4 -2
  23. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +12 -11
  24. data/app/views/katello/api/v2/content_facet/base.json.rabl +9 -10
  25. data/app/views/katello/hosts/_errata_counts.html.erb +13 -0
  26. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -1
  27. data/lib/katello/plugin.rb +1 -1
  28. data/lib/katello/tasks/upgrades/4.9/update_custom_products_enablement.rake +4 -2
  29. data/lib/katello/version.rb +1 -1
  30. data/webpack/components/RoutedTabs/index.js +1 -0
  31. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +2 -2
  32. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +1 -0
  33. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +1 -1
  34. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +3 -3
  35. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +3 -3
  36. data/webpack/redux/actions/RedHatRepositories/helpers.js +3 -5
  37. data/webpack/scenes/Content/Details/ContentRepositories.js +1 -1
  38. data/webpack/scenes/Content/Table/ContentTable.js +1 -1
  39. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +1 -14
  40. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +0 -4
  41. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentEnvironments.js +1 -1
  42. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +1 -1
  43. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +41 -32
  44. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +32 -26
  45. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +10 -2
  46. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +10 -2
  47. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +10 -2
  48. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +10 -2
  49. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +10 -2
  50. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +10 -2
  51. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +10 -2
  52. data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +2 -2
  53. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +3 -3
  54. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompare.js +1 -0
  55. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +1 -1
  56. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +1 -1
  57. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +1 -0
  58. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +7 -0
  59. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +28 -4
  60. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetails.fixtures.json +1 -0
  61. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +13 -2
  62. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +4 -1
  63. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +33 -10
  64. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +0 -2
  65. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +1 -1
  66. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +7 -2
  67. data/webpack/scenes/Subscriptions/Manifest/DeleteManifestModalText.js +38 -21
  68. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +19 -4
  69. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +1 -0
  70. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +1 -0
  71. metadata +10 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d870b3e8317aae2cc5675bdebddc2541257c470714209df06d79135ebc751643
4
- data.tar.gz: e19a405204719de4c723e6b7a0c4612e40983698df33562f74e28e0eb2fb83f6
3
+ metadata.gz: 2725e254c69e3a52955ec2e85605097ad13751770b46de79a14bb6153451e5b7
4
+ data.tar.gz: a59ffe3ac6b743b36ac2207a44c333dc504975b54d23efb2d9d04aa13741c575
5
5
  SHA512:
6
- metadata.gz: ee637b366b689e48fdbde217e2255b683c35095ffcbc3ad1234b9446ba7757be992a5b33a61650dc1fc5ac25ff4474185e2e58772991475c0f6a78627bbd70c4
7
- data.tar.gz: 6eac40d9467c4365c19c82ecdce5d53f42418f511c7e35e12f987c5e58b432c3919f0ff0a2c1d581084e14e8f1ca29147f298a505331ec1d6907a6f132b4e209
6
+ metadata.gz: 78951d090b4e05283c65ebb11d2c18475ffc2afa26cb2c1f981a425f18cd85bf9a82c84c06e33dc8c05348a1b9f8af845adb482fd0075116f75da85c847e5d31
7
+ data.tar.gz: 5c2acdd95ed253669357a68142f42c8b09ba5b34603bfa9acf1e029cdc32c9696d1edb40a8e616e032747c6771110ca54bd048b4108a342d755b1d000270766c
@@ -87,7 +87,7 @@ module Katello
87
87
  end
88
88
  end
89
89
 
90
- api :POST, '/capsules/:id/reclaim_space', N_('Reclaim space from all On Demand repositories on a smart proxy')
90
+ api :POST, '/capsules/:id/content/reclaim_space', N_('Reclaim space from all On Demand repositories on a smart proxy')
91
91
  param :id, :number, :required => true, :desc => N_('Id of the smart proxy')
92
92
  def reclaim_space
93
93
  find_capsule(true)
@@ -78,11 +78,8 @@ module Katello
78
78
 
79
79
  api :PUT, "/content_view_versions/:id/republish_repositories", N_("Forces a republish of the version's repositories' metadata")
80
80
  param :id, :number, :desc => N_("Content view version identifier"), :required => true
81
- param :force, :bool, :desc => N_("Force metadata regeneration to proceed. Dangerous when repositories use the 'Complete Mirroring' mirroring policy"), :required => true
81
+ param :force, :bool, :desc => N_("Force metadata regeneration to proceed. (Deprecated)"), deprecated: true
82
82
  def republish_repositories
83
- unless ::Foreman::Cast.to_bool(params[:force])
84
- fail HttpErrors::BadRequest, _("Metadata republishing must be forced because it is a dangerous operation.")
85
- end
86
83
  task = async_task(::Actions::Katello::ContentViewVersion::RepublishRepositories, @content_view_version)
87
84
  respond_for_async :resource => task
88
85
  end
@@ -258,7 +258,8 @@ module Katello
258
258
  fail HttpErrors::BadRequest, _("Both major and minor parameters have to be used to override a CV version")
259
259
  end
260
260
 
261
- if (::Foreman::Cast.to_bool(params[:publish_only_if_needed]) && !@content_view.needs_publish?)
261
+ cv_needs_publish = @content_view.needs_publish?
262
+ if (::Foreman::Cast.to_bool(params[:publish_only_if_needed]) && !cv_needs_publish.nil? && !cv_needs_publish)
262
263
  fail HttpErrors::BadRequest, _("Content view does not need a publish since there are no audited changes since the last publish." \
263
264
  " Pass check_needs_publish parameter as false if you don't want to check if content view needs a publish.")
264
265
  end
@@ -180,11 +180,14 @@ module Katello
180
180
  protected
181
181
 
182
182
  def action_permission
183
- if %w(download_debug_certificate redhat_provider repo_discover cdn_configuration
184
- cancel_repo_discover).include?(params[:action])
185
- :edit
186
- elsif params[:action] == "releases"
183
+ if params[:action] == "releases"
184
+ :view
185
+ elsif params[:action] == "download_debug_certificate" &&
186
+ Organization.find(params[:id]).authorized?(:export_content)
187
187
  :view
188
+ elsif %w(download_debug_certificate redhat_provider repo_discover cdn_configuration
189
+ cancel_repo_discover).include?(params[:action])
190
+ :edit
188
191
  else
189
192
  super
190
193
  end
@@ -323,12 +323,12 @@ module Katello
323
323
  render :json => repo_types.values
324
324
  end
325
325
 
326
- api :PUT, "/repositories/:id/republish", N_("Forces a republish of the specified repository, regenerating metadata and symlinks on the filesystem.")
326
+ api :PUT, "/repositories/:id/republish", N_("Forces a republish of the specified repository, regenerating metadata and symlinks on the filesystem. Not allowed for repositories with the 'Complete Mirroring' mirroring policy.")
327
327
  param :id, :number, :desc => N_("Repository identifier"), :required => true
328
- param :force, :bool, :desc => N_("Force metadata regeneration to proceed. Dangerous when repositories use the 'Complete Mirroring' mirroring policy."), :required => true
328
+ param :force, :bool, :desc => N_("Force metadata regeneration to proceed. (Deprecated)"), deprecated: true
329
329
  def republish
330
- unless ::Foreman::Cast.to_bool(params[:force])
331
- fail HttpErrors::BadRequest, _('Metadata republishing must be forced because it is a dangerous operation.')
330
+ if @repository.mirroring_policy == Katello::RootRepository::MIRRORING_POLICY_COMPLETE
331
+ fail HttpErrors::BadRequest, _("Metadata republishing is not allowed on repositories with the 'Complete Mirroring' mirroring policy.")
332
332
  end
333
333
  task = async_task(::Actions::Katello::Repository::MetadataGenerate, @repository)
334
334
  respond_for_async :resource => task
@@ -55,7 +55,7 @@ module Actions
55
55
 
56
56
  def trigger_capsule_sync(_execution_plan)
57
57
  environment = ::Katello::KTEnvironment.find(input[:environment_id])
58
- if !input[:incremental_update] && sync_proxies?(environment)
58
+ if !input[:incremental_update] && sync_proxies?(environment) && Setting[:foreman_proxy_content_auto_sync]
59
59
  ForemanTasks.async_task(ContentView::CapsuleSync,
60
60
  ::Katello::ContentView.find(input[:content_view_id]),
61
61
  environment)
@@ -15,7 +15,8 @@ module Actions
15
15
  helper.creatable.each do |root|
16
16
  plan_action(::Actions::Katello::RepositorySet::EnableRepository,
17
17
  root[:product], root[:content], root[:substitutions],
18
- override_url: root[:override_url])
18
+ override_url: root[:override_url],
19
+ override_arch: root[:override_arch])
19
20
  end
20
21
  helper.updatable.each do |root|
21
22
  plan_action(::Actions::Katello::Repository::Update, root[:repository], root[:options])
@@ -5,7 +5,7 @@ module Actions
5
5
  def plan(content_view_version)
6
6
  action_subject(content_view_version.content_view)
7
7
  plan_self(:version_id => content_view_version.id)
8
- plan_action(::Actions::Katello::Repository::BulkMetadataGenerate, content_view_version.repositories)
8
+ plan_action(::Actions::Katello::Repository::BulkMetadataGenerate, content_view_version.repositories.joins(:root).where.not(root: { mirroring_policy: ::Katello::RootRepository::MIRRORING_POLICY_COMPLETE }))
9
9
  end
10
10
 
11
11
  def run
@@ -0,0 +1,22 @@
1
+ module Actions
2
+ module Katello
3
+ module OrphanCleanup
4
+ class RemoveOrphanedContentUnits < Actions::Base
5
+ def run
6
+ models = []
7
+
8
+ ::Katello::RepositoryTypeManager.enabled_repository_types.each_value do |repo_type|
9
+ models << repo_type.content_types_to_index
10
+ end
11
+ models.flatten.each do |content_type|
12
+ content_type.model_class.orphaned.destroy_all
13
+ end
14
+ end
15
+
16
+ def rescue_strategy
17
+ Dynflow::Action::Rescue::Skip
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -7,27 +7,16 @@ module Actions
7
7
  end
8
8
  def plan(proxy)
9
9
  sequence do
10
+ if proxy.pulp_primary?
11
+ ::Katello::RootRepository.orphaned.destroy_all
12
+ plan_action(RemoveOrphanedContentUnits)
13
+ end
10
14
  if proxy.pulp3_enabled?
11
15
  plan_action(
12
16
  Actions::Pulp3::Orchestration::OrphanCleanup::RemoveOrphans,
13
17
  proxy)
14
18
  end
15
- plan_self
16
- end
17
- end
18
-
19
- def run
20
- models = []
21
- ::Katello::RepositoryTypeManager.enabled_repository_types.each_value do |repo_type|
22
- indexable_types = repo_type.content_types_to_index
23
- models += indexable_types&.map(&:model_class)
24
- models.select! { |model| model.many_repository_associations }
25
- end
26
- models.each do |model|
27
- 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
28
19
  end
29
-
30
- ::Katello::RootRepository.orphaned.destroy_all
31
20
  end
32
21
  end
33
22
  end
@@ -23,7 +23,7 @@ module Actions
23
23
  rpm_filenames: rpm_filenames,
24
24
  copy_contents: copy_contents,
25
25
  solve_dependencies: content_view.solve_dependencies,
26
- metadata_generate: !incremental)
26
+ generate_metadata: true)
27
27
  end
28
28
  end
29
29
 
@@ -10,7 +10,7 @@ module Actions
10
10
  plan_action(::Actions::Katello::Repository::MultiCloneContents, extended_repo_map,
11
11
  copy_contents: true,
12
12
  solve_dependencies: true,
13
- metadata_generate: !incremental)
13
+ generate_metadata: true)
14
14
  end
15
15
  end
16
16
 
@@ -6,7 +6,8 @@ module Actions
6
6
  _("Enable")
7
7
  end
8
8
 
9
- def plan(product, content, substitutions, override_url: nil)
9
+ def plan(product, content, substitutions, override_url: nil,
10
+ override_arch: nil)
10
11
  mapper = ::Katello::Candlepin::RepositoryMapper.new(product,
11
12
  content,
12
13
  substitutions)
@@ -15,6 +16,7 @@ module Actions
15
16
  fail ::Katello::Errors::ConflictException, _("The repository is already enabled")
16
17
  end
17
18
  repository = mapper.build_repository
19
+ repository.root.arch = override_arch if override_arch.present?
18
20
  if override_url
19
21
  repository.root.url = override_url
20
22
  repository.root.download_policy = ::Katello::RootRepository::DOWNLOAD_IMMEDIATE if URI(override_url).scheme == 'file'
@@ -11,10 +11,14 @@ module Katello
11
11
  super
12
12
  end
13
13
 
14
- def fetch_paths(content_path)
14
+ def fetch_repo_set(content_path)
15
15
  url = "/katello/api/v2/repository_sets?organization_id=#{organization['id']}&search=#{CGI.escape("path = #{content_path}")}"
16
16
  response = get(url)
17
- repo_set = JSON.parse(response)['results'].first
17
+ JSON.parse(response)['results'].first
18
+ end
19
+
20
+ def fetch_paths(content_path)
21
+ repo_set = fetch_repo_set(content_path)
18
22
 
19
23
  fail _("Upstream organization %s does not provide this content path") % @organization_label if repo_set.nil?
20
24
 
@@ -33,8 +37,8 @@ module Katello
33
37
  results = json_body['results']
34
38
 
35
39
  results.map do |repo|
36
- Katello::Content.substitute_content_path(arch: repo[:arch],
37
- releasever: repo[:minor],
40
+ Katello::Content.substitute_content_path(arch: repo['arch'],
41
+ releasever: repo['minor'],
38
42
  content_path: content_path)
39
43
  end
40
44
  end
@@ -169,9 +169,9 @@ module Katello
169
169
 
170
170
  def orphaned
171
171
  if many_repository_associations
172
- where.not(:id => repository_association_class.where(:repository_id => ::Katello::Repository.all).select(unit_id_field))
172
+ where.not(:id => repository_association_class.select(unit_id_field))
173
173
  else
174
- where.not(:repository_id => ::Katello::Repository.all)
174
+ where.not(:repository_id => ::Katello::Repository.select(:id))
175
175
  end
176
176
  end
177
177
 
@@ -799,6 +799,7 @@ module Katello
799
799
  # True:
800
800
  # a) When content/repo/filter change audit records exist
801
801
  # b) CV hasn't ever been published
802
+ # c) CV dependency_solving != latest_version.applied_filters.dependency_solving
802
803
  # nil:
803
804
  # a) When CV version creation audit is missing(Indicating audit cleanup)
804
805
  # b) Version doesn't have audited_filters set indicating
@@ -815,6 +816,8 @@ module Katello
815
816
  # return true if the audit records clearly show we have unpublished changes
816
817
  return true if (audited_cv_repositories_since_last_publish.present? || audited_cv_repository_changed.present? ||
817
818
  audited_cv_filters_changed.present? || audited_cv_filter_rules_changed.present?)
819
+ # return true if the dependency solving changed for CV between last publish and now
820
+ return true if dependency_solving_changed?
818
821
  # if we didn't return `true` already, either the audit records show that we don't need to publish, or we may
819
822
  # have insufficient data to make the determination (either audits were cleaned, or never got created at all).
820
823
  # first, check for the `create` audit record; its absence indicates that audits were cleaned some time after
@@ -831,6 +834,10 @@ module Katello
831
834
  latest_version_object.applied_filters.nil? ? nil : false
832
835
  end
833
836
 
837
+ def dependency_solving_changed?
838
+ latest_version_object.applied_filters && solve_dependencies != latest_version_object.applied_filters['dependency_solving']
839
+ end
840
+
834
841
  def filtered?
835
842
  filters.present?
836
843
  end
@@ -935,7 +935,6 @@ module Katello
935
935
  repository_type.content_types_to_index.each do |type|
936
936
  Katello::Logging.time("CONTENT_INDEX", data: {type: type.model_class}) do
937
937
  Katello::ContentUnitIndexer.new(content_type: type, repository: self, optimized: !full_index).import_all
938
- type.model_class.orphaned.destroy_all
939
938
  end
940
939
  end
941
940
  repository_type.index_additional_data_proc&.call(self)
@@ -130,7 +130,7 @@ module Katello
130
130
  where(:http_proxy_policy => RootRepository::USE_SELECTED_HTTP_PROXY).
131
131
  where(:http_proxy_id => http_proxy_id)
132
132
  }
133
- scope :orphaned, -> { where.not(id: Katello::Repository.pluck(:root_id).uniq) }
133
+ scope :orphaned, -> { where.not(id: Katello::Repository.select(:root_id)) }
134
134
  scope :redhat, -> { joins(:provider).merge(Katello::Provider.redhat) }
135
135
  scope :custom, -> { where.not(:id => self.redhat) }
136
136
  delegate :redhat?, :provider, :organization, to: :product
@@ -29,10 +29,12 @@ module Katello
29
29
 
30
30
  root = product.root_repositories.find do |r|
31
31
  if repo.content&.id && repo.redhat
32
- r.content.cp_content_id == repo.content.id &&
32
+ repo_exists = r.content.cp_content_id == repo.content.id &&
33
33
  r.arch == repo.arch &&
34
34
  r.major == repo.major &&
35
35
  r.minor == repo.minor
36
+
37
+ repo_exists || r.label == repo.label
36
38
  else
37
39
  r.label == repo.label
38
40
  end
@@ -46,11 +48,13 @@ module Katello
46
48
  basearch: repo.arch,
47
49
  releasever: repo.minor
48
50
  }
49
- creatable << { product: product,
50
- content: product_content,
51
- substitutions: substitutions,
52
- override_url: fetch_feed_url(repo)
53
- }
51
+ creatable << {
52
+ product: product,
53
+ content: product_content,
54
+ substitutions: substitutions,
55
+ override_url: fetch_feed_url(repo),
56
+ override_arch: repo.arch
57
+ }
54
58
  else
55
59
  creatable << { repository: product.add_repo(create_repo_params(repo, product)) }
56
60
  end
@@ -70,7 +70,7 @@ module Katello
70
70
  rescue api.client_module::ApiError => e
71
71
  if e.message.include? 'Could not find the following content units'
72
72
  raise ::Katello::Errors::Pulp3Error, "Content units that do not exist in Pulp were requested to be copied."\
73
- " Please run a complete sync on the following repository: #{repository_reference.root_repository.name}. Original error: #{e.message}"
73
+ " Please run `foreman-rake katello:delete_orphaned_content` to fix the following repository: #{repository_reference.root_repository.name}. Original error: #{e.message}"
74
74
  else
75
75
  raise e
76
76
  end
@@ -39,6 +39,7 @@ module Katello
39
39
 
40
40
  def self.api(smart_proxy, repository_type_label)
41
41
  repo_type = RepositoryTypeManager.enabled_repository_types[repository_type_label]
42
+ fail _("%s content type is not enabled." % repository_type_label) unless repo_type
42
43
  repo_type.pulp3_api(smart_proxy)
43
44
  end
44
45
 
@@ -496,7 +497,8 @@ module Katello
496
497
  rescue api.client_module::ApiError => e
497
498
  if e.message.include? 'Could not find the following content units'
498
499
  raise ::Katello::Errors::Pulp3Error, "Content units that do not exist in Pulp were requested to be copied."\
499
- " Please run a complete sync on the following repository: #{repository_reference.root_repository.name}. Original error: #{e.message}"
500
+ " Please run `foreman-rake katello:delete_orphaned_content` to fix the following repository:"\
501
+ " #{repository_reference.root_repository.name}. Original error: #{e.message}"
500
502
  else
501
503
  raise e
502
504
  end
@@ -508,7 +510,7 @@ module Katello
508
510
  rescue api.client_module::ApiError => e
509
511
  if e.message.include? 'Could not find the following content units'
510
512
  raise ::Katello::Errors::Pulp3Error, "Content units that do not exist in Pulp were requested to be copied."\
511
- " Please run a complete sync on the following repository:"\
513
+ " Please run `foreman-rake katello:delete_orphaned_content` to fix the following repository:"\
512
514
  " #{::Katello::Pulp3::RepositoryReference.find_by(repository_href: repository_href).root_repository.name}. Original error: #{e.message}"
513
515
  else
514
516
  raise e
@@ -79,18 +79,19 @@ module Katello
79
79
  known_acss = smart_proxy.smart_proxy_alternate_content_sources
80
80
  known_acs_hrefs = known_acss.pluck(:alternate_content_source_href) if known_acss.present?
81
81
 
82
- file_acs_api = ::Katello::Pulp3::Repository.api(smart_proxy, 'file').alternate_content_source_api
83
- yum_acs_api = ::Katello::Pulp3::Repository.api(smart_proxy, 'yum').alternate_content_source_api
84
-
85
- orphan_file_acs_hrefs = file_acs_api.list.results.map(&:pulp_href) - known_acs_hrefs
86
- orphan_yum_acs_hrefs = yum_acs_api.list.results.map(&:pulp_href) - known_acs_hrefs
87
-
88
- orphan_file_acs_hrefs.each do |orphan_file_acs_href|
89
- tasks << file_acs_api.delete(orphan_file_acs_href)
82
+ if RepositoryTypeManager.enabled_repository_types['file']
83
+ file_acs_api = ::Katello::Pulp3::Repository.api(smart_proxy, 'file').alternate_content_source_api
84
+ orphan_file_acs_hrefs = file_acs_api.list.results.map(&:pulp_href) - known_acs_hrefs
85
+ orphan_file_acs_hrefs.each do |orphan_file_acs_href|
86
+ tasks << file_acs_api.delete(orphan_file_acs_href)
87
+ end
90
88
  end
91
-
92
- orphan_yum_acs_hrefs.each do |orphan_yum_acs_href|
93
- tasks << yum_acs_api.delete(orphan_yum_acs_href)
89
+ if RepositoryTypeManager.enabled_repository_types['yum']
90
+ yum_acs_api = ::Katello::Pulp3::Repository.api(smart_proxy, 'yum').alternate_content_source_api
91
+ orphan_yum_acs_hrefs = yum_acs_api.list.results.map(&:pulp_href) - known_acs_hrefs
92
+ orphan_yum_acs_hrefs.each do |orphan_yum_acs_href|
93
+ tasks << yum_acs_api.delete(orphan_yum_acs_href)
94
+ end
94
95
  end
95
96
  end
96
97
 
@@ -1,6 +1,4 @@
1
1
  attributes :id, :uuid
2
- attributes :content_view_id, :content_view_name
3
- attributes :lifecycle_environment_id, :lifecycle_environment_name
4
2
  attributes :content_source_id, :content_source_name
5
3
  attributes :kickstart_repository_id, :kickstart_repository_name
6
4
  attributes :errata_counts
@@ -10,6 +8,15 @@ attributes :applicable_rpm_count => :applicable_package_count
10
8
  attributes :upgradable_rpm_count => :upgradable_package_count
11
9
  attributes :applicable_module_stream_count, :upgradable_module_stream_count
12
10
 
11
+ child :content_view_environments => :content_view_environments do
12
+ node :content_view do |cve|
13
+ { id: cve.content_view.id, name: cve.content_view.name, composite: cve.content_view.composite }
14
+ end
15
+ node :lifecycle_environment do |cve|
16
+ { id: cve.lifecycle_environment.id, name: cve.lifecycle_environment.name }
17
+ end
18
+ end
19
+
13
20
  node :content_view do |content_facet|
14
21
  content_view = content_facet.single_content_view
15
22
  if content_view.present?
@@ -31,14 +38,6 @@ node :lifecycle_environment do |content_facet|
31
38
  end
32
39
  end
33
40
 
34
- child :content_views => :content_views do
35
- attributes :id, :name, :composite
36
- end
37
-
38
- child :lifecycle_environments => :lifecycle_environments do
39
- attributes :id, :name
40
- end
41
-
42
41
  child :content_source => :content_source do
43
42
  attributes :id, :name, :url
44
43
  end
@@ -1,4 +1,8 @@
1
+ <% if Setting["host_details_ui"] %>
2
+ <a href="/new/hosts/<%= host.name %>#/Content/errata">
3
+ <% else %>
1
4
  <a href="/content_hosts/<%= host.id %>/errata">
5
+ <% end %>
2
6
  <span class="aligned-errata-count">
3
7
  <span class="errata-count <%= counts[:security].to_i.positive? ? 'red' : 'black' %>">
4
8
  <span>
@@ -20,8 +24,13 @@
20
24
  </span>
21
25
  </span>
22
26
  </a>
27
+
23
28
  <% if !host.operatingsystem_name&.match(/Debian|Ubuntu/) %>
29
+ <% if Setting["host_details_ui"] %>
30
+ <a href="/new/hosts/<%= host.name %>#/Content/packages">
31
+ <% else %>
24
32
  <a href="/content_hosts/<%= host.id %>/packages/applicable">
33
+ <% end %>
25
34
  <span class="aligned-errata-count">
26
35
  <span class="errata-count <%= host.content_facet_attributes&.upgradable_rpm_count&.positive? ? 'green' : 'black' %>"
27
36
  <span>
@@ -33,7 +42,11 @@
33
42
  </a>
34
43
  <% end %>
35
44
  <% if host.operatingsystem_name&.match(/Debian|Ubuntu/) %>
45
+ <% if Setting["host_details_ui"] %>
46
+ <a href="/new/hosts/<%= host.name %>#/Content/packages">
47
+ <% else %>
36
48
  <a href="/content_hosts/<%= host.id %>/debs/applicable">
49
+ <% end %>
37
50
  <span class="aligned-errata-count">
38
51
  <span class="errata-count <%= host.content_facet_attributes&.upgradable_deb_count&.positive? ? 'green' : 'black' %>"
39
52
  <span>
@@ -18,7 +18,7 @@ angular.module('Bastion.repositories').factory('Repository',
18
18
  update: { method: 'PUT' },
19
19
  sync: { method: 'POST', params: { action: 'sync' } },
20
20
  verifyChecksum: { method: 'POST', params: { action: 'verify_checksum' }},
21
- republishMetadata: { method: 'PUT', params: { action: 'republish', force: true }},
21
+ republishMetadata: { method: 'PUT', params: { action: 'republish'}},
22
22
  reclaimSpace: { method: 'POST', params: { action: 'reclaim_space' }},
23
23
  removePackages: { method: 'PUT', params: { action: 'remove_packages'}},
24
24
  removeContent: { method: 'PUT', params: { action: 'remove_content'}},
@@ -748,7 +748,7 @@ Foreman::Plugin.register :katello do
748
748
  :attach_subscriptions, :view_host_collections,
749
749
  :view_organizations, :view_lifecycle_environments, :view_products,
750
750
  :view_locations, :view_domains, :view_architectures,
751
- :view_operatingsystems, :view_smart_proxies
751
+ :view_operatingsystems, :view_smart_proxies, :view_params
752
752
  ]
753
753
 
754
754
  role 'Content Importer', [
@@ -3,8 +3,10 @@ namespace :katello do
3
3
  namespace '4.9' do
4
4
  desc "Update custom products enablement"
5
5
  task :update_custom_products_enablement => ['environment'] do
6
- migrator = Katello::Util::DefaultEnablementMigrator.new
7
- migrator.execute!
6
+ if ::Katello::ProductContent.custom.where(enabled: true).exists?
7
+ migrator = Katello::Util::DefaultEnablementMigrator.new
8
+ migrator.execute!
9
+ end
8
10
  end
9
11
  end
10
12
  end
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "4.9.0.rc2".freeze
2
+ VERSION = "4.9.1".freeze
3
3
  end
@@ -23,6 +23,7 @@ const RoutedTabs = ({
23
23
  >
24
24
  {tabs.map(({ key, title }) => (
25
25
  <Tab
26
+ ouiaId={`routed-tabs-tab-${key}`}
26
27
  href={`#/${key}`}
27
28
  key={key}
28
29
  eventKey={key}
@@ -106,7 +106,7 @@ const HostContentViewDetails = ({
106
106
  <h3>{__('Content view')}</h3>
107
107
  </Flex>
108
108
  <Flex direction={{ default: 'row', sm: 'row' }} flexWrap={{ default: 'wrap' }}>
109
- <a style={{ fontSize: '14px' }} href={`/content_views/${contentView.id}`}>{`${contentView.name}`}</a>
109
+ <a style={{ fontSize: '14px' }} href={`/content_views/${contentView.id}`}>{contentView.name}</a>
110
110
  <Tooltip
111
111
  position="top"
112
112
  enableFlip
@@ -119,7 +119,7 @@ const HostContentViewDetails = ({
119
119
  }}
120
120
  />}
121
121
  >
122
- <Label isTruncated color="purple" href={`/lifecycle_environments/${lifecycleEnvironment.id}`}>{`${lifecycleEnvironment.name}`}</Label>
122
+ <Label isTruncated color="purple" href={`/lifecycle_environments/${lifecycleEnvironment.id}`}>{lifecycleEnvironment.name}</Label>
123
123
  </Tooltip>
124
124
  </Flex>
125
125
  </Flex>
@@ -24,6 +24,7 @@ const ContentTab = ({ location: { pathname } }) => {
24
24
  >
25
25
  {filteredTabs.map(({ key, title }) => (
26
26
  <Tab
27
+ ouiaId={`host-content-tabs-tab-${key}`}
27
28
  key={key}
28
29
  eventKey={key}
29
30
  title={<TabTitleText>{title}</TabTitleText>}
@@ -580,7 +580,7 @@ export const PackagesTab = () => {
580
580
  }
581
581
 
582
582
  return (
583
- <Tr key={`${id}`} ouiaId={`action-row-${id}`}>
583
+ <Tr key={id} ouiaId={`action-row-${id}`}>
584
584
  {showActions ? (
585
585
  <Td
586
586
  select={{
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`ActivationKeys renders 1`] = `
4
4
  <FormGroup
5
- fieldId="reg_katello_ak"
5
+ fieldId="activation_keys_field"
6
6
  helperText="From host group: "
7
7
  helperTextInvalid={
8
8
  <a
@@ -36,7 +36,7 @@ exports[`ActivationKeys renders 1`] = `
36
36
  favoritesLabel="Favorites"
37
37
  hasInlineFilter={false}
38
38
  hasPlaceholderStyle={false}
39
- id="reg_katello_ak"
39
+ id="activation_keys_field"
40
40
  inlineFilterPlaceholderText={null}
41
41
  inputAutoComplete="off"
42
42
  inputIdPrefix=""
@@ -58,7 +58,7 @@ exports[`ActivationKeys renders 1`] = `
58
58
  onSelect={[Function]}
59
59
  onToggle={[Function]}
60
60
  onTypeaheadInputChanged={null}
61
- ouiaId="reg-katello-ak"
61
+ ouiaId="activation-keys-field"
62
62
  ouiaSafe={true}
63
63
  placeholderText="No Activation keys to select"
64
64
  position="left"
@@ -45,7 +45,7 @@ const ActivationKeys = ({
45
45
  return (
46
46
  <FormGroup
47
47
  label={__('Activation Keys')}
48
- fieldId="reg_katello_ak"
48
+ fieldId="activation_keys_field"
49
49
  helperText={hostGroupActivationKeys && sprintf('From host group: %s', hostGroupActivationKeys)}
50
50
  helperTextInvalid={activationKeys?.length === 0 ? <a href="/activation_keys/new">{__('Create new activation key')}</a> : __('No Activation Keys selected')}
51
51
  validated={validateAKField(hostGroupId, pluginValues?.activationKeys, hostGroupActivationKeys)}
@@ -53,14 +53,14 @@ const ActivationKeys = ({
53
53
  isRequired
54
54
  >
55
55
  <Select
56
- ouiaId="reg-katello-ak"
56
+ ouiaId="activation-keys-field"
57
57
  selections={selectedKeys}
58
58
  variant={SelectVariant.typeaheadMulti}
59
59
  onToggle={() => setIsOpen(!isOpen)}
60
60
  onSelect={onSelect}
61
61
  onClear={() => updatePluginValues([])}
62
62
  isOpen={isOpen}
63
- id="reg_katello_ak"
63
+ id="activation_keys_field"
64
64
  className="without_select2"
65
65
  isDisabled={isLoading || activationKeys?.length === 0}
66
66
  placeholderText={activationKeys?.length === 0 ? __('No Activation keys to select') : ''}