katello 4.15.1 → 4.16.0.rc1

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

Potentially problematic release.


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

Files changed (498) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/common/katello_object.js +2 -2
  3. data/app/assets/javascripts/katello/locale/bn/katello.js +248 -263
  4. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +247 -262
  5. data/app/assets/javascripts/katello/locale/ca/katello.js +247 -262
  6. data/app/assets/javascripts/katello/locale/cs/katello.js +521 -536
  7. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +253 -268
  8. data/app/assets/javascripts/katello/locale/de/katello.js +248 -263
  9. data/app/assets/javascripts/katello/locale/de_AT/katello.js +247 -262
  10. data/app/assets/javascripts/katello/locale/de_DE/katello.js +249 -264
  11. data/app/assets/javascripts/katello/locale/el/katello.js +251 -266
  12. data/app/assets/javascripts/katello/locale/en/katello.js +253 -268
  13. data/app/assets/javascripts/katello/locale/en_GB/katello.js +263 -278
  14. data/app/assets/javascripts/katello/locale/en_US/katello.js +247 -262
  15. data/app/assets/javascripts/katello/locale/es/katello.js +248 -263
  16. data/app/assets/javascripts/katello/locale/et_EE/katello.js +247 -262
  17. data/app/assets/javascripts/katello/locale/fr/katello.js +250 -265
  18. data/app/assets/javascripts/katello/locale/gl/katello.js +247 -262
  19. data/app/assets/javascripts/katello/locale/gu/katello.js +249 -264
  20. data/app/assets/javascripts/katello/locale/he_IL/katello.js +249 -264
  21. data/app/assets/javascripts/katello/locale/hi/katello.js +248 -263
  22. data/app/assets/javascripts/katello/locale/id/katello.js +261 -275
  23. data/app/assets/javascripts/katello/locale/it/katello.js +252 -267
  24. data/app/assets/javascripts/katello/locale/ja/katello.js +250 -265
  25. data/app/assets/javascripts/katello/locale/ka/katello.js +247 -262
  26. data/app/assets/javascripts/katello/locale/kn/katello.js +248 -263
  27. data/app/assets/javascripts/katello/locale/ko/katello.js +248 -263
  28. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +247 -262
  29. data/app/assets/javascripts/katello/locale/mr/katello.js +248 -263
  30. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +252 -267
  31. data/app/assets/javascripts/katello/locale/or/katello.js +248 -263
  32. data/app/assets/javascripts/katello/locale/pa/katello.js +248 -263
  33. data/app/assets/javascripts/katello/locale/pl/katello.js +248 -263
  34. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +247 -262
  35. data/app/assets/javascripts/katello/locale/pt/katello.js +248 -263
  36. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +248 -263
  37. data/app/assets/javascripts/katello/locale/ro/katello.js +247 -262
  38. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +247 -262
  39. data/app/assets/javascripts/katello/locale/ru/katello.js +253 -268
  40. data/app/assets/javascripts/katello/locale/sl/katello.js +247 -262
  41. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +248 -263
  42. data/app/assets/javascripts/katello/locale/ta/katello.js +248 -263
  43. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +247 -262
  44. data/app/assets/javascripts/katello/locale/te/katello.js +248 -263
  45. data/app/assets/javascripts/katello/locale/tr/katello.js +247 -262
  46. data/app/assets/javascripts/katello/locale/vi/katello.js +247 -262
  47. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +247 -262
  48. data/app/assets/javascripts/katello/locale/zh/katello.js +247 -262
  49. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +250 -265
  50. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +255 -270
  51. data/app/assets/javascripts/katello/sync_management/sync_management.js +16 -2
  52. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +33 -9
  53. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
  54. data/app/controllers/katello/api/v2/activation_keys_controller.rb +4 -9
  55. data/app/controllers/katello/api/v2/content_view_filter_rules_controller.rb +3 -1
  56. data/app/controllers/katello/api/v2/content_views_controller.rb +4 -1
  57. data/app/controllers/katello/api/v2/environments_controller.rb +4 -0
  58. data/app/controllers/katello/api/v2/errata_controller.rb +12 -1
  59. data/app/controllers/katello/api/v2/flatpak_remote_repositories_controller.rb +81 -0
  60. data/app/controllers/katello/api/v2/flatpak_remotes_controller.rb +86 -0
  61. data/app/controllers/katello/api/v2/host_bootc_images_controller.rb +71 -0
  62. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +1 -3
  63. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +3 -5
  64. data/app/controllers/katello/api/v2/repositories_controller.rb +11 -3
  65. data/app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb +0 -8
  66. data/app/controllers/katello/concerns/api/v2/http_proxies_controller_extensions.rb +17 -0
  67. data/app/controllers/katello/concerns/http_proxies_controller_extensions.rb +20 -0
  68. data/app/controllers/katello/sync_management_controller.rb +6 -2
  69. data/app/helpers/katello/content_source_helper.rb +8 -1
  70. data/app/helpers/katello/content_view_helper.rb +3 -1
  71. data/app/lib/actions/candlepin/activation_key/create.rb +1 -3
  72. data/app/lib/actions/candlepin/activation_key/update.rb +1 -3
  73. data/app/lib/actions/candlepin/environment/set_content.rb +17 -4
  74. data/app/lib/actions/katello/activation_key/create.rb +1 -2
  75. data/app/lib/actions/katello/activation_key/update.rb +2 -4
  76. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +7 -1
  77. data/app/lib/actions/katello/content_view/presenters/incremental_updates_presenter.rb +3 -2
  78. data/app/lib/actions/katello/content_view/publish.rb +7 -2
  79. data/app/lib/actions/katello/content_view_environment/reassign_objects.rb +11 -2
  80. data/app/lib/actions/katello/content_view_version/incremental_update.rb +31 -22
  81. data/app/lib/actions/katello/flatpak/mirror_remote_repository.rb +30 -0
  82. data/app/lib/actions/katello/flatpak/scan_remote.rb +17 -12
  83. data/app/lib/actions/katello/host/update_system_purpose.rb +1 -6
  84. data/app/lib/actions/pulp3/orchestration/repository/import_upload.rb +18 -2
  85. data/app/lib/actions/pulp3/repository/multi_copy_units.rb +4 -0
  86. data/app/lib/katello/api/v2/rendering.rb +2 -1
  87. data/app/lib/katello/concerns/bookmark_controller_validator_extensions.rb +13 -0
  88. data/app/lib/katello/resources/candlepin/activation_key.rb +3 -5
  89. data/app/lib/katello/validators/alternate_content_source_path_validator.rb +2 -2
  90. data/app/lib/katello/validators/container_image_name_validator.rb +1 -1
  91. data/app/lib/katello/validators/content_validator.rb +1 -1
  92. data/app/lib/katello/validators/content_view_environment_coherent_default_validator.rb +2 -2
  93. data/app/lib/katello/validators/content_view_environment_org_validator.rb +2 -2
  94. data/app/lib/katello/validators/content_view_environment_validator.rb +3 -3
  95. data/app/lib/katello/validators/content_view_erratum_filter_rule_validator.rb +12 -12
  96. data/app/lib/katello/validators/content_view_filter_version_validator.rb +1 -1
  97. data/app/lib/katello/validators/generated_content_view_validator.rb +1 -1
  98. data/app/lib/katello/validators/gpg_key_content_type_validator.rb +2 -2
  99. data/app/lib/katello/validators/gpg_key_content_validator.rb +5 -5
  100. data/app/lib/katello/validators/katello_label_format_validator.rb +4 -4
  101. data/app/lib/katello/validators/katello_name_format_validator.rb +2 -2
  102. data/app/lib/katello/validators/katello_url_format_validator.rb +1 -1
  103. data/app/lib/katello/validators/library_presence_validator.rb +1 -1
  104. data/app/lib/katello/validators/no_trailing_space_validator.rb +1 -1
  105. data/app/lib/katello/validators/non_library_environment_validator.rb +1 -1
  106. data/app/lib/katello/validators/not_in_library_validator.rb +1 -1
  107. data/app/lib/katello/validators/path_descendents_validator.rb +1 -1
  108. data/app/lib/katello/validators/prior_validator.rb +1 -1
  109. data/app/lib/katello/validators/product_unique_attribute_validator.rb +1 -1
  110. data/app/lib/katello/validators/repo_disablement_validator.rb +2 -2
  111. data/app/lib/katello/validators/root_repository_unique_attribute_validator.rb +1 -1
  112. data/app/lib/katello/validators/self_reference_environment_validator.rb +1 -1
  113. data/app/lib/katello/validators/unique_field_in_org.rb +1 -1
  114. data/app/models/katello/activation_key.rb +6 -17
  115. data/app/models/katello/authorization/flatpak_remote.rb +33 -0
  116. data/app/models/katello/concerns/content_facet_host_extensions.rb +2 -1
  117. data/app/models/katello/concerns/host_managed_extensions.rb +8 -5
  118. data/app/models/katello/concerns/http_proxy_extensions.rb +4 -0
  119. data/app/models/katello/concerns/smart_proxy_extensions.rb +30 -6
  120. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +0 -8
  121. data/app/models/katello/content_view.rb +3 -1
  122. data/app/models/katello/content_view_erratum_filter.rb +18 -2
  123. data/app/models/katello/content_view_version.rb +6 -0
  124. data/app/models/katello/docker_manifest.rb +8 -0
  125. data/app/models/katello/docker_manifest_list.rb +8 -0
  126. data/app/models/katello/erratum.rb +8 -2
  127. data/app/models/katello/flatpak_remote.rb +16 -0
  128. data/app/models/katello/flatpak_remote_repository.rb +18 -0
  129. data/app/models/katello/flatpak_remote_repository_manifest.rb +4 -0
  130. data/app/models/katello/glue/candlepin/pool.rb +1 -1
  131. data/app/models/katello/glue/pulp/repos.rb +12 -1
  132. data/app/models/katello/host/content_facet.rb +42 -3
  133. data/app/models/katello/host/subscription_facet.rb +4 -12
  134. data/app/models/katello/repository.rb +21 -8
  135. data/app/models/katello/rhel_lifecycle_status.rb +6 -0
  136. data/app/models/katello/root_repository.rb +3 -8
  137. data/app/overrides/add_organization_attributes.rb +6 -0
  138. data/app/services/katello/product_content_finder.rb +2 -1
  139. data/app/services/katello/pulp3/docker_manifest.rb +3 -2
  140. data/app/services/katello/pulp3/docker_manifest_list.rb +3 -2
  141. data/app/services/katello/pulp3/repository/ansible_collection.rb +8 -1
  142. data/app/services/katello/pulp3/repository/apt.rb +16 -18
  143. data/app/services/katello/pulp3/repository/file.rb +4 -2
  144. data/app/services/katello/pulp3/repository.rb +4 -0
  145. data/app/services/katello/pulp3/task.rb +2 -2
  146. data/app/views/foreman/job_templates/bootc_action.erb +26 -0
  147. data/app/views/foreman/job_templates/bootc_rollback.erb +13 -0
  148. data/app/views/foreman/job_templates/bootc_status.erb +13 -0
  149. data/app/views/foreman/job_templates/bootc_switch.erb +13 -0
  150. data/app/views/foreman/job_templates/bootc_upgrade.erb +13 -0
  151. data/app/views/foreman/job_templates/flatpak_install.erb +23 -0
  152. data/app/views/foreman/job_templates/flatpak_login_action.erb +30 -0
  153. data/app/views/foreman/job_templates/flatpak_setup.erb +27 -0
  154. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +1 -1
  155. data/app/views/foreman/job_templates/install_errata_by_search_query_-_katello_ansible_default.erb +1 -1
  156. data/app/views/foreman/job_templates/resolve_traces_-_katello_ansible_default.erb +1 -1
  157. data/app/views/foreman/job_templates/update_packages_by_search_query_-_katello_ansible_default.erb +1 -1
  158. data/app/views/katello/api/v2/activation_keys/base.json.rabl +0 -4
  159. data/app/views/katello/api/v2/content_facet/base.json.rabl +2 -1
  160. data/app/views/katello/api/v2/content_view_filter_rules/show.json.rabl +1 -0
  161. data/app/views/katello/api/v2/content_view_versions/base.json.rabl +5 -1
  162. data/app/views/katello/api/v2/docker_manifest_lists/show.json.rabl +1 -1
  163. data/app/views/katello/api/v2/docker_manifests/show.json.rabl +1 -1
  164. data/app/views/katello/api/v2/flatpak_remote_repositories/base.json.rabl +4 -0
  165. data/app/views/katello/api/v2/flatpak_remote_repositories/index.json.rabl +7 -0
  166. data/app/views/katello/api/v2/flatpak_remote_repositories/show.json.rabl +13 -0
  167. data/app/views/katello/api/v2/flatpak_remotes/base.json.rabl +5 -0
  168. data/app/views/katello/api/v2/flatpak_remotes/index.json.rabl +8 -0
  169. data/app/views/katello/api/v2/flatpak_remotes/permissions.json.rabl +11 -0
  170. data/app/views/katello/api/v2/flatpak_remotes/show.json.rabl +3 -0
  171. data/app/views/katello/api/v2/hosts/base.json.rabl +0 -8
  172. data/app/views/katello/api/v2/hosts/os_attributes.json.rabl +13 -0
  173. data/app/views/katello/api/v2/http_proxies/show.json.rabl +1 -0
  174. data/app/views/katello/api/v2/repositories/base.json.rabl +1 -0
  175. data/app/views/katello/api/v2/repositories/show.json.rabl +1 -0
  176. data/app/views/katello/api/v2/subscription_facet/base.json.rabl +0 -4
  177. data/app/views/katello/api/v2/subscriptions/show.json.rabl +1 -1
  178. data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +10 -4
  179. data/app/views/overrides/http_proxies/_update_setting_input.html.erb +18 -0
  180. data/app/views/overrides/organizations/_step_1_override.html.erb +5 -0
  181. data/config/initializers/monkeys.rb +0 -1
  182. data/config/initializers/pagelets.rb +6 -0
  183. data/config/routes/api/registry.rb +1 -0
  184. data/config/routes/api/v2.rb +21 -0
  185. data/config/routes/overrides.rb +1 -0
  186. data/config/routes.rb +2 -0
  187. data/db/migrate/20190605014649_add_purpose_addons.rb +0 -12
  188. data/db/migrate/20200213184848_create_evr_type.rb +126 -1
  189. data/db/migrate/20200818192230_update_system_purpose_status.rb +0 -1
  190. data/db/migrate/20240207191223_remove_entitlement_mode_host_statuses.rb +0 -1
  191. data/db/migrate/20240924161240_katello_recreate_evr_constructs.rb +160 -0
  192. data/db/migrate/20241022121706_add_sync_dependencies_option.rb +5 -0
  193. data/db/migrate/20241101144625_remove_system_purpose_addons.rb +9 -0
  194. data/db/migrate/20241107002541_add_registry_url_to_katello_flatpak_remotes.rb +5 -0
  195. data/db/migrate/20241112145802_add_manifest_entity_to_content_facets.rb +7 -0
  196. data/db/migrate/20241120213713_add_allow_other_types_to_content_view_erratum_filter_rules.rb +6 -0
  197. data/db/migrate/20241206183052_add_content_type_to_container_manifests_and_lists.rb +9 -0
  198. data/db/seeds.d/75-job_templates.rb +5 -1
  199. data/engines/bastion/vendor/assets/javascripts/bastion/angular/angular.js +2 -2
  200. data/engines/bastion/vendor/assets/javascripts/bastion/angular-bootstrap/ui-bootstrap-tpls.js +3 -3
  201. data/engines/bastion/vendor/assets/javascripts/bastion/angular-bootstrap/ui-bootstrap.js +3 -3
  202. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-details-info.controller.js +0 -5
  203. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-details.controller.js +1 -41
  204. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-info.html +0 -12
  205. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/subscription-add-or-remove.html +1 -1
  206. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-system-purpose-modal.controller.js +1 -41
  207. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-traces-modal.controller.js +1 -1
  208. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-errata-modal.html +2 -2
  209. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-subscriptions-modal.html +2 -2
  210. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-system-purpose-modal.html +0 -13
  211. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +1 -1
  212. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details-info.controller.js +0 -5
  213. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +1 -35
  214. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +2 -14
  215. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-provisioning-info.html +1 -1
  216. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +2 -2
  217. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/debs.controller.js +46 -22
  218. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/deb-content-views.controller.js +2 -1
  219. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/views/debs.html +4 -0
  220. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-content-views.html +1 -1
  221. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-details.html +1 -1
  222. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-errata.html +1 -1
  223. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/errata-tasks-list.html +2 -1
  224. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +85 -29
  225. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/bn.po +338 -93
  226. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/bn_IN.po +340 -95
  227. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ca.po +340 -95
  228. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/cs_CZ.po +341 -96
  229. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de.po +31 -54
  230. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de_AT.po +338 -93
  231. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de_DE.po +338 -93
  232. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/el.po +341 -96
  233. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/en_GB.po +349 -104
  234. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/en_US.po +338 -93
  235. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/es.po +33 -56
  236. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/et_EE.po +338 -93
  237. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +80 -68
  238. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/gl.po +340 -95
  239. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/gu.po +340 -95
  240. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/he_IL.po +339 -111
  241. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/hi.po +340 -95
  242. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/id.po +379 -130
  243. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/it.po +342 -103
  244. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +70 -83
  245. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ka.po +84 -90
  246. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/kn.po +340 -95
  247. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +130 -138
  248. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ml_IN.po +338 -93
  249. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/mr.po +340 -95
  250. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/nl_NL.po +343 -97
  251. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/or.po +340 -95
  252. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pa.po +340 -95
  253. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pl.po +340 -95
  254. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pl_PL.po +338 -93
  255. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt.po +338 -93
  256. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt_BR.po +40 -63
  257. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ro.po +338 -93
  258. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ro_RO.po +338 -93
  259. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ru.po +343 -102
  260. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/sl.po +338 -93
  261. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/sv_SE.po +340 -95
  262. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ta.po +338 -93
  263. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ta_IN.po +340 -95
  264. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/te.po +340 -95
  265. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/tr.po +338 -93
  266. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/vi.po +338 -93
  267. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/vi_VN.po +338 -93
  268. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh.po +338 -93
  269. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +70 -83
  270. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_TW.po +362 -105
  271. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +29 -29
  272. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/views/package-info.html +1 -1
  273. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/products-bulk-advanced-sync-modal.controller.js +1 -1
  274. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/views/products-bulk-sync-plan-modal.html +2 -2
  275. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +24 -8
  276. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-tasks.html +2 -1
  277. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +2 -2
  278. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +21 -8
  279. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/os-versions.service.js +1 -0
  280. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/views/product-info.html +3 -3
  281. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/views/product-tasks.html +2 -1
  282. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery-create.html +4 -2
  283. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery.html +2 -1
  284. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +3 -3
  285. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/partials/product-table-sync-status.html +1 -1
  286. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/subscription-start-date.html +1 -1
  287. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/views/sync-plan-info.html +1 -1
  288. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/views/sync-plans.html +2 -2
  289. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/tasks-table.directive.js +2 -1
  290. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/views/task-details.html +2 -2
  291. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/views/tasks-index.html +1 -1
  292. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/views/tasks-table.html +1 -1
  293. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/views/user-tasks-table.html +1 -1
  294. data/lib/katello/engine.rb +6 -0
  295. data/lib/katello/permission_creator.rb +37 -0
  296. data/lib/katello/permissions/host_permissions.rb +2 -0
  297. data/lib/katello/permissions/registry_permissions.rb +1 -0
  298. data/lib/katello/plugin.rb +18 -1
  299. data/lib/katello/repository_types/python.rb +1 -1
  300. data/lib/katello/version.rb +1 -1
  301. data/lib/katello.rb +2 -0
  302. data/locale/Makefile +20 -24
  303. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  304. data/locale/bn/katello.po +248 -263
  305. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  306. data/locale/bn_IN/katello.po +247 -262
  307. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  308. data/locale/ca/katello.po +247 -262
  309. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  310. data/locale/cs/katello.po +524 -799
  311. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  312. data/locale/cs_CZ/katello.po +254 -269
  313. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  314. data/locale/de/katello.po +248 -263
  315. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  316. data/locale/de_AT/katello.po +247 -262
  317. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  318. data/locale/de_DE/katello.po +250 -265
  319. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  320. data/locale/el/katello.po +252 -267
  321. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  322. data/locale/en/katello.po +257 -271
  323. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  324. data/locale/en_GB/katello.po +264 -279
  325. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  326. data/locale/en_US/katello.po +247 -262
  327. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  328. data/locale/es/katello.po +248 -263
  329. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  330. data/locale/et_EE/katello.po +247 -262
  331. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  332. data/locale/fr/katello.po +250 -265
  333. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  334. data/locale/gl/katello.po +247 -262
  335. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  336. data/locale/gu/katello.po +250 -265
  337. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  338. data/locale/he_IL/katello.po +249 -264
  339. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  340. data/locale/hi/katello.po +248 -263
  341. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  342. data/locale/id/katello.po +264 -275
  343. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  344. data/locale/it/katello.po +254 -270
  345. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  346. data/locale/ja/katello.po +250 -265
  347. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  348. data/locale/ka/katello.po +247 -262
  349. data/locale/katello.pot +1216 -1215
  350. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  351. data/locale/kn/katello.po +248 -263
  352. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  353. data/locale/ko/katello.po +248 -263
  354. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  355. data/locale/ml_IN/katello.po +247 -262
  356. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  357. data/locale/mr/katello.po +248 -263
  358. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  359. data/locale/nl_NL/katello.po +254 -268
  360. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  361. data/locale/or/katello.po +248 -263
  362. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  363. data/locale/pa/katello.po +248 -263
  364. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  365. data/locale/pl/katello.po +249 -264
  366. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  367. data/locale/pl_PL/katello.po +247 -262
  368. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  369. data/locale/pt/katello.po +248 -263
  370. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  371. data/locale/pt_BR/katello.po +248 -263
  372. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  373. data/locale/ro/katello.po +247 -262
  374. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  375. data/locale/ro_RO/katello.po +247 -262
  376. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  377. data/locale/ru/katello.po +255 -270
  378. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  379. data/locale/sl/katello.po +247 -262
  380. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  381. data/locale/sv_SE/katello.po +249 -264
  382. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  383. data/locale/ta/katello.po +248 -263
  384. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  385. data/locale/ta_IN/katello.po +247 -262
  386. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  387. data/locale/te/katello.po +248 -263
  388. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  389. data/locale/tr/katello.po +247 -262
  390. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  391. data/locale/vi/katello.po +247 -262
  392. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  393. data/locale/vi_VN/katello.po +247 -262
  394. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  395. data/locale/zh/katello.po +247 -262
  396. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  397. data/locale/zh_CN/katello.po +250 -265
  398. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  399. data/locale/zh_TW/katello.po +257 -272
  400. data/webpack/ForemanColumnExtensions/index.js +73 -3
  401. data/webpack/ForemanColumnExtensions/index.scss +9 -0
  402. data/webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js +1 -0
  403. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +1 -1
  404. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +1 -20
  405. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +3 -61
  406. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeCard.test.js +0 -5
  407. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeEditModal.test.js +0 -5
  408. data/webpack/components/extensions/HostDetails/DetailsTabCards/ImageModeCard.js +87 -0
  409. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +28 -2
  410. data/webpack/components/extensions/HostDetails/Tabs/DebsTab/DebInstallModal.js +1 -1
  411. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +2 -2
  412. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +1 -1
  413. data/webpack/components/extensions/Hosts/FontAwesomeImageModeIcon.js +55 -0
  414. data/webpack/containers/Application/config.js +5 -0
  415. data/webpack/global_index.js +3 -1
  416. data/webpack/redux/actions/RedHatRepositories/helpers.js +9 -0
  417. data/webpack/scenes/BootedContainerImages/BootedContainerImagesConstants.js +5 -0
  418. data/webpack/scenes/BootedContainerImages/BootedContainerImagesPage.js +242 -0
  419. data/webpack/scenes/BootedContainerImages/__tests__/bootedContainerImages.fixtures.js +42 -0
  420. data/webpack/scenes/BootedContainerImages/__tests__/bootedContainerImagesPage.test.js +233 -0
  421. data/webpack/scenes/BootedContainerImages/index.js +4 -0
  422. data/webpack/scenes/ContentViews/Delete/__tests__/affectedHosts.fixtures.json +1 -2
  423. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +39 -7
  424. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +13 -2
  425. data/webpack/scenes/ContentViews/Details/Filters/CVFilterDetailType.js +1 -1
  426. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErrataDateFilterContent.test.js +1 -0
  427. data/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js +4 -2
  428. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/hosts.fixtures.json +1 -2
  429. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js +20 -1
  430. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignHostsForm.js +20 -1
  431. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionRemoveReview.js +128 -18
  432. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvAffectedActivationKeys.fixture.json +0 -1
  433. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvAffectedHosts.fixture.json +1 -2
  434. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js +6 -4
  435. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +5 -1
  436. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +6 -1
  437. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +1 -1
  438. data/webpack/scenes/ContentViews/expansions/DetailsExpansion.js +5 -1
  439. data/webpack/scenes/SmartProxy/ExpandableCvDetails.js +4 -2
  440. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +38 -0
  441. data/webpack/scenes/Subscriptions/Details/SubscriptionPurposeAttributes.js +0 -1
  442. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailInfo.test.js.snap +0 -10
  443. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +0 -3
  444. data/webpack/scenes/Subscriptions/Details/__tests__/subscriptionDetails.fixtures.js +0 -1
  445. metadata +61 -64
  446. data/app/models/katello/activation_key_purpose_addon.rb +0 -6
  447. data/app/models/katello/purpose_addon.rb +0 -11
  448. data/app/models/katello/subscription_facet_purpose_addon.rb +0 -6
  449. data/lib/monkeys/fx_sqlite_skip.rb +0 -13
  450. data/locale/action_names.rb +0 -181
  451. data/locale/bn/katello.po.time_stamp +0 -0
  452. data/locale/bn_IN/katello.po.time_stamp +0 -0
  453. data/locale/ca/katello.po.time_stamp +0 -0
  454. data/locale/cs/katello.po.time_stamp +0 -0
  455. data/locale/cs_CZ/katello.po.time_stamp +0 -0
  456. data/locale/de/katello.po.time_stamp +0 -0
  457. data/locale/de_AT/katello.po.time_stamp +0 -0
  458. data/locale/de_DE/katello.po.time_stamp +0 -0
  459. data/locale/el/katello.po.time_stamp +0 -0
  460. data/locale/en/katello.po.time_stamp +0 -0
  461. data/locale/en_GB/katello.po.time_stamp +0 -0
  462. data/locale/en_US/katello.po.time_stamp +0 -0
  463. data/locale/es/katello.po.time_stamp +0 -0
  464. data/locale/et_EE/katello.po.time_stamp +0 -0
  465. data/locale/fr/katello.po.time_stamp +0 -0
  466. data/locale/gl/katello.po.time_stamp +0 -0
  467. data/locale/gu/katello.po.time_stamp +0 -0
  468. data/locale/he_IL/katello.po.time_stamp +0 -0
  469. data/locale/hi/katello.po.time_stamp +0 -0
  470. data/locale/id/katello.po.time_stamp +0 -0
  471. data/locale/it/katello.po.time_stamp +0 -0
  472. data/locale/ja/katello.po.time_stamp +0 -0
  473. data/locale/ka/katello.po.time_stamp +0 -0
  474. data/locale/kn/katello.po.time_stamp +0 -0
  475. data/locale/ko/katello.po.time_stamp +0 -0
  476. data/locale/ml_IN/katello.po.time_stamp +0 -0
  477. data/locale/mr/katello.po.time_stamp +0 -0
  478. data/locale/nl_NL/katello.po.time_stamp +0 -0
  479. data/locale/or/katello.po.time_stamp +0 -0
  480. data/locale/pa/katello.po.time_stamp +0 -0
  481. data/locale/pl/katello.po.time_stamp +0 -0
  482. data/locale/pl_PL/katello.po.time_stamp +0 -0
  483. data/locale/pt/katello.po.time_stamp +0 -0
  484. data/locale/pt_BR/katello.po.time_stamp +0 -0
  485. data/locale/ro/katello.po.time_stamp +0 -0
  486. data/locale/ro_RO/katello.po.time_stamp +0 -0
  487. data/locale/ru/katello.po.time_stamp +0 -0
  488. data/locale/sl/katello.po.time_stamp +0 -0
  489. data/locale/sv_SE/katello.po.time_stamp +0 -0
  490. data/locale/ta/katello.po.time_stamp +0 -0
  491. data/locale/ta_IN/katello.po.time_stamp +0 -0
  492. data/locale/te/katello.po.time_stamp +0 -0
  493. data/locale/tr/katello.po.time_stamp +0 -0
  494. data/locale/vi/katello.po.time_stamp +0 -0
  495. data/locale/vi_VN/katello.po.time_stamp +0 -0
  496. data/locale/zh/katello.po.time_stamp +0 -0
  497. data/locale/zh_CN/katello.po.time_stamp +0 -0
  498. data/locale/zh_TW/katello.po.time_stamp +0 -0
@@ -7,13 +7,78 @@ import {
7
7
  PackageIcon,
8
8
  } from '@patternfly/react-icons';
9
9
  import { Link } from 'react-router-dom';
10
- import { Flex, FlexItem, Popover, Badge } from '@patternfly/react-core';
10
+ import {
11
+ Flex,
12
+ FlexItem,
13
+ Popover,
14
+ Badge,
15
+ DescriptionList,
16
+ DescriptionListGroup,
17
+ DescriptionListDescription as Dd,
18
+ DescriptionListTerm as Dt,
19
+ Text,
20
+ TextVariants,
21
+ } from '@patternfly/react-core';
11
22
  import { translate as __ } from 'foremanReact/common/I18n';
12
23
  import RelativeDateTime from 'foremanReact/components/common/dates/RelativeDateTime';
13
24
  import { ContentViewEnvironmentDisplay } from '../components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard';
14
25
  import { truncate } from '../utils/helpers';
26
+ import RepoIcon from '../scenes/ContentViews/Details/Repositories/RepoIcon';
27
+ import FontAwesomeImageModeIcon from '../components/extensions/Hosts/FontAwesomeImageModeIcon';
28
+ import './index.scss';
15
29
 
16
30
  const hostsIndexColumnExtensions = [
31
+ {
32
+ columnName: 'bootc_booted_image',
33
+ title: (
34
+ <span id="image-mode-column-title-icon">
35
+ <FontAwesomeImageModeIcon title={__('Image mode / package mode')} />
36
+ </span>
37
+ ),
38
+ wrapper: (hostDetails) => {
39
+ const imageMode = hostDetails?.content_facet_attributes?.bootc_booted_image;
40
+ const digest = hostDetails?.content_facet_attributes?.bootc_booted_digest;
41
+ return (
42
+ <span className={imageMode ? 'image-mode-column-td-icon' : 'package-mode-column-td-icon'}>
43
+ {imageMode ?
44
+ <Popover
45
+ id="image-mode-tooltip"
46
+ className="image-mode-tooltip"
47
+ maxWidth="74rem"
48
+ headerContent={hostDetails.display_name}
49
+ bodyContent={
50
+ <Flex direction={{ default: 'column' }}>
51
+ <FlexItem>
52
+ <Flex direction={{ default: 'row' }} alignItems={{ default: 'alignItemsCenter' }}>
53
+ <FlexItem>
54
+ <FontAwesomeImageModeIcon />
55
+ </FlexItem>
56
+ <Text ouiaId="image-mode-popover-h4" component={TextVariants.h4}>{__('Image-mode host')}</Text>
57
+ </Flex>
58
+ </FlexItem>
59
+ <DescriptionList isCompact isHorizontal>
60
+ <DescriptionListGroup>
61
+ <Dt>{__('Running image')}</Dt>
62
+ <Dd>{hostDetails.content_facet_attributes.bootc_booted_image}</Dd>
63
+ </DescriptionListGroup>
64
+ <DescriptionListGroup>
65
+ <Dt>{__('Digest')}</Dt>
66
+ <Dd>{digest}</Dd>
67
+ </DescriptionListGroup>
68
+ </DescriptionList>
69
+ </Flex>
70
+ }
71
+ >
72
+ <FontAwesomeImageModeIcon title={__('Image mode')} />
73
+ </Popover>
74
+ : <span style={{ color: 'var(--pf-global--palette--black-600)' }}><RepoIcon type="yum" customTooltip={__('Package mode')} /></span>
75
+ }
76
+ </span>
77
+ );
78
+ },
79
+ weight: 35, // between power status (0) and name (50)
80
+ isSorted: true,
81
+ },
17
82
  {
18
83
  columnName: 'rhel_lifecycle_status',
19
84
  title: __('RHEL Lifecycle status'),
@@ -32,6 +97,7 @@ const hostsIndexColumnExtensions = [
32
97
  const registered = !!hostDetails?.subscription_facet_attributes?.uuid;
33
98
  const { security, bugfix, enhancement } = errataCounts ?? {};
34
99
  const upgradableRpmCount = hostDetails?.content_facet_attributes?.upgradable_package_count;
100
+ const upgradableDebCount = hostDetails?.content_facet_attributes?.upgradable_deb_count;
35
101
  if (!registered) return '—';
36
102
  const hostErrataUrl = type => `hosts/${hostDetails?.name}#/Content/errata?type=${type}&show=installable`;
37
103
  return (
@@ -54,10 +120,14 @@ const hostsIndexColumnExtensions = [
54
120
  <Link to={hostErrataUrl('enhancement')}>{enhancement}</Link>
55
121
  </FlexItem>
56
122
  }
57
- {upgradableRpmCount !== undefined &&
123
+ {(upgradableRpmCount !== undefined || upgradableDebCount !== undefined) &&
58
124
  <FlexItem>
59
125
  <PackageIcon />
60
- <Link to={`hosts/${hostDetails?.name}#/Content/Packages?status=Upgradable`}>{upgradableRpmCount}</Link>
126
+ { hostDetails?.operatingsystem_family === 'Debian' ?
127
+ <Link to={`hosts/${hostDetails?.name}#/Content/Debs?status=Upgradable`}>{upgradableDebCount}</Link>
128
+ :
129
+ <Link to={`hosts/${hostDetails?.name}#/Content/Packages?status=Upgradable`}>{upgradableRpmCount}</Link>
130
+ }
61
131
  </FlexItem>
62
132
  }
63
133
  </Flex>
@@ -0,0 +1,9 @@
1
+ #image-mode-column-title-icon {
2
+ padding: 5px;
3
+ }
4
+ .image-mode-column-td-icon {
5
+ padding: 6px;
6
+ }
7
+ .package-mode-column-td-icon {
8
+ padding: 4px;
9
+ }
@@ -1,3 +1,4 @@
1
1
  // eslint-disable-next-line import/prefer-default-export
2
2
  export const useForemanSettings = () => ({ perPage: 20 });
3
3
  export const useForemanVersion = () => 'nightly';
4
+ export const useForemanHostsPageUrl = () => '/new/hosts';
@@ -130,7 +130,7 @@ const ErrataOverviewCard = ({ hostDetails }) => {
130
130
  <ErrataToggleGroupItem
131
131
  text={__('Installable')}
132
132
  aria-label="Show installable errata chart"
133
- tooltipText={__('Installable errata are applicable errata that are available in the host\'s content view and lifecycle environment.')}
133
+ tooltipText={__('Installable errata are applicable errata that are available in the host\'s assigned content view environments.')}
134
134
  isSelected={errataCategory === 'installable'}
135
135
  onChange={selected => selected && setErrataCategory('installable')}
136
136
  />
@@ -17,8 +17,6 @@ import {
17
17
  FlexItem,
18
18
  GridItem,
19
19
  Label,
20
- List,
21
- ListItem,
22
20
  Tooltip,
23
21
  Skeleton,
24
22
  CardExpandableContent,
@@ -41,12 +39,11 @@ const SystemPurposeCard = ({ hostDetails, akDetails }) => {
41
39
  const { organization_id: orgId, name } = details;
42
40
  const subscriptionFacetAttributes = details?.subscription_facet_attributes;
43
41
  const {
44
- purposeRole, purposeUsage, purposeAddons, releaseVersion, serviceLevel,
42
+ purposeRole, purposeUsage, releaseVersion, serviceLevel,
45
43
  } = propsToCamelCase((subscriptionFacetAttributes || details) ?? {});
46
44
  const sysPurposeProps = {
47
45
  purposeRole,
48
46
  purposeUsage,
49
- purposeAddons,
50
47
  releaseVersion,
51
48
  serviceLevel,
52
49
  };
@@ -142,21 +139,6 @@ const SystemPurposeCard = ({ hostDetails, akDetails }) => {
142
139
  <Dd>
143
140
  {dataIsLoading ? <Skeleton /> : releaseVersion}
144
141
  </Dd>
145
- {!!purposeAddons?.length && (
146
- <>
147
- <Dt>{__('Add-ons')}</Dt>
148
- {dataIsLoading ? <Skeleton /> : (
149
- <Dd>
150
- <List isPlain>
151
- {purposeAddons.map(addon => (
152
- <ListItem key={addon}>{addon}</ListItem>
153
- ))}
154
- </List>
155
- </Dd>
156
- )}
157
- </>
158
- )
159
- }
160
142
  </DescriptionListGroup>
161
143
  </DescriptionList>
162
144
  {showEditButton && (
@@ -201,7 +183,6 @@ SystemPurposeCard.propTypes = {
201
183
  purpose_role: PropTypes.string,
202
184
  release_version: PropTypes.string,
203
185
  service_level: PropTypes.string,
204
- purpose_addons: PropTypes.arrayOf(PropTypes.string),
205
186
  permissions: PropTypes.shape({
206
187
  edit_activation_keys: PropTypes.bool,
207
188
  }),
@@ -1,6 +1,5 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
  import { useSelector, useDispatch } from 'react-redux';
3
- import { isEqual } from 'lodash';
4
3
  import PropTypes from 'prop-types';
5
4
  import { STATUS } from 'foremanReact/constants';
6
5
  import { propsToCamelCase } from 'foremanReact/common/helpers';
@@ -11,9 +10,6 @@ import {
11
10
  FormGroup,
12
11
  FormSelect,
13
12
  FormSelectOption,
14
- Select,
15
- SelectOption,
16
- SelectVariant,
17
13
  } from '@patternfly/react-core';
18
14
  import { FormattedMessage } from 'react-intl';
19
15
  import { translate as __ } from 'foremanReact/common/I18n';
@@ -29,27 +25,23 @@ import { defaultUsages, defaultRoles, defaultServiceLevels } from './SystemPurpo
29
25
  import { getActivationKey } from '../../../../../scenes/ActivationKeys/Details/ActivationKeyActions';
30
26
 
31
27
  const SystemPurposeEditModal = ({
32
- closeModal, name, purposeRole, purposeUsage, purposeAddons,
28
+ closeModal, name, purposeRole, purposeUsage,
33
29
  serviceLevel, releaseVersion, isOpen, orgId, id, type,
34
30
  }) => {
35
31
  const initialPurposeRole = purposeRole ?? '';
36
32
  const initialServiceLevel = serviceLevel ?? '';
37
33
  const initialPurposeUsage = purposeUsage ?? '';
38
34
  const initialReleaseVersion = releaseVersion ?? '';
39
- const initialPurposeAddons = purposeAddons ?? [];
40
35
  const [selectedRole, setSelectedRole] = useState(initialPurposeRole);
41
36
  const [selectedServiceLevel, setSelectedServiceLevel] = useState(initialServiceLevel);
42
37
  const [selectedUsage, setSelectedUsage] = useState(initialPurposeUsage);
43
- const [addonSelectOpen, setAddonSelectOpen] = useState(false);
44
- const [selectedAddons, setSelectedAddons] = useState(initialPurposeAddons);
45
38
  const [selectedReleaseVersion, setSelectedReleaseVersion] = useState(initialReleaseVersion);
46
39
 
47
40
  const unmodified = (
48
41
  selectedRole === initialPurposeRole &&
49
42
  selectedServiceLevel === initialServiceLevel &&
50
43
  selectedUsage === initialPurposeUsage &&
51
- selectedReleaseVersion === initialReleaseVersion &&
52
- isEqual(selectedAddons, initialPurposeAddons)
44
+ selectedReleaseVersion === initialReleaseVersion
53
45
  );
54
46
  const dispatch = useDispatch();
55
47
 
@@ -58,7 +50,7 @@ const SystemPurposeEditModal = ({
58
50
  const orgDetails = propsToCamelCase(organizationDetails ?? { systemPurposes: {} });
59
51
  const availableSyspurposeAttributes = orgDetails?.systemPurposes ?? {};
60
52
  const availableServiceLevels = orgDetails?.serviceLevels ?? [];
61
- const { addons: availableAddons, roles: availableRoles, usage: availableUsages }
53
+ const { roles: availableRoles, usage: availableUsages }
62
54
  = availableSyspurposeAttributes;
63
55
  const selectorAPIKey = type === 'host' ? 'AVAILABLE_RELEASE_VERSIONS' : 'RELEASES';
64
56
 
@@ -79,19 +71,6 @@ const SystemPurposeEditModal = ({
79
71
  }
80
72
  }, [type, id, availableReleaseVersionsStatus, actionToDispatch, dispatch]);
81
73
 
82
- const toggleAddonSelect = isOpenState => setAddonSelectOpen(isOpenState);
83
-
84
- const onAddonSelect = (_event, selected) => {
85
- const newSelectedAddons = new Set(selectedAddons);
86
- if (!selected) return;
87
- if (newSelectedAddons.has(selected)) {
88
- newSelectedAddons.delete(selected);
89
- } else {
90
- newSelectedAddons.add(selected);
91
- }
92
- setSelectedAddons([...newSelectedAddons]);
93
- };
94
-
95
74
  const refreshHostDetails = () => dispatch({
96
75
  type: 'API_GET',
97
76
  payload: {
@@ -122,14 +101,6 @@ const SystemPurposeEditModal = ({
122
101
  const usageOptions =
123
102
  buildOptions(defaultUsages, availableUsages, selectedUsage, purposeUsage);
124
103
 
125
- // addons may be present on the host but not available from subscriptions,
126
- // so we combine the options here
127
- const addonToObject = addon => ({ label: addon, value: addon });
128
- const addonsOptions =
129
- [...new Set([ // don't repeat addons if they are already selected
130
- ...purposeAddons.map(addonToObject), ...availableAddons?.map(addonToObject) ?? [],
131
- ])];
132
-
133
104
  const serviceLevelOptions =
134
105
  buildOptions(defaultServiceLevels, availableServiceLevels, selectedServiceLevel, serviceLevel);
135
106
 
@@ -148,7 +119,6 @@ const SystemPurposeEditModal = ({
148
119
  autoheal: true,
149
120
  purpose_role: optionsToValue(roleOptions, selectedRole),
150
121
  purpose_usage: optionsToValue(usageOptions, selectedUsage),
151
- purpose_addons: selectedAddons,
152
122
  release_version: optionsToValue(releaseVersionOptions, selectedReleaseVersion),
153
123
  service_level: optionsToValue(serviceLevelOptions, selectedServiceLevel),
154
124
  },
@@ -161,7 +131,6 @@ const SystemPurposeEditModal = ({
161
131
  autoheal: true,
162
132
  purpose_role: optionsToValue(roleOptions, selectedRole),
163
133
  purpose_usage: optionsToValue(usageOptions, selectedUsage),
164
- purpose_addons: selectedAddons,
165
134
  release_version: optionsToValue(releaseVersionOptions, selectedReleaseVersion),
166
135
  service_level: optionsToValue(serviceLevelOptions, selectedServiceLevel),
167
136
  },
@@ -174,7 +143,6 @@ const SystemPurposeEditModal = ({
174
143
  setSelectedRole(initialPurposeRole);
175
144
  setSelectedServiceLevel(initialServiceLevel);
176
145
  setSelectedUsage(initialPurposeUsage);
177
- setSelectedAddons(initialPurposeAddons);
178
146
  setSelectedReleaseVersion(initialReleaseVersion);
179
147
  closeModal();
180
148
  };
@@ -277,31 +245,6 @@ const SystemPurposeEditModal = ({
277
245
  ))}
278
246
  </FormSelect>
279
247
  </FormGroup>
280
- <FormGroup label={__('Add-ons')} fieldId="addons">
281
- <span id="syspurpose-addons-title" hidden>
282
- Checkbox Title
283
- </span>
284
- <Select
285
- variant={SelectVariant.typeaheadMulti}
286
- aria-label="syspurpose-addons"
287
- ouiaId="syspurpose-addons-select"
288
- onToggle={toggleAddonSelect}
289
- onSelect={onAddonSelect}
290
- selections={selectedAddons}
291
- isOpen={addonSelectOpen}
292
- placeholderText={__('Select add-ons')}
293
- aria-labelledby="syspurpose-addons-title"
294
- menuAppendTo="parent"
295
- >
296
- {addonsOptions.map(option => (
297
- <SelectOption
298
- key={option.value}
299
- value={option.value}
300
- label={option.label}
301
- />
302
- ))}
303
- </Select>
304
- </FormGroup>
305
248
  </Form>
306
249
  </Modal>
307
250
  );
@@ -314,7 +257,6 @@ SystemPurposeEditModal.propTypes = {
314
257
  name: PropTypes.string,
315
258
  purposeRole: PropTypes.string.isRequired,
316
259
  purposeUsage: PropTypes.string.isRequired,
317
- purposeAddons: PropTypes.arrayOf(PropTypes.string).isRequired,
318
260
  serviceLevel: PropTypes.string.isRequired,
319
261
  releaseVersion: PropTypes.string,
320
262
  isOpen: PropTypes.bool.isRequired,
@@ -16,7 +16,6 @@ const baseHostDetails = {
16
16
  edit_hosts: true,
17
17
  },
18
18
  subscription_facet_attributes: {
19
- purpose_addons: ['Addon1', 'Addon2'],
20
19
  purpose_role: 'Red Hat Enterprise Linux Server',
21
20
  purpose_usage: 'Production',
22
21
  service_level: 'Premium',
@@ -61,8 +60,6 @@ test('shows system purpose details for a host', async (done) => {
61
60
  expect(getByText('Red Hat Enterprise Linux Server')).toBeInTheDocument();
62
61
  expect(getByText('Production')).toBeInTheDocument();
63
62
  expect(getByText('Premium')).toBeInTheDocument();
64
- expect(getByText('Addon1')).toBeInTheDocument();
65
- expect(getByText('Addon2')).toBeInTheDocument();
66
63
  expect(getByText('8')).toBeInTheDocument();
67
64
 
68
65
  assertNockRequest(orgScope);
@@ -77,8 +74,6 @@ test('shows system purpose details for an activation key', () => {
77
74
  expect(getByText('Red Hat Enterprise Linux Server')).toBeInTheDocument();
78
75
  expect(getByText('Production')).toBeInTheDocument();
79
76
  expect(getByText('Premium')).toBeInTheDocument();
80
- expect(getByText('Addon1')).toBeInTheDocument();
81
- expect(getByText('Addon2')).toBeInTheDocument();
82
77
  expect(getByText('8')).toBeInTheDocument();
83
78
  });
84
79
 
@@ -22,7 +22,6 @@ const baseHostDetails = {
22
22
  edit_hosts: true,
23
23
  },
24
24
  subscription_facet_attributes: {
25
- purpose_addons: ['Addon1', 'Addon2'],
26
25
  purpose_role: 'Red Hat Enterprise Linux Server',
27
26
  purpose_usage: 'Production',
28
27
  service_level: 'Premium',
@@ -85,8 +84,6 @@ describe('SystemPurposeEditModal', () => {
85
84
  expect(getByText('Red Hat Enterprise Linux Server')).toBeInTheDocument();
86
85
  expect(getByText('Production')).toBeInTheDocument();
87
86
  expect(getByText('Premium')).toBeInTheDocument();
88
- expect(getByText('Addon1')).toBeInTheDocument();
89
- expect(getByText('Addon2')).toBeInTheDocument();
90
87
  expect(getByText('8')).toBeInTheDocument();
91
88
 
92
89
  assertNockRequest(orgScope);
@@ -136,7 +133,6 @@ describe('SystemPurposeEditModal', () => {
136
133
  // we're going to change role from 'Server' to 'Workstation'
137
134
  purpose_role: 'Red Hat Enterprise Linux Workstation',
138
135
  purpose_usage: 'Production',
139
- purpose_addons: ['Addon1', 'Addon2'],
140
136
  release_version: '8',
141
137
  service_level: 'Premium',
142
138
  },
@@ -191,7 +187,6 @@ describe('SystemPurposeEditModal', () => {
191
187
  autoheal: true,
192
188
  purpose_role: 'Red Hat Enterprise Linux Workstation',
193
189
  purpose_usage: 'Production',
194
- purpose_addons: ['Addon1', 'Addon2'],
195
190
  release_version: '8',
196
191
  service_level: 'Premium',
197
192
  },
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import {
5
+ DescriptionList,
6
+ DescriptionListGroup,
7
+ DescriptionListDescription as Dd,
8
+ DescriptionListTerm as Dt,
9
+ } from '@patternfly/react-core';
10
+ import CardTemplate from 'foremanReact/components/HostDetails/Templates/CardItem/CardTemplate';
11
+ import FontAwesomeImageModeIcon from '../../../../components/extensions/Hosts/FontAwesomeImageModeIcon';
12
+ import { createJob } from '../Tabs/customizedRexUrlHelpers';
13
+
14
+ const cardHeader = (
15
+ <>
16
+ <span style={{ marginRight: '0.5rem' }}>{__('Image mode details')}</span>
17
+ <FontAwesomeImageModeIcon />
18
+ </>
19
+ );
20
+ const actionUrl = hostname => createJob({
21
+ hostname,
22
+ feature: 'katello_bootc_action',
23
+ inputs: {},
24
+ });
25
+
26
+ const ImageModeCard = ({ isExpandedGlobal, hostDetails }) => {
27
+ const imageMode = hostDetails?.content_facet_attributes?.bootc_booted_image;
28
+ if (!imageMode) return null;
29
+ const getValueOrDash = value => (value || '—');
30
+ return (
31
+ <CardTemplate
32
+ header={cardHeader}
33
+ expandable
34
+ masonryLayout
35
+ isExpandedGlobal={isExpandedGlobal}
36
+ >
37
+ <a href={actionUrl(hostDetails.name)}>{__('Modify via remote execution')}</a>
38
+ <DescriptionList isHorizontal>
39
+ <DescriptionListGroup>
40
+ <Dt>{__('Running image')}</Dt>
41
+ <Dd>{getValueOrDash(hostDetails.content_facet_attributes.bootc_booted_image)}</Dd>
42
+ <Dt>{__('Running image digest')}</Dt>
43
+ <Dd>{getValueOrDash(hostDetails.content_facet_attributes.bootc_booted_digest)}</Dd>
44
+
45
+ <Dt>{__('Staged image')}</Dt>
46
+ <Dd>{getValueOrDash(hostDetails.content_facet_attributes.bootc_staged_image)}</Dd>
47
+ <Dt>{__('Staged image digest')}</Dt>
48
+ <Dd>{getValueOrDash(hostDetails.content_facet_attributes.bootc_staged_digest)}</Dd>
49
+
50
+ <Dt>{__('Available image')}</Dt>
51
+ <Dd>{getValueOrDash(hostDetails.content_facet_attributes.bootc_available_image)}</Dd>
52
+ <Dt>{__('Available image digest')}</Dt>
53
+ <Dd>{getValueOrDash(hostDetails.content_facet_attributes.bootc_available_digest)}</Dd>
54
+
55
+ <Dt>{__('Rollback image')}</Dt>
56
+ <Dd>{getValueOrDash(hostDetails.content_facet_attributes.bootc_rollback_image)}</Dd>
57
+ <Dt>{__('Rollback image digest')}</Dt>
58
+ <Dd>{getValueOrDash(hostDetails.content_facet_attributes.bootc_rollback_digest)}</Dd>
59
+ </DescriptionListGroup>
60
+ </DescriptionList>
61
+ </CardTemplate>
62
+ );
63
+ };
64
+
65
+ ImageModeCard.propTypes = {
66
+ isExpandedGlobal: PropTypes.bool,
67
+ hostDetails: PropTypes.shape({
68
+ name: PropTypes.string,
69
+ content_facet_attributes: PropTypes.shape({
70
+ bootc_booted_image: PropTypes.string,
71
+ bootc_booted_digest: PropTypes.string,
72
+ bootc_staged_image: PropTypes.string,
73
+ bootc_staged_digest: PropTypes.string,
74
+ bootc_available_image: PropTypes.string,
75
+ bootc_available_digest: PropTypes.string,
76
+ bootc_rollback_image: PropTypes.string,
77
+ bootc_rollback_digest: PropTypes.string,
78
+ }),
79
+ }),
80
+ };
81
+
82
+ ImageModeCard.defaultProps = {
83
+ isExpandedGlobal: false,
84
+ hostDetails: {},
85
+ };
86
+
87
+ export default ImageModeCard;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import { FormattedMessage } from 'react-intl';
3
4
  import { translate as __ } from 'foremanReact/common/I18n';
4
5
  import {
5
6
  DescriptionList,
@@ -55,12 +56,14 @@ const RegistrationCard = ({ isExpandedGlobal, hostDetails }) => {
55
56
  const subscriptionFacetAttributes
56
57
  = propsToCamelCase(hostDetails?.subscription_facet_attributes || {});
57
58
  const {
58
- registeredAt, activationKeys, user,
59
+ registeredAt, registeredThrough, activationKeys, user,
59
60
  }
60
61
  = subscriptionFacetAttributes;
61
62
  const contentFacetAttributes
62
63
  = propsToCamelCase(hostDetails?.content_facet_attributes || {});
63
64
  const { contentSourceName } = contentFacetAttributes;
65
+ const { contentSource } = propsToCamelCase(contentFacetAttributes || {});
66
+ const { loadBalanced, registrationHost } = propsToCamelCase(contentSource || {});
64
67
  const login = user?.login;
65
68
  if (!registeredAt) return null;
66
69
  return (
@@ -79,9 +82,32 @@ const RegistrationCard = ({ isExpandedGlobal, hostDetails }) => {
79
82
  <DescriptionListTerm>{__('Registered by')}</DescriptionListTerm>
80
83
  <RegisteredBy user={login} activationKeys={activationKeys} />
81
84
  </DescriptionListGroup>
85
+ <DescriptionListGroup>
86
+ <DescriptionListTerm>{__('Registered to')}</DescriptionListTerm>
87
+ <DescriptionListDescription>{registeredThrough}</DescriptionListDescription>
88
+ </DescriptionListGroup>
89
+ {loadBalanced && (
90
+ <DescriptionListGroup>
91
+ <DescriptionListTerm>{__('Load balancer')}</DescriptionListTerm>
92
+ <DescriptionListDescription>{registrationHost}</DescriptionListDescription>
93
+ </DescriptionListGroup>
94
+ )}
82
95
  <DescriptionListGroup>
83
96
  <DescriptionListTerm>{__('Content source')}</DescriptionListTerm>
84
- <DescriptionListDescription>{contentSourceName}</DescriptionListDescription>
97
+ {!loadBalanced && (
98
+ <DescriptionListDescription>{contentSourceName}</DescriptionListDescription>
99
+ )}
100
+ {loadBalanced && (
101
+ <DescriptionListDescription>
102
+ <FormattedMessage
103
+ id="load-balancer-content-source-text"
104
+ defaultMessage={__('Content may come from {contentSourceName} or any other Smart Proxy behind the load balancer.')}
105
+ values={{
106
+ contentSourceName: <strong>{contentSourceName}</strong>,
107
+ }}
108
+ />
109
+ </DescriptionListDescription>
110
+ )}
85
111
  </DescriptionListGroup>
86
112
  </DescriptionList>
87
113
  </CardTemplate>
@@ -87,7 +87,7 @@ const DebInstallModal = ({
87
87
  isOpen, closeModal, hostId, hostName, triggerPackageInstall,
88
88
  }) => {
89
89
  const emptyContentTitle = __('No packages available to install');
90
- const emptyContentBody = __('No packages available to install on this host. Please check the host\'s content view and lifecycle environment.');
90
+ const emptyContentBody = __('No packages available to install on this host. Please check the host\'s assigned content view environments.');
91
91
  const emptySearchTitle = __('No matching packages found');
92
92
  const emptySearchBody = __('Try changing your search settings.');
93
93
  const columnHeaders = ['', __('Package'), __('Version')];
@@ -427,7 +427,7 @@ export const ErrataTab = () => {
427
427
  />
428
428
  <ErrataToggleGroupItem
429
429
  text={__('Installable')}
430
- tooltipText={__('Installable errata are applicable errata that are available in the host\'s content view and lifecycle environment.')}
430
+ tooltipText={__('Installable errata are applicable errata that are available in the host\'s assigned content view environments.')}
431
431
  buttonId="installableToggle"
432
432
  aria-label="Show installable errata"
433
433
  isSelected={toggleGroupState === INSTALLABLE}
@@ -557,7 +557,7 @@ export const ErrataTab = () => {
557
557
  <span>
558
558
  <Tooltip
559
559
  content={
560
- __("This erratum is not installable because it is not in this host's content view and lifecycle environment.")
560
+ __("This erratum is not installable because it is not in this host's assigned content view environments.")
561
561
  }
562
562
  >
563
563
 
@@ -87,7 +87,7 @@ const PackageInstallModal = ({
87
87
  isOpen, closeModal, hostId, hostName, triggerPackageInstall,
88
88
  }) => {
89
89
  const emptyContentTitle = __('No packages available to install');
90
- const emptyContentBody = __('No packages available to install on this host. Please check the host\'s content view and lifecycle environment.');
90
+ const emptyContentBody = __('No packages available to install on this host. Please check the host\'s assigned content view environments.');
91
91
  const emptySearchTitle = __('No matching packages found');
92
92
  const emptySearchBody = __('Try changing your search settings.');
93
93
  const columnHeaders = ['', __('Package'), __('Version')];
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import propTypes from 'prop-types';
3
+ import { Tooltip } from '@patternfly/react-core';
4
+ import { translate as __ } from 'foremanReact/common/I18n';
5
+
6
+ const FontAwesomeImageModeIcon = ({ fill, margin, title }) => (
7
+ <Tooltip content={title}>
8
+ <svg
9
+ id="Layer_2"
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ viewBox="0 0 221.37 221.44"
12
+ width="14px"
13
+ height="14px"
14
+ version="1.1"
15
+ xmlSpace="preserve"
16
+ style={{
17
+ fillRule: 'evenodd',
18
+ clipRule: 'evenodd',
19
+ strokeLinejoin: 'round',
20
+ strokeMiterlimit: 2,
21
+ margin: margin || '-2px',
22
+ }}
23
+ >
24
+ <g id="Layer_1-2">
25
+ <circle
26
+ fill={fill}
27
+ className="cls-1"
28
+ cx="77.01"
29
+ cy="87"
30
+ r="20.41"
31
+ transform="translate(-39.07 79) rotate(-45)"
32
+ />
33
+ <path
34
+ className="cls-1"
35
+ fill={fill}
36
+ d="M205.48,40.09L120.07,1.72c-5.84-2.28-12.28-2.29-18.13-.02L15.93,40.09h0C6.25,43.85,0,52.98,0,63.37v91.2c0,9.48,5.5,18.28,14.02,22.44l85.84,41.91c3.45,1.68,7.2,2.52,10.95,2.52,4.03,0,8.05-.97,11.69-2.89l85.58-45.31c8.2-4.34,13.29-12.8,13.29-22.07V63.35c0-10.36-6.24-19.49-15.88-23.26ZM110.97,28.55l82.09,37.07v60.44l-39.44-37.64c-2.09-2.09-5.48-2.09-7.57,0l-60.43,60.43-24.76-24.76c-2.09-2.09-5.48-2.09-7.57,0l-25,26.93v-85.39L110.97,28.55Z"
37
+ />
38
+ </g>
39
+ </svg>
40
+ </Tooltip>
41
+ );
42
+
43
+ FontAwesomeImageModeIcon.propTypes = {
44
+ fill: propTypes.string,
45
+ margin: propTypes.string,
46
+ title: propTypes.string,
47
+ };
48
+
49
+ FontAwesomeImageModeIcon.defaultProps = {
50
+ fill: 'var(--pf-global--palette--black-600)',
51
+ margin: '-2px',
52
+ title: __('Image mode'),
53
+ };
54
+
55
+ export default FontAwesomeImageModeIcon;
@@ -15,6 +15,7 @@ import ContentDetails from '../../scenes/Content/Details';
15
15
  import withHeader from './withHeaders';
16
16
  import ChangeContentSource from '../../scenes/Hosts/ChangeContentSource';
17
17
  import AlternateContentSource from '../../scenes/AlternateContentSources';
18
+ import BootedContainerImages from '../../scenes/BootedContainerImages';
18
19
 
19
20
  // eslint-disable-next-line import/prefer-default-export
20
21
  export const links = [
@@ -85,4 +86,8 @@ export const links = [
85
86
  component: WithOrganization(withHeader(AlternateContentSource, { title: __('Alternate Content Sources') })),
86
87
  exact: false,
87
88
  },
89
+ {
90
+ path: 'booted_container_images',
91
+ component: WithOrganization(withHeader(BootedContainerImages, { title: __('Booted container images') })),
92
+ },
88
93
  ];