katello 4.18.0 → 4.19.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (345) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/locale/bn/katello.js +52 -349
  3. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +52 -349
  4. data/app/assets/javascripts/katello/locale/ca/katello.js +52 -349
  5. data/app/assets/javascripts/katello/locale/cs/katello.js +53 -350
  6. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +54 -351
  7. data/app/assets/javascripts/katello/locale/de/katello.js +56 -353
  8. data/app/assets/javascripts/katello/locale/de_AT/katello.js +52 -349
  9. data/app/assets/javascripts/katello/locale/de_DE/katello.js +52 -349
  10. data/app/assets/javascripts/katello/locale/el/katello.js +54 -351
  11. data/app/assets/javascripts/katello/locale/en/katello.js +53 -350
  12. data/app/assets/javascripts/katello/locale/en_GB/katello.js +53 -350
  13. data/app/assets/javascripts/katello/locale/en_US/katello.js +52 -349
  14. data/app/assets/javascripts/katello/locale/es/katello.js +56 -353
  15. data/app/assets/javascripts/katello/locale/et_EE/katello.js +52 -349
  16. data/app/assets/javascripts/katello/locale/fr/katello.js +138 -435
  17. data/app/assets/javascripts/katello/locale/gl/katello.js +52 -349
  18. data/app/assets/javascripts/katello/locale/gu/katello.js +52 -349
  19. data/app/assets/javascripts/katello/locale/he_IL/katello.js +52 -349
  20. data/app/assets/javascripts/katello/locale/hi/katello.js +52 -349
  21. data/app/assets/javascripts/katello/locale/id/katello.js +52 -349
  22. data/app/assets/javascripts/katello/locale/it/katello.js +53 -350
  23. data/app/assets/javascripts/katello/locale/ja/katello.js +142 -439
  24. data/app/assets/javascripts/katello/locale/ka/katello.js +56 -353
  25. data/app/assets/javascripts/katello/locale/kn/katello.js +52 -349
  26. data/app/assets/javascripts/katello/locale/ko/katello.js +135 -432
  27. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +52 -349
  28. data/app/assets/javascripts/katello/locale/mr/katello.js +52 -349
  29. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +52 -349
  30. data/app/assets/javascripts/katello/locale/or/katello.js +52 -349
  31. data/app/assets/javascripts/katello/locale/pa/katello.js +52 -349
  32. data/app/assets/javascripts/katello/locale/pl/katello.js +52 -349
  33. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +52 -349
  34. data/app/assets/javascripts/katello/locale/pt/katello.js +52 -349
  35. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +56 -353
  36. data/app/assets/javascripts/katello/locale/ro/katello.js +52 -349
  37. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +52 -349
  38. data/app/assets/javascripts/katello/locale/ru/katello.js +54 -351
  39. data/app/assets/javascripts/katello/locale/sl/katello.js +52 -349
  40. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +52 -349
  41. data/app/assets/javascripts/katello/locale/ta/katello.js +52 -349
  42. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +52 -349
  43. data/app/assets/javascripts/katello/locale/te/katello.js +52 -349
  44. data/app/assets/javascripts/katello/locale/tr/katello.js +52 -349
  45. data/app/assets/javascripts/katello/locale/vi/katello.js +52 -349
  46. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +52 -349
  47. data/app/assets/javascripts/katello/locale/zh/katello.js +52 -349
  48. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +135 -432
  49. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +54 -351
  50. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +46 -13
  51. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
  52. data/app/controllers/katello/api/v2/activation_keys_controller.rb +3 -65
  53. data/app/controllers/katello/api/v2/content_export_incrementals_controller.rb +56 -34
  54. data/app/controllers/katello/api/v2/content_view_filter_rules_controller.rb +1 -1
  55. data/app/controllers/katello/api/v2/content_views_controller.rb +18 -3
  56. data/app/controllers/katello/api/v2/debs_controller.rb +21 -11
  57. data/app/controllers/katello/api/v2/docker_tags_controller.rb +7 -0
  58. data/app/controllers/katello/api/v2/errata_controller.rb +4 -4
  59. data/app/controllers/katello/api/v2/flatpak_remote_repositories_controller.rb +21 -19
  60. data/app/controllers/katello/api/v2/host_debs_controller.rb +16 -1
  61. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +3 -60
  62. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +10 -53
  63. data/app/controllers/katello/api/v2/repositories_controller.rb +0 -1
  64. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +3 -0
  65. data/app/lib/actions/candlepin/activation_key/create.rb +0 -2
  66. data/app/lib/actions/candlepin/activation_key/update.rb +0 -2
  67. data/app/lib/actions/candlepin/product/content_create.rb +3 -5
  68. data/app/lib/actions/candlepin/product/content_update.rb +2 -3
  69. data/app/lib/actions/helpers/rolling_cv_repos.rb +1 -1
  70. data/app/lib/actions/katello/activation_key/create.rb +0 -1
  71. data/app/lib/actions/katello/activation_key/update.rb +0 -2
  72. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +1 -6
  73. data/app/lib/actions/katello/content_credential/update.rb +1 -1
  74. data/app/lib/actions/katello/content_view/add_rolling_repo_clone.rb +18 -24
  75. data/app/lib/actions/katello/content_view/create.rb +9 -4
  76. data/app/lib/actions/katello/content_view/publish.rb +7 -7
  77. data/app/lib/actions/katello/content_view/refresh_rolling_repo.rb +6 -1
  78. data/app/lib/actions/katello/content_view/remove_rolling_repo_clone.rb +16 -11
  79. data/app/lib/actions/katello/content_view/update.rb +34 -7
  80. data/app/lib/actions/katello/product/content_create.rb +2 -2
  81. data/app/lib/actions/katello/product/content_destroy.rb +1 -1
  82. data/app/lib/actions/katello/repository/check_matching_content.rb +1 -1
  83. data/app/lib/actions/katello/repository/clone_contents.rb +1 -1
  84. data/app/lib/actions/katello/repository/create.rb +1 -1
  85. data/app/lib/actions/katello/repository/destroy.rb +4 -4
  86. data/app/lib/actions/katello/repository/finish_upload.rb +1 -1
  87. data/app/lib/actions/katello/repository/sync.rb +1 -1
  88. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -2
  89. data/app/lib/actions/pulp3/orchestration/repository/generate_metadata.rb +1 -1
  90. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +1 -1
  91. data/app/lib/actions/pulp3/repository/save_publication.rb +3 -1
  92. data/app/lib/actions/pulp3/repository/save_version.rb +45 -24
  93. data/app/lib/actions/pulp3/repository/save_versions.rb +2 -1
  94. data/app/lib/katello/resources/candlepin/activation_key.rb +3 -4
  95. data/app/lib/katello/resources/candlepin/upstream_job.rb +9 -1
  96. data/app/lib/katello/resources/candlepin.rb +4 -0
  97. data/app/models/katello/authorization/repository.rb +17 -4
  98. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +0 -7
  99. data/app/models/katello/content_view_deb_filter.rb +10 -0
  100. data/app/models/katello/content_view_deb_filter_rule.rb +7 -0
  101. data/app/models/katello/deb.rb +10 -12
  102. data/app/models/katello/erratum.rb +1 -1
  103. data/app/models/katello/glue/provider.rb +14 -3
  104. data/app/models/katello/host/content_facet.rb +1 -1
  105. data/app/models/katello/host/subscription_facet.rb +1 -7
  106. data/app/models/katello/product_content.rb +2 -2
  107. data/app/models/katello/repository.rb +4 -23
  108. data/app/models/katello/root_repository.rb +2 -5
  109. data/app/services/katello/candlepin/event_handler.rb +0 -33
  110. data/app/services/katello/candlepin/message_handler.rb +0 -41
  111. data/app/services/katello/content_unit_indexer.rb +59 -13
  112. data/app/services/katello/product_content_finder.rb +16 -7
  113. data/app/services/katello/pulp3/alternate_content_source.rb +2 -2
  114. data/app/services/katello/pulp3/ansible_collection.rb +1 -0
  115. data/app/services/katello/pulp3/api/content_guard.rb +5 -5
  116. data/app/services/katello/pulp3/api/core.rb +10 -0
  117. data/app/services/katello/pulp3/content_view_version/export.rb +25 -10
  118. data/app/services/katello/pulp3/deb.rb +1 -0
  119. data/app/services/katello/pulp3/docker_manifest.rb +1 -0
  120. data/app/services/katello/pulp3/docker_manifest_list.rb +1 -0
  121. data/app/services/katello/pulp3/docker_tag.rb +1 -0
  122. data/app/services/katello/pulp3/file_unit.rb +1 -0
  123. data/app/services/katello/pulp3/generic_content_unit.rb +1 -0
  124. data/app/services/katello/pulp3/module_stream.rb +1 -0
  125. data/app/services/katello/pulp3/package_group.rb +1 -0
  126. data/app/services/katello/pulp3/repository/apt.rb +30 -13
  127. data/app/services/katello/pulp3/repository.rb +59 -10
  128. data/app/services/katello/pulp3/rpm.rb +3 -2
  129. data/app/services/katello/pulp3/srpm.rb +3 -2
  130. data/app/services/katello/pulp3/task_group.rb +1 -1
  131. data/app/services/katello/registration_manager.rb +19 -17
  132. data/app/services/katello/repository_type_manager.rb +7 -5
  133. data/app/services/katello/smart_proxy_helper.rb +1 -6
  134. data/app/views/foreman/job_templates/upload_profile.erb +5 -0
  135. data/app/views/katello/api/v2/activation_keys/base.json.rabl +1 -1
  136. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  137. data/app/views/katello/api/v2/debs/thindex.json.rabl +6 -0
  138. data/app/views/katello/api/v2/docker_tags/_base.json.rabl +32 -0
  139. data/app/views/katello/api/v2/docker_tags/show.json.rabl +0 -5
  140. data/app/views/katello/api/v2/flatpak_remotes/index.json.rabl +6 -0
  141. data/app/views/katello/api/v2/host_debs/installed_debs.json.rabl +6 -0
  142. data/app/views/katello/api/v2/hosts_bulk_actions/applicable_errata.json.rabl +1 -1
  143. data/app/views/katello/api/v2/hosts_bulk_actions/applicable_erratum.json.rabl +9 -0
  144. data/app/views/katello/api/v2/hosts_bulk_actions/installable_errata.json.rabl +1 -1
  145. data/app/views/katello/api/v2/hosts_bulk_actions/{erratum.json.rabl → installable_erratum.json.rabl} +3 -3
  146. data/app/views/katello/api/v2/subscription_facet/base.json.rabl +1 -1
  147. data/config/initializers/monkeys.rb +1 -0
  148. data/config/routes/api/v2.rb +2 -2
  149. data/config/routes/overrides.rb +2 -7
  150. data/config/routes.rb +2 -0
  151. data/db/migrate/20211019192121_create_cdn_configuration.katello.rb +1 -1
  152. data/db/migrate/20250912000000_add_pulp_prn_fields.rb +73 -0
  153. data/db/migrate/20250912000001_populate_pulp_prn_fields.rb +403 -0
  154. data/db/migrate/20251009142516_remove_auto_attach_from_activation_keys.rb +5 -0
  155. data/db/migrate/20251009142517_remove_autoheal_from_subscription_facets.rb +5 -0
  156. data/db/seeds.d/111-upgrade_tasks.rb +2 -0
  157. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/el.po +2 -2
  158. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +6 -1
  159. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +5 -2
  160. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +5 -2
  161. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +5 -2
  162. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +4 -4
  163. data/lib/katello/permission_creator.rb +2 -2
  164. data/lib/katello/permissions/host_permissions.rb +0 -6
  165. data/lib/katello/plugin.rb +16 -8
  166. data/lib/katello/tasks/jenkins.rake +1 -1
  167. data/lib/katello/tasks/upgrades/4.19/enable_structured_apt_for_deb.rake +87 -0
  168. data/lib/katello/tasks/upgrades/4.19/populate_repository_version_prns.rake +32 -0
  169. data/lib/katello/version.rb +1 -1
  170. data/lib/monkeys/fix_rpm_repository_gpgcheck.rb +38 -0
  171. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  172. data/locale/bn/katello.po +52 -349
  173. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  174. data/locale/bn_IN/katello.po +52 -349
  175. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  176. data/locale/ca/katello.po +52 -349
  177. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  178. data/locale/cs/katello.po +54 -350
  179. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  180. data/locale/cs_CZ/katello.po +54 -351
  181. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  182. data/locale/de/katello.po +56 -353
  183. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  184. data/locale/de_AT/katello.po +52 -349
  185. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  186. data/locale/de_DE/katello.po +52 -349
  187. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  188. data/locale/el/katello.po +55 -352
  189. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  190. data/locale/en/katello.po +54 -350
  191. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  192. data/locale/en_GB/katello.po +53 -350
  193. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  194. data/locale/en_US/katello.po +52 -349
  195. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  196. data/locale/es/katello.po +56 -353
  197. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  198. data/locale/et_EE/katello.po +52 -349
  199. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  200. data/locale/fr/katello.po +139 -435
  201. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  202. data/locale/gl/katello.po +52 -349
  203. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  204. data/locale/gu/katello.po +52 -349
  205. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  206. data/locale/he_IL/katello.po +52 -349
  207. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  208. data/locale/hi/katello.po +52 -349
  209. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  210. data/locale/id/katello.po +52 -349
  211. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  212. data/locale/it/katello.po +53 -350
  213. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  214. data/locale/ja/katello.po +143 -439
  215. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  216. data/locale/ka/katello.po +56 -353
  217. data/locale/katello.pot +695 -1152
  218. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  219. data/locale/kn/katello.po +52 -349
  220. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  221. data/locale/ko/katello.po +136 -432
  222. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  223. data/locale/ml_IN/katello.po +52 -349
  224. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  225. data/locale/mr/katello.po +52 -349
  226. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  227. data/locale/nl_NL/katello.po +52 -349
  228. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  229. data/locale/or/katello.po +52 -349
  230. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  231. data/locale/pa/katello.po +52 -349
  232. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  233. data/locale/pl/katello.po +52 -349
  234. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  235. data/locale/pl_PL/katello.po +52 -349
  236. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  237. data/locale/pt/katello.po +52 -349
  238. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  239. data/locale/pt_BR/katello.po +56 -353
  240. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  241. data/locale/ro/katello.po +52 -349
  242. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  243. data/locale/ro_RO/katello.po +52 -349
  244. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  245. data/locale/ru/katello.po +54 -351
  246. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  247. data/locale/sl/katello.po +52 -349
  248. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  249. data/locale/sv_SE/katello.po +52 -349
  250. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  251. data/locale/ta/katello.po +52 -349
  252. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  253. data/locale/ta_IN/katello.po +52 -349
  254. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  255. data/locale/te/katello.po +52 -349
  256. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  257. data/locale/tr/katello.po +52 -349
  258. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  259. data/locale/vi/katello.po +52 -349
  260. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  261. data/locale/vi_VN/katello.po +52 -349
  262. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  263. data/locale/zh/katello.po +52 -349
  264. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  265. data/locale/zh_CN/katello.po +136 -432
  266. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  267. data/locale/zh_TW/katello.po +54 -351
  268. data/webpack/components/Content/Details/__tests__/__snapshots__/ContentDetails.test.js.snap +2 -2
  269. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +0 -2
  270. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeEditModal.test.js +0 -2
  271. data/webpack/components/extensions/Hosts/ActionsBar/index.js +1 -0
  272. data/webpack/components/extensions/Hosts/BulkActions/BulkActionsConstants.js +7 -0
  273. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/BulkChangeHostCollectionsModal.js +388 -0
  274. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/__tests__/BulkChangeHostCollectionsModal.test.js +640 -0
  275. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/actions.js +28 -0
  276. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/index.js +71 -0
  277. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/BulkErrataWizard.js +1 -1
  278. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/02_BulkPackagesTable.js +10 -3
  279. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/BulkPackagesWizard.js +51 -24
  280. data/webpack/components/extensions/Hosts/BulkActions/HostReview.js +7 -0
  281. data/webpack/containers/Application/config.js +11 -1
  282. data/webpack/global_index.js +3 -0
  283. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/BootedContainerImagesConstants.js +1 -1
  284. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/BootedContainerImagesPage.js +7 -43
  285. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/__tests__/bootedContainerImagesPage.test.js +1 -1
  286. data/webpack/scenes/ContainerImages/ContainerImagesPage.js +86 -0
  287. data/webpack/scenes/ContainerImages/LabelsAnnotationsModal.js +105 -0
  288. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetails.js +218 -0
  289. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetailsActions.js +15 -0
  290. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetailsSelectors.js +16 -0
  291. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/ManifestDetails.test.js +395 -0
  292. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/manifestDetails.fixtures.json +43 -0
  293. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/manifestList.fixtures.json +58 -0
  294. data/webpack/scenes/ContainerImages/Synced/Details/index.js +4 -0
  295. data/webpack/scenes/ContainerImages/Synced/SyncedContainerImagesPage.js +359 -0
  296. data/webpack/scenes/ContainerImages/Synced/SyncedContainerImagesPage.scss +21 -0
  297. data/webpack/scenes/ContainerImages/Synced/__tests__/LabelsAnnotationsModal.test.js +69 -0
  298. data/webpack/scenes/ContainerImages/Synced/__tests__/SyncedContainerImagesPage.test.js +335 -0
  299. data/webpack/scenes/ContainerImages/Synced/__tests__/syncedContainerImages.fixtures.json +105 -0
  300. data/webpack/scenes/ContainerImages/TableEmptyState.js +67 -0
  301. data/webpack/scenes/ContainerImages/containerImagesHelpers.js +48 -0
  302. data/webpack/scenes/ContainerImages/index.js +4 -0
  303. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +29 -3
  304. data/webpack/scenes/ContentViews/Create/__tests__/contentViewCreateResult.fixtures.json +1 -0
  305. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +45 -1
  306. data/webpack/scenes/ContentViews/Delete/__tests__/affectedHosts.fixtures.json +0 -1
  307. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +59 -1
  308. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +1 -0
  309. data/webpack/scenes/ContentViews/Details/Filters/Rules/DebPackage/AddEditDebPackageRuleModal.js +164 -24
  310. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVDebFilterContent.test.js +268 -0
  311. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvDebFilterDetail.fixtures.json +95 -0
  312. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvDebFilterRules.fixtures.json +31 -0
  313. data/webpack/scenes/ContentViews/Details/Filters/__tests__/emptyCVDebFilterRules.fixtures.json +10 -0
  314. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/hosts.fixtures.json +0 -1
  315. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvAffectedHosts.fixture.json +0 -1
  316. data/webpack/scenes/ContentViews/Details/__tests__/contentViewRollingDetail.test.js +15 -0
  317. data/webpack/scenes/ContentViews/Details/__tests__/contentViewRollingDetails.fixtures.json +1 -0
  318. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +9 -0
  319. data/webpack/scenes/FlatpakRemotes/CreateEdit/CreateFlatpakRemoteModal.js +5 -3
  320. data/webpack/scenes/FlatpakRemotes/CreateEdit/EditFlatpakRemotesModal.js +1 -1
  321. data/webpack/scenes/FlatpakRemotes/CreateEdit/FlatpakRemoteform.js +35 -3
  322. data/webpack/scenes/FlatpakRemotes/Details/FlatpakRemoteDetails.js +1 -1
  323. data/webpack/scenes/FlatpakRemotes/Details/RemoteRepositories/RemoteRepositoriesTable.css +3 -0
  324. data/webpack/scenes/FlatpakRemotes/Details/RemoteRepositories/RemoteRepositoriesTable.js +63 -132
  325. data/webpack/scenes/FlatpakRemotes/FlatpakRemotesPage.js +67 -143
  326. data/webpack/scenes/SmartProxy/ExpandableCvDetails.js +10 -2
  327. data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +13 -2
  328. data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -0
  329. data/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +8 -2
  330. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +67 -1
  331. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +2 -2
  332. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +0 -2
  333. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +2 -2
  334. metadata +83 -55
  335. data/app/lib/actions/katello/host/attach_subscriptions.rb +0 -59
  336. data/app/lib/actions/katello/host/auto_attach_subscriptions.rb +0 -22
  337. data/app/lib/actions/katello/host/remove_subscriptions.rb +0 -50
  338. data/app/lib/actions/katello/organization/simple_content_access/disable.rb +0 -25
  339. data/app/lib/actions/katello/organization/simple_content_access/enable.rb +0 -25
  340. data/app/lib/actions/katello/organization/simple_content_access/toggle.rb +0 -42
  341. data/lib/katello/tasks/migrate_structure_content_for_deb.rake +0 -105
  342. data/lib/katello/tasks/upgrades/4.2/remove_checksum_values.rake +0 -17
  343. data/locale/action_names.rb +0 -186
  344. /data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/__tests__/bootedContainerImages.fixtures.js +0 -0
  345. /data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/index.js +0 -0
@@ -46,27 +46,9 @@ module Katello
46
46
  case subject
47
47
  when 'pool.created', 'pool.deleted'
48
48
  content['entityId']
49
- when 'entitlement.created', 'entitlement.deleted'
50
- content['referenceId']
51
49
  end
52
50
  end
53
51
 
54
- def create_pool_on_host
55
- return if self.subscription_facet.nil? || pool.nil?
56
- old_host_ids = subscription_facet_host_ids
57
- ::Katello::SubscriptionFacetPool.where(subscription_facet_id: self.subscription_facet.id,
58
- pool_id: pool.id).first_or_create
59
- pool.import_audit_record(old_host_ids)
60
- end
61
-
62
- def remove_pool_from_host
63
- return if self.subscription_facet.nil? || pool.nil?
64
- old_host_ids = subscription_facet_host_ids
65
- ::Katello::SubscriptionFacetPool.where(subscription_facet_id: self.subscription_facet.id,
66
- pool_id: pool.id).destroy_all
67
- pool.import_audit_record(old_host_ids)
68
- end
69
-
70
52
  def import_pool(index_hosts = true)
71
53
  if pool
72
54
  ::Katello::EventQueue.push_event(::Katello::Events::ImportPool::EVENT_TYPE, pool.id)
@@ -86,29 +68,6 @@ module Katello
86
68
  Rails.logger.info "Deleted Katello::Pool with cp_id=#{pool_id}"
87
69
  end
88
70
  end
89
-
90
- def handle_content_access_mode_modified
91
- # Ideally the target_name would be the Candlepin Owner key
92
- # Since it's the displayName, and we don't update that after org creation, there could be a mismatch
93
- # For now, find the Candlepin Owner displayName from this event, and tie it back to a Katello org based on owner key
94
- owners = Katello::Resources::Candlepin::Owner.all
95
- owner = owners.find { |o| o['displayName'] == target_name }
96
-
97
- unless owner
98
- fail("Candlepin Owner %s could not be found" % target_name)
99
- end
100
-
101
- org = ::Organization.find_by!(label: owner['key'])
102
-
103
- Rails.logger.error "Received content_access_mode_modified event for org #{org.label}. This event is no longer supported."
104
- org.simple_content_access?(cached: false)
105
- end
106
-
107
- private
108
-
109
- def subscription_facet_host_ids
110
- ::Katello::SubscriptionFacetPool.where(pool_id: pool_id).joins(:subscription_facet).pluck(:host_id)
111
- end
112
71
  end
113
72
  end
114
73
  end
@@ -39,18 +39,14 @@ module Katello
39
39
  end
40
40
 
41
41
  # Even after this bug (https://github.com/pulp/pulp_rpm/issues/2821) is fixed,
42
- # it is possible to have duplicate errata asosociated to a repo.
42
+ # it is possible to have duplicate errata associated to a repo.
43
43
  if @content_type.label == 'erratum'
44
44
  to_insert.uniq! { |row| row["pulp_id"] || row[:pulp_id] }
45
45
  end
46
46
 
47
47
  next if to_insert.empty?
48
48
  insert_timestamps(to_insert)
49
- if @content_type.mutable
50
- @model_class.upsert_all(to_insert, unique_by: :pulp_id)
51
- else
52
- @model_class.insert_all(to_insert, unique_by: :pulp_id)
53
- end
49
+ upsert_with_deadlock_retry(to_insert)
54
50
  end
55
51
 
56
52
  import_associations(units) if @repository
@@ -107,11 +103,13 @@ module Katello
107
103
  def push(unit)
108
104
  if @service_class.backend_unit_identifier
109
105
  pulp_href = unit.dig(@service_class.backend_unit_identifier)
106
+ pulp_prn = unit['prn']
110
107
  else
111
108
  pulp_href = nil
109
+ pulp_prn = nil
112
110
  end
113
111
  unit_id = unit[@service_class.unit_identifier]
114
- @values[unit_id] = pulp_href
112
+ @values[unit_id] = { href: pulp_href, prn: pulp_prn }
115
113
  end
116
114
 
117
115
  def db_values
@@ -121,7 +119,10 @@ module Katello
121
119
  @final_values = ::Katello::ContentUnitIndexer.pulp_id_to_id_map(@content_type, @values.keys).map do |pulp_id, katello_id|
122
120
  #:repository_id => X, :erratum_id => y
123
121
  row = {:repository_id => @repository.id, @content_type.model_class.unit_id_field => katello_id}
124
- row[pulp_href_association_name] = @values[pulp_id] if pulp_href_association_name
122
+ if pulp_href_association_name
123
+ row[pulp_href_association_name] = @values[pulp_id][:href]
124
+ row[pulp_prn_association_name] = @values[pulp_id][:prn] if pulp_prn_association_name
125
+ end
125
126
  row
126
127
  end
127
128
  ContentUnitIndexer.insert_timestamps(@content_type.model_class, @final_values)
@@ -131,6 +132,10 @@ module Katello
131
132
  def pulp_href_association_name
132
133
  'erratum_pulp3_href' if @content_type.label == 'erratum'
133
134
  end
135
+
136
+ def pulp_prn_association_name
137
+ 'erratum_prn' if @content_type.label == 'erratum'
138
+ end
134
139
  end
135
140
 
136
141
  def insert_timestamps(units)
@@ -154,17 +159,19 @@ module Katello
154
159
  @service_class.supports_id_fetch?
155
160
  end
156
161
 
157
- def sync_repository_associations(assocication_tracker, additive: false)
162
+ def sync_repository_associations(association_tracker, additive: false)
158
163
  unless additive
159
164
  ActiveRecord::Base.connection.uncached do
160
165
  repo_associations_to_destroy = @model_class.repository_association_class.where(repository_id: @repository.id).where.
161
- not(@model_class.unit_id_field => assocication_tracker.unit_ids)
166
+ not(@model_class.unit_id_field => association_tracker.unit_ids)
162
167
  clean_filter_rules(repo_associations_to_destroy) if repo_associations_to_destroy.present? && [::Katello::ModuleStream, ::Katello::Erratum, ::Katello::PackageGroup].include?(@model_class)
163
168
  repo_associations_to_destroy.destroy_all
164
169
  end
165
170
  end
166
- return if assocication_tracker.db_values.empty?
167
- @model_class.repository_association_class.upsert_all(assocication_tracker.db_values, :unique_by => association_class_uniqiness_attributes)
171
+ return if association_tracker.db_values.empty?
172
+ @model_class.repository_association_class.upsert_all(association_tracker.db_values, :unique_by => association_class_uniqueness_attributes)
173
+
174
+ clean_duplicate_docker_tags if @model_class == Katello::DockerTag
168
175
  end
169
176
 
170
177
  def clean_filter_rules(repo_associations_to_destroy)
@@ -190,7 +197,46 @@ module Katello
190
197
  end
191
198
  end
192
199
 
193
- def association_class_uniqiness_attributes
200
+ def clean_duplicate_docker_tags
201
+ # Deduplicate docker tags by name, keeping the one with the newest updated_at
202
+ deduplicated_tags = @repository.docker_tags.group_by(&:name).map { |_name, tags| tags.max_by(&:updated_at) }
203
+ return if deduplicated_tags.empty?
204
+ valid_names = deduplicated_tags.map(&:name)
205
+ valid_taggable_ids = deduplicated_tags.map(&:id)
206
+
207
+ # Remove duplicate tags with same names as valid tags, keeping only the newest ones
208
+ # Lookup by docker_manifest is important; docker_tags usually only contains the newest tag.
209
+ tag_ids_to_remove = @repository.docker_manifests
210
+ .joins(:docker_tags)
211
+ .where(katello_docker_tags: { name: valid_names })
212
+ .where.not(katello_docker_tags: {id: valid_taggable_ids})
213
+ .pluck('katello_docker_tags.id')
214
+
215
+ return if tag_ids_to_remove.empty?
216
+ Rails.logger.info("Removing #{tag_ids_to_remove.count} duplicate docker tag associations in repository '#{@repository.label}'")
217
+ Katello::DockerTag.where(id: tag_ids_to_remove).destroy_all
218
+ end
219
+
220
+ def upsert_with_deadlock_retry(to_insert)
221
+ retry_count = 0
222
+ begin
223
+ if @content_type.mutable
224
+ @model_class.upsert_all(to_insert, unique_by: :pulp_id)
225
+ else
226
+ @model_class.insert_all(to_insert, unique_by: :pulp_id)
227
+ end
228
+ rescue ActiveRecord::Deadlocked
229
+ retry_count += 1
230
+ if retry_count <= 3
231
+ sleep(rand(1..5))
232
+ retry
233
+ else
234
+ raise
235
+ end
236
+ end
237
+ end
238
+
239
+ def association_class_uniqueness_attributes
194
240
  columns = [@model_class.unit_id_field, 'repository_id']
195
241
  found = ActiveRecord::Base.connection.indexes(@model_class.repository_association_class.table_name).find do |index|
196
242
  index.columns.sort == columns.sort
@@ -22,13 +22,22 @@ module Katello
22
22
 
23
23
  roots = Katello::RootRepository.where(:product_id => considered_products).subscribable
24
24
  roots = roots.in_content_view_version(versions).distinct if versions.present?
25
- content_ids = roots.where.not(:content_id => nil).pluck(:content_id)
26
- structured_apt_roots = roots.where(:content_id => nil)
27
- if structured_apt_roots.any?
28
- deb_repos_query = Katello::Repository.where(root: structured_apt_roots)
29
- environment = consumable.respond_to?(:environment) ? consumable.environment : consumable.content_view_environments.select(:environment_id).map(&:environment_id)
30
- deb_repos = match_environment ? deb_repos_query.where(content_view_version: versions, environment: environment) : deb_repos_query.where(:library_instance_id => nil)
31
- content_ids += deb_repos.pluck(:content_id)
25
+ content_ids = roots.where.not(:content_type => ::Katello::Repository::DEB_TYPE).pluck(:content_id)
26
+ deb_roots = roots.where(:content_type => ::Katello::Repository::DEB_TYPE)
27
+ if deb_roots.any?
28
+ # deb? roots need to be considered separately because they do not have content_ids on the root!
29
+ deb_repos_query = Katello::Repository.where(root: deb_roots)
30
+ deb_repos_library = Set.new
31
+ deb_repos_batch = []
32
+ if match_environment
33
+ consumable.content_view_environments.each do |cve|
34
+ deb_repos_batch = deb_repos_query.where("content_view_version_id = ? AND environment_id = ?", cve.content_view_version_id, cve.environment_id).where.not(library_instance_id: deb_repos_library.to_a)
35
+ deb_repos_library.merge(deb_repos_batch.pluck(:library_instance_id))
36
+ content_ids += deb_repos_batch.pluck(:content_id)
37
+ end
38
+ else
39
+ content_ids += deb_repos_query.where(:library_instance_id => nil).pluck(:content_id)
40
+ end
32
41
  end
33
42
 
34
43
  consumable.organization.enabled_product_content_for(content_ids)
@@ -81,7 +81,7 @@ module Katello
81
81
  def create_remote
82
82
  if smart_proxy_acs&.remote_href.nil?
83
83
  response = super
84
- smart_proxy_acs.update!(remote_href: response.pulp_href)
84
+ smart_proxy_acs.update!(remote_href: response.pulp_href, remote_prn: response.prn)
85
85
  end
86
86
  end
87
87
 
@@ -106,7 +106,7 @@ module Katello
106
106
  end
107
107
  response = api.alternate_content_source_api.create(name: generate_backend_object_name, paths: paths.sort,
108
108
  remote: smart_proxy_acs.remote_href)
109
- smart_proxy_acs.update!(alternate_content_source_href: response.pulp_href)
109
+ smart_proxy_acs.update!(alternate_content_source_href: response.pulp_href, alternate_content_source_prn: response.prn)
110
110
  return response
111
111
  end
112
112
  end
@@ -22,6 +22,7 @@ module Katello
22
22
  def self.generate_model_row(unit)
23
23
  {
24
24
  pulp_id: unit['pulp_href'],
25
+ pulp_prn: unit['prn'],
25
26
  checksum: unit['sha256'],
26
27
  namespace: unit['namespace'],
27
28
  version: unit['version'],
@@ -31,21 +31,21 @@ module Katello
31
31
  def refresh
32
32
  found = list(name: default_name).results.first
33
33
  if found && found.ca_certificate != ca_cert
34
- partial_update(found.pulp_href)
34
+ partial_update(found.pulp_href) # Still use pulp_href for API calls
35
35
  else
36
36
  found = create
37
37
  end
38
- persist_if_needed(found.pulp_href)
38
+ persist_if_needed(found)
39
39
  end
40
40
 
41
- def persist_if_needed(href)
41
+ def persist_if_needed(content_guard_obj)
42
42
  return if self.smart_proxy.pulp_mirror?
43
43
  Katello::Util::Support.active_record_retry do
44
44
  found = Katello::Pulp3::ContentGuard.find_by(:name => default_name)
45
45
  if found
46
- found.update(pulp_href: href)
46
+ found.update(pulp_href: content_guard_obj.pulp_href, pulp_prn: content_guard_obj.prn)
47
47
  else
48
- Katello::Pulp3::ContentGuard.create(name: default_name, pulp_href: href)
48
+ Katello::Pulp3::ContentGuard.create(name: default_name, pulp_href: content_guard_obj.pulp_href, pulp_prn: content_guard_obj.prn)
49
49
  end
50
50
  end
51
51
  end
@@ -64,6 +64,10 @@ module Katello
64
64
  PulpcoreClient::RepositoriesApi.new(core_api_client)
65
65
  end
66
66
 
67
+ def core_repository_versions_api
68
+ PulpcoreClient::RepositoryVersionsApi.new(core_api_client)
69
+ end
70
+
67
71
  def repositories_api
68
72
  repository_type.repositories_api_class.new(api_client)
69
73
  end
@@ -237,6 +241,12 @@ module Katello
237
241
  end
238
242
  end
239
243
 
244
+ def core_repository_versions_list_all(options = {})
245
+ self.class.fetch_from_list do |page_opts|
246
+ core_repository_versions_api.list(page_opts.merge(options))
247
+ end
248
+ end
249
+
240
250
  def list_all(options = {})
241
251
  self.class.fetch_from_list do |page_opts|
242
252
  repositories_api.list(page_opts.merge(options))
@@ -133,12 +133,27 @@ module Katello
133
133
  MetadataGenerator.new(export_service: self).generate!
134
134
  end
135
135
 
136
- def self.find_generated_export_view(destination_server:, organization:, name:, generated_for:, create_by_default: false)
137
- name += "-#{destination_server}" unless destination_server.blank?
138
- select_method = create_by_default ? :first_or_create : :first
139
- ::Katello::ContentView.where(name: name,
140
- organization: organization,
141
- generated_for: generated_for).send(select_method)
136
+ def self.find_export_view(name:, organization:, generated_for:, destination_server: nil)
137
+ full_name = destination_server.blank? ? name : "#{name}-#{destination_server}"
138
+
139
+ ::Katello::ContentView.where(
140
+ name: full_name,
141
+ organization: organization,
142
+ generated_for: generated_for
143
+ ).first
144
+ end
145
+
146
+ # Find or create export view
147
+ def self.find_or_create_export_view(name:, organization:, generated_for:, destination_server: nil)
148
+ find_export_view(name: name, organization: organization, generated_for: generated_for, destination_server: destination_server) ||
149
+ begin
150
+ full_name = destination_server.blank? ? name : "#{name}-#{destination_server}"
151
+ ::Katello::ContentView.create!(
152
+ name: full_name,
153
+ organization: organization,
154
+ generated_for: generated_for
155
+ )
156
+ end
142
157
  end
143
158
 
144
159
  def format
@@ -151,13 +166,13 @@ module Katello
151
166
  when UNDEFINED
152
167
  fail ::Katello::Errors::InvalidExportFormat, _("Export format must be specified for library exports.")
153
168
  when IMPORTABLE
154
- return find_generated_export_view(create_by_default: true,
169
+ return find_or_create_export_view(
155
170
  destination_server: destination_server,
156
171
  organization: organization,
157
172
  name: ::Katello::ContentView::EXPORT_LIBRARY,
158
173
  generated_for: :library_export)
159
174
  when SYNCABLE
160
- return find_generated_export_view(create_by_default: true,
175
+ return find_or_create_export_view(
161
176
  destination_server: destination_server,
162
177
  organization: organization,
163
178
  name: "#{::Katello::ContentView::EXPORT_LIBRARY}-SYNCABLE",
@@ -172,10 +187,10 @@ module Katello
172
187
  when UNDEFINED
173
188
  fail ::Katello::Errors::InvalidExportFormat, _("Export format must be specified for non-incremental repository exports.")
174
189
  when IMPORTABLE
175
- return find_generated_export_view(create_by_default: true, destination_server: nil, organization: repository.organization,
190
+ return find_or_create_export_view(destination_server: nil, organization: repository.organization,
176
191
  name: "Export-#{repository.label}-#{repository.library_instance_or_self.id}", generated_for: :repository_export)
177
192
  when SYNCABLE
178
- return find_generated_export_view(create_by_default: true, destination_server: nil, organization: repository.organization,
193
+ return find_or_create_export_view(destination_server: nil, organization: repository.organization,
179
194
  name: "Export-SYNCABLE-#{repository.label}-#{repository.library_instance_or_self.id}", generated_for: :repository_export_syncable)
180
195
  else
181
196
  fail ::Katello::Errors::InvalidExportFormat, _("Unknown repository export format '%s'.") % format
@@ -31,6 +31,7 @@ module Katello
31
31
  unit = unit.try(:with_indifferent_access)
32
32
  return {
33
33
  pulp_id: unit[unit_identifier],
34
+ pulp_prn: unit[:prn],
34
35
  checksum: unit[:sha256],
35
36
  filename: unit[:relative_path],
36
37
  name: unit[:package],
@@ -27,6 +27,7 @@ module Katello
27
27
  schema_version: unit['schema_version'],
28
28
  digest: unit['digest'],
29
29
  pulp_id: unit[unit_identifier],
30
+ pulp_prn: unit['prn'],
30
31
  annotations: unit['annotations'],
31
32
  labels: unit['labels'],
32
33
  is_bootable: unit['is_bootable'] || unit['type'] == 'bootable',
@@ -29,6 +29,7 @@ module Katello
29
29
  schema_version: unit['schema_version'],
30
30
  digest: unit['digest'],
31
31
  pulp_id: unit[unit_identifier],
32
+ pulp_prn: unit['prn'],
32
33
  annotations: unit['annotations'],
33
34
  labels: unit['labels'],
34
35
  is_bootable: unit['is_bootable'] || unit['type'] == 'bootable',
@@ -18,6 +18,7 @@ module Katello
18
18
  def self.generate_model_row(unit)
19
19
  row = {
20
20
  pulp_id: unit[unit_identifier],
21
+ pulp_prn: unit['prn'],
21
22
  name: unit['name'],
22
23
  }
23
24
 
@@ -25,6 +25,7 @@ module Katello
25
25
 
26
26
  {
27
27
  pulp_id: unit[unit_identifier],
28
+ pulp_prn: unit['prn'],
28
29
  name: filename,
29
30
  path: unit['relative_path'],
30
31
  checksum: unit['sha256'],
@@ -20,6 +20,7 @@ module Katello
20
20
  def self.generate_model_row(unit, content_type)
21
21
  {
22
22
  pulp_id: unit['pulp_href'],
23
+ pulp_prn: unit['prn'],
23
24
  name: content_type&.model_name&.call(unit),
24
25
  version: content_type&.model_version&.call(unit),
25
26
  filename: content_type&.model_filename&.call(unit),
@@ -68,6 +68,7 @@ module Katello
68
68
  shared_attributes = unit.keys & Katello::ModuleStream.column_names
69
69
  to_return = unit.select { |key, _v| shared_attributes.include?(key) }
70
70
  to_return['pulp_id'] = unit['pulp_href']
71
+ to_return['pulp_prn'] = unit['prn']
71
72
  to_return[:created_at] = DateTime.now
72
73
  to_return[:updated_at] = DateTime.now
73
74
  to_return
@@ -58,6 +58,7 @@ module Katello
58
58
  def self.generate_model_row(unit)
59
59
  custom_json = {}
60
60
  custom_json['pulp_id'] = unit['pulp_href']
61
+ custom_json['pulp_prn'] = unit['prn']
61
62
  custom_json['name'] = unit['name']
62
63
  custom_json['description'] = unit['description']
63
64
  custom_json
@@ -7,6 +7,15 @@ module Katello
7
7
  UNIT_LIMIT = 10_000
8
8
  SIGNING_SERVICE_NAME = 'katello_deb_sign'.freeze
9
9
 
10
+ def pulp_primary_api
11
+ # Sometimes we need to make sure we are talking to the pulp primary and not a smart proxy!
12
+ if smart_proxy.pulp_primary?
13
+ api
14
+ else
15
+ self.class.instance_for_type(repo, ::SmartProxy.pulp_primary).api
16
+ end
17
+ end
18
+
10
19
  def initialize_empty
11
20
  # For every empty APT library instance repository we must add at least a release component to
12
21
  # ensure we have a publishable repo with consumable metadata. Otherwise smart proxy syncs will
@@ -15,6 +24,25 @@ module Katello
15
24
  api.content_release_components_api.create(opts)
16
25
  end
17
26
 
27
+ def pulp_components
28
+ return [] if repo.version_href.blank?
29
+ return ["all"] if version_missing_structure_content?
30
+ pulp_primary_api.content_release_components_api.list({:repository_version => repo.version_href}).results.map { |x| x.plain_component }.uniq
31
+ end
32
+
33
+ def sanitize_pulp_distribution(distribution)
34
+ return "flat-repo" if distribution == "/"
35
+ return distribution.chomp("/") if distribution&.end_with?("/")
36
+ # Only needed for repository versions created with pulp_deb <= 3.6
37
+ distribution
38
+ end
39
+
40
+ def pulp_distributions
41
+ return [] if repo.version_href.blank?
42
+ return ["default"] if version_missing_structure_content?
43
+ pulp_primary_api.content_release_components_api.list({:repository_version => repo.version_href}).results.map { |x| sanitize_pulp_distribution(x.distribution) }.uniq
44
+ end
45
+
18
46
  def remote_options
19
47
  deb_remote_options = {
20
48
  policy: root.download_policy,
@@ -39,13 +67,7 @@ module Katello
39
67
  end
40
68
 
41
69
  def mirror_remote_options
42
- distributions = if repo.deb_using_structured_apt? && !version_missing_structure_content?
43
- repo.deb_pulp_distributions.join(' ')
44
- else
45
- 'default'
46
- end
47
-
48
- super.merge({distributions: distributions})
70
+ super.merge({distributions: pulp_distributions.join(' ')})
49
71
  end
50
72
 
51
73
  def version_missing_structure_content?
@@ -54,9 +76,7 @@ module Katello
54
76
  # It may also affect filtered CV versions created with very old Katello versions.
55
77
  # This method can identify such cases, so that we may fall back to simple publishing.
56
78
  return false if repo.version_href.blank?
57
- # We cannot just use api here, because this is sometimes the proxy api, and we always want to talk to the primary!
58
- api_primary = self.class.instance_for_type(repo, ::SmartProxy.pulp_primary).api
59
- version = api_primary.repository_versions_api.read(repo.version_href)
79
+ version = pulp_primary_api.repository_versions_api.read(repo.version_href)
60
80
  apt_content_types = version&.content_summary&.present&.keys
61
81
  return apt_content_types.include?('deb.package') && !apt_content_types.include?('deb.package_release_component')
62
82
  end
@@ -67,9 +87,6 @@ module Katello
67
87
  if version_missing_structure_content?
68
88
  popts.merge!({ structured: false })
69
89
  popts.merge!({ simple: true })
70
- else
71
- popts.merge!({ structured: true })
72
- popts.merge!({ simple: true }) unless repository.deb_using_structured_apt?
73
90
  end
74
91
  popts[:signing_service] = ss[0].pulp_href if ss && ss.length == 1
75
92
  popts
@@ -25,6 +25,21 @@ module Katello
25
25
  href.include?('/publications/')
26
26
  end
27
27
 
28
+ # Build a PRN from a Pulp href
29
+ # @param href [String] Pulp href (e.g., "/pulp/api/v3/contentguards/certguard/rhsm/uuid/")
30
+ # @param pulp_plugin [String] Pulp plugin name (e.g., "certguard", "container", "rpm")
31
+ # @param pulp_model [String] Pulp model name (e.g., "rhsmcertguard", "containerrepository", "rpmrepository")
32
+ # @return [String, nil] PRN string (e.g., "prn:certguard.rhsmcertguard:uuid") or nil if href doesn't match expected format
33
+ def self.build_prn(href, pulp_plugin, pulp_model)
34
+ return nil unless href
35
+
36
+ # Extract UUID from href (last non-empty path segment)
37
+ uuid = href.split('/').reject(&:empty?).last
38
+ return nil unless uuid
39
+
40
+ "prn:#{pulp_plugin}.#{pulp_model}:#{uuid}"
41
+ end
42
+
28
43
  def partial_repo_path
29
44
  fail NotImplementedError
30
45
  end
@@ -70,14 +85,14 @@ module Katello
70
85
 
71
86
  def create_remote
72
87
  response = super
73
- repo.update!(:remote_href => response.pulp_href)
88
+ repo.update!(:remote_href => response.pulp_href, :remote_prn => response.prn)
74
89
  end
75
90
 
76
91
  def update_remote
77
92
  href = repo.remote_href
78
93
  if remote_options[:url].blank?
79
94
  if href
80
- repo.update(remote_href: nil)
95
+ repo.update(remote_href: nil, remote_prn: nil)
81
96
  delete_remote(href: href)
82
97
  end
83
98
  else
@@ -109,7 +124,10 @@ module Katello
109
124
  end
110
125
 
111
126
  def self.instance_for_type(repo, smart_proxy)
112
- Katello::RepositoryTypeManager.enabled_repository_types[repo.root.content_type].pulp3_service_class.new(repo, smart_proxy)
127
+ repo_types = Katello::RepositoryTypeManager.enabled_repository_types(false)
128
+ # Populate cache on first call if empty
129
+ repo_types = Katello::RepositoryTypeManager.enabled_repository_types if repo_types.empty?
130
+ repo_types[repo.root.content_type].pulp3_service_class.new(repo, smart_proxy)
113
131
  end
114
132
 
115
133
  def should_purge_empty_contents?
@@ -157,7 +175,8 @@ module Katello
157
175
 
158
176
  def distribution_needs_update?
159
177
  if distribution_reference
160
- expected = secure_distribution_options(relative_path).except(:name).compact
178
+ # FIXME: Workaround for https://github.com/pulp/pulpcore/issues/7004
179
+ expected = secure_distribution_options(relative_path).except(:name, :content_guard_prn).compact
161
180
  actual = get_distribution&.to_hash || {}
162
181
  expected != actual.slice(*expected.keys)
163
182
  elsif repo.environment
@@ -180,7 +199,8 @@ module Katello
180
199
  RepositoryReference.where(
181
200
  root_repository_id: repo.root_id,
182
201
  content_view_id: repo.content_view.id,
183
- repository_href: response.pulp_href).create!
202
+ repository_href: response.pulp_href,
203
+ repository_prn: response.prn).create!
184
204
  response
185
205
  end
186
206
  end
@@ -279,7 +299,9 @@ module Katello
279
299
  end
280
300
 
281
301
  def create_distribution(path)
282
- distribution_data = api.distribution_class.new(secure_distribution_options(path))
302
+ options = secure_distribution_options(path)
303
+ options.delete(:content_guard_prn) # Remove PRN field before sending to Pulp
304
+ distribution_data = api.distribution_class.new(options)
283
305
  unless ::Katello::RepositoryTypeManager.find(repo.content_type).pulp3_skip_publication
284
306
  fail_missing_publication(distribution_data.publication)
285
307
  end
@@ -300,7 +322,8 @@ module Katello
300
322
  unless ::Katello::RepositoryTypeManager.find(repo.content_type).pulp3_skip_publication
301
323
  fail_missing_publication(options[:publication])
302
324
  end
303
- distribution_reference.update(:content_guard_href => options[:content_guard])
325
+ content_guard_prn = options.delete(:content_guard_prn) # Extract PRN and remove from options
326
+ distribution_reference.update(:content_guard_href => options[:content_guard], :content_guard_prn => content_guard_prn)
304
327
  api.distributions_api.partial_update(distribution_reference.href, options)
305
328
  end
306
329
  end
@@ -368,7 +391,23 @@ module Katello
368
391
  def save_distribution_references(hrefs)
369
392
  hrefs.each do |href|
370
393
  pulp3_distribution_data = api.get_distribution(href)
371
- path, content_guard_href = pulp3_distribution_data&.base_path, pulp3_distribution_data&.content_guard
394
+ path = pulp3_distribution_data&.base_path
395
+ content_guard_href = pulp3_distribution_data&.content_guard
396
+
397
+ # FIXME: Workaround for ansible distributions not returning PRN
398
+ # Remove once https://github.com/pulp/pulp_ansible/issues/2320 is fixed
399
+ if repo.ansible_collection?
400
+ prn = self.class.build_prn(href, 'ansible', 'ansibledistribution')
401
+ else
402
+ prn = pulp3_distribution_data&.prn
403
+ end
404
+
405
+ # Build content_guard PRN from href if content_guard exists
406
+ # FIXME: Workaround for https://github.com/pulp/pulpcore/issues/7004
407
+ content_guard_prn = if content_guard_href&.include?('/contentguards/certguard/rhsm/')
408
+ self.class.build_prn(content_guard_href, 'certguard', 'rhsmcertguard')
409
+ end
410
+
372
411
  if distribution_reference
373
412
  found_distribution = read_distribution(distribution_reference.href)
374
413
  unless found_distribution
@@ -377,7 +416,14 @@ module Katello
377
416
  end
378
417
  unless distribution_reference
379
418
  # Ensure that duplicates won't be created in the case of a race condition
380
- DistributionReference.where(path: path, href: href, repository_id: repo.id, content_guard_href: content_guard_href).first_or_create!
419
+ DistributionReference.where(
420
+ path: path,
421
+ href: href,
422
+ prn: prn,
423
+ repository_id: repo.id,
424
+ content_guard_href: content_guard_href,
425
+ content_guard_prn: content_guard_prn
426
+ ).first_or_create!
381
427
  end
382
428
  end
383
429
  end
@@ -444,8 +490,11 @@ module Katello
444
490
  secured_distribution_options = {}
445
491
  if root.unprotected
446
492
  secured_distribution_options[:content_guard] = nil
493
+ secured_distribution_options[:content_guard_prn] = nil
447
494
  else
448
- secured_distribution_options[:content_guard] = ::Katello::Pulp3::ContentGuard.first.pulp_href
495
+ content_guard = ::Katello::Pulp3::ContentGuard.first
496
+ secured_distribution_options[:content_guard] = content_guard.pulp_href
497
+ secured_distribution_options[:content_guard_prn] = content_guard.pulp_prn
449
498
  end
450
499
  secured_distribution_options.merge!(distribution_options(path))
451
500
  end