katello 4.12.1 → 4.13.0

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 (245) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/locale/bn/katello.js +3365 -3350
  3. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +3136 -3121
  4. data/app/assets/javascripts/katello/locale/ca/katello.js +3588 -3576
  5. data/app/assets/javascripts/katello/locale/cs/katello.js +3499 -3487
  6. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +4186 -4186
  7. data/app/assets/javascripts/katello/locale/de/katello.js +5553 -5562
  8. data/app/assets/javascripts/katello/locale/de_AT/katello.js +3008 -2993
  9. data/app/assets/javascripts/katello/locale/de_DE/katello.js +3066 -3051
  10. data/app/assets/javascripts/katello/locale/el/katello.js +3376 -3370
  11. data/app/assets/javascripts/katello/locale/en/katello.js +3008 -2993
  12. data/app/assets/javascripts/katello/locale/en_GB/katello.js +3076 -3073
  13. data/app/assets/javascripts/katello/locale/en_US/katello.js +3008 -2993
  14. data/app/assets/javascripts/katello/locale/es/katello.js +5366 -5372
  15. data/app/assets/javascripts/katello/locale/et_EE/katello.js +3008 -2993
  16. data/app/assets/javascripts/katello/locale/fr/katello.js +5975 -5984
  17. data/app/assets/javascripts/katello/locale/gl/katello.js +3125 -3113
  18. data/app/assets/javascripts/katello/locale/gu/katello.js +3119 -3104
  19. data/app/assets/javascripts/katello/locale/he_IL/katello.js +3020 -3005
  20. data/app/assets/javascripts/katello/locale/hi/katello.js +3137 -3122
  21. data/app/assets/javascripts/katello/locale/id/katello.js +3008 -2993
  22. data/app/assets/javascripts/katello/locale/it/katello.js +4469 -4466
  23. data/app/assets/javascripts/katello/locale/ja/katello.js +5969 -5978
  24. data/app/assets/javascripts/katello/locale/ka/katello.js +5649 -5652
  25. data/app/assets/javascripts/katello/locale/kn/katello.js +3136 -3121
  26. data/app/assets/javascripts/katello/locale/ko/katello.js +4717 -4720
  27. data/app/assets/javascripts/katello/locale/locale/katello.js +1050 -1084
  28. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +3008 -2993
  29. data/app/assets/javascripts/katello/locale/mr/katello.js +3136 -3121
  30. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +3116 -3101
  31. data/app/assets/javascripts/katello/locale/or/katello.js +3137 -3122
  32. data/app/assets/javascripts/katello/locale/pa/katello.js +3136 -3121
  33. data/app/assets/javascripts/katello/locale/pl/katello.js +3210 -3195
  34. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +3008 -2993
  35. data/app/assets/javascripts/katello/locale/pt/katello.js +3009 -2994
  36. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +5362 -5368
  37. data/app/assets/javascripts/katello/locale/ro/katello.js +3008 -2993
  38. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +3008 -2993
  39. data/app/assets/javascripts/katello/locale/ru/katello.js +4638 -4641
  40. data/app/assets/javascripts/katello/locale/sl/katello.js +3051 -3036
  41. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +3156 -3144
  42. data/app/assets/javascripts/katello/locale/ta/katello.js +3365 -3350
  43. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +3121 -3106
  44. data/app/assets/javascripts/katello/locale/te/katello.js +3136 -3121
  45. data/app/assets/javascripts/katello/locale/tr/katello.js +3025 -3010
  46. data/app/assets/javascripts/katello/locale/vi/katello.js +3008 -2993
  47. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +3008 -2993
  48. data/app/assets/javascripts/katello/locale/zh/katello.js +3008 -2993
  49. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +5968 -5977
  50. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +4694 -4697
  51. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +370 -132
  52. data/app/controllers/katello/api/rhsm/candlepin_dynflow_proxy_controller.rb +12 -20
  53. data/app/controllers/katello/api/v2/activation_keys_controller.rb +10 -4
  54. data/app/controllers/katello/api/v2/capsule_content_controller.rb +24 -0
  55. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +9 -2
  56. data/app/controllers/katello/api/v2/debs_controller.rb +1 -1
  57. data/app/controllers/katello/api/v2/errata_controller.rb +1 -1
  58. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +12 -4
  59. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +3 -3
  60. data/app/controllers/katello/api/v2/organizations_controller.rb +0 -11
  61. data/app/controllers/katello/api/v2/packages_controller.rb +1 -1
  62. data/app/controllers/katello/api/v2/repositories_controller.rb +19 -13
  63. data/app/controllers/katello/api/v2/repository_sets_controller.rb +2 -1
  64. data/app/controllers/katello/api/v2/simple_content_access_controller.rb +9 -22
  65. data/app/controllers/katello/concerns/api/v2/authorization.rb +1 -1
  66. data/app/helpers/katello/subscription_mailer_helper.rb +1 -1
  67. data/app/jobs/create_manifest_expire_soon_warning_notifications.rb +11 -0
  68. data/app/lib/actions/candlepin/owner/regenerate_upstream_identity_cert.rb +21 -0
  69. data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
  70. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +7 -2
  71. data/app/lib/actions/katello/capsule_content/verify_checksum.rb +75 -0
  72. data/app/lib/actions/katello/content_view/promote.rb +1 -1
  73. data/app/lib/actions/katello/content_view/publish.rb +1 -1
  74. data/app/lib/actions/katello/content_view_version/verify_checksum.rb +29 -0
  75. data/app/lib/actions/katello/host/hypervisors_update.rb +1 -0
  76. data/app/lib/actions/katello/host/update_content_view.rb +2 -2
  77. data/app/lib/actions/katello/organization/manifest_delete.rb +6 -1
  78. data/app/lib/actions/katello/organization/manifest_import.rb +5 -0
  79. data/app/lib/actions/katello/organization/manifest_refresh.rb +3 -0
  80. data/app/lib/actions/katello/repository/create.rb +17 -11
  81. data/app/lib/actions/katello/repository/create_root.rb +4 -2
  82. data/app/lib/actions/katello/repository/metadata_generate.rb +7 -1
  83. data/app/lib/actions/katello/repository/remove_content.rb +1 -0
  84. data/app/lib/actions/katello/repository/sync.rb +2 -1
  85. data/app/lib/actions/katello/repository/upload_files.rb +1 -0
  86. data/app/lib/actions/katello/upstream_subscriptions/bind_entitlement.rb +1 -1
  87. data/app/lib/actions/pulp3/capsule_content/verify_checksum.rb +27 -0
  88. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +7 -9
  89. data/app/lib/actions/pulp3/orchestration/content_view_version/syncable_export.rb +5 -4
  90. data/app/lib/actions/pulp3/orchestration/orphan_cleanup/remove_orphans.rb +1 -0
  91. data/app/lib/actions/pulp3/orphan_cleanup/purge_completed_tasks.rb +15 -0
  92. data/app/lib/katello/concerns/base_template_scope_extensions.rb +7 -2
  93. data/app/lib/katello/http_resource.rb +6 -1
  94. data/app/lib/katello/resources/candlepin/consumer.rb +1 -1
  95. data/app/lib/katello/resources/candlepin/upstream_consumer.rb +18 -6
  96. data/app/lib/katello/resources/candlepin/upstream_job.rb +1 -1
  97. data/app/lib/katello/resources/registry.rb +25 -0
  98. data/app/mailers/katello/subscription_mailer.rb +3 -6
  99. data/app/models/katello/concerns/organization_extensions.rb +42 -3
  100. data/app/models/katello/content_view.rb +30 -0
  101. data/app/models/katello/content_view_environment_content_facet.rb +4 -2
  102. data/app/models/katello/glue/provider.rb +19 -12
  103. data/app/models/katello/glue/pulp/repos.rb +11 -3
  104. data/app/models/katello/host/content_facet.rb +1 -1
  105. data/app/models/katello/host/subscription_facet.rb +1 -1
  106. data/app/models/katello/ping.rb +1 -1
  107. data/app/models/katello/repository.rb +32 -1
  108. data/app/models/katello/root_repository.rb +4 -6
  109. data/app/models/katello/trace_status.rb +1 -1
  110. data/app/services/katello/content_unit_indexer.rb +9 -0
  111. data/app/services/katello/pulp3/alternate_content_source.rb +4 -6
  112. data/app/services/katello/pulp3/api/core.rb +21 -0
  113. data/app/services/katello/pulp3/api/docker.rb +4 -0
  114. data/app/services/katello/pulp3/api/yum.rb +11 -0
  115. data/app/services/katello/pulp3/docker_manifest.rb +5 -1
  116. data/app/services/katello/pulp3/repository/generic.rb +1 -1
  117. data/app/services/katello/pulp3/repository/yum.rb +1 -6
  118. data/app/services/katello/pulp3/repository.rb +26 -6
  119. data/app/services/katello/pulp3/repository_mirror.rb +13 -12
  120. data/app/services/katello/pulp3/service_common.rb +2 -10
  121. data/app/services/katello/pulp3/smart_proxy_repository.rb +0 -2
  122. data/app/services/katello/ui_notifications/subscriptions/manifest_expire_soon_warning.rb +75 -0
  123. data/app/views/foreman/job_templates/update_package_-_katello_ansible_default.erb +5 -1
  124. data/app/views/foreman/job_templates/update_packages_by_search_query_-_katello_ansible_default.erb +2 -2
  125. data/app/views/foreman/job_templates/upload_profile.erb +16 -0
  126. data/app/views/foreman/smart_proxies/_content_tab.html.erb +3 -1
  127. data/app/views/katello/api/v2/content_view_filter_rules/show.json.rabl +9 -0
  128. data/app/views/katello/api/v2/docker_manifests/show.json.rabl +1 -0
  129. data/app/views/katello/api/v2/organizations/show.json.rabl +9 -1
  130. data/app/views/overrides/activation_keys/_host_environment_select.html.erb +1 -1
  131. data/app/views/overrides/activation_keys/_host_media_type_select.html.erb +15 -5
  132. data/config/routes/api/registry.rb +4 -8
  133. data/config/routes/api/v2.rb +2 -0
  134. data/db/migrate/20240423112842_add_fields_to_katello_docker_manifest.rb +8 -0
  135. data/db/migrate/20240502192021_change_katello_repository_rpms_id_seq_to_big_int.rb +9 -0
  136. data/db/migrate/20240520142245_add_container_push_props_to_repo.rb +7 -0
  137. data/db/migrate/20240531193030_remove_sha1_repository_checksum_type.rb +10 -0
  138. data/db/seeds.d/109-katello-notification-blueprints.rb +6 -0
  139. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-repository-sets.controller.js +3 -3
  140. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/views/new-content-credential.html +2 -1
  141. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-repository-sets.controller.js +3 -3
  142. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +0 -15
  143. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/checksum.service.js +6 -1
  144. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +8 -6
  145. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +12 -13
  146. data/lib/katello/permission_creator.rb +3 -3
  147. data/lib/katello/permissions/registry_permissions.rb +4 -7
  148. data/lib/katello/plugin.rb +21 -8
  149. data/lib/katello/repository_types/ostree.rb +7 -0
  150. data/lib/katello/scheduled_jobs.rb +7 -1
  151. data/lib/katello/tasks/clean_backend_objects.rake +1 -1
  152. data/lib/katello/tasks/repository.rake +22 -0
  153. data/lib/katello/version.rb +1 -1
  154. data/locale/action_names.rb +4 -3
  155. data/locale/bn/katello.po +166 -151
  156. data/locale/bn_IN/katello.po +166 -151
  157. data/locale/ca/katello.po +166 -151
  158. data/locale/cs/katello.po +166 -151
  159. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  160. data/locale/cs_CZ/katello.po +172 -157
  161. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  162. data/locale/de/katello.po +178 -163
  163. data/locale/de_AT/katello.po +166 -151
  164. data/locale/de_DE/katello.po +166 -151
  165. data/locale/el/katello.po +166 -151
  166. data/locale/en/katello.po +166 -151
  167. data/locale/en_GB/katello.po +166 -151
  168. data/locale/en_US/katello.po +166 -151
  169. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  170. data/locale/es/katello.po +178 -163
  171. data/locale/et_EE/katello.po +166 -151
  172. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  173. data/locale/fr/katello.po +179 -164
  174. data/locale/gl/katello.po +166 -151
  175. data/locale/gu/katello.po +166 -151
  176. data/locale/he_IL/katello.po +166 -151
  177. data/locale/hi/katello.po +166 -151
  178. data/locale/id/katello.po +166 -151
  179. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  180. data/locale/it/katello.po +169 -154
  181. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  182. data/locale/ja/katello.po +179 -164
  183. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  184. data/locale/ka/katello.po +177 -162
  185. data/locale/katello.pot +1119 -1062
  186. data/locale/kn/katello.po +166 -151
  187. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  188. data/locale/ko/katello.po +174 -159
  189. data/locale/ml_IN/katello.po +166 -151
  190. data/locale/mr/katello.po +166 -151
  191. data/locale/nl_NL/katello.po +166 -151
  192. data/locale/or/katello.po +166 -151
  193. data/locale/pa/katello.po +166 -151
  194. data/locale/pl/katello.po +166 -151
  195. data/locale/pl_PL/katello.po +166 -151
  196. data/locale/pt/katello.po +166 -151
  197. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  198. data/locale/pt_BR/katello.po +178 -163
  199. data/locale/ro/katello.po +166 -151
  200. data/locale/ro_RO/katello.po +166 -151
  201. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  202. data/locale/ru/katello.po +171 -156
  203. data/locale/sl/katello.po +166 -151
  204. data/locale/sv_SE/katello.po +166 -151
  205. data/locale/ta/katello.po +166 -151
  206. data/locale/ta_IN/katello.po +166 -151
  207. data/locale/te/katello.po +166 -151
  208. data/locale/tr/katello.po +166 -151
  209. data/locale/vi/katello.po +166 -151
  210. data/locale/vi_VN/katello.po +166 -151
  211. data/locale/zh/katello.po +166 -151
  212. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  213. data/locale/zh_CN/katello.po +179 -164
  214. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  215. data/locale/zh_TW/katello.po +171 -156
  216. data/package.json +0 -1
  217. data/webpack/ForemanColumnExtensions/index.js +129 -0
  218. data/webpack/components/Content/ContentTable.js +0 -1
  219. data/webpack/components/Content/__tests__/__snapshots__/ContentTable.test.js.snap +0 -1
  220. data/webpack/components/Table/TableWrapper.js +14 -0
  221. data/webpack/components/extensions/HostDetails/ActionsBar/index.js +1 -1
  222. data/webpack/components/extensions/Hosts/ActionsBar/index.js +20 -1
  223. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/BulkChangeHostCVModal.js +220 -0
  224. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/actions.js +23 -0
  225. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/index.js +25 -0
  226. data/webpack/components/extensions/Hosts/BulkActions/__tests__/bulkChangeHostCVModal.test.js +133 -0
  227. data/webpack/global_index.js +9 -0
  228. data/webpack/scenes/Hosts/ChangeContentSource/actions.js +3 -1
  229. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +62 -24
  230. data/webpack/scenes/Hosts/ChangeContentSource/index.js +24 -16
  231. data/webpack/scenes/ModuleStreams/ModuleStreamsPage.js +33 -39
  232. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamPage.test.js +4 -2
  233. data/webpack/scenes/ModuleStreams/__tests__/__snapshots__/ModuleStreamsTable.test.js.snap +0 -1
  234. data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +1 -0
  235. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +66 -5
  236. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +16 -13
  237. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +14 -8
  238. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +1 -0
  239. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +1 -1
  240. metadata +60 -42
  241. data/app/lib/actions/katello/host/upload_package_profile.rb +0 -45
  242. data/app/lib/actions/katello/host/upload_profiles.rb +0 -47
  243. data/webpack/utils/__tests__/useParamsWithHash.test.js +0 -22
  244. data/webpack/utils/paramsFromHash.js +0 -16
  245. data/webpack/utils/useUrlParams.js +0 -14
@@ -44,7 +44,7 @@ module Katello
44
44
 
45
45
  validates_with ::AssociationExistsValidator, attributes: [:content_source]
46
46
  validates_with Katello::Validators::GeneratedContentViewValidator
47
- validates_associated :content_view_environment_content_facets
47
+ validates_associated :content_view_environment_content_facets, :message => _("invalid: The content source must sync the lifecycle environment assigned to the host. See the logs for more information.")
48
48
  validates :host, :presence => true, :allow_blank => false
49
49
 
50
50
  attr_accessor :cves_changed
@@ -67,7 +67,7 @@ module Katello
67
67
  self.purpose_addon_ids = consumer_params['addOns'].map { |addon_name| ::Katello::PurposeAddon.find_or_create_by(name: addon_name).id }
68
68
  end
69
69
 
70
- unless consumer_params['releaseVer'].blank?
70
+ unless consumer_params['releaseVer'].nil?
71
71
  release = consumer_params['releaseVer']
72
72
  release = release['releaseVer'] if release.is_a?(Hash)
73
73
  self.release_version = release
@@ -2,7 +2,7 @@ module Katello
2
2
  class Ping
3
3
  OK_RETURN_CODE = 'ok'.freeze
4
4
  FAIL_RETURN_CODE = 'FAIL'.freeze
5
- PACKAGES = %w(katello candlepin pulp foreman hammer).freeze
5
+ PACKAGES = %w(katello candlepin pulp foreman hammer dynflow).freeze
6
6
 
7
7
  class << self
8
8
  def services(capsule_id = nil)
@@ -118,7 +118,7 @@ module Katello
118
118
  end}
119
119
 
120
120
  before_validation :set_pulp_id
121
- before_validation :set_container_repository_name, :if => :docker?
121
+ before_validation :set_container_repository_name, :unless => :skip_container_name?
122
122
 
123
123
  scope :has_url, -> { joins(:root).where.not("#{RootRepository.table_name}.url" => nil) }
124
124
  scope :on_demand, -> { joins(:root).where("#{RootRepository.table_name}.download_policy" => ::Katello::RootRepository::DOWNLOAD_ON_DEMAND) }
@@ -268,6 +268,10 @@ module Katello
268
268
  self.content_view_version.content_view
269
269
  end
270
270
 
271
+ def skip_container_name?
272
+ self.library_instance? && self.root.docker? && self.root.is_container_push
273
+ end
274
+
271
275
  def library_instance?
272
276
  self.content_view.default?
273
277
  end
@@ -651,6 +655,33 @@ module Katello
651
655
  for_resource(self).order(:started_at).last
652
656
  end
653
657
 
658
+ def blocking_task
659
+ blocking_task_labels = [
660
+ ::Actions::Katello::Repository::Sync.name,
661
+ ::Actions::Katello::Repository::UploadFiles.name,
662
+ ::Actions::Katello::Repository::RemoveContent.name,
663
+ ::Actions::Katello::Repository::MetadataGenerate.name
664
+ ]
665
+ ForemanTasks::Task::DynflowTask.where(:label => blocking_task_labels)
666
+ .where.not(state: 'stopped')
667
+ .for_resource(self)
668
+ .order(:started_at)
669
+ .last
670
+ end
671
+
672
+ def check_ready_to_act!
673
+ blocking_tasks = content_views&.map { |cv| cv.blocking_task }&.compact
674
+
675
+ if blocking_tasks&.any?
676
+ errored_tasks = blocking_tasks
677
+ .uniq
678
+ .map { |task| "- #{Setting['foreman_url']}/foreman_tasks/tasks/#{task&.id}" }
679
+ .join("\n")
680
+ fail _("This repository has pending tasks in associated content views. Please wait for the tasks: " + errored_tasks +
681
+ " to complete before proceeding.")
682
+ end
683
+ end
684
+
654
685
  # returns other instances of this repo with the same library
655
686
  # equivalent of repo
656
687
  def environmental_instances(view)
@@ -17,7 +17,7 @@ module Katello
17
17
  DOWNLOAD_POLICIES = [DOWNLOAD_IMMEDIATE, DOWNLOAD_ON_DEMAND].freeze
18
18
 
19
19
  IGNORABLE_CONTENT_UNIT_TYPES = %w(srpm treeinfo).freeze
20
- CHECKSUM_TYPES = %w(sha1 sha256).freeze
20
+ CHECKSUM_TYPES = %w(sha256 sha384 sha512).freeze
21
21
 
22
22
  SUBSCRIBABLE_TYPES = [Repository::YUM_TYPE, Repository::OSTREE_TYPE, Repository::DEB_TYPE].freeze
23
23
  SKIPABLE_METADATA_TYPES = [Repository::YUM_TYPE, Repository::DEB_TYPE].freeze
@@ -112,6 +112,8 @@ module Katello
112
112
  only_integer: true
113
113
  }
114
114
 
115
+ validates :container_push_name_format, inclusion: { in: ['label', 'id'].freeze, allow_nil: true}
116
+
115
117
  scope :subscribable, -> { where(content_type: RootRepository::SUBSCRIBABLE_TYPES) }
116
118
  scope :skipable_metadata_check, -> { where(content_type: RootRepository::SKIPABLE_METADATA_TYPES) }
117
119
  scope :has_url, -> { where.not(:url => nil) }
@@ -195,7 +197,7 @@ module Katello
195
197
  def ensure_docker_repo_unprotected
196
198
  unless unprotected
197
199
  errors.add(:base, _("Container Image Repositories are not protected at this time. " \
198
- "They need to be published via http to be available to containers."))
200
+ "They need to be published via http to be available to containers."))
199
201
  end
200
202
  end
201
203
 
@@ -387,10 +389,6 @@ module Katello
387
389
  Katello::RepositoryTypeManager.generic_repository_types(false).values.map(&:id).map(&:to_s).flatten.include? self.content_type
388
390
  end
389
391
 
390
- def metadata_generate_needed?
391
- (%w(unprotected checksum_type container_repsoitory_name) & previous_changes.keys).any?
392
- end
393
-
394
392
  def using_mirrored_content?
395
393
  self.mirroring_policy != Katello::RootRepository::MIRRORING_POLICY_ADDITIVE
396
394
  end
@@ -36,7 +36,7 @@ module Katello
36
36
  end
37
37
 
38
38
  def to_status(_options = {})
39
- traces = host.host_traces.pluck(:app_type)
39
+ traces = host.host_traces.reload.pluck(:app_type)
40
40
  traces.delete(Katello::HostTracer::TRACE_APP_TYPE_SESSION)
41
41
 
42
42
  if traces.include?(Katello::HostTracer::TRACE_APP_TYPE_STATIC)
@@ -55,6 +55,15 @@ module Katello
55
55
  end
56
56
  end
57
57
 
58
+ def reimport_units
59
+ units_from_pulp.each do |units|
60
+ to_update = units.map do |unit|
61
+ @service_class.generate_model_row(unit)
62
+ end
63
+ @model_class.upsert_all(to_update, unique_by: :pulp_id)
64
+ end
65
+ end
66
+
58
67
  def import_associations(units)
59
68
  pulp_id_to_id = self.class.pulp_id_to_id_map(@content_type, units.map { |unit| unit[@service_class.unit_identifier] })
60
69
  @service_class.insert_child_associations(units, pulp_id_to_id) if @service_class.respond_to?(:insert_child_associations)
@@ -88,18 +88,16 @@ module Katello
88
88
  end
89
89
 
90
90
  def get_remote(href = smart_proxy_acs.remote_href)
91
- acs.base_url&.start_with?('uln') ? api.remotes_uln_api.read(href) : api.remotes_api.read(href)
91
+ api.get_remotes_api(href: href).read(href)
92
92
  end
93
93
 
94
- def update_remote
95
- api.remotes_api.partial_update(smart_proxy_acs.remote_href, remote_options)
94
+ def update_remote(href = smart_proxy_acs.remote_href)
95
+ api.get_remotes_api(href: href).partial_update(href, remote_options)
96
96
  end
97
97
 
98
- # The old repo URL is needed to determine which remote API to use.
99
98
  def delete_remote(options = {})
100
99
  options[:href] ||= smart_proxy_acs.remote_href
101
- options[:old_url] ||= remote_options[:url]
102
- ignore_404_exception { options[:old_url]&.start_with?('uln') ? api.remotes_uln_api.delete(options[:href]) : api.remotes_api.delete(options[:href]) } if options[:href]
100
+ ignore_404_exception { api.get_remotes_api(href: options[:href]).delete(options[:href]) } if options[:href]
103
101
  end
104
102
 
105
103
  def create
@@ -47,6 +47,11 @@ module Katello
47
47
  fail NotImplementedError
48
48
  end
49
49
 
50
+ # Method is called with either :url or :href parameters for the sake of yum content.
51
+ def get_remotes_api(*)
52
+ remotes_api
53
+ end
54
+
50
55
  def publications_api
51
56
  repository_type.publications_api_class.new(api_client) #Optional
52
57
  end
@@ -136,6 +141,10 @@ module Katello
136
141
  client
137
142
  end
138
143
 
144
+ def repair_api
145
+ PulpcoreClient::RepairApi.new(core_api_client)
146
+ end
147
+
139
148
  def uploads_api
140
149
  PulpcoreClient::UploadsApi.new(core_api_client)
141
150
  end
@@ -167,6 +176,14 @@ module Katello
167
176
  nil
168
177
  end
169
178
 
179
+ def purge_class
180
+ PulpcoreClient::Purge
181
+ end
182
+
183
+ def purge_completed_tasks
184
+ tasks_api.purge(purge_class.new(finished_before: DateTime.now - Setting[:completed_pulp_task_protection_days]))
185
+ end
186
+
170
187
  def delete_orphans
171
188
  [orphans_api.cleanup(PulpcoreClient::OrphansCleanup.new(orphan_protection_time: (smart_proxy.pulp_mirror? ? 0 : Setting[:orphan_protection_time])))]
172
189
  end
@@ -230,6 +247,10 @@ module Katello
230
247
  end
231
248
  end
232
249
 
250
+ def repair
251
+ repair_api.post(PulpcoreClient::Repair.new(verify_checksums: true))
252
+ end
253
+
233
254
  def self.fetch_from_list
234
255
  page_size = Setting[:bulk_load_size]
235
256
  page_opts = { "offset" => 0, limit: page_size }
@@ -15,6 +15,10 @@ module Katello
15
15
  def recursive_add_api
16
16
  PulpContainerClient::ContainerRecursiveAddApi.new(api_client)
17
17
  end
18
+
19
+ def container_push_api
20
+ PulpContainerClient::RepositoriesContainerPushApi.new(api_client)
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -32,6 +32,17 @@ module Katello
32
32
  PulpRpmClient::RemotesUlnApi.new(api_client)
33
33
  end
34
34
 
35
+ def get_remotes_api(href: nil, url: nil)
36
+ fail 'Provide exactly one of href or url for yum remote selection!' if url.blank? && href.blank?
37
+ fail 'The href must be a pulp_rpm remote href!' if href && !href.start_with?('/pulp/api/v3/remotes/rpm/')
38
+
39
+ if href&.start_with?('/pulp/api/v3/remotes/rpm/uln/') || url&.start_with?('uln')
40
+ remotes_uln_api
41
+ else
42
+ remotes_api
43
+ end
44
+ end
45
+
35
46
  def copy_api
36
47
  PulpRpmClient::RpmCopyApi.new(api_client)
37
48
  end
@@ -26,7 +26,11 @@ module Katello
26
26
  {
27
27
  schema_version: unit['schema_version'],
28
28
  digest: unit['digest'],
29
- pulp_id: unit[unit_identifier]
29
+ pulp_id: unit[unit_identifier],
30
+ annotations: unit['annotations'],
31
+ labels: unit['labels'],
32
+ is_bootable: unit['is_bootable'],
33
+ is_flatpak: unit['is_flatpak']
30
34
  }
31
35
  end
32
36
  end
@@ -3,7 +3,7 @@ module Katello
3
3
  class Repository
4
4
  class Generic < ::Katello::Pulp3::Repository
5
5
  def copy_content_for_source(source_repository, _options = {})
6
- copy_units_by_href(source_repository.files.pluck(:pulp_id))
6
+ copy_units_by_href(source_repository.generic_content_units&.pluck(:pulp_id))
7
7
  end
8
8
 
9
9
  def distribution_options(path)
@@ -22,12 +22,7 @@ module Katello
22
22
 
23
23
  def publication_options(repository_version)
24
24
  options = super(repository_version)
25
- options.merge(
26
- {
27
- metadata_checksum_type: root.checksum_type,
28
- package_checksum_type: root.checksum_type
29
- }
30
- )
25
+ options.merge(checksum_type: root.checksum_type)
31
26
  end
32
27
 
33
28
  def specific_create_options
@@ -91,16 +91,21 @@ module Katello
91
91
  end
92
92
 
93
93
  def remote_partial_update
94
- if remote_options[:url]&.start_with?('uln')
95
- api.remotes_uln_api.partial_update(repo.remote_href, remote_options)
96
- else
97
- api.remotes_api.partial_update(repo.remote_href, remote_options)
94
+ url_type = remote_options[:url]&.start_with?('uln') ? 'uln' : 'default'
95
+ remote_type = repo.remote_href.start_with?('/pulp/api/v3/remotes/rpm/uln/') ? 'uln' : 'default'
96
+ href = repo.remote_href
97
+
98
+ if url_type == remote_type
99
+ api.get_remotes_api(href: href).partial_update(href, remote_options)
100
+ else # We need to recreate a remote of the correct type!
101
+ create_remote
102
+ delete_remote(href: href)
98
103
  end
99
104
  end
100
105
 
101
106
  def delete_remote(options = {})
102
107
  options[:href] ||= repo.remote_href
103
- ignore_404_exception { remote_options[:url]&.start_with?('uln') ? api.remotes_uln_api.delete(options[:href]) : api.remotes_api.delete(options[:href]) } if options[:href]
108
+ ignore_404_exception { api.get_remotes_api(href: options[:href]).delete(options[:href]) } if options[:href]
104
109
  end
105
110
 
106
111
  def self.instance_for_type(repo, smart_proxy)
@@ -139,7 +144,7 @@ module Katello
139
144
  end
140
145
 
141
146
  def get_remote(href = repo.remote_href)
142
- repo.url&.start_with?('uln') ? api.remotes_uln_api.read(href) : api.remotes_api.read(href)
147
+ api.get_remotes_api(href: href).read(href)
143
148
  end
144
149
 
145
150
  def get_distribution(href = distribution_reference.href)
@@ -210,6 +215,10 @@ module Katello
210
215
  api.publications_api.create(publication_data)
211
216
  end
212
217
 
218
+ def delete_publication
219
+ ignore_404_exception { api.publications_api.delete(repo.publication_href) } if repo.publication_href
220
+ end
221
+
213
222
  def publication_options(repository_version)
214
223
  {
215
224
  repository_version: repository_version
@@ -329,6 +338,17 @@ module Katello
329
338
 
330
339
  def delete_version
331
340
  ignore_404_exception { api.repository_versions_api.delete(repo.version_href) } unless version_zero?
341
+ rescue api.api_exception_class => e
342
+ if e.message.include?("are currently being used to distribute content")
343
+ Rails.logger.warn "Exception when calling repository_versions_api->delete: #{e}"
344
+ publication_href = repo.publication_href
345
+ Rails.logger.warn "Trying to delete publication #{publication_href} for repository #{repo.id}}"
346
+ Rails.logger.error "Could not delete version: #{repo.version_href} because conflicting publication could not be looked up" unless publication_href
347
+ if publication_href
348
+ ignore_404_exception { api.publications_api.delete(publication_href) }
349
+ ignore_404_exception { api.repository_versions_api.delete(repo.version_href) }
350
+ end
351
+ end
332
352
  end
333
353
 
334
354
  def create_version(options = {})
@@ -24,11 +24,9 @@ module Katello
24
24
  def refresh_entities
25
25
  href = remote_href
26
26
  if href
27
- if remote_options[:url]&.start_with?('uln')
28
- [api.remotes_uln_api.partial_update(href, remote_options)]
29
- else
30
- [api.remotes_api.partial_update(href, remote_options)]
31
- end
27
+ # Do not consider remotes_uln_api, since the Katello server is not a ULN server. Even if the sync
28
+ # to Katello used ULN, the sync from Katello server to smart proxy will use a normal RPM remote!
29
+ [api.remotes_api.partial_update(href, remote_options)]
32
30
  else
33
31
  create_remote
34
32
  []
@@ -111,13 +109,10 @@ module Katello
111
109
  end
112
110
 
113
111
  def create_remote
114
- if remote_options[:url]&.start_with?('uln')
115
- remote_file_data = @repo_service.api.class.remote_uln_class.new(remote_options)
116
- api.remotes_uln_api.create(remote_file_data)
117
- else
118
- remote_file_data = @repo_service.api.remote_class.new(remote_options)
119
- api.remotes_api.create(remote_file_data)
120
- end
112
+ # Do not consider remotes_uln_api, since the Katello server is not a ULN server. Even if the sync
113
+ # to Katello used ULN, the sync from Katello server to smart proxy will use a normal RPM remote!
114
+ remote_file_data = @repo_service.api.remote_class.new(remote_options)
115
+ api.remotes_api.create(remote_file_data)
121
116
  end
122
117
 
123
118
  def compute_remote_options
@@ -240,6 +235,12 @@ module Katello
240
235
  distribution_data = api.distribution_class.new(distribution_options(path))
241
236
  repo_service.distributions_api.create(distribution_data)
242
237
  end
238
+
239
+ def repair
240
+ data = api.repair_class.new
241
+ fail "Could not lookup a version_href for repo #{repo_service.repo.id}" if version_href.nil?
242
+ api.repository_versions_api.repair(version_href, data)
243
+ end
243
244
  end
244
245
  end
245
246
  end
@@ -9,11 +9,7 @@ module Katello
9
9
  remote_file_data = api.remote_class.new(remote_options)
10
10
  end
11
11
  reformat_api_exception do
12
- if remote_options[:url]&.start_with?('uln')
13
- response = api.remotes_uln_api.create(remote_file_data)
14
- else
15
- response = api.remotes_api.create(remote_file_data)
16
- end
12
+ response = api.get_remotes_api(url: remote_options[:url]).create(remote_file_data)
17
13
  end
18
14
  response
19
15
  end
@@ -37,11 +33,7 @@ module Katello
37
33
  end
38
34
 
39
35
  reformat_api_exception do
40
- if remote_options[:url]&.start_with?('uln')
41
- response = api.remotes_uln_api.create(remote_file_data)
42
- else
43
- response = api.remotes_api.create(remote_file_data)
44
- end
36
+ response = api.get_remotes_api(url: remote_options[:url]).create(remote_file_data)
45
37
  #delete is async, but if its not properly deleted, orphan cleanup will take care of it later
46
38
  delete_remote(href: response.pulp_href)
47
39
  end
@@ -35,13 +35,11 @@ module Katello
35
35
 
36
36
  def delete_orphan_repository_versions
37
37
  tasks = []
38
-
39
38
  orphan_repository_versions.each do |api, version_hrefs|
40
39
  tasks << version_hrefs.collect do |href|
41
40
  api.repository_versions_api.delete(href)
42
41
  end
43
42
  end
44
-
45
43
  tasks.flatten
46
44
  end
47
45
 
@@ -0,0 +1,75 @@
1
+ module Katello
2
+ module UINotifications
3
+ module Subscriptions
4
+ class ManifestExpireSoonWarning
5
+ class << self
6
+ def deliver!
7
+ ::Organization.unscoped.all.each do |organization|
8
+ if (notification = existing_notification(organization))
9
+ days_remaining = organization.manifest_expire_days_remaining
10
+ if days_remaining == 0 || days_remaining > Setting[:expire_soon_days].to_i
11
+ # if the manifest has already expired, delete the notification;
12
+ # user will have a ManifestExpiredWarning instead.
13
+ # If user changes the expire_soon_days setting, remove notifications
14
+ # that are no longer relevant.
15
+ Rails.logger.debug("ManifestExpireSoonWarning: deleting notification for #{organization.name}")
16
+ notification.destroy
17
+ next
18
+ end
19
+ # don't update if the message hasn't changed
20
+ next unless message(organization).to_s !=
21
+ notification.message.to_s
22
+ notification.update(
23
+ :message => message(organization),
24
+ :actions => actions
25
+ )
26
+ else
27
+ next unless organization.manifest_expiring_soon?
28
+ ::Notification.create!(
29
+ :subject => organization,
30
+ :initiator => User.anonymous_admin,
31
+ :audience => Notification::AUDIENCE_SUBJECT,
32
+ :message => message(organization),
33
+ :actions => actions,
34
+ :notification_blueprint => blueprint
35
+ )
36
+ end
37
+ end
38
+ end
39
+
40
+ def existing_notification(subject)
41
+ matching_notification = Notification.unscoped.find_by(:subject => subject, :notification_blueprint => blueprint)
42
+ return false if matching_notification.blank?
43
+ matching_notification
44
+ end
45
+
46
+ def message(organization)
47
+ ::UINotifications::StringParser.new(
48
+ blueprint.message,
49
+ :manifest_expire_date => organization.manifest_expiration_date&.to_date,
50
+ :subject => organization,
51
+ :days_remaining => organization.manifest_expire_days_remaining
52
+ )
53
+ end
54
+
55
+ def actions
56
+ {
57
+ :links => [
58
+ {
59
+ :href => "/subscriptions",
60
+ :title => _('Subscriptions'),
61
+ :external => false
62
+ }
63
+ ]
64
+ }
65
+ end
66
+
67
+ def blueprint
68
+ @blueprint ||= NotificationBlueprint.unscoped.find_by(
69
+ :name => 'manifest_expire_soon_warning')
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -13,4 +13,8 @@ provider_type: Ansible
13
13
  kind: job_template
14
14
  %>
15
15
 
16
- <%= render_template('Run Command - Ansible Default', :command => "yum -y update #{input('package')}") %>
16
+ <%
17
+ pkgs = input('package')
18
+ pkgs = '"*"' if pkgs.empty?
19
+ -%>
20
+ <%= render_template('Package Action - Ansible Default', :state => 'latest', :name => pkgs) %>
@@ -3,7 +3,7 @@ kind: job_template
3
3
  name: Update packages by search query - Katello Ansible Default
4
4
  job_category: Katello
5
5
  description_format: 'Update package(s) %{Packages search query}'
6
- feature: katello_package_remove_by_search
6
+ feature: katello_package_update_by_search
7
7
  provider_type: Ansible
8
8
  template_inputs:
9
9
  - name: Packages search query
@@ -22,7 +22,7 @@ template_inputs:
22
22
  versions: input('Selected update versions')
23
23
  ) -%>
24
24
  <% if package_names.empty? -%>
25
- <%= render_template('Run Command - Ansible Default', :command => "yum -y update") %>
25
+ <%= render_template('Package Action - Ansible Default', :state => 'latest', :name => '"*"') %>
26
26
  <% else -%>
27
27
  ---
28
28
  - hosts: all
@@ -0,0 +1,16 @@
1
+ <%#
2
+ kind: job_template
3
+ name: Upload profile - Katello Script Default
4
+ job_category: Katello
5
+ model: JobTemplate
6
+ provider_type: script
7
+ description_format: Upload package profile for a host
8
+ feature: katello_upload_profile
9
+ %>
10
+ #!/bin/sh
11
+ <% if @host.operatingsystem.family == 'Redhat' -%>
12
+ dnf uploadprofile --force-upload
13
+ <% else -%>
14
+ package-profile-upload --force-upload
15
+ <% end -%>
16
+ subscription-manager repos
@@ -1,3 +1,5 @@
1
- <%= javascript_include_tag *webpack_asset_paths('katello', extension: 'js') %>
1
+ <% content_for(:javascripts) do %>
2
+ <%= webpacked_plugins_js_for :katello %>
3
+ <% end %>
2
4
  <% @smartProxyId= @smart_proxy.id %>
3
5
  <%= react_component('Content', smartProxyId: @smartProxyId, organizationId: Organization.current&.id,) %>
@@ -15,4 +15,13 @@ attributes :architecture, :if => lambda { |rule| rule.respond_to?(:architecture)
15
15
  attributes :types, :if => lambda { |rule| rule.respond_to?(:types) && !rule.types.blank? }
16
16
  attributes :date_type, :if => lambda { |rule| rule.respond_to?(:date_type) }
17
17
  attributes :module_stream_id, :if => lambda { |rule| rule.respond_to?(:module_stream_id) && !rule.module_stream_id.blank? }
18
+ if @resource&.try(:module_stream)
19
+ node :module_stream do |rule|
20
+ {
21
+ :module_stream_id => rule.module_stream.id,
22
+ :module_stream_name => rule.module_stream.name,
23
+ :module_stream_stream => rule.module_stream.stream
24
+ }
25
+ end
26
+ end
18
27
  extends 'katello/api/v2/common/timestamps'
@@ -1,6 +1,7 @@
1
1
  object @resource
2
2
 
3
3
  attributes :id, :schema_version, :digest, :manifest_type
4
+ attributes :annotations, :labels, :is_bootable, :is_flatpak
4
5
 
5
6
  child :docker_tags => :tags do
6
7
  attributes :associated_meta_tag_identifier => :id
@@ -3,10 +3,18 @@ object @organization
3
3
  extends "api/v2/taxonomies/show"
4
4
 
5
5
  attributes :task_id, :label, :redhat_repository_url
6
-
6
+ attributes :manifest_expiration_date, :manifest_expire_days_remaining
7
7
  attributes :system_purposes, :system_purposes
8
8
  attributes :service_levels, :service_level
9
9
 
10
+ node :manifest_expiring_soon do |org|
11
+ org.manifest_expiring_soon?
12
+ end
13
+
14
+ node :manifest_expired do |org|
15
+ org.manifest_expired?
16
+ end
17
+
10
18
  node :simple_content_access do |org|
11
19
  org.simple_content_access?
12
20
  end
@@ -8,7 +8,7 @@
8
8
 
9
9
  <% if edit_action? && !using_hostgroups_page? && !using_discovered_hosts_page? %>
10
10
  <div style="margin-left: 270px">
11
- <%= link_to _("Change content source"), "/change_host_content_source?host_id=#{@host.id}" %>
11
+ <%= link_to _("Change content source"), "/change_host_content_source?fromPage=hostEdit&host_id=#{@host.id}&initialContentSourceId=#{@host.content_source_id}" %>
12
12
  </div>
13
13
  <% end %>
14
14