katello 4.5.0.rc2 → 4.5.1

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/content_exports_controller.rb +33 -3
  3. data/app/lib/actions/katello/content_view/promote_to_environment.rb +4 -2
  4. data/app/lib/actions/katello/content_view/publish.rb +5 -2
  5. data/app/lib/actions/katello/organization/environment_contents_refresh.rb +20 -0
  6. data/app/lib/actions/katello/organization/manifest_refresh.rb +2 -0
  7. data/app/lib/actions/pulp3/content_view_version/create_export_history.rb +3 -1
  8. data/app/lib/actions/pulp3/content_view_version/create_exporter.rb +9 -2
  9. data/app/lib/actions/pulp3/content_view_version/create_syncable_export_history.rb +45 -0
  10. data/app/lib/actions/pulp3/content_view_version/destroy_exporter.rb +6 -1
  11. data/app/lib/actions/pulp3/content_view_version/export.rb +8 -3
  12. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +28 -13
  13. data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +4 -2
  14. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +4 -2
  15. data/app/lib/actions/pulp3/orchestration/content_view_version/syncable_export.rb +82 -0
  16. data/app/lib/katello/concerns/base_template_scope_extensions.rb +24 -11
  17. data/app/models/katello/authorization/repository.rb +4 -2
  18. data/app/models/katello/content_view.rb +37 -29
  19. data/app/services/katello/content_unit_indexer.rb +1 -2
  20. data/app/services/katello/organization_creator.rb +14 -3
  21. data/app/services/katello/pulp3/api/core.rb +8 -0
  22. data/app/services/katello/pulp3/content_view_version/export.rb +38 -11
  23. data/app/services/katello/pulp3/content_view_version/import.rb +12 -5
  24. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +20 -5
  25. data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +3 -1
  26. data/app/services/katello/pulp3/content_view_version/syncable_format_export.rb +34 -0
  27. data/app/services/katello/pulp3/deb.rb +3 -1
  28. data/app/services/katello/pulp3/erratum.rb +4 -1
  29. data/app/services/katello/pulp3/pulp_content_unit.rb +2 -0
  30. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +4 -3
  31. data/db/migrate/20211220185935_clean_duplicate_content_units.rb +11 -9
  32. data/db/seeds.d/102-organizations.rb +1 -1
  33. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/activation-keys.routes.js +1 -1
  34. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-details.html +1 -1
  35. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages.controller.js +11 -3
  36. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -1
  37. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
  38. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +0 -3
  39. data/lib/katello/tasks/refresh_alternate_content_sources.rake +9 -4
  40. data/lib/katello/version.rb +1 -1
  41. data/locale/fr/katello.po +2 -2
  42. data/package.json +3 -0
  43. data/webpack/components/Table/TableHooks.js +2 -1
  44. data/webpack/components/Table/__test__/useBulkSelect.test.js +99 -0
  45. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +13 -1
  46. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +0 -6
  47. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +6 -9
  48. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +1 -1
  49. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +30 -3
  50. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +44 -19
  51. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +2 -2
  52. metadata +19 -59
  53. data/lib/katello/tasks/reset.rake.bak +0 -67
  54. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  55. data/locale/bn/katello.po.time_stamp +0 -0
  56. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  57. data/locale/cs/katello.po.time_stamp +0 -0
  58. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  59. data/locale/de/katello.po.time_stamp +0 -0
  60. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  61. data/locale/en/katello.po.time_stamp +0 -0
  62. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  63. data/locale/es/katello.po.time_stamp +0 -0
  64. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  65. data/locale/fr/katello.po.time_stamp +0 -0
  66. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  67. data/locale/gu/katello.po.time_stamp +0 -0
  68. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  69. data/locale/hi/katello.po.time_stamp +0 -0
  70. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  71. data/locale/it/katello.po.time_stamp +0 -0
  72. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  73. data/locale/ja/katello.po.time_stamp +0 -0
  74. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  75. data/locale/kn/katello.po.time_stamp +0 -0
  76. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  77. data/locale/ko/katello.po.time_stamp +0 -0
  78. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  79. data/locale/mr/katello.po.time_stamp +0 -0
  80. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  81. data/locale/or/katello.po.time_stamp +0 -0
  82. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  83. data/locale/pa/katello.po.time_stamp +0 -0
  84. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  85. data/locale/pt/katello.po.time_stamp +0 -0
  86. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  87. data/locale/pt_BR/katello.po.time_stamp +0 -0
  88. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  89. data/locale/ru/katello.po.time_stamp +0 -0
  90. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  91. data/locale/ta/katello.po.time_stamp +0 -0
  92. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  93. data/locale/te/katello.po.time_stamp +0 -0
  94. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  95. data/locale/zh_CN/katello.po.time_stamp +0 -0
  96. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  97. data/locale/zh_TW/katello.po.time_stamp +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5922047abc1b1bd8649e30bbaaf5eaf2e09f09bc9abb5e1b61920c0b84b1b57b
4
- data.tar.gz: 8105c45f9d16ca034430e89224f9bb81fa95c02d38ca638268864e34a9d57e2b
3
+ metadata.gz: 668ae7f77ea1cb1924c60b96931b249de9198b20caa055ee5142422ee5e72d44
4
+ data.tar.gz: 746ebbe54eb3ad9f4208b344b4bb671143a21489e19a16720c2987a2ffa6719e
5
5
  SHA512:
6
- metadata.gz: '069335f24169763ce80081693498c668a115893acb4e9c7b2a1486d54d5394f53b9d21cb6442acd6cba990f07d58e6b75f7ec0d9e32515165226fb833874a311'
7
- data.tar.gz: 22cda386e45a6d989daff56fe3897d07a75205282b2aa1e901bf7c333fd38d72869ab3dd808641a5535d8f72063c2961aa575c2420dfa51c2f98a3ab4152b28c
6
+ metadata.gz: 41d0ed1bfd6b88b4414a79c3f8479b3a6ad2c170f055fb707434b7ba72b6e51c83d7582c03bef5bb6a297583a2553776cf324d945311c66442d8c54a40fe7e6a
7
+ data.tar.gz: 35a1df76e4d090c8628d9c9d22fc623f12ab436fa229c6a55142e3fc53b3a82b6bd5e42e56d0e9282e9efa0fb6d925f378eedcc9c49cdb65335f146842dcbbae
@@ -34,12 +34,18 @@ module Katello
34
34
  "no greater than the specified size in gigabytes."), :required => false
35
35
  param :fail_on_missing_content, :bool, :desc => N_("Fails if any of the repositories belonging to this version"\
36
36
  " are unexportable. False by default."), :required => false
37
+ param :format, ::Katello::Pulp3::ContentViewVersion::Export::FORMATS,
38
+ :desc => N_("Export formats. Choose syncable if content is to be imported via repository sync. "\
39
+ "Choose importable if content is to be imported via hammer content-import.
40
+ Defaults to importable."),
41
+ :required => false
37
42
  def version
38
43
  tasks = async_task(::Actions::Katello::ContentViewVersion::Export,
39
44
  content_view_version: @version,
40
45
  destination_server: params[:destination_server],
41
46
  chunk_size: params[:chunk_size_gb],
42
- fail_on_missing_content: ::Foreman::Cast.to_bool(params[:fail_on_missing_content]))
47
+ fail_on_missing_content: ::Foreman::Cast.to_bool(params[:fail_on_missing_content]),
48
+ format: find_export_format)
43
49
  respond_for_async :resource => tasks
44
50
  end
45
51
 
@@ -50,12 +56,18 @@ module Katello
50
56
  "no greater than the specified size in gigabytes."), :required => false
51
57
  param :fail_on_missing_content, :bool, :desc => N_("Fails if any of the repositories belonging to this organization"\
52
58
  " are unexportable. False by default."), :required => false
59
+ param :format, ::Katello::Pulp3::ContentViewVersion::Export::FORMATS,
60
+ :desc => N_("Export formats. Choose syncable if content is to be imported via repository sync. "\
61
+ "Choose importable if content is to be imported via hammer content-import.
62
+ Defaults to importable."),
63
+ :required => false
53
64
  def library
54
65
  tasks = async_task(::Actions::Pulp3::Orchestration::ContentViewVersion::ExportLibrary,
55
66
  @organization,
56
67
  destination_server: params[:destination_server],
57
68
  chunk_size: params[:chunk_size_gb],
58
- fail_on_missing_content: ::Foreman::Cast.to_bool(params[:fail_on_missing_content]))
69
+ fail_on_missing_content: ::Foreman::Cast.to_bool(params[:fail_on_missing_content]),
70
+ format: find_export_format)
59
71
  respond_for_async :resource => tasks
60
72
  end
61
73
 
@@ -63,10 +75,16 @@ module Katello
63
75
  param :id, :number, :desc => N_("Repository identifier"), :required => true
64
76
  param :chunk_size_gb, :number, :desc => N_("Split the exported content into archives "\
65
77
  "no greater than the specified size in gigabytes."), :required => false
78
+ param :format, ::Katello::Pulp3::ContentViewVersion::Export::FORMATS,
79
+ :desc => N_("Export formats. Choose syncable if content is to be imported via repository sync. "\
80
+ "Choose importable if content is to be imported via hammer content-import.
81
+ Defaults to importable."),
82
+ :required => false
66
83
  def repository
67
84
  tasks = async_task(::Actions::Pulp3::Orchestration::ContentViewVersion::ExportRepository,
68
85
  @repository,
69
- chunk_size: params[:chunk_size_gb])
86
+ chunk_size: params[:chunk_size_gb],
87
+ format: find_export_format)
70
88
  respond_for_async :resource => tasks
71
89
  end
72
90
 
@@ -90,5 +108,17 @@ module Katello
90
108
  throw_resource_not_found(name: 'organization', id: params[:organization_id])
91
109
  end
92
110
  end
111
+
112
+ def find_export_format
113
+ if params[:format]
114
+ unless ::Katello::Pulp3::ContentViewVersion::Export::FORMATS.include?(params[:format])
115
+ fail HttpErrors::UnprocessableEntity, _('Invalid export format provided. Format must be one of %s ') %
116
+ ::Katello::Pulp3::ContentViewVersion::Export::FORMATS.join(',')
117
+ end
118
+ params[:format]
119
+ else
120
+ ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE
121
+ end
122
+ end
93
123
  end
94
124
  end
@@ -1,8 +1,8 @@
1
- # rubocop:disable Lint/SuppressedException
2
1
  module Actions
3
2
  module Katello
4
3
  module ContentView
5
4
  class PromoteToEnvironment < Actions::EntryAction
5
+ execution_plan_hooks.use :trigger_capsule_sync, :on => :success
6
6
  def plan(version, environment, description, incremental_update = false)
7
7
  history = ::Katello::ContentViewHistory.create!(:content_view_version => version, :user => ::User.current.login,
8
8
  :environment => environment, :task => self.task,
@@ -51,13 +51,15 @@ module Actions
51
51
  history = ::Katello::ContentViewHistory.find(input[:history_id])
52
52
  history.status = ::Katello::ContentViewHistory::SUCCESSFUL
53
53
  history.save!
54
+ end
54
55
 
56
+ def trigger_capsule_sync(_execution_plan)
57
+ environment = ::Katello::KTEnvironment.find(input[:environment_id])
55
58
  if !input[:incremental_update] && sync_proxies?(environment)
56
59
  ForemanTasks.async_task(ContentView::CapsuleSync,
57
60
  ::Katello::ContentView.find(input[:content_view_id]),
58
61
  environment)
59
62
  end
60
- rescue ::Katello::Errors::CapsuleCannotBeReached # skip any capsules that cannot be connected to
61
63
  end
62
64
 
63
65
  private
@@ -1,4 +1,3 @@
1
- # rubocop:disable Lint/SuppressedException
2
1
  module Actions
3
2
  module Katello
4
3
  module ContentView
@@ -7,6 +6,8 @@ module Actions
7
6
  include ::Katello::ContentViewHelper
8
7
  include ::Actions::ObservableAction
9
8
  attr_accessor :version
9
+ execution_plan_hooks.use :trigger_capsule_sync, :on => :success
10
+
10
11
  # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity
11
12
  def plan(content_view, description = "", options = {importing: false}) # rubocop:disable Metrics/PerceivedComplexity
12
13
  action_subject(content_view)
@@ -118,6 +119,9 @@ module Actions
118
119
  history = ::Katello::ContentViewHistory.find(input[:history_id])
119
120
  history.status = ::Katello::ContentViewHistory::SUCCESSFUL
120
121
  history.save!
122
+ end
123
+
124
+ def trigger_capsule_sync(_execution_plan)
121
125
  environment = ::Katello::KTEnvironment.find(input[:environment_id])
122
126
  view = ::Katello::ContentView.find(input[:content_view_id])
123
127
  if SmartProxy.sync_needed?(environment) && !input[:skip_promotion]
@@ -125,7 +129,6 @@ module Actions
125
129
  view,
126
130
  environment)
127
131
  end
128
- rescue ::Katello::Errors::CapsuleCannotBeReached # skip any capsules that cannot be connected to
129
132
  end
130
133
 
131
134
  def content_view_version_id
@@ -0,0 +1,20 @@
1
+ module Actions
2
+ module Katello
3
+ module Organization
4
+ class EnvironmentContentsRefresh < Actions::AbstractAsyncTask
5
+ middleware.use Actions::Middleware::PropagateCandlepinErrors
6
+
7
+ def plan(organization)
8
+ organization.content_view_environments.each do |cve|
9
+ plan_action(
10
+ Actions::Candlepin::Environment::SetContent,
11
+ cve.content_view,
12
+ cve.owner,
13
+ cve
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -29,6 +29,8 @@ module Actions
29
29
  import_products = plan_action(Candlepin::Owner::ImportProducts,
30
30
  :organization_id => organization.id,
31
31
  :dependency => owner_import.output)
32
+ plan_action(Katello::Organization::EnvironmentContentsRefresh,
33
+ organization)
32
34
  if manifest_update
33
35
  plan_refresh_repos(import_products, organization)
34
36
  end
@@ -27,9 +27,10 @@ module Actions
27
27
  cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
28
28
  from_cvv = ::Katello::ContentViewVersion.find(input[:from_content_view_version_id]) unless input[:from_content_view_version_id].blank?
29
29
 
30
- export_metadata = ::Katello::Pulp3::ContentViewVersion::Export.new(
30
+ export_metadata = ::Katello::Pulp3::ContentViewVersion::Export.create(
31
31
  content_view_version: cvv,
32
32
  smart_proxy: smart_proxy,
33
+ format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE,
33
34
  from_content_view_version: from_cvv).generate_metadata
34
35
 
35
36
  toc_path_info = output[:exported_file_checksum].find { |item| item.first.end_with?("toc.json") }
@@ -46,6 +47,7 @@ module Actions
46
47
  metadata: export_metadata)
47
48
  )
48
49
  output[:export_history_id] = history.id
50
+ output[:format] = ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE
49
51
  end
50
52
 
51
53
  def humanized_name
@@ -6,13 +6,20 @@ module Actions
6
6
  param :smart_proxy_id, Integer
7
7
  param :content_view_version_id, Integer
8
8
  param :destination_server, String
9
+ param :format, String
10
+ param :base_path, String
11
+ param :repository_id, Integer
9
12
  end
10
13
 
11
14
  def run
12
15
  cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
13
- output[:exporter_data] = ::Katello::Pulp3::ContentViewVersion::Export.new(smart_proxy: smart_proxy,
16
+ repository = ::Katello::Repository.find(input[:repository_id]) unless input[:repository_id].blank?
17
+ output[:exporter_data] = ::Katello::Pulp3::ContentViewVersion::Export.create(smart_proxy: smart_proxy,
14
18
  content_view_version: cvv,
15
- destination_server: input[:destination_server]).create_exporter
19
+ destination_server: input[:destination_server],
20
+ format: input[:format],
21
+ base_path: input[:base_path],
22
+ repository: repository).create_exporter
16
23
  end
17
24
  end
18
25
  end
@@ -0,0 +1,45 @@
1
+ module Actions
2
+ module Pulp3
3
+ module ContentViewVersion
4
+ class CreateSyncableExportHistory < Actions::EntryAction
5
+ input_format do
6
+ param :smart_proxy_id, Integer
7
+ param :base_path, String
8
+ param :content_view_version_id, Integer
9
+ param :destination_server, String
10
+ end
11
+
12
+ output_format do
13
+ param :export_history_id, Integer
14
+ param :path, String
15
+ end
16
+
17
+ def run
18
+ smart_proxy = ::SmartProxy.unscoped.find(input[:smart_proxy_id])
19
+ output[:path] = input[:base_path]
20
+ cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
21
+ export_metadata = ::Katello::Pulp3::ContentViewVersion::Export.create(
22
+ content_view_version: cvv,
23
+ smart_proxy: smart_proxy,
24
+ format: input[:format]).generate_metadata
25
+
26
+ history = ::Katello::ContentViewVersionExportHistory.create!(
27
+ content_view_version_id: input[:content_view_version_id],
28
+ destination_server: input[:destination_server],
29
+ path: input[:base_path],
30
+ metadata: export_metadata,
31
+ audit_comment: ::Katello::ContentViewVersionExportHistory.generate_audit_comment(content_view_version: cvv,
32
+ user: User.current,
33
+ metadata: export_metadata)
34
+ )
35
+ output[:export_history_id] = history.id
36
+ output[:format] = ::Katello::Pulp3::ContentViewVersion::Export::SYNCABLE
37
+ end
38
+
39
+ def humanized_name
40
+ _("Create Syncable Export History")
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -5,10 +5,15 @@ module Actions
5
5
  input_format do
6
6
  param :smart_proxy_id, Integer
7
7
  param :exporter_data, Hash
8
+ param :format, String
9
+ param :repository_id, Integer
8
10
  end
9
11
 
10
12
  def invoke_external_task
11
- ::Katello::Pulp3::ContentViewVersion::Export.new(smart_proxy: smart_proxy).destroy_exporter(input[:exporter_data][:pulp_href])
13
+ repository = ::Katello::Repository.find(input[:repository_id]) unless input[:repository_id].blank?
14
+ ::Katello::Pulp3::ContentViewVersion::Export.create(smart_proxy: smart_proxy,
15
+ format: input[:format],
16
+ repository: repository).destroy_exporter(input[:exporter_data])
12
17
  end
13
18
  end
14
19
  end
@@ -7,16 +7,21 @@ module Actions
7
7
  param :from_content_view_version_id, Integer
8
8
  param :smart_proxy_id, Integer
9
9
  param :exporter_data, Hash
10
+ param :format, String
10
11
  param :chunk_size, Integer
12
+ param :repository_id, Integer
11
13
  end
12
14
 
13
15
  def invoke_external_task
16
+ repository = ::Katello::Repository.find(input[:repository_id]) unless input[:repository_id].blank?
14
17
  cvv = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
15
18
  from_cvv = ::Katello::ContentViewVersion.find(input[:from_content_view_version_id]) unless input[:from_content_view_version_id].blank?
16
- ::Katello::Pulp3::ContentViewVersion::Export.new(smart_proxy: smart_proxy,
19
+ ::Katello::Pulp3::ContentViewVersion::Export.create(smart_proxy: smart_proxy,
17
20
  content_view_version: cvv,
18
- from_content_view_version: from_cvv)
19
- .create_export(input[:exporter_data][:pulp_href],
21
+ from_content_view_version: from_cvv,
22
+ format: input[:format],
23
+ repository: repository)
24
+ .create_export(input[:exporter_data],
20
25
  chunk_size: input[:chunk_size])
21
26
  end
22
27
  end
@@ -10,6 +10,7 @@ module Actions
10
10
  param :export_history_id, Integer
11
11
  param :exporter_data, Hash
12
12
  param :destination_server, String
13
+ param :format, String
13
14
  end
14
15
 
15
16
  output_format do
@@ -19,16 +20,30 @@ module Actions
19
20
  def plan(content_view_version:, destination_server: nil,
20
21
  chunk_size: nil, from_history: nil,
21
22
  validate_incremental: true,
22
- fail_on_missing_content: false)
23
+ fail_on_missing_content: false,
24
+ format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE)
25
+ smart_proxy = SmartProxy.pulp_primary!
26
+
27
+ if format == ::Katello::Pulp3::ContentViewVersion::Export::SYNCABLE
28
+ sequence do
29
+ export_output = plan_action(SyncableExport,
30
+ content_view_version: content_view_version,
31
+ smart_proxy: smart_proxy,
32
+ destination_server: destination_server).output
33
+ plan_self(export_history_id: export_output[:export_history_id],
34
+ export_path: export_output[:export_path])
35
+ end
36
+ return
37
+ end
23
38
 
24
39
  sequence do
25
- smart_proxy = SmartProxy.pulp_primary!
26
40
  from_content_view_version = from_history&.content_view_version
27
- export_service = ::Katello::Pulp3::ContentViewVersion::Export.new(
41
+ export_service = ::Katello::Pulp3::ContentViewVersion::Export.create(
28
42
  smart_proxy: smart_proxy,
29
43
  content_view_version: content_view_version,
30
44
  destination_server: destination_server,
31
- from_content_view_version: from_content_view_version)
45
+ from_content_view_version: from_content_view_version,
46
+ format: format)
32
47
  export_service.validate!(fail_on_missing_content: fail_on_missing_content,
33
48
  validate_incremental: validate_incremental,
34
49
  chunk_size: chunk_size)
@@ -36,14 +51,16 @@ module Actions
36
51
  action_output = plan_action(::Actions::Pulp3::ContentViewVersion::CreateExporter,
37
52
  content_view_version_id: content_view_version.id,
38
53
  smart_proxy_id: smart_proxy.id,
39
- destination_server: destination_server).output
54
+ destination_server: destination_server,
55
+ format: format).output
40
56
 
41
57
  plan_action(::Actions::Pulp3::ContentViewVersion::Export,
42
58
  content_view_version_id: content_view_version.id,
43
59
  smart_proxy_id: smart_proxy.id,
44
60
  exporter_data: action_output[:exporter_data],
45
61
  chunk_size: chunk_size,
46
- from_content_view_version_id: from_content_view_version&.id)
62
+ from_content_view_version_id: from_content_view_version&.id,
63
+ format: format)
47
64
 
48
65
  history_output = plan_action(
49
66
  ::Actions::Pulp3::ContentViewVersion::CreateExportHistory,
@@ -52,18 +69,16 @@ module Actions
52
69
  pulp_href: action_output[:exporter_data][:pulp_href],
53
70
  content_view_version_id: content_view_version.id,
54
71
  from_content_view_version_id: from_content_view_version&.id,
55
- destination_server: destination_server
72
+ destination_server: destination_server,
73
+ format: format
56
74
  ).output
57
75
 
58
76
  plan_action(::Actions::Pulp3::ContentViewVersion::DestroyExporter,
59
77
  smart_proxy_id: smart_proxy.id,
60
- exporter_data: action_output[:exporter_data])
78
+ exporter_data: action_output[:exporter_data],
79
+ format: format)
61
80
 
62
- plan_self(exporter_data: action_output[:exporter_data], smart_proxy_id: smart_proxy.id,
63
- destination_server: destination_server,
64
- content_view_version_id: content_view_version.id,
65
- from_content_view_version_id: from_content_view_version&.id,
66
- export_history_id: history_output[:export_history_id],
81
+ plan_self(export_history_id: history_output[:export_history_id],
67
82
  exported_file_checksum: history_output[:exported_file_checksum],
68
83
  export_path: history_output[:path])
69
84
  end
@@ -6,7 +6,8 @@ module Actions
6
6
  def plan(organization, destination_server: nil,
7
7
  chunk_size: nil,
8
8
  from_history: nil,
9
- fail_on_missing_content: false)
9
+ fail_on_missing_content: false,
10
+ format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE)
10
11
  action_subject(organization)
11
12
  validate_repositories_immediate!(organization) if fail_on_missing_content
12
13
 
@@ -24,7 +25,8 @@ module Actions
24
25
  chunk_size: chunk_size,
25
26
  from_history: from_history,
26
27
  validate_incremental: false,
27
- fail_on_missing_content: fail_on_missing_content)
28
+ fail_on_missing_content: fail_on_missing_content,
29
+ format: format)
28
30
  plan_self(export_action_output: export_action.output)
29
31
  end
30
32
  end
@@ -5,7 +5,8 @@ module Actions
5
5
  class ExportRepository < Actions::EntryAction
6
6
  def plan(repository,
7
7
  chunk_size: nil,
8
- from_history: nil)
8
+ from_history: nil,
9
+ format: ::Katello::Pulp3::ContentViewVersion::Export::IMPORTABLE)
9
10
  action_subject(repository)
10
11
  validate_repositories_immediate!(repository)
11
12
 
@@ -19,7 +20,8 @@ module Actions
19
20
  export_action = plan_action(Actions::Katello::ContentViewVersion::Export,
20
21
  content_view_version: publish_action.version,
21
22
  chunk_size: chunk_size,
22
- from_history: from_history)
23
+ from_history: from_history,
24
+ format: format)
23
25
  plan_self(export_action_output: export_action.output)
24
26
  end
25
27
  end
@@ -0,0 +1,82 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Orchestration
4
+ module ContentViewVersion
5
+ class SyncableExport < Actions::EntryAction
6
+ input_format do
7
+ param :smart_proxy_id, Integer
8
+ param :content_view_version_id, Integer
9
+ param :export_history_id, Integer
10
+ param :export_path, String
11
+ end
12
+
13
+ output_format do
14
+ param :export_path, String
15
+ param :export_history_id, Integer
16
+ end
17
+
18
+ def plan(content_view_version:,
19
+ smart_proxy:,
20
+ fail_on_missing_content: false,
21
+ destination_server:)
22
+ format = ::Katello::Pulp3::ContentViewVersion::Export::SYNCABLE
23
+ sequence do
24
+ export_service = ::Katello::Pulp3::ContentViewVersion::Export.create(
25
+ smart_proxy: smart_proxy,
26
+ content_view_version: content_view_version,
27
+ format: format,
28
+ destination_server: destination_server)
29
+ export_service.validate!(fail_on_missing_content: fail_on_missing_content)
30
+ base_path = export_service.generate_exporter_path
31
+ export_service.repositories.each do |repository|
32
+ action_output = plan_action(::Actions::Pulp3::ContentViewVersion::CreateExporter,
33
+ content_view_version_id: content_view_version.id,
34
+ smart_proxy_id: smart_proxy.id,
35
+ format: format,
36
+ base_path: base_path,
37
+ repository_id: repository.id,
38
+ destination_server: destination_server).output
39
+
40
+ plan_action(::Actions::Pulp3::ContentViewVersion::Export,
41
+ content_view_version_id: content_view_version.id,
42
+ smart_proxy_id: smart_proxy.id,
43
+ exporter_data: action_output[:exporter_data],
44
+ format: format,
45
+ repository_id: repository.id)
46
+
47
+ plan_action(::Actions::Pulp3::ContentViewVersion::DestroyExporter,
48
+ smart_proxy_id: smart_proxy.id,
49
+ exporter_data: action_output[:exporter_data],
50
+ format: format,
51
+ repository_id: repository.id)
52
+ end
53
+
54
+ history_output = plan_action(
55
+ ::Actions::Pulp3::ContentViewVersion::CreateSyncableExportHistory,
56
+ smart_proxy_id: smart_proxy.id,
57
+ content_view_version_id: content_view_version.id,
58
+ destination_server: destination_server,
59
+ format: format,
60
+ base_path: base_path
61
+ ).output
62
+
63
+ plan_self(export_history_id: history_output[:export_history_id],
64
+ export_path: base_path)
65
+ end
66
+ end
67
+
68
+ def run
69
+ output.update(
70
+ export_history_id: input[:export_history_id],
71
+ export_path: input[:export_path]
72
+ )
73
+ end
74
+
75
+ def rescue_strategy
76
+ Dynflow::Action::Rescue::Skip
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -206,21 +206,22 @@ module Katello
206
206
  search_up_to = up_to.present? ? "ended_at < \"#{up_to}\"" : nil
207
207
  search_since = since.present? ? "ended_at > \"#{since}\"" : nil
208
208
  search_result = status.present? && status != 'all' ? "result = #{status}" : nil
209
- search = [search_up_to, search_since, search_result].compact.join(' and ')
209
+ labels = 'label ^ (Actions::Katello::Host::Erratum::Install, Actions::Katello::Host::Erratum::ApplicableErrataInstall)'
210
+ select = 'foreman_tasks_tasks.*'
210
211
 
211
212
  if Katello.with_remote_execution?
212
- condition = ["state = 'stopped' AND ((label = 'Actions::RemoteExecution::RunHostJob' AND templates.id = ?) " \
213
- "OR label = 'Actions::Katello::Host::Erratum::Install' OR label = 'Actions::Katello::Host::Erratum::ApplicableErrataInstall')",
214
- RemoteExecutionFeature.feature('katello_errata_install').job_template_id]
213
+ new_labels = 'label = Actions::RemoteExecution::RunHostJob AND remote_execution_feature.label ^ (katello_errata_install, katello_errata_install_by_search)'
214
+ labels = [labels, new_labels].map { |label| "(#{label})" }.join(' OR ')
215
+ select += ',template_invocations.id AS template_invocation_id'
215
216
  else
216
- condition = "state = 'stopped' AND (label = 'Actions::Katello::Host::Erratum::Install' OR label = 'Actions::Katello::Host::Erratum::ApplicableErrataInstall')"
217
+ select += ',NULL AS template_invocation_id'
217
218
  end
218
219
 
220
+ search = [search_up_to, search_since, search_result, "state = stopped", labels].compact.join(' and ')
221
+
219
222
  tasks = load_resource(klass: ForemanTasks::Task,
220
- where: condition,
221
223
  permission: 'view_foreman_tasks',
222
- joins: 'LEFT OUTER JOIN template_invocations ON foreman_tasks_tasks.id = template_invocations.run_host_job_task_id LEFT OUTER JOIN templates ON template_invocations.template_id = templates.id',
223
- select: 'foreman_tasks_tasks.*,template_invocations.id AS template_invocation_id',
224
+ select: select,
224
225
  search: search)
225
226
  only_host_ids = ::Host.search_for(host_filter).pluck(:id) if host_filter
226
227
 
@@ -325,9 +326,21 @@ module Katello
325
326
  # Pick katello agent errata if present
326
327
  # Otherwise pick rex errata. There are multiple template inputs, such as errata, pre_script and post_script we only need the
327
328
  # errata input here.
328
- @_tasks_errata_cache[task.id] ||= agent_input.presence || TemplateInvocationInputValue.joins(:template_input)
329
- .where("template_invocation_id = ? AND template_inputs.name = ?", task.template_invocation_id, 'errata')
330
- .first.value.split(',')
329
+ @_tasks_errata_cache[task.id] ||= agent_input.presence || errata_ids_from_template_invocation(task, task_input)
330
+ end
331
+
332
+ def errata_ids_from_template_invocation(task, task_input)
333
+ if task_input.key?('job_features') && task_input['job_features'].include?('katello_errata_install_by_search')
334
+ # This may give wrong results if the template is not rendered yet
335
+ # This also will not work for jobs run before we started storing
336
+ # resolved ids in the template
337
+ script = task.execution_plan.actions[1].try(:input).try(:[], 'script') || ''
338
+ found = script.lines.find { |line| line.start_with? '# RESOLVED_ERRATA_IDS=' } || ''
339
+ (found.chomp.split('=', 2).last || '').split(',')
340
+ else
341
+ TemplateInvocationInputValue.joins(:template_input).where("template_invocation_id = ? AND template_inputs.name = ?", task.template_invocation_id, 'errata')
342
+ .first.value.split(',')
343
+ end
331
344
  end
332
345
  end
333
346
  end
@@ -5,11 +5,13 @@ module Katello
5
5
  delegate :editable?, to: :product
6
6
 
7
7
  def deletable?(remove_from_content_view_versions = true)
8
- product.editable? && (remove_from_content_view_versions || !promoted? || !self.content_views.generated_for_none.exists?)
8
+ return false unless product.editable?
9
+ remove_from_content_view_versions || !promoted? || (self.content_views.exists? && !self.content_views.generated_for_none.exists?)
9
10
  end
10
11
 
11
12
  def redhat_deletable?(remove_from_content_view_versions = false)
12
- (remove_from_content_view_versions || !self.promoted? || !self.content_views.generated_for_none.exists?) && self.product.editable?
13
+ return false unless product.editable?
14
+ remove_from_content_view_versions || !self.promoted? || (self.content_views.exists? && !self.content_views.generated_for_none.exists?)
13
15
  end
14
16
 
15
17
  def readable?