katello 4.18.1 → 4.19.0.rc2

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 (388) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/locale/bn/katello.js +379 -109
  3. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +379 -109
  4. data/app/assets/javascripts/katello/locale/ca/katello.js +379 -109
  5. data/app/assets/javascripts/katello/locale/cs/katello.js +380 -110
  6. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +382 -112
  7. data/app/assets/javascripts/katello/locale/de/katello.js +385 -115
  8. data/app/assets/javascripts/katello/locale/de_AT/katello.js +379 -109
  9. data/app/assets/javascripts/katello/locale/de_DE/katello.js +379 -109
  10. data/app/assets/javascripts/katello/locale/el/katello.js +380 -110
  11. data/app/assets/javascripts/katello/locale/en/katello.js +380 -110
  12. data/app/assets/javascripts/katello/locale/en_GB/katello.js +379 -109
  13. data/app/assets/javascripts/katello/locale/en_US/katello.js +379 -109
  14. data/app/assets/javascripts/katello/locale/es/katello.js +383 -113
  15. data/app/assets/javascripts/katello/locale/et_EE/katello.js +379 -109
  16. data/app/assets/javascripts/katello/locale/fr/katello.js +388 -118
  17. data/app/assets/javascripts/katello/locale/gl/katello.js +379 -109
  18. data/app/assets/javascripts/katello/locale/gu/katello.js +379 -109
  19. data/app/assets/javascripts/katello/locale/he_IL/katello.js +379 -109
  20. data/app/assets/javascripts/katello/locale/hi/katello.js +379 -109
  21. data/app/assets/javascripts/katello/locale/id/katello.js +379 -109
  22. data/app/assets/javascripts/katello/locale/it/katello.js +379 -109
  23. data/app/assets/javascripts/katello/locale/ja/katello.js +388 -118
  24. data/app/assets/javascripts/katello/locale/ka/katello.js +385 -115
  25. data/app/assets/javascripts/katello/locale/kn/katello.js +379 -109
  26. data/app/assets/javascripts/katello/locale/ko/katello.js +388 -118
  27. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +379 -109
  28. data/app/assets/javascripts/katello/locale/mr/katello.js +379 -109
  29. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +379 -109
  30. data/app/assets/javascripts/katello/locale/or/katello.js +379 -109
  31. data/app/assets/javascripts/katello/locale/pa/katello.js +379 -109
  32. data/app/assets/javascripts/katello/locale/pl/katello.js +379 -109
  33. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +379 -109
  34. data/app/assets/javascripts/katello/locale/pt/katello.js +379 -109
  35. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +383 -113
  36. data/app/assets/javascripts/katello/locale/ro/katello.js +379 -109
  37. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +379 -109
  38. data/app/assets/javascripts/katello/locale/ru/katello.js +381 -111
  39. data/app/assets/javascripts/katello/locale/sl/katello.js +379 -109
  40. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +379 -109
  41. data/app/assets/javascripts/katello/locale/ta/katello.js +379 -109
  42. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +379 -109
  43. data/app/assets/javascripts/katello/locale/te/katello.js +379 -109
  44. data/app/assets/javascripts/katello/locale/tr/katello.js +379 -109
  45. data/app/assets/javascripts/katello/locale/vi/katello.js +379 -109
  46. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +379 -109
  47. data/app/assets/javascripts/katello/locale/zh/katello.js +379 -109
  48. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +388 -118
  49. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +381 -111
  50. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +41 -12
  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_view_filter_rules_controller.rb +1 -1
  54. data/app/controllers/katello/api/v2/content_views_controller.rb +18 -3
  55. data/app/controllers/katello/api/v2/debs_controller.rb +21 -11
  56. data/app/controllers/katello/api/v2/docker_tags_controller.rb +7 -0
  57. data/app/controllers/katello/api/v2/flatpak_remote_repositories_controller.rb +21 -19
  58. data/app/controllers/katello/api/v2/host_debs_controller.rb +16 -1
  59. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +3 -60
  60. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +10 -53
  61. data/app/controllers/katello/api/v2/repositories_controller.rb +0 -1
  62. data/app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb +10 -0
  63. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +3 -0
  64. data/app/lib/actions/candlepin/activation_key/create.rb +0 -2
  65. data/app/lib/actions/candlepin/activation_key/update.rb +0 -2
  66. data/app/lib/actions/candlepin/product/content_create.rb +3 -5
  67. data/app/lib/actions/candlepin/product/content_update.rb +2 -3
  68. data/app/lib/actions/helpers/rolling_cv_repos.rb +1 -1
  69. data/app/lib/actions/katello/activation_key/create.rb +0 -1
  70. data/app/lib/actions/katello/activation_key/update.rb +0 -2
  71. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +1 -6
  72. data/app/lib/actions/katello/content_credential/update.rb +1 -1
  73. data/app/lib/actions/katello/content_view/add_rolling_repo_clone.rb +18 -24
  74. data/app/lib/actions/katello/content_view/create.rb +9 -4
  75. data/app/lib/actions/katello/content_view/refresh_rolling_repo.rb +6 -1
  76. data/app/lib/actions/katello/content_view/remove_rolling_repo_clone.rb +16 -11
  77. data/app/lib/actions/katello/content_view/update.rb +34 -7
  78. data/app/lib/actions/katello/product/content_create.rb +2 -2
  79. data/app/lib/actions/katello/product/content_destroy.rb +1 -1
  80. data/app/lib/actions/katello/repository/check_matching_content.rb +1 -1
  81. data/app/lib/actions/katello/repository/clone_contents.rb +1 -1
  82. data/app/lib/actions/katello/repository/create.rb +1 -1
  83. data/app/lib/actions/katello/repository/destroy.rb +4 -4
  84. data/app/lib/actions/katello/repository/finish_upload.rb +1 -1
  85. data/app/lib/actions/katello/repository/sync.rb +1 -1
  86. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -2
  87. data/app/lib/actions/pulp3/orchestration/repository/generate_metadata.rb +1 -1
  88. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +1 -1
  89. data/app/lib/actions/pulp3/repository/save_publication.rb +3 -1
  90. data/app/lib/actions/pulp3/repository/save_version.rb +45 -24
  91. data/app/lib/actions/pulp3/repository/save_versions.rb +2 -1
  92. data/app/lib/katello/resources/candlepin/activation_key.rb +3 -4
  93. data/app/lib/katello/resources/candlepin/upstream_job.rb +9 -1
  94. data/app/lib/katello/resources/candlepin.rb +4 -0
  95. data/app/models/katello/authorization/repository.rb +17 -4
  96. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +0 -7
  97. data/app/models/katello/content_view_deb_filter.rb +10 -0
  98. data/app/models/katello/content_view_deb_filter_rule.rb +7 -0
  99. data/app/models/katello/deb.rb +10 -10
  100. data/app/models/katello/erratum.rb +1 -1
  101. data/app/models/katello/glue/provider.rb +14 -3
  102. data/app/models/katello/host/content_facet.rb +1 -1
  103. data/app/models/katello/host/subscription_facet.rb +1 -7
  104. data/app/models/katello/product_content.rb +2 -2
  105. data/app/models/katello/repository.rb +4 -23
  106. data/app/models/katello/root_repository.rb +2 -5
  107. data/app/services/katello/candlepin/event_handler.rb +0 -33
  108. data/app/services/katello/candlepin/message_handler.rb +0 -41
  109. data/app/services/katello/content_unit_indexer.rb +59 -13
  110. data/app/services/katello/product_content_finder.rb +5 -4
  111. data/app/services/katello/pulp3/alternate_content_source.rb +2 -2
  112. data/app/services/katello/pulp3/ansible_collection.rb +1 -0
  113. data/app/services/katello/pulp3/api/content_guard.rb +5 -5
  114. data/app/services/katello/pulp3/api/core.rb +10 -0
  115. data/app/services/katello/pulp3/deb.rb +1 -0
  116. data/app/services/katello/pulp3/docker_manifest.rb +1 -0
  117. data/app/services/katello/pulp3/docker_manifest_list.rb +1 -0
  118. data/app/services/katello/pulp3/docker_tag.rb +1 -0
  119. data/app/services/katello/pulp3/file_unit.rb +1 -0
  120. data/app/services/katello/pulp3/generic_content_unit.rb +1 -0
  121. data/app/services/katello/pulp3/module_stream.rb +1 -0
  122. data/app/services/katello/pulp3/package_group.rb +1 -0
  123. data/app/services/katello/pulp3/repository/apt.rb +41 -16
  124. data/app/services/katello/pulp3/repository.rb +59 -10
  125. data/app/services/katello/pulp3/rpm.rb +3 -2
  126. data/app/services/katello/pulp3/srpm.rb +3 -2
  127. data/app/services/katello/pulp3/task_group.rb +1 -1
  128. data/app/services/katello/registration_manager.rb +19 -17
  129. data/app/services/katello/repository_type_manager.rb +7 -5
  130. data/app/services/katello/smart_proxy_helper.rb +1 -6
  131. data/app/views/foreman/job_templates/upload_profile.erb +5 -0
  132. data/app/views/katello/api/v2/activation_keys/base.json.rabl +1 -1
  133. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  134. data/app/views/katello/api/v2/debs/thindex.json.rabl +6 -0
  135. data/app/views/katello/api/v2/docker_tags/_base.json.rabl +32 -0
  136. data/app/views/katello/api/v2/docker_tags/show.json.rabl +0 -5
  137. data/app/views/katello/api/v2/flatpak_remotes/index.json.rabl +6 -0
  138. data/app/views/katello/api/v2/host_debs/installed_debs.json.rabl +6 -0
  139. data/app/views/katello/api/v2/hosts_bulk_actions/applicable_errata.json.rabl +1 -1
  140. data/app/views/katello/api/v2/hosts_bulk_actions/applicable_erratum.json.rabl +9 -0
  141. data/app/views/katello/api/v2/hosts_bulk_actions/installable_errata.json.rabl +1 -1
  142. data/app/views/katello/api/v2/hosts_bulk_actions/{erratum.json.rabl → installable_erratum.json.rabl} +3 -3
  143. data/app/views/katello/api/v2/subscription_facet/base.json.rabl +1 -1
  144. data/config/initializers/monkeys.rb +1 -0
  145. data/config/routes/api/v2.rb +2 -2
  146. data/config/routes/overrides.rb +2 -7
  147. data/config/routes.rb +2 -0
  148. data/db/migrate/20211019192121_create_cdn_configuration.katello.rb +1 -1
  149. data/db/migrate/20250912000000_add_pulp_prn_fields.rb +73 -0
  150. data/db/migrate/20250912000001_populate_pulp_prn_fields.rb +403 -0
  151. data/db/migrate/20251009142516_remove_auto_attach_from_activation_keys.rb +5 -0
  152. data/db/migrate/20251009142517_remove_autoheal_from_subscription_facets.rb +5 -0
  153. data/db/seeds.d/111-upgrade_tasks.rb +2 -0
  154. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/bn.po +10 -0
  155. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/bn_IN.po +10 -0
  156. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ca.po +10 -0
  157. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/cs_CZ.po +10 -0
  158. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de.po +10 -0
  159. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de_AT.po +10 -0
  160. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de_DE.po +10 -0
  161. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/el.po +12 -2
  162. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/en_GB.po +10 -0
  163. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/en_US.po +10 -0
  164. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/es.po +10 -0
  165. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/et_EE.po +10 -0
  166. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +10 -0
  167. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/gl.po +10 -0
  168. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/gu.po +10 -0
  169. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/he_IL.po +10 -0
  170. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/hi.po +10 -0
  171. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/id.po +10 -0
  172. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/it.po +10 -0
  173. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +10 -0
  174. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ka.po +10 -0
  175. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/kn.po +10 -0
  176. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +10 -0
  177. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ml_IN.po +10 -0
  178. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/mr.po +10 -0
  179. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/nl_NL.po +10 -0
  180. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/or.po +10 -0
  181. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pa.po +10 -0
  182. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pl.po +10 -0
  183. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pl_PL.po +10 -0
  184. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt.po +10 -0
  185. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt_BR.po +10 -0
  186. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ro.po +10 -0
  187. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ro_RO.po +10 -0
  188. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ru.po +10 -0
  189. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/sl.po +10 -0
  190. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/sv_SE.po +10 -0
  191. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ta.po +10 -0
  192. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ta_IN.po +10 -0
  193. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/te.po +10 -0
  194. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/tr.po +10 -0
  195. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/vi.po +10 -0
  196. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/vi_VN.po +10 -0
  197. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh.po +10 -0
  198. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +10 -0
  199. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_TW.po +10 -0
  200. data/lib/katello/permission_creator.rb +2 -2
  201. data/lib/katello/permissions/host_permissions.rb +0 -6
  202. data/lib/katello/plugin.rb +17 -8
  203. data/lib/katello/tasks/jenkins.rake +1 -1
  204. data/lib/katello/tasks/upgrades/4.19/enable_structured_apt_for_deb.rake +87 -0
  205. data/lib/katello/tasks/upgrades/4.19/populate_repository_version_prns.rake +32 -0
  206. data/lib/katello/version.rb +1 -1
  207. data/lib/monkeys/fix_rpm_repository_gpgcheck.rb +38 -0
  208. data/locale/action_names.rb +0 -6
  209. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  210. data/locale/bn/katello.po +379 -109
  211. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  212. data/locale/bn_IN/katello.po +379 -109
  213. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  214. data/locale/ca/katello.po +379 -109
  215. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  216. data/locale/cs/katello.po +380 -111
  217. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  218. data/locale/cs_CZ/katello.po +382 -112
  219. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  220. data/locale/de/katello.po +386 -116
  221. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  222. data/locale/de_AT/katello.po +379 -109
  223. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  224. data/locale/de_DE/katello.po +379 -109
  225. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  226. data/locale/el/katello.po +381 -111
  227. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  228. data/locale/en/katello.po +380 -111
  229. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  230. data/locale/en_GB/katello.po +379 -109
  231. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  232. data/locale/en_US/katello.po +379 -109
  233. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  234. data/locale/es/katello.po +383 -113
  235. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  236. data/locale/et_EE/katello.po +379 -109
  237. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  238. data/locale/fr/katello.po +389 -119
  239. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  240. data/locale/gl/katello.po +379 -109
  241. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  242. data/locale/gu/katello.po +379 -109
  243. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  244. data/locale/he_IL/katello.po +379 -109
  245. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  246. data/locale/hi/katello.po +379 -109
  247. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  248. data/locale/id/katello.po +379 -109
  249. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  250. data/locale/it/katello.po +379 -109
  251. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  252. data/locale/ja/katello.po +390 -119
  253. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  254. data/locale/ka/katello.po +385 -115
  255. data/locale/katello.pot +1273 -831
  256. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  257. data/locale/kn/katello.po +379 -109
  258. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  259. data/locale/ko/katello.po +389 -119
  260. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  261. data/locale/ml_IN/katello.po +379 -109
  262. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  263. data/locale/mr/katello.po +379 -109
  264. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  265. data/locale/nl_NL/katello.po +379 -109
  266. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  267. data/locale/or/katello.po +379 -109
  268. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  269. data/locale/pa/katello.po +379 -109
  270. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  271. data/locale/pl/katello.po +379 -109
  272. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  273. data/locale/pl_PL/katello.po +379 -109
  274. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  275. data/locale/pt/katello.po +379 -109
  276. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  277. data/locale/pt_BR/katello.po +383 -113
  278. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  279. data/locale/ro/katello.po +379 -109
  280. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  281. data/locale/ro_RO/katello.po +379 -109
  282. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  283. data/locale/ru/katello.po +381 -111
  284. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  285. data/locale/sl/katello.po +379 -109
  286. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  287. data/locale/sv_SE/katello.po +379 -109
  288. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  289. data/locale/ta/katello.po +379 -109
  290. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  291. data/locale/ta_IN/katello.po +379 -109
  292. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  293. data/locale/te/katello.po +379 -109
  294. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  295. data/locale/tr/katello.po +379 -109
  296. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  297. data/locale/vi/katello.po +379 -109
  298. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  299. data/locale/vi_VN/katello.po +379 -109
  300. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  301. data/locale/zh/katello.po +379 -109
  302. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  303. data/locale/zh_CN/katello.po +389 -119
  304. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  305. data/locale/zh_TW/katello.po +381 -111
  306. data/webpack/ForemanColumnExtensions/index.js +46 -2
  307. data/webpack/components/Content/Details/__tests__/__snapshots__/ContentDetails.test.js.snap +2 -2
  308. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +0 -2
  309. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeEditModal.test.js +0 -2
  310. data/webpack/components/extensions/Hosts/ActionsBar/index.js +1 -0
  311. data/webpack/components/extensions/Hosts/BulkActions/BulkActionsConstants.js +7 -0
  312. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/BulkChangeHostCollectionsModal.js +388 -0
  313. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/__tests__/BulkChangeHostCollectionsModal.test.js +640 -0
  314. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/actions.js +28 -0
  315. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/index.js +71 -0
  316. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/02_BulkErrataTable.js +1 -1
  317. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/BulkErrataWizard.js +1 -1
  318. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/02_BulkPackagesTable.js +11 -4
  319. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/BulkPackagesWizard.js +51 -24
  320. data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/01_BulkRepositorySetsTable.js +1 -1
  321. data/webpack/components/extensions/Hosts/BulkActions/HostReview.js +8 -1
  322. data/webpack/containers/Application/config.js +11 -1
  323. data/webpack/global_index.js +3 -0
  324. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/BootedContainerImagesConstants.js +1 -1
  325. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/BootedContainerImagesPage.js +7 -43
  326. data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/__tests__/bootedContainerImagesPage.test.js +1 -1
  327. data/webpack/scenes/ContainerImages/ContainerImagesPage.js +86 -0
  328. data/webpack/scenes/ContainerImages/LabelsAnnotationsModal.js +105 -0
  329. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetails.js +218 -0
  330. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetailsActions.js +15 -0
  331. data/webpack/scenes/ContainerImages/Synced/Details/ManifestDetailsSelectors.js +16 -0
  332. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/ManifestDetails.test.js +395 -0
  333. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/manifestDetails.fixtures.json +43 -0
  334. data/webpack/scenes/ContainerImages/Synced/Details/__tests__/manifestList.fixtures.json +58 -0
  335. data/webpack/scenes/ContainerImages/Synced/Details/index.js +4 -0
  336. data/webpack/scenes/ContainerImages/Synced/SyncedContainerImagesPage.js +359 -0
  337. data/webpack/scenes/ContainerImages/Synced/SyncedContainerImagesPage.scss +21 -0
  338. data/webpack/scenes/ContainerImages/Synced/__tests__/LabelsAnnotationsModal.test.js +69 -0
  339. data/webpack/scenes/ContainerImages/Synced/__tests__/SyncedContainerImagesPage.test.js +335 -0
  340. data/webpack/scenes/ContainerImages/Synced/__tests__/syncedContainerImages.fixtures.json +105 -0
  341. data/webpack/scenes/ContainerImages/TableEmptyState.js +67 -0
  342. data/webpack/scenes/ContainerImages/containerImagesHelpers.js +48 -0
  343. data/webpack/scenes/ContainerImages/index.js +4 -0
  344. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +29 -3
  345. data/webpack/scenes/ContentViews/Create/__tests__/contentViewCreateResult.fixtures.json +1 -0
  346. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +45 -1
  347. data/webpack/scenes/ContentViews/Delete/__tests__/affectedHosts.fixtures.json +0 -1
  348. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +59 -1
  349. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +1 -0
  350. data/webpack/scenes/ContentViews/Details/Filters/Rules/DebPackage/AddEditDebPackageRuleModal.js +164 -24
  351. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVDebFilterContent.test.js +268 -0
  352. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvDebFilterDetail.fixtures.json +95 -0
  353. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvDebFilterRules.fixtures.json +31 -0
  354. data/webpack/scenes/ContentViews/Details/Filters/__tests__/emptyCVDebFilterRules.fixtures.json +10 -0
  355. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/hosts.fixtures.json +0 -1
  356. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvAffectedHosts.fixture.json +0 -1
  357. data/webpack/scenes/ContentViews/Details/__tests__/contentViewRollingDetail.test.js +15 -0
  358. data/webpack/scenes/ContentViews/Details/__tests__/contentViewRollingDetails.fixtures.json +1 -0
  359. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +9 -0
  360. data/webpack/scenes/FlatpakRemotes/CreateEdit/CreateFlatpakRemoteModal.js +5 -3
  361. data/webpack/scenes/FlatpakRemotes/CreateEdit/EditFlatpakRemotesModal.js +1 -1
  362. data/webpack/scenes/FlatpakRemotes/CreateEdit/FlatpakRemoteform.js +35 -3
  363. data/webpack/scenes/FlatpakRemotes/Details/FlatpakRemoteDetails.js +1 -1
  364. data/webpack/scenes/FlatpakRemotes/Details/RemoteRepositories/RemoteRepositoriesTable.css +3 -0
  365. data/webpack/scenes/FlatpakRemotes/Details/RemoteRepositories/RemoteRepositoriesTable.js +63 -132
  366. data/webpack/scenes/FlatpakRemotes/FlatpakRemotesPage.js +67 -143
  367. data/webpack/scenes/SmartProxy/ExpandableCvDetails.js +10 -2
  368. data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +13 -2
  369. data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -0
  370. data/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +8 -2
  371. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +67 -1
  372. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +2 -2
  373. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +0 -2
  374. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +15 -5
  375. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +22 -5
  376. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +141 -0
  377. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +2 -2
  378. metadata +82 -56
  379. data/app/lib/actions/katello/host/attach_subscriptions.rb +0 -59
  380. data/app/lib/actions/katello/host/auto_attach_subscriptions.rb +0 -22
  381. data/app/lib/actions/katello/host/remove_subscriptions.rb +0 -50
  382. data/app/lib/actions/katello/organization/simple_content_access/disable.rb +0 -25
  383. data/app/lib/actions/katello/organization/simple_content_access/enable.rb +0 -25
  384. data/app/lib/actions/katello/organization/simple_content_access/toggle.rb +0 -42
  385. data/lib/katello/tasks/migrate_structure_content_for_deb.rake +0 -105
  386. data/lib/katello/tasks/upgrades/4.2/remove_checksum_values.rake +0 -17
  387. /data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/__tests__/bootedContainerImages.fixtures.js +0 -0
  388. /data/webpack/scenes/{BootedContainerImages → ContainerImages/Booted}/index.js +0 -0
@@ -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,10 +22,11 @@ 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)
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)
29
30
  deb_repos_library = Set.new
30
31
  deb_repos_batch = []
31
32
  if match_environment
@@ -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))
@@ -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,26 +67,26 @@ 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?
52
- # There may be old pulp_deb repo versions that have no package_release_components to go with the packages.
74
+ # There may be old pulp_deb repo versions that have no structure content for some or all packages.
53
75
  # This could be because packages were uploaded with Katello < 4.12
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.
78
+ #
79
+ # Note: For performance reasons, we identify affected repos using a heuristic.
80
+ # Namely, repo versions that have more packages than PRC (package_release_components) are affected.
81
+ # In theory, there could be repo versions where some packages have multiple PRC, while others have zero.
82
+ # If this results in an overall PRC count > than the number of packages, then the repo version is not
83
+ # identified as affected. We have not seen such cases in the real world, and checking each package
84
+ # individually would be prohibitively inefficent.
56
85
  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)
60
- apt_content_types = version&.content_summary&.present&.keys
61
- return apt_content_types.include?('deb.package') && !apt_content_types.include?('deb.package_release_component')
86
+ version_content = pulp_primary_api.repository_versions_api.read(repo.version_href).content_summary.present
87
+ packages = version_content.fetch('deb.package', {:count => 0})
88
+ prc = version_content.fetch('deb.package_release_component', {:count => 0})
89
+ return packages.fetch(:count) > prc.fetch(:count)
62
90
  end
63
91
 
64
92
  def publication_options(repository)
@@ -67,9 +95,6 @@ module Katello
67
95
  if version_missing_structure_content?
68
96
  popts.merge!({ structured: false })
69
97
  popts.merge!({ simple: true })
70
- else
71
- popts.merge!({ structured: true })
72
- popts.merge!({ simple: true }) unless repository.deb_using_structured_apt?
73
98
  end
74
99
  popts[:signing_service] = ss[0].pulp_href if ss && ss.length == 1
75
100
  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
@@ -5,7 +5,7 @@ module Katello
5
5
  CONTENT_TYPE = "rpm".freeze
6
6
  PULPCORE_CONTENT_TYPE = "rpm.package".freeze
7
7
 
8
- PULP_INDEXED_FIELDS = %w(pulp_href name version release arch epoch summary is_modular rpm_sourcerpm location_href pkgId).freeze
8
+ PULP_INDEXED_FIELDS = %w(pulp_href prn name version release arch epoch summary is_modular rpm_sourcerpm location_href pkgId).freeze
9
9
 
10
10
  lazy_accessor :description, :license, :buildhost, :vendor, :relativepath, :children, :checksumtype,
11
11
  :changelog, :group, :size, :url, :build_time, :group,
@@ -90,7 +90,8 @@ module Katello
90
90
  custom_json = {}
91
91
  custom_json['modular'] = unit['is_modular']
92
92
  custom_json['pulp_id'] = unit['pulp_href']
93
- (PULP_INDEXED_FIELDS - ['is_modular', 'pulp_href', 'rpm_sourcerpm', 'pkgId', 'location_href']).
93
+ custom_json['pulp_prn'] = unit['prn'] # Also store PRN alongside pulp_id
94
+ (PULP_INDEXED_FIELDS - ['is_modular', 'pulp_href', 'prn', 'rpm_sourcerpm', 'pkgId', 'location_href']).
94
95
  each { |field| custom_json[field] = unit[field] }
95
96
  custom_json['release_sortable'] = Util::Package.sortable_version(unit['release'])
96
97
  custom_json['version_sortable'] = Util::Package.sortable_version(unit['version'])
@@ -6,7 +6,7 @@ module Katello
6
6
 
7
7
  CONTENT_TYPE = "srpm".freeze
8
8
 
9
- PULP_INDEXED_FIELDS = %w(pulp_href name version release arch epoch summary location_href pkgId).freeze
9
+ PULP_INDEXED_FIELDS = %w(pulp_href prn name version release arch epoch summary location_href pkgId).freeze
10
10
 
11
11
  lazy_accessor :pulp_facts, :initializer => :backend_data
12
12
 
@@ -68,7 +68,8 @@ module Katello
68
68
  def self.generate_model_row(unit)
69
69
  custom_json = {}
70
70
  custom_json['pulp_id'] = unit['pulp_href']
71
- (PULP_INDEXED_FIELDS - ['pulp_href', 'pkgId', 'location_href']).
71
+ custom_json['pulp_prn'] = unit['prn']
72
+ (PULP_INDEXED_FIELDS - ['pulp_href', 'prn', 'pkgId', 'location_href']).
72
73
  each { |field| custom_json[field] = unit[field] }
73
74
  custom_json['release_sortable'] = Util::Package.sortable_version(unit['release'])
74
75
  custom_json['version_sortable'] = Util::Package.sortable_version(unit['version'])
@@ -55,7 +55,7 @@ module Katello
55
55
  end
56
56
 
57
57
  def done?
58
- task_group_data['all_tasks_dispatched'] == true && IN_PROGRESS_STATES.all? { |state| task_group_data[state] == 0 }
58
+ IN_PROGRESS_STATES.all? { |state| task_group_data[state] == 0 }
59
59
  end
60
60
 
61
61
  def group_progress_reports