katello 4.3.0 → 4.4.0

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

Potentially problematic release.


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

Files changed (443) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/common/vendor.js +0 -1
  3. data/app/controllers/katello/api/v2/api_controller.rb +13 -4
  4. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +3 -0
  5. data/app/controllers/katello/api/v2/content_views_controller.rb +48 -0
  6. data/app/controllers/katello/api/v2/environments_controller.rb +2 -0
  7. data/app/controllers/katello/api/v2/host_packages_controller.rb +21 -1
  8. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +30 -1
  9. data/app/controllers/katello/api/v2/organizations_controller.rb +10 -6
  10. data/app/controllers/katello/api/v2/packages_controller.rb +4 -0
  11. data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +10 -1
  12. data/app/controllers/katello/api/v2/repositories_controller.rb +20 -7
  13. data/app/controllers/katello/api/v2/repository_sets_controller.rb +7 -0
  14. data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +3 -0
  15. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +32 -0
  16. data/app/controllers/katello/remote_execution_controller.rb +5 -4
  17. data/app/helpers/katello/content_source_helper.rb +43 -0
  18. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +4 -0
  19. data/app/lib/actions/katello/cdn_configuration/update.rb +6 -8
  20. data/app/lib/actions/katello/content_view/publish.rb +5 -0
  21. data/app/lib/actions/katello/content_view_version/incremental_update.rb +17 -3
  22. data/app/lib/actions/katello/repository/discover.rb +1 -14
  23. data/app/lib/actions/katello/repository/errata_mail.rb +4 -5
  24. data/app/lib/actions/katello/repository/filtered_index_content.rb +1 -1
  25. data/app/lib/actions/katello/repository/sync.rb +2 -2
  26. data/app/lib/actions/pulp3/abstract.rb +1 -1
  27. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +14 -4
  28. data/app/lib/actions/pulp3/content_view_version/create_import_history.rb +1 -2
  29. data/app/lib/actions/pulp3/content_view_version/import.rb +7 -0
  30. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +7 -5
  31. data/app/lib/actions/pulp3/repository/copy_content.rb +1 -1
  32. data/app/lib/actions/pulp3/repository/reclaim_space.rb +3 -10
  33. data/app/lib/actions/pulp3/repository/save_artifact.rb +1 -0
  34. data/app/lib/katello/concerns/base_template_scope_extensions.rb +11 -0
  35. data/app/lib/katello/errors.rb +3 -3
  36. data/app/lib/katello/logging.rb +6 -1
  37. data/app/lib/katello/repo_discovery.rb +27 -19
  38. data/app/lib/katello/resources/cdn/katello_cdn.rb +71 -10
  39. data/app/lib/katello/resources/cdn.rb +4 -2
  40. data/app/lib/katello/util/deduplication_migrator.rb +105 -0
  41. data/app/lib/katello/util/pulpcore_content_filters.rb +2 -1
  42. data/app/models/katello/candlepin/repository_mapper.rb +12 -3
  43. data/app/models/katello/cdn_configuration.rb +40 -6
  44. data/app/models/katello/concerns/audit_comment_extensions.rb +17 -0
  45. data/app/models/katello/concerns/host_managed_extensions.rb +33 -1
  46. data/app/models/katello/concerns/organization_extensions.rb +5 -1
  47. data/app/models/katello/concerns/pulp_database_unit.rb +59 -173
  48. data/app/models/katello/concerns/remote_execution_proxy_selector_extensions.rb +11 -0
  49. data/app/models/katello/concerns/smart_proxy_extensions.rb +2 -1
  50. data/app/models/katello/content_view.rb +4 -4
  51. data/app/models/katello/content_view_filter.rb +1 -1
  52. data/app/models/katello/content_view_history.rb +1 -1
  53. data/app/models/katello/content_view_version.rb +6 -2
  54. data/app/models/katello/content_view_version_export_history.rb +3 -2
  55. data/app/models/katello/content_view_version_import_history.rb +4 -4
  56. data/app/models/katello/deb.rb +1 -3
  57. data/app/models/katello/docker_meta_tag.rb +1 -1
  58. data/app/models/katello/erratum.rb +0 -15
  59. data/app/models/katello/glue/pulp/repos.rb +1 -1
  60. data/app/models/katello/host/content_facet.rb +2 -27
  61. data/app/models/katello/host/info_provider.rb +9 -0
  62. data/app/models/katello/host/subscription_facet.rb +2 -2
  63. data/app/models/katello/host_available_module_stream.rb +10 -0
  64. data/app/models/katello/hostgroup/content_facet.rb +2 -2
  65. data/app/models/katello/installed_package.rb +1 -0
  66. data/app/models/katello/kt_environment.rb +1 -0
  67. data/app/models/katello/product.rb +1 -1
  68. data/app/models/katello/product_content.rb +2 -2
  69. data/app/models/katello/repository.rb +10 -9
  70. data/app/models/katello/root_repository.rb +38 -15
  71. data/app/models/katello/rpm.rb +8 -2
  72. data/app/models/setting/content.rb +15 -5
  73. data/app/services/cert/rhsm_client.rb +1 -5
  74. data/app/services/katello/content_unit_indexer.rb +166 -0
  75. data/app/services/katello/organization_creator.rb +19 -7
  76. data/app/services/katello/pulp/repository/docker.rb +1 -1
  77. data/app/services/katello/pulp/repository/yum.rb +0 -54
  78. data/app/services/katello/pulp/repository.rb +0 -6
  79. data/app/services/katello/pulp3/ansible_collection.rb +26 -10
  80. data/app/services/katello/pulp3/api/apt.rb +7 -0
  81. data/app/services/katello/pulp3/api/yum.rb +4 -0
  82. data/app/services/katello/pulp3/content_view_version/import.rb +11 -2
  83. data/app/services/katello/pulp3/deb.rb +10 -9
  84. data/app/services/katello/pulp3/docker_manifest.rb +6 -5
  85. data/app/services/katello/pulp3/docker_manifest_list.rb +23 -6
  86. data/app/services/katello/pulp3/docker_tag.rb +16 -7
  87. data/app/services/katello/pulp3/erratum.rb +51 -56
  88. data/app/services/katello/pulp3/file_unit.rb +9 -6
  89. data/app/services/katello/pulp3/generic_content_unit.rb +11 -12
  90. data/app/services/katello/pulp3/module_stream.rb +76 -30
  91. data/app/services/katello/pulp3/package_group.rb +5 -5
  92. data/app/services/katello/pulp3/pulp_content_unit.rb +19 -11
  93. data/app/services/katello/pulp3/repository/apt.rb +5 -3
  94. data/app/services/katello/pulp3/repository/docker.rb +14 -7
  95. data/app/services/katello/pulp3/repository/generic.rb +1 -1
  96. data/app/services/katello/pulp3/repository/yum.rb +21 -16
  97. data/app/services/katello/pulp3/repository.rb +29 -8
  98. data/app/services/katello/pulp3/repository_mirror.rb +18 -5
  99. data/app/services/katello/pulp3/rpm.rb +13 -13
  100. data/app/services/katello/pulp3/srpm.rb +10 -9
  101. data/app/services/katello/registration_manager.rb +1 -0
  102. data/app/services/katello/repository_type.rb +15 -4
  103. data/app/services/katello/repository_type_manager.rb +1 -1
  104. data/app/services/katello/ui_notifications/subscriptions/manifest_expired_warning.rb +1 -1
  105. data/app/services/katello/upstream_connection_checker.rb +2 -2
  106. data/app/views/foreman/job_templates/change_content_source.erb +1 -31
  107. data/app/views/foreman/job_templates/install_errata.erb +6 -9
  108. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +26 -0
  109. data/app/views/foreman/job_templates/install_packages_by_search_query.erb +19 -0
  110. data/app/views/foreman/job_templates/remove_packages_by_search_query.erb +19 -0
  111. data/app/views/foreman/job_templates/update_packages_by_search_query.erb +19 -0
  112. data/app/views/katello/api/v2/cdn_configurations/show.json.rabl +1 -1
  113. data/app/views/katello/api/v2/content_views/base.json.rabl +8 -4
  114. data/app/views/katello/api/v2/environments/show.json.rabl +9 -0
  115. data/app/views/katello/api/v2/host_module_streams/base.json.rabl +1 -0
  116. data/app/views/katello/api/v2/repositories/show.json.rabl +4 -2
  117. data/app/views/katello/layouts/react.html.erb +0 -1
  118. data/app/views/katello/sync_management/_repo.html.erb +36 -25
  119. data/config/initializers/monkeys.rb +0 -1
  120. data/config/routes/api/v2.rb +1 -0
  121. data/config/routes/overrides.rb +3 -0
  122. data/config/routes.rb +2 -0
  123. data/db/migrate/20150930183738_migrate_content_hosts.rb +1 -1
  124. data/db/migrate/20180612164926_add_content_org_id.rb +2 -2
  125. data/db/migrate/20210119162528_delete_puppet_and_ostree_repos.rb +2 -0
  126. data/db/migrate/20211019192121_create_cdn_configuration.katello.rb +11 -2
  127. data/db/migrate/20211201154845_add_unique_indexes.rb +20 -0
  128. data/db/migrate/20211208034230_add_content_view_and_lifecycle_environment.rb +6 -0
  129. data/db/migrate/20211220185935_clean_duplicate_content_units.rb +144 -0
  130. data/db/migrate/20220110223754_update_disconnected_settings.rb +20 -0
  131. data/db/migrate/20220120163252_fix_docker_download_policy.rb +11 -0
  132. data/db/migrate/20220124191056_add_type_to_cdn_configuration.rb +16 -0
  133. data/db/migrate/20220127120843_fix_debian_download_policy.rb +11 -0
  134. data/db/migrate/20220204171908_rename_docker_tags_whitelist_and_add_exclude_tags.rb +8 -0
  135. data/db/migrate/20220207140355_change_deb_attributes_size_limit.rb +7 -0
  136. data/db/migrate/20220209205137_expand_sync_timeout_settings.rb +23 -0
  137. data/db/migrate/20220303160220_remove_duplicate_errata.rb +34 -0
  138. data/db/seeds.d/111-upgrade_tasks.rb +2 -1
  139. data/engines/bastion/app/views/bastion/layouts/application.html.erb +0 -1
  140. data/engines/bastion/app/views/bastion/layouts/assets.html.erb +0 -1
  141. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.controller.js +1 -1
  142. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-products.controller.js +1 -1
  143. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-repositories.controller.js +1 -1
  144. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-traces-modal.html +1 -1
  145. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment.html +26 -1
  146. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +10 -3
  147. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +212 -152
  148. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/packages.controller.js +1 -0
  149. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +24 -8
  150. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-manage-content.controller.js +2 -3
  151. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +8 -3
  152. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +34 -30
  153. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +21 -2
  154. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +35 -15
  155. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +5 -4
  156. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.routes.js +4 -3
  157. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-products.html +1 -1
  158. data/lib/katello/engine.rb +4 -0
  159. data/lib/katello/permission_creator.rb +1 -1
  160. data/lib/katello/permissions/host_permissions.rb +3 -1
  161. data/lib/katello/plugin.rb +6 -1
  162. data/lib/katello/repository_types/deb.rb +0 -1
  163. data/lib/katello/repository_types/docker.rb +4 -4
  164. data/lib/katello/repository_types/file.rb +0 -1
  165. data/lib/katello/repository_types/ostree.rb +4 -6
  166. data/lib/katello/repository_types/python.rb +5 -1
  167. data/lib/katello/repository_types/yum.rb +2 -9
  168. data/lib/katello/tasks/content_view_import_only.rake +34 -0
  169. data/lib/katello/tasks/import_applicability.rake +1 -1
  170. data/lib/katello/tasks/jenkins.rake +0 -2
  171. data/lib/katello/tasks/pulp2to3_migrate_deb_attributes.rake +20 -0
  172. data/lib/katello/tasks/repository.rake +4 -1
  173. data/lib/katello/tasks/upgrades/4.4/publish_import_cvvs.rake +17 -0
  174. data/lib/katello/version.rb +1 -1
  175. data/locale/action_names.rb +8 -7
  176. data/locale/bn/katello.po +1402 -650
  177. data/locale/cs/katello.po +1217 -96
  178. data/locale/de/katello.po +2359 -1347
  179. data/locale/en/katello.po +1216 -94
  180. data/locale/es/katello.po +2201 -1172
  181. data/locale/fr/katello.po +2601 -1615
  182. data/locale/gu/katello.po +1564 -814
  183. data/locale/hi/katello.po +1563 -810
  184. data/locale/it/katello.po +1311 -282
  185. data/locale/ja/katello.po +2534 -1518
  186. data/locale/katello.pot +3430 -1326
  187. data/locale/kn/katello.po +1564 -812
  188. data/locale/ko/katello.po +1441 -409
  189. data/locale/mr/katello.po +1564 -776
  190. data/locale/or/katello.po +1565 -813
  191. data/locale/pa/katello.po +1559 -792
  192. data/locale/pt/katello.po +1314 -277
  193. data/locale/pt_BR/katello.po +2226 -1181
  194. data/locale/ru/katello.po +1587 -563
  195. data/locale/ta/katello.po +1373 -619
  196. data/locale/te/katello.po +1564 -810
  197. data/locale/zh_CN/katello.po +2936 -1890
  198. data/locale/zh_TW/katello.po +1508 -606
  199. data/webpack/__mocks__/foremanReact/{redux/actions/toasts.js → components/ToastsList/index.js} +3 -2
  200. data/webpack/components/ActionableDetail.js +35 -21
  201. data/webpack/components/Content/Details/__tests__/ContentDetailInfo.test.js +0 -2
  202. data/webpack/components/Content/Details/__tests__/ContentDetailRepositories.test.js +0 -2
  203. data/webpack/components/Content/Details/__tests__/ContentDetails.test.js +0 -2
  204. data/webpack/components/Content/__tests__/ContentPage.test.js +0 -2
  205. data/webpack/components/Content/__tests__/ContentTable.test.js +0 -2
  206. data/webpack/components/EditableSwitch.js +8 -2
  207. data/webpack/components/EditableTextInput/EditableTextInput.js +44 -86
  208. data/webpack/components/EditableTextInput/__tests__/editableTextInput.test.js +3 -3
  209. data/webpack/components/Errata/index.js +66 -58
  210. data/webpack/components/ErratumTypeLabel.js +16 -16
  211. data/webpack/components/MultiSelect/index.js +2 -2
  212. data/webpack/components/Packages/index.js +1 -1
  213. data/webpack/components/RoutedTabs/index.js +1 -17
  214. data/webpack/components/Search/Search.js +5 -2
  215. data/webpack/components/Search/__tests__/search.test.js +2 -3
  216. data/webpack/components/Select/Select.js +1 -1
  217. data/webpack/components/SelectOrg/SelectOrgReducer.js +15 -15
  218. data/webpack/components/SelectOrg/SetOrganization.js +2 -2
  219. data/webpack/components/Table/PageControls.js +3 -6
  220. data/webpack/components/Table/TableHooks.js +47 -7
  221. data/webpack/components/Table/TableWrapper.js +17 -3
  222. data/webpack/components/TypeAhead/TypeAhead.js +5 -1
  223. data/webpack/components/TypeAhead/helpers/commonPropTypes.js +1 -1
  224. data/webpack/components/TypeAhead/helpers/helpers.js +14 -14
  225. data/webpack/components/TypeAhead/pf3Search/TypeAheadSearch.js +1 -1
  226. data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +4 -1
  227. data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +2 -1
  228. data/webpack/components/WithOrganization/withOrganization.js +3 -3
  229. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard.js +3 -2
  230. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +5 -5
  231. data/webpack/components/extensions/HostDetails/Cards/__tests__/contentViewDetailsCard.test.js +30 -31
  232. data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +30 -3
  233. data/webpack/components/extensions/HostDetails/HostDetailsActions.js +2 -0
  234. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +7 -5
  235. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +1 -0
  236. data/webpack/components/extensions/HostDetails/Tabs/{ErrataTab.js → ErrataTab/ErrataTab.js} +30 -21
  237. data/webpack/components/extensions/HostDetails/Tabs/{ErrataTab.scss → ErrataTab/ErrataTab.scss} +0 -0
  238. data/webpack/components/extensions/HostDetails/Tabs/{ErratumExpansionContents.js → ErrataTab/ErratumExpansionContents.js} +3 -3
  239. data/webpack/components/extensions/HostDetails/Tabs/{ErratumExpansionDetail.js → ErrataTab/ErratumExpansionDetail.js} +0 -0
  240. data/webpack/components/extensions/HostDetails/{HostErrata → Tabs/ErrataTab}/HostErrataActions.js +3 -3
  241. data/webpack/components/extensions/HostDetails/{HostErrata → Tabs/ErrataTab}/HostErrataConstants.js +11 -0
  242. data/webpack/components/extensions/HostDetails/{HostErrata → Tabs/ErrataTab}/HostErrataSelectors.js +0 -0
  243. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsActions.js +16 -0
  244. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsConstants.js +3 -0
  245. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsSelectors.js +19 -0
  246. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +241 -0
  247. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/moduleStreamsTab.test.js +108 -0
  248. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/modules.fixtures.json +34 -0
  249. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesActions.js +58 -0
  250. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesConstants.js +15 -0
  251. data/webpack/components/extensions/HostDetails/{HostPackages → Tabs/PackagesTab}/HostPackagesSelectors.js +0 -0
  252. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +279 -0
  253. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.scss +3 -0
  254. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +420 -0
  255. data/webpack/components/extensions/HostDetails/Tabs/{PackagesTab.scss → PackagesTab/PackagesTab.scss} +0 -0
  256. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/YumInstallablePackagesActions.js +18 -0
  257. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/YumInstallablePackagesConstants.js +3 -0
  258. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/YumInstallablePackagesSelectors.js +16 -0
  259. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +103 -4
  260. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +6 -1
  261. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +6 -3
  262. data/webpack/components/extensions/HostDetails/Tabs/{EnableTracerEmptyState.js → TracesTab/EnableTracerEmptyState.js} +0 -0
  263. data/webpack/components/extensions/HostDetails/Tabs/{EnableTracerModal.js → TracesTab/EnableTracerModal.js} +3 -2
  264. data/webpack/components/extensions/HostDetails/Tabs/{HostTracesActions.js → TracesTab/HostTracesActions.js} +2 -2
  265. data/webpack/components/extensions/HostDetails/Tabs/{HostTracesConstants.js → TracesTab/HostTracesConstants.js} +0 -0
  266. data/webpack/components/extensions/HostDetails/Tabs/{HostTracesSelectors.js → TracesTab/HostTracesSelectors.js} +0 -0
  267. data/webpack/components/extensions/HostDetails/Tabs/{TracesTab.js → TracesTab/TracesTab.js} +8 -5
  268. data/webpack/components/extensions/HostDetails/Tabs/{TracesTab.scss → TracesTab/TracesTab.scss} +0 -0
  269. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +17 -18
  270. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packageInstallModal.test.js +385 -0
  271. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packages.fixtures.json +1 -1
  272. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +313 -12
  273. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +2 -2
  274. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +26 -30
  275. data/webpack/components/extensions/HostDetails/Tabs/__tests__/yumInstallablePackages.fixtures.json +72 -0
  276. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +25 -5
  277. data/webpack/components/extensions/HostDetails/hostDetailsHelpers.js +28 -0
  278. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +4 -0
  279. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +1 -1
  280. data/webpack/components/extensions/RegistrationCommands/fields/LifecycleEnvironment.js +1 -1
  281. data/webpack/components/extensions/about/SystemStatuses.js +1 -1
  282. data/webpack/components/extensions/about/SystemStatusesReducer.js +10 -10
  283. data/webpack/components/pf3Table/components/Table.js +4 -5
  284. data/webpack/components/pf3Table/components/Table.test.js +0 -3
  285. data/webpack/components/pf3Table/components/TableBody.js +2 -2
  286. data/webpack/components/pf3Table/components/__snapshots__/Table.test.js.snap +9 -8
  287. data/webpack/containers/Application/config.js +5 -0
  288. data/webpack/global_index.js +5 -4
  289. data/webpack/global_test_setup.js +1 -1
  290. data/webpack/index.js +7 -0
  291. data/webpack/redux/OrganizationProducts/OrganizationProductsReducer.js +15 -15
  292. data/webpack/redux/reducers/RedHatRepositories/enabled.js +43 -43
  293. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.js +43 -43
  294. data/webpack/redux/reducers/RedHatRepositories/sets.js +31 -31
  295. data/webpack/scenes/AnsibleCollections/AnsibleCollectionsReducer.js +26 -26
  296. data/webpack/scenes/AnsibleCollections/Details/AnsibleCollectionDetailsReducer.js +19 -19
  297. data/webpack/scenes/AnsibleCollections/Details/__tests__/AnsibleCollectionDetails.test.js +0 -2
  298. data/webpack/scenes/AnsibleCollections/__tests__/AnsibleCollectionPage.test.js +0 -2
  299. data/webpack/scenes/AnsibleCollections/__tests__/AnsibleCollectionsTable.test.js +0 -2
  300. data/webpack/scenes/Content/ContentConfig.js +55 -5
  301. data/webpack/scenes/Content/ContentPage.js +1 -1
  302. data/webpack/scenes/Content/Details/ContentDetails.js +1 -1
  303. data/webpack/scenes/Content/Details/ContentInfo.js +1 -1
  304. data/webpack/scenes/Content/Details/ContentRepositories.js +1 -1
  305. data/webpack/scenes/Content/Details/__tests__/contentDetail.test.js +4 -4
  306. data/webpack/scenes/Content/Table/ContentTable.js +2 -2
  307. data/webpack/scenes/Content/__tests__/contentTable.test.js +3 -3
  308. data/webpack/scenes/ContentViews/ContentViewsConstants.js +2 -1
  309. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +2 -1
  310. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignHostsForm.js +2 -2
  311. data/webpack/scenes/ContentViews/Delete/__tests__/contentViewDelete.test.js +6 -6
  312. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +1 -1
  313. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +2 -2
  314. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +22 -28
  315. data/webpack/scenes/ContentViews/Details/ContentViewDetailReducer.js +8 -8
  316. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +5 -5
  317. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +8 -3
  318. data/webpack/scenes/ContentViews/Details/DetailsContainer.js +11 -16
  319. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositoryTable.js +1 -1
  320. data/webpack/scenes/ContentViews/Details/Filters/ArtifactsWithNoErrata.js +8 -8
  321. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +1 -1
  322. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +1 -1
  323. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +1 -1
  324. data/webpack/scenes/ContentViews/Details/Filters/CVFilterDetailType.js +46 -46
  325. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +14 -14
  326. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +14 -14
  327. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +1 -1
  328. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetails.js +2 -2
  329. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +14 -8
  330. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +1 -1
  331. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/__tests__/CVRpmMatchContentModal.test.js +2 -2
  332. data/webpack/scenes/ContentViews/Details/Filters/Rules/Package/AddEditPackageRuleModal.js +17 -17
  333. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +2 -3
  334. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +2 -9
  335. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +3 -5
  336. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilters.test.js +2 -10
  337. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErrataIDFilter.test.js +2 -3
  338. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvModuleStreamFilter.test.js +2 -3
  339. data/webpack/scenes/ContentViews/Details/Histories/__tests__/contentViewHistory.test.js +2 -2
  340. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +1 -1
  341. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +24 -3
  342. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewAddRemove.test.js +11 -5
  343. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionContent.js +28 -28
  344. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +1 -1
  345. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js +18 -18
  346. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js +3 -3
  347. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignHostsForm.js +3 -3
  348. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js +6 -6
  349. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +1 -1
  350. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +1 -1
  351. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +31 -35
  352. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +9 -8
  353. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +28 -34
  354. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +46 -34
  355. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionRepositoryCell.js +66 -49
  356. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.test.js +5 -5
  357. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +3 -3
  358. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +5 -3
  359. data/webpack/scenes/ContentViews/Publish/CVPublishFinish.js +2 -2
  360. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +4 -4
  361. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +2 -2
  362. data/webpack/scenes/ContentViews/components/EnvironmentLabels.js +18 -18
  363. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +10 -10
  364. data/webpack/scenes/ContentViews/expansions/DetailsExpansion.js +2 -2
  365. data/webpack/scenes/Hosts/ChangeContentSource/actions.js +43 -0
  366. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +87 -0
  367. data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceTemplate.js +90 -0
  368. data/webpack/scenes/Hosts/ChangeContentSource/components/FormField.js +43 -0
  369. data/webpack/scenes/Hosts/ChangeContentSource/constants.js +3 -0
  370. data/webpack/scenes/Hosts/ChangeContentSource/helpers.js +27 -0
  371. data/webpack/scenes/Hosts/ChangeContentSource/index.js +126 -0
  372. data/webpack/scenes/Hosts/ChangeContentSource/selectors.js +42 -0
  373. data/webpack/scenes/Hosts/ChangeContentSource/styles.scss +11 -0
  374. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetailsReducer.js +18 -18
  375. data/webpack/scenes/ModuleStreams/Details/Profiles/__tests__/ModuleStreamDetailProfiles.test.js +0 -1
  376. data/webpack/scenes/ModuleStreams/Details/__tests__/ModuleStreamDetails.test.js +0 -2
  377. data/webpack/scenes/ModuleStreams/ModuleStreamsReducer.js +26 -26
  378. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamPage.test.js +0 -2
  379. data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamsTable.test.js +0 -2
  380. data/webpack/scenes/Organizations/OrganizationActions.js +5 -1
  381. data/webpack/scenes/Organizations/OrganizationReducer.js +8 -8
  382. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +31 -1
  383. data/webpack/scenes/RedHatRepositories/__tests__/RedHatRepositoriesPage.test.js +16 -0
  384. data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +11 -2
  385. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepositoryContent.js +4 -4
  386. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepositories.js +1 -1
  387. data/webpack/scenes/RedHatRepositories/helpers.js +5 -5
  388. data/webpack/scenes/RedHatRepositories/index.js +11 -3
  389. data/webpack/scenes/Settings/SettingsReducer.js +14 -14
  390. data/webpack/scenes/Settings/Tables/TableReducer.js +23 -23
  391. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailInfo.js +2 -2
  392. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProductContent.js +15 -15
  393. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProducts.js +1 -1
  394. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +34 -34
  395. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +13 -13
  396. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/AirGappedTypeForm.js +81 -0
  397. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationConstants.js +13 -0
  398. data/webpack/scenes/Subscriptions/Manifest/{CdnConfigurationForm.scss → CdnConfigurationTab/CdnConfigurationForm.scss} +0 -0
  399. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +106 -0
  400. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/UpstreamServerTypeForm.js +260 -0
  401. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/AirGappedTypeForm.test.js +44 -0
  402. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CdnTypeForm.test.js +67 -0
  403. data/webpack/scenes/Subscriptions/Manifest/{__tests__/CdnConfigurationForm.test.js → CdnConfigurationTab/__tests__/UpstreamServerTypeForm.test.js} +46 -17
  404. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/index.js +97 -0
  405. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +11 -6
  406. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +16 -16
  407. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +149 -149
  408. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsReducer.js +41 -41
  409. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsPage.test.js +0 -1
  410. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +0 -1
  411. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +3 -2
  412. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +4 -0
  413. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +9 -0
  414. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Dialogs/DeleteDialog.js +6 -6
  415. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Table.js +12 -12
  416. data/webpack/scenes/Tasks/TaskActions.js +1 -1
  417. data/webpack/scenes/Tasks/__tests__/__snapshots__/TaskActions.test.js.snap +3 -2
  418. data/webpack/services/api/testHelpers.js +5 -3
  419. data/webpack/services/index.js +36 -36
  420. data/webpack/utils/helpers.js +11 -8
  421. metadata +100 -65
  422. data/app/services/katello/pulp/deb.rb +0 -55
  423. data/app/services/katello/pulp/distribution.rb +0 -7
  424. data/app/services/katello/pulp/docker_blob.rb +0 -7
  425. data/app/services/katello/pulp/docker_manifest.rb +0 -13
  426. data/app/services/katello/pulp/docker_manifest_list.rb +0 -14
  427. data/app/services/katello/pulp/docker_tag.rb +0 -14
  428. data/app/services/katello/pulp/erratum.rb +0 -129
  429. data/app/services/katello/pulp/file_unit.rb +0 -21
  430. data/app/services/katello/pulp/module_stream.rb +0 -39
  431. data/app/services/katello/pulp/package_category.rb +0 -7
  432. data/app/services/katello/pulp/package_group.rb +0 -20
  433. data/app/services/katello/pulp/pulp_content_unit.rb +0 -156
  434. data/app/services/katello/pulp/rpm.rb +0 -57
  435. data/app/services/katello/pulp/srpm.rb +0 -29
  436. data/app/services/katello/pulp/yum_metadata_file.rb +0 -30
  437. data/lib/monkeys/pulp3_13_checksumfix.rb +0 -17
  438. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationHooks.js +0 -2
  439. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +0 -2
  440. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesActions.js +0 -11
  441. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesConstants.js +0 -2
  442. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab.js +0 -127
  443. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationForm.js +0 -185
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bebacc5b4b127cfadaeb424ce9f04aa6e2ba132a0d8d959d8456bd393418abf
4
- data.tar.gz: 473b94c0aec5d6b73a174f334edf1f9079d42c53d16ef0ab60cc939af0e0e4b0
3
+ metadata.gz: e193a2273fbdeccfaeb286b7a86738e7bbb1bb78120a663e4309aac912ef4501
4
+ data.tar.gz: afbec4d28494d215e8b7c318cd403a632d3c8c14ccff79f809cc01f4fc713f3d
5
5
  SHA512:
6
- metadata.gz: 000e85ae93b95be282c88d10eec6f364526cfdb9e377de7b56d82a8df882e8390c40690b4d7b0740c24196fa10d20d166b48779f3422699e7a970bfb1722cdc2
7
- data.tar.gz: 23a1e59f555ddbe334a98d6937aa64de3d46b1bc6b8fb33a61166e317792686fae9f30af480d0037226eebf6d341769a15acd1972d7bb05d20696ab6af1fb9dc
6
+ metadata.gz: da5af110e6327f56eff8c5f72eb1e80936142b534e68d9bdc9f081efa9838f35b0eb03d99e461e59f9c0f2be1a55f7955f2fee6d97b8874f35ce4ba60bb4c1df
7
+ data.tar.gz: 6c6db26dac3ffa0ace7837e9774d56d93cba08df34fee0616bde18816a6785e5c54d697768d2f5a39bbd40a67b990462bb9e2e7e2d44cfdd74043221ca820dd6
@@ -1,5 +1,4 @@
1
1
  //= require "jquery-ui/widgets/dialog"
2
- //= require "jquery-ui/widgets/sortable"
3
2
  //= require "jquery-ui/widgets/progressbar"
4
3
  //= require "jquery-ui/effect"
5
4
  //= require "jquery-ui/effect.all"
@@ -126,7 +126,7 @@ module Katello
126
126
  end
127
127
  rescue ScopedSearch::QueryNotSupported, ActiveRecord::StatementInvalid => error
128
128
  message = error.message
129
- if error.class == ActiveRecord::StatementInvalid
129
+ if error.instance_of? ActiveRecord::StatementInvalid
130
130
  Rails.logger.error("Invalid search: #{error.message}")
131
131
  message = _('Your search query was invalid. Please revise it and try again. The full error has been sent to the application logs.')
132
132
  end
@@ -141,7 +141,7 @@ module Katello
141
141
  protected
142
142
 
143
143
  def scoped_search_query(query, group)
144
- if group
144
+ if group && !query_has_group_by?(query)
145
145
  query.select(group).group(group)
146
146
  else
147
147
  query
@@ -149,7 +149,12 @@ module Katello
149
149
  end
150
150
 
151
151
  def scoped_search_total(query, group)
152
- scoped_search_query(query, group).length
152
+ count_query = scoped_search_query(query, group)
153
+ if query_has_group_by?(count_query)
154
+ count_query.length
155
+ else
156
+ count_query.count
157
+ end
153
158
  end
154
159
 
155
160
  def scoped_search_total_selectable(query, group)
@@ -157,10 +162,14 @@ module Katello
157
162
  if self.respond_to?(:total_selectable, true)
158
163
  total_selectable(q)
159
164
  else
160
- q.length
165
+ group ? q.length : q.count
161
166
  end
162
167
  end
163
168
 
169
+ def query_has_group_by?(query)
170
+ query.to_sql.include?('GROUP BY')
171
+ end
172
+
164
173
  def scoped_search_results(query:, subtotal: 0, total: 0, page: 0, per_page: 0, error: nil, selectable: nil)
165
174
  {
166
175
  :results => query,
@@ -163,6 +163,9 @@ module Katello
163
163
 
164
164
  def find_optional_readable_content_view
165
165
  @view = ContentView.readable.find_by(:id => params[:content_view_id])
166
+ if params[:content_view_id] && !@view
167
+ fail HttpErrors::NotFound, _("Couldn't find content view with id: '%s'") % params[:content_view_id]
168
+ end
166
169
  end
167
170
 
168
171
  def find_publishable_content_view
@@ -2,6 +2,7 @@ module Katello
2
2
  class Api::V2::ContentViewsController < Api::V2::ApiController
3
3
  include Concerns::Authorization::Api::V2::ContentViewsController
4
4
  include Katello::Concerns::FilteredAutoCompleteSearch
5
+ include Katello::Concerns::Api::V2::BulkExtensions
5
6
 
6
7
  before_action :find_authorized_katello_resource, :except => [:index, :create, :copy, :auto_complete_search]
7
8
  before_action :ensure_non_default, :except => [:index, :create, :copy, :auto_complete_search]
@@ -24,6 +25,18 @@ module Katello
24
25
  param :import_only, :bool, :desc => N_("Designate this Content View for importing from upstream servers only. Defaults to false")
25
26
  end
26
27
 
28
+ def_param_group :bulk_content_view_version_ids do
29
+ param :included, Hash, :desc => N_("Versions to exclusively include in the action"), :required => true, :action_aware => true do
30
+ param :search, String, :required => false, :desc => N_("Search string for versions to perform an action on")
31
+ param :ids, Array, :required => false, :desc => N_("List of versions to perform an action on")
32
+ end
33
+ param :excluded, Hash, :desc => N_("Versions to explicitly exclude in the action."\
34
+ " All other versions will be included in the action,"\
35
+ " unless an included parameter is passed as well."), :required => true, :action_aware => true do
36
+ param :ids, Array, :required => false, :desc => N_("List of versions to exclude and not run an action on")
37
+ end
38
+ end
39
+
27
40
  def filtered_associations
28
41
  {
29
42
  :component_ids => Katello::ContentViewVersion,
@@ -40,6 +53,7 @@ module Katello
40
53
  param :composite, :bool, :desc => N_("Filter only composite content views")
41
54
  param :without, Array, :desc => N_("Do not include this array of content views")
42
55
  param :name, String, :desc => N_("Name of the content view"), :required => false
56
+ param :label, String, :desc => N_("Label of the content view"), :required => false
43
57
  param_group :search, Api::V2::ApiController
44
58
  add_scoped_search_description_for(ContentView)
45
59
  def index
@@ -56,6 +70,7 @@ module Katello
56
70
  content_views = ::Foreman::Cast.to_bool(params[:noncomposite]) ? content_views.non_composite : content_views.composite if params[:noncomposite]
57
71
  content_views = ::Foreman::Cast.to_bool(params[:composite]) ? content_views.composite : content_views.non_composite if params[:composite]
58
72
  content_views = content_views.where(:name => params[:name]) if params[:name]
73
+ content_views = content_views.where(:label => params[:label]) if params[:label]
59
74
  content_views = content_views.where("#{ContentView.table_name}.id NOT IN (?)", params[:without]) if params[:without]
60
75
  content_views
61
76
  end
@@ -175,6 +190,39 @@ module Katello
175
190
  respond_for_async :resource => task
176
191
  end
177
192
 
193
+ api :PUT, "/content_views/:id/bulk_delete_versions", N_("Bulk remove versions from a content view and reassign systems and keys")
194
+ param_group :bulk_content_view_version_ids
195
+ param :id, :number, :desc => N_("content view numeric identifier"), :required => true
196
+ param :system_content_view_id, :number, :desc => N_("content view to reassign orphaned systems to")
197
+ param :system_environment_id, :number, :desc => N_("environment to reassign orphaned systems to")
198
+ param :key_content_view_id, :number, :desc => N_("content view to reassign orphaned activation keys to")
199
+ param :key_environment_id, :number, :desc => N_("environment to reassign orphaned activation keys to")
200
+ def bulk_delete_versions
201
+ params[:bulk_content_view_version_ids] ||= {}
202
+
203
+ versions = find_bulk_items(bulk_params: params[:bulk_content_view_version_ids],
204
+ model_scope: ::Katello::ContentViewVersion.where(content_view_id: @content_view.id),
205
+ key: :id)
206
+ cv_envs = ContentViewEnvironment.where(:content_view_version_id => versions.pluck(:id),
207
+ :content_view_id => @content_view.id
208
+ )
209
+
210
+ if !params[:destroy_content_view] && cv_envs.empty? && versions.empty?
211
+ fail _("There either were no environments nor versions specified or there were invalid environments/versions specified. "\
212
+ "Please check environment_ids and content_view_version_ids parameters.")
213
+ end
214
+
215
+ options = params.slice(:system_content_view_id,
216
+ :system_environment_id,
217
+ :key_content_view_id,
218
+ :key_environment_id
219
+ ).reject { |_k, v| v.nil? }.to_unsafe_h
220
+ options[:content_view_versions] = versions
221
+ options[:content_view_environments] = cv_envs
222
+ task = async_task(::Actions::Katello::ContentView::Remove, @content_view, options)
223
+ respond_for_async :resource => task
224
+ end
225
+
178
226
  api :PUT, "/content_views/:id/remove_filters", N_("Delete multiple filters from a content view")
179
227
  param :id, :number, :desc => N_("content view numeric identifier"), :required => true
180
228
  param :filter_ids, Array, of: :number, :desc => N_("filter identifiers"), :required => true
@@ -48,6 +48,7 @@ module Katello
48
48
  param :organization_id, :number, :desc => N_("organization identifier")
49
49
  param :library, [true, false], :desc => N_("set true if you want to see only library environments")
50
50
  param :name, String, :desc => N_("filter only environments containing this name")
51
+ param :label, String, :desc => N_("filter only environments containing this label"), :required => false
51
52
  param_group :search, Api::V2::ApiController
52
53
  add_scoped_search_description_for(KTEnvironment)
53
54
  def index
@@ -58,6 +59,7 @@ module Katello
58
59
  query = KTEnvironment.readable
59
60
  query = query.where(organization: @organization) if @organization
60
61
  query = query.where(:name => params[:name]) if params[:name]
62
+ query = query.where(:label => params[:label]) if params[:label]
61
63
  query = query.where(:library => params[:library]) if params[:library]
62
64
  query
63
65
  end
@@ -2,6 +2,10 @@ module Katello
2
2
  class Api::V2::HostPackagesController < Api::V2::ApiController
3
3
  include Katello::Concerns::FilteredAutoCompleteSearch
4
4
 
5
+ UPGRADABLE = "upgradable".freeze
6
+ UP_TO_DATE = "up-to-date".freeze
7
+ VERSION_STATUSES = [UPGRADABLE, UP_TO_DATE].freeze
8
+
5
9
  before_action :require_packages_or_groups, :only => [:install, :remove]
6
10
  before_action :require_packages_only, :only => [:upgrade]
7
11
  before_action :find_editable_host_with_facet, :except => :index
@@ -21,9 +25,11 @@ module Katello
21
25
  api :GET, "/hosts/:host_id/packages", N_("List packages installed on the host")
22
26
  param :host_id, :number, :required => true, :desc => N_("ID of the host")
23
27
  param :include_latest_upgradable, :boolean, :desc => N_("Also include the latest upgradable package version for each host package")
28
+ param :status, String, :desc => N_("Return only packages of a particular status (upgradable or up-to-date)"), :required => false
24
29
  param_group :search, Api::V2::ApiController
25
30
  add_scoped_search_description_for(Katello::InstalledPackage)
26
31
  def index
32
+ validate_index_params!
27
33
  collection = scoped_search(index_relation, :name, :asc, :resource_class => ::Katello::InstalledPackage)
28
34
  collection[:results] = HostPackagePresenter.with_latest(collection[:results], @host) if ::Foreman::Cast.to_bool(params[:include_latest_upgradable])
29
35
  respond_for_index(:collection => collection)
@@ -84,7 +90,15 @@ module Katello
84
90
  end
85
91
 
86
92
  def index_relation
87
- @host.installed_packages
93
+ packages = @host.installed_packages
94
+ upgradable_packages = ::Katello::Rpm.installable_for_hosts([@host]).select(:name)
95
+ if params[:status].present?
96
+ packages = case params[:status]
97
+ when 'up-to-date' then packages.where.not(name: upgradable_packages)
98
+ when 'upgradable' then packages.where(name: upgradable_packages)
99
+ end
100
+ end
101
+ packages
88
102
  end
89
103
 
90
104
  def resource_class
@@ -137,5 +151,11 @@ module Katello
137
151
  group.gsub(/^@/, "")
138
152
  end
139
153
  end
154
+
155
+ def validate_index_params!
156
+ if params[:status].present?
157
+ fail _("Status must be one of: %s" % VERSION_STATUSES.join(', ')) unless VERSION_STATUSES.include?(params[:status])
158
+ end
159
+ end
140
160
  end
141
161
  end
@@ -3,11 +3,13 @@ module Katello
3
3
  class Api::V2::HostsBulkActionsController < Api::V2::ApiController
4
4
  include Concerns::Api::V2::BulkHostsExtensions
5
5
  include Katello::Concerns::Api::V2::ContentOverridesController
6
+ include Katello::ContentSourceHelper
7
+ include ::Foreman::Renderer::Scope::Macros::Base
6
8
 
7
9
  before_action :find_host_collections, only: [:bulk_add_host_collections, :bulk_remove_host_collections]
8
10
  before_action :find_environment, only: [:environment_content_view]
9
11
  before_action :find_content_view, only: [:environment_content_view]
10
- before_action :find_editable_hosts, except: [:destroy_hosts, :resolve_traces]
12
+ before_action :find_editable_hosts, except: [:destroy_hosts, :resolve_traces, :change_content_source]
11
13
  before_action :find_deletable_hosts, only: [:destroy_hosts]
12
14
  before_action :find_readable_hosts, only: [:applicable_errata, :installable_errata, :available_incremental_updates]
13
15
  before_action :find_errata, only: [:available_incremental_updates]
@@ -305,6 +307,33 @@ module Katello
305
307
  template: '../../../api/v2/module_streams/name_streams')
306
308
  end
307
309
 
310
+ api :PUT, "/hosts/bulk/change_content_source", N_("Update the content source for specified hosts and generate the reconfiguration script")
311
+ param :host_ids, Array, required: true, desc: N_("The ids of the hosts to alter. Hosts not managed by Katello are ignored")
312
+ param :environment_id, :number, required: true, desc: N_("The id of the lifecycle environment")
313
+ param :content_view_id, :number, required: true, desc: N_("The id of the content view")
314
+ param :content_source_id, :number, required: true, desc: N_("The id of the content source")
315
+ def change_content_source
316
+ hosts = ::Host.where(id: params[:host_ids])
317
+ throw_resource_not_found(name: 'host', id: params[:host_ids]) unless hosts.any?
318
+
319
+ lifecycle_environment = KTEnvironment.readable.find(params[:environment_id])
320
+ content_view = Katello::ContentView.readable.find(params[:content_view_id])
321
+ content_source = SmartProxy.authorized(:view_smart_proxies).find(params[:content_source_id])
322
+ template = prepare_ssl_cert(foreman_server_ca_cert) + configure_subman(content_source)
323
+
324
+ hosts.each do |host|
325
+ next unless host.content_facet
326
+
327
+ host.content_facet.lifecycle_environment = lifecycle_environment
328
+ host.content_facet.content_view = content_view
329
+ host.content_facet.content_source = content_source
330
+
331
+ host.update_candlepin_associations
332
+ end
333
+
334
+ render plain: template
335
+ end
336
+
308
337
  private
309
338
 
310
339
  def find_errata
@@ -134,13 +134,17 @@ module Katello
134
134
 
135
135
  api :PUT, "/organizations/:id/cdn_configuration", N_("Update the CDN configuration")
136
136
  param :id, String, :desc => N_("ID of the Organization"), :required => true
137
- param :ssl_ca_credential_id, Integer, :desc => N_("Content Credential to use for SSL CA")
138
- param :username, String, :desc => N_("Username for authentication")
139
- param :password, String, :desc => N_("Password for authentication")
140
- param :upstream_organization_label, String, :desc => N_("Upstream organization to sync CDN content from")
141
- param :url, String, :desc => N_("Upstream server to sync CDN content from")
137
+ param :type, String, :desc => N_("CDN configuration type. One of %s.") % CdnConfiguration::TYPES, :required => true
138
+ param :url, String, :desc => N_("Upstream foreman server to sync CDN content from. Relevant only for 'upstream_server' type.")
139
+ param :username, String, :desc => N_("Username for authentication. Relevant only for 'upstream_server' type.")
140
+ param :password, String, :desc => N_("Password for authentication. Relevant only for 'upstream_server' type.")
141
+ param :upstream_organization_label, String, :desc => N_("Upstream organization to sync CDN content from. Relevant only for 'upstream_server' type.")
142
+ param :upstream_content_view_label, String, :desc => N_("Upstream Content View Label, default: Default_Organization_View. Relevant only for 'upstream_server' type.")
143
+ param :upstream_lifecycle_environment_label, String, :desc => N_("Upstream Lifecycle Environment, default: Library. Relevant only for 'upstream_server' type.")
144
+ param :ssl_ca_credential_id, Integer, :desc => N_("Content Credential to use for SSL CA. Relevant only for 'upstream_server' type.")
142
145
  def cdn_configuration
143
- config_keys = [:url, :username, :password, :upstream_organization_label, :ssl_ca_credential_id]
146
+ config_keys = [:url, :username, :password, :upstream_organization_label, :ssl_ca_credential_id, :type,
147
+ :upstream_lifecycle_environment_label, :upstream_content_view_label]
144
148
  config_params = params.slice(*config_keys).permit!.to_h
145
149
 
146
150
  task = sync_task(::Actions::Katello::CdnConfiguration::Update, @organization.cdn_configuration, config_params)
@@ -53,9 +53,13 @@ module Katello
53
53
  def custom_index_relation(collection)
54
54
  applicable = ::Foreman::Cast.to_bool(params[:packages_restrict_applicable]) || params[:host_id]
55
55
  upgradable = ::Foreman::Cast.to_bool(params[:packages_restrict_upgradable])
56
+ not_installed = ::Foreman::Cast.to_bool(params[:packages_restrict_not_installed])
56
57
 
57
58
  if upgradable
58
59
  collection = collection.installable_for_hosts(@hosts)
60
+ elsif not_installed && params[:host_id]
61
+ host = @hosts.first
62
+ collection = Katello::Rpm.yum_installable_for_host(host)
59
63
  elsif applicable
60
64
  collection = collection.applicable_to_hosts(@hosts)
61
65
  end
@@ -53,7 +53,16 @@ module Katello
53
53
  api :POST, "/repositories/bulk/reclaim_space", N_("Reclaim space from On Demand repositories")
54
54
  param :ids, Array, :desc => N_("List of repository ids"), :required => true
55
55
  def reclaim_space_from_repositories
56
- task = async_task(::Actions::Pulp3::Repository::ReclaimSpace, @repositories)
56
+ if @repositories.empty?
57
+ fail _("No repositories selected.")
58
+ end
59
+ repositories = @repositories.select { |repo| repo.download_policy == ::Katello::RootRepository::DOWNLOAD_ON_DEMAND }
60
+ if repositories.empty?
61
+ fail _("Only On Demand repositories may have space reclaimed.")
62
+ end
63
+ task = async_task(::Actions::BulkAction,
64
+ ::Actions::Pulp3::Repository::ReclaimSpace,
65
+ repositories)
57
66
 
58
67
  respond_for_async :resource => task
59
68
  end
@@ -50,8 +50,10 @@ module Katello
50
50
  param :unprotected, :bool, :desc => N_("true if this repository can be published via HTTP")
51
51
  param :checksum_type, String, :desc => N_("Checksum of the repository, currently 'sha1' & 'sha256' are supported")
52
52
  param :docker_upstream_name, String, :desc => N_("Name of the upstream docker repository")
53
- param :docker_tags_whitelist, Array, :desc => N_("Comma-separated list of tags to sync for Container Image repository")
54
- param :download_policy, ["immediate", "on_demand"], :desc => N_("download policy for yum repos (either 'immediate' or 'on_demand')")
53
+ param :docker_tags_whitelist, Array, :desc => N_("Comma-separated list of tags to sync for Container Image repository (Deprecated)"), :deprecated => true
54
+ param :include_tags, Array, :desc => N_("Comma-separated list of tags to sync for a container image repository")
55
+ param :exclude_tags, Array, :desc => N_("Comma-separated list of tags to exclude when syncing a container image repository. Default: any tag ending in \"-source\"")
56
+ param :download_policy, ["immediate", "on_demand"], :desc => N_("download policy for yum, deb, and docker repos (either 'immediate' or 'on_demand')")
55
57
  param :download_concurrency, :number, :desc => N_("Used to determine download concurrency of the repository in pulp3. Use value less than 20. Defaults to 10")
56
58
  param :mirror_on_sync, :bool, :desc => N_("true if this repository when synced has to be mirrored from the source and stale rpms removed (Deprecated)")
57
59
  param :mirroring_policy, Katello::RootRepository::MIRRORING_POLICIES, :desc => N_("Policy to set for mirroring content. Must be one of %s.") % RootRepository::MIRRORING_POLICIES
@@ -325,6 +327,9 @@ module Katello
325
327
  api :POST, "/repositories/:id/reclaim_space", N_("Reclaim space from an On Demand repository")
326
328
  param :id, :number, :required => true, :desc => N_("repository ID")
327
329
  def reclaim_space
330
+ if @repository.download_policy != ::Katello::RootRepository::DOWNLOAD_ON_DEMAND
331
+ fail HttpErrors::BadRequest, _("Only On Demand repositories may have space reclaimed.")
332
+ end
328
333
  task = async_task(::Actions::Pulp3::Repository::ReclaimSpace, @repository)
329
334
  respond_for_async :resource => task
330
335
  rescue Errors::InvalidActionOptionError => e
@@ -507,7 +512,7 @@ module Katello
507
512
  {:os_versions => []}, :deb_releases, :deb_components, :deb_architectures, :description,
508
513
  :http_proxy_policy, :http_proxy_id, :retain_package_versions_count, {:ignorable_content => []}
509
514
  ]
510
- keys += [{:docker_tags_whitelist => []}, :docker_upstream_name] if params[:action] == 'create' || @repository&.docker?
515
+ keys += [{:docker_tags_whitelist => []}, {:include_tags => []}, {:exclude_tags => []}, :docker_upstream_name] if params[:action] == 'create' || @repository&.docker?
511
516
  keys += [:ansible_collection_requirements, :ansible_collection_auth_url, :ansible_collection_auth_token] if params[:action] == 'create' || @repository&.ansible_collection?
512
517
  keys += [:label, :content_type] if params[:action] == "create"
513
518
 
@@ -540,13 +545,20 @@ module Katello
540
545
  credential_value
541
546
  end
542
547
 
543
- # rubocop:disable Metrics/PerceivedComplexity
548
+ # rubocop:disable Metrics/PerceivedComplexity,Metrics/MethodLength
544
549
  def construct_repo_from_params(repo_params) # rubocop:disable Metrics/AbcSize
545
550
  root = @product.add_repo(repo_params.slice(:label, :name, :description, :url, :content_type, :arch, :unprotected,
546
551
  :gpg_key, :ssl_ca_cert, :ssl_client_cert, :ssl_client_key,
547
552
  :checksum_type, :download_policy, :http_proxy_policy).to_h.with_indifferent_access)
548
553
  root.docker_upstream_name = repo_params[:docker_upstream_name] if repo_params[:docker_upstream_name]
549
- root.docker_tags_whitelist = repo_params.fetch(:docker_tags_whitelist, []) if root.docker?
554
+ if root.docker?
555
+ if repo_params[:docker_tags_whitelist].present?
556
+ root.include_tags = repo_params.fetch(:docker_tags_whitelist, [])
557
+ else
558
+ root.include_tags = repo_params.fetch(:include_tags, [])
559
+ end
560
+ end
561
+ root.exclude_tags = repo_params.fetch(:exclude_tags, ['*-source']) if root.docker?
550
562
  root.verify_ssl_on_sync = ::Foreman::Cast.to_bool(repo_params[:verify_ssl_on_sync]) if repo_params.key?(:verify_ssl_on_sync)
551
563
  root.mirroring_policy = repo_params[:mirroring_policy] || Katello::RootRepository::MIRRORING_POLICY_CONTENT
552
564
  root.upstream_username = repo_params[:upstream_username] if repo_params.key?(:upstream_username)
@@ -577,7 +589,7 @@ module Katello
577
589
 
578
590
  root
579
591
  end
580
- # rubocop:enable Metrics/CyclomaticComplexity
592
+ # rubocop:enable Metrics/CyclomaticComplexity,Metrics/MethodLength
581
593
 
582
594
  def handle_mirror_on_sync(repo_params)
583
595
  if !repo_params.key?(:mirroring_policy) && repo_params.key?(:mirror_on_sync)
@@ -648,7 +660,8 @@ module Katello
648
660
 
649
661
  def generic_remote_options_hash(repo_params)
650
662
  generic_remote_options = {}
651
- RepositoryTypeManager.generic_remote_options(content_type: repo_params[:content_type]).each do |option|
663
+ content_type = @repository&.content_type || repo_params[:content_type]
664
+ RepositoryTypeManager.generic_remote_options(content_type: content_type).each do |option|
652
665
  generic_remote_options[option.name] = repo_params[option.name]
653
666
  end
654
667
  generic_remote_options
@@ -13,6 +13,7 @@ module Katello
13
13
  before_action :find_authorized_host, :only => [:index, :auto_complete_search]
14
14
  before_action :find_organization
15
15
  before_action :find_product_content, :except => [:index, :auto_complete_search]
16
+ before_action :check_airgapped, :only => [:index]
16
17
 
17
18
  resource_description do
18
19
  api_version "v2"
@@ -209,5 +210,11 @@ module Katello
209
210
  params[:host_id] ||= params[:id]
210
211
  end
211
212
  end
213
+
214
+ def check_airgapped
215
+ if @organization.cdn_configuration.airgapped?
216
+ respond_for_index(:collection => { :error => _("Repositories are not available for enablement while CDN configuration is set to Air-gapped (disconnected).") }, :status => :forbidden)
217
+ end
218
+ end
212
219
  end
213
220
  end
@@ -130,6 +130,9 @@ module Katello
130
130
  end
131
131
 
132
132
  def filter_by_content_view_version(version, collection)
133
+ if params[:content_type]
134
+ return collection.where(:id => version.send(controller_name, params[:content_type]))
135
+ end
133
136
  collection.where(:id => version.send(controller_name))
134
137
  end
135
138
 
@@ -9,6 +9,8 @@ module Katello
9
9
  case params[:action]
10
10
  when 'content_hosts'
11
11
  'view'
12
+ when 'change_content_source'
13
+ 'edit'
12
14
  else
13
15
  super
14
16
  end
@@ -68,6 +70,36 @@ module Katello
68
70
  end
69
71
  end
70
72
  end
73
+
74
+ def change_content_source_data
75
+ hosts = ::Host.where(id: params[:host_ids])
76
+ content_hosts_ids = []
77
+ hosts_without_content = []
78
+
79
+ hosts.each do |host|
80
+ if host.content_facet
81
+ content_hosts_ids << host.id
82
+ else
83
+ hosts_without_content << host.name
84
+ end
85
+ end
86
+
87
+ environments = KTEnvironment.readable.where(organization: Organization.current).includes([:organization, :env_priors, :priors]).order(:name)
88
+ content_sources = SmartProxy.authorized(:view_smart_proxies).with_content.includes([:smart_proxy_features])
89
+
90
+ if Katello.with_remote_execution?
91
+ template_id = JobTemplate.find_by(name: 'Change content source')&.id
92
+ job_invocation_path = new_job_invocation_path(template_id: template_id, host_ids: content_hosts_ids) if template_id
93
+ end
94
+
95
+ render json: {
96
+ content_hosts_ids: content_hosts_ids,
97
+ hosts_without_content: hosts_without_content,
98
+ environments: environments,
99
+ content_sources: content_sources,
100
+ job_invocation_path: job_invocation_path
101
+ }
102
+ end
71
103
  end
72
104
  end
73
105
  end
@@ -47,11 +47,12 @@ module Katello
47
47
  end
48
48
 
49
49
  def inputs
50
- if feature_name == 'katello_errata_install'
51
- { "Errata Search Query" => "errata_id ^ (#{errata_inputs.join(',')})" }
52
- elsif feature_name == 'katello_service_restart'
50
+ case feature_name
51
+ when 'katello_errata_install'
52
+ { :errata => errata_inputs }
53
+ when 'katello_service_restart'
53
54
  { :helper => params[:name] }
54
- elsif feature_name == 'katello_module_stream_action'
55
+ when 'katello_module_stream_action'
55
56
  fail HttpErrors::NotFound, _('module streams not found') if params[:module_spec].blank?
56
57
  fail HttpErrors::NotFound, _('actions not found') if params[:module_stream_action].blank?
57
58
  inputs = { :module_spec => params[:module_spec], :action => params[:module_stream_action] }
@@ -0,0 +1,43 @@
1
+ module Katello
2
+ module ContentSourceHelper
3
+ def missing_content_source(host)
4
+ <<~CMD
5
+ echo "Host [#{host.name}] doesn't have an assigned content source!"
6
+ exit 1
7
+ CMD
8
+ end
9
+
10
+ def prepare_ssl_cert(ca_cert)
11
+ <<~CMD
12
+ # Prepare SSL certificate
13
+
14
+ KATELLO_SERVER_CA_CERT=/etc/rhsm/ca/katello-server-ca.pem
15
+ SSL_CA_CERT=$(mktemp)
16
+ cat << EOF > $SSL_CA_CERT
17
+ #{ca_cert}
18
+ EOF
19
+
20
+ mkdir -p /etc/rhsm/ca
21
+ cp -f $SSL_CA_CERT $KATELLO_SERVER_CA_CERT
22
+ chmod 644 $KATELLO_SERVER_CA_CERT
23
+
24
+ CMD
25
+ end
26
+
27
+ def configure_subman(content_source)
28
+ <<~CMD
29
+ # Configure subscription-manager
30
+ RHSM_CFG=/etc/rhsm/rhsm.conf
31
+
32
+ test -f $RHSM_CFG.bak || cp $RHSM_CFG $RHSM_CFG.bak
33
+
34
+ subscription-manager config \
35
+ --server.hostname="#{content_source.rhsm_url.host}" \
36
+ --server.port="#{content_source.rhsm_url.port}" \
37
+ --server.prefix="#{content_source.rhsm_url.path}" \
38
+ --rhsm.repo_ca_cert="$KATELLO_SERVER_CA_CERT" \
39
+ --rhsm.baseurl="#{content_source.pulp_content_url}"
40
+ CMD
41
+ end
42
+ end
43
+ end
@@ -266,5 +266,9 @@ module Katello
266
266
  :priority => 900
267
267
  }]
268
268
  end
269
+
270
+ def hosts_change_content_source
271
+ [{ action: [_('Change Content Source'), '/change_host_content_source', false], priority: 100 }]
272
+ end
269
273
  end
270
274
  end
@@ -5,24 +5,22 @@ module Actions
5
5
  def plan(cdn_configuration, options)
6
6
  cdn_configuration.update!(options)
7
7
 
8
- if cdn_configuration.redhat?
9
- cdn_configuration.ssl_cert = nil
10
- cdn_configuration.ssl_key = nil
11
- else
8
+ if cdn_configuration.upstream_server?
12
9
  resource = ::Katello::Resources::CDN::CdnResource.create(cdn_configuration: cdn_configuration)
10
+ resource.validate!
13
11
  keypair = resource.debug_certificate
14
12
  cdn_configuration.ssl_cert = OpenSSL::X509::Certificate.new(keypair)
15
13
  cdn_configuration.ssl_key = OpenSSL::PKey::RSA.new(keypair)
16
- end
17
14
 
18
- cdn_configuration.save!
15
+ cdn_configuration.save!
16
+ end
19
17
 
20
18
  org = cdn_configuration.organization
21
19
  roots = ::Katello::RootRepository.redhat.in_organization(org)
22
20
  roots.each do |root|
23
- full_path = if cdn_configuration.redhat?
21
+ full_path = if cdn_configuration.redhat_cdn?
24
22
  root.product.repo_url(root.library_instance.generate_content_path)
25
- else
23
+ elsif cdn_configuration.upstream_server?
26
24
  resource.repository_url(content_label: root.content.label)
27
25
  end
28
26
  plan_action(::Actions::Katello::Repository::Update, root, url: full_path)
@@ -200,6 +200,11 @@ module Actions
200
200
  plan_action(Katello::Repository::IndexContent, id: id, full_index: true)
201
201
  end
202
202
  end
203
+ concurrence do
204
+ version.importable_repositories.each do |repo|
205
+ plan_action(::Actions::Katello::Repository::MetadataGenerate, repo)
206
+ end
207
+ end
203
208
  plan_action(::Actions::Pulp3::Orchestration::ContentViewVersion::CopyVersionUnitsToLibrary, version)
204
209
  end
205
210
  end
@@ -72,6 +72,18 @@ module Actions
72
72
 
73
73
  unless extended_repo_mapping.empty? || unit_map.values.flatten.empty?
74
74
  sequence do
75
+ # Pre-copy content if dest_repo is a soft copy of its library instance.
76
+ # Don't use extended_repo_mapping because the source repositories are library instances.
77
+ # We want the old CV snapshot repositories here so as to not pull in excess new content.
78
+ separated_repo_map[:pulp3_yum_multicopy].each do |source_repos, dest_repo|
79
+ if dest_repo.soft_copy_of_library?
80
+ source_repos.each do |source_repo|
81
+ # remove_all flag is set to cover the case of incrementally updating more than once with different content.
82
+ # Without it, content from the previous incremental update will be copied as well due to how Pulp repo versions work.
83
+ plan_action(Pulp3::Repository::CopyContent, source_repo, SmartProxy.pulp_primary, dest_repo, copy_all: true, remove_all: true)
84
+ end
85
+ end
86
+ end
75
87
  copy_action_outputs << plan_action(Pulp3::Repository::MultiCopyUnits, extended_repo_mapping, unit_map,
76
88
  dependency_solving: dep_solve).output
77
89
  repos_to_clone.each do |source_repos|
@@ -125,10 +137,12 @@ module Actions
125
137
  source_library_repo = source_repos.first.library_instance? ? source_repos.first : source_repos.first.library_instance
126
138
 
127
139
  source_repos = [source_library_repo]
128
- if old_version_repo.version_href
129
- base_version = old_version_repo.version_href.split("/")[-1].to_i
130
- else
140
+ if old_version_repo.version_href.nil?
131
141
  base_version = 0
142
+ elsif old_version_repo.soft_copy_of_library?
143
+ base_version = nil
144
+ else
145
+ base_version = old_version_repo.version_href.split("/")[-1].to_i
132
146
  end
133
147
 
134
148
  pulp3_repo_mapping[source_repos.map(&:id)] = { dest_repo: dest_repo.id, base_version: base_version }