katello 4.3.0 → 4.3.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/repositories_controller.rb +2 -1
  3. data/app/controllers/katello/remote_execution_controller.rb +5 -4
  4. data/app/lib/actions/katello/content_view/publish.rb +5 -0
  5. data/app/lib/actions/katello/content_view_version/incremental_update.rb +17 -3
  6. data/app/lib/actions/pulp3/content_view_version/import.rb +7 -0
  7. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +7 -5
  8. data/app/lib/actions/pulp3/repository/copy_content.rb +1 -1
  9. data/app/lib/actions/pulp3/repository/save_artifact.rb +1 -0
  10. data/app/lib/katello/resources/cdn.rb +1 -1
  11. data/app/models/katello/concerns/pulp_database_unit.rb +1 -1
  12. data/app/models/katello/docker_meta_tag.rb +1 -1
  13. data/app/models/katello/repository.rb +5 -0
  14. data/app/services/cert/rhsm_client.rb +1 -5
  15. data/app/services/katello/pulp3/content_view_version/import.rb +11 -2
  16. data/app/services/katello/pulp3/erratum.rb +9 -1
  17. data/app/services/katello/pulp3/generic_content_unit.rb +2 -1
  18. data/app/services/katello/pulp3/pulp_content_unit.rb +5 -7
  19. data/app/services/katello/pulp3/repository/yum.rb +10 -2
  20. data/app/services/katello/pulp3/repository.rb +11 -4
  21. data/app/views/foreman/job_templates/install_errata.erb +6 -9
  22. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +26 -0
  23. data/db/migrate/20211019192121_create_cdn_configuration.katello.rb +11 -2
  24. data/db/seeds.d/111-upgrade_tasks.rb +2 -1
  25. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/packages.controller.js +1 -0
  26. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-manage-content.controller.js +2 -3
  27. data/lib/katello/plugin.rb +1 -0
  28. data/lib/katello/repository_types/ostree.rb +2 -0
  29. data/lib/katello/tasks/content_view_import_only.rake +34 -0
  30. data/lib/katello/tasks/upgrades/4.4/publish_import_cvvs.rake +17 -0
  31. data/lib/katello/version.rb +1 -1
  32. data/webpack/components/WithOrganization/withOrganization.js +1 -0
  33. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +2 -2
  34. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +1 -1
  35. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +5 -5
  36. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +1 -1
  37. data/webpack/scenes/Content/ContentConfig.js +55 -5
  38. data/webpack/scenes/Content/ContentPage.js +1 -1
  39. data/webpack/scenes/Content/Details/ContentDetails.js +1 -1
  40. data/webpack/scenes/Content/Details/ContentInfo.js +1 -1
  41. data/webpack/scenes/Content/Details/ContentRepositories.js +1 -1
  42. data/webpack/scenes/Content/Table/ContentTable.js +1 -1
  43. data/webpack/scenes/ContentViews/ContentViewsConstants.js +2 -1
  44. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +11 -10
  45. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +5 -5
  46. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +1 -1
  47. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionContent.js +16 -17
  48. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +1 -1
  49. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +30 -34
  50. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +8 -8
  51. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionRepositoryCell.js +1 -1
  52. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +1 -1
  53. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bebacc5b4b127cfadaeb424ce9f04aa6e2ba132a0d8d959d8456bd393418abf
4
- data.tar.gz: 473b94c0aec5d6b73a174f334edf1f9079d42c53d16ef0ab60cc939af0e0e4b0
3
+ metadata.gz: f1a33ac3431921424a7d17bcd6f90afbb0f0ed372e6c7873ea1b2afa35cde5d2
4
+ data.tar.gz: 864c45929eea0df21199da1bafc4598f504887578c8c7fa860e3d03729fcf0aa
5
5
  SHA512:
6
- metadata.gz: 000e85ae93b95be282c88d10eec6f364526cfdb9e377de7b56d82a8df882e8390c40690b4d7b0740c24196fa10d20d166b48779f3422699e7a970bfb1722cdc2
7
- data.tar.gz: 23a1e59f555ddbe334a98d6937aa64de3d46b1bc6b8fb33a61166e317792686fae9f30af480d0037226eebf6d341769a15acd1972d7bb05d20696ab6af1fb9dc
6
+ metadata.gz: 938cb19362f4c5add3bd334c4889a95462a2c3f071a2d3764a43c59bfeac6bef1bb036f99b0d168dbf10953664e7fc5f8623f6b4a0a09021be7e9f1931b8be64
7
+ data.tar.gz: bb12015598a2ac15cfbd0aad5f9a18d7c86142c8157e73cf134a22b93470d0da64c977c59fb74fb2819ad5e2c15b8f77f0b1283d0b9a674205bd1e0f6ac9dc89
@@ -648,7 +648,8 @@ module Katello
648
648
 
649
649
  def generic_remote_options_hash(repo_params)
650
650
  generic_remote_options = {}
651
- RepositoryTypeManager.generic_remote_options(content_type: repo_params[:content_type]).each do |option|
651
+ content_type = @repository&.content_type || repo_params[:content_type]
652
+ RepositoryTypeManager.generic_remote_options(content_type: content_type).each do |option|
652
653
  generic_remote_options[option.name] = repo_params[option.name]
653
654
  end
654
655
  generic_remote_options
@@ -47,11 +47,12 @@ module Katello
47
47
  end
48
48
 
49
49
  def inputs
50
- if feature_name == 'katello_errata_install'
51
- { "Errata Search Query" => "errata_id ^ (#{errata_inputs.join(',')})" }
52
- elsif feature_name == 'katello_service_restart'
50
+ case feature_name
51
+ when 'katello_errata_install'
52
+ { :errata => errata_inputs }
53
+ when 'katello_service_restart'
53
54
  { :helper => params[:name] }
54
- elsif feature_name == 'katello_module_stream_action'
55
+ when 'katello_module_stream_action'
55
56
  fail HttpErrors::NotFound, _('module streams not found') if params[:module_spec].blank?
56
57
  fail HttpErrors::NotFound, _('actions not found') if params[:module_stream_action].blank?
57
58
  inputs = { :module_spec => params[:module_spec], :action => params[:module_stream_action] }
@@ -200,6 +200,11 @@ module Actions
200
200
  plan_action(Katello::Repository::IndexContent, id: id, full_index: true)
201
201
  end
202
202
  end
203
+ concurrence do
204
+ version.importable_repositories.each do |repo|
205
+ plan_action(::Actions::Katello::Repository::MetadataGenerate, repo)
206
+ end
207
+ end
203
208
  plan_action(::Actions::Pulp3::Orchestration::ContentViewVersion::CopyVersionUnitsToLibrary, version)
204
209
  end
205
210
  end
@@ -72,6 +72,18 @@ module Actions
72
72
 
73
73
  unless extended_repo_mapping.empty? || unit_map.values.flatten.empty?
74
74
  sequence do
75
+ # Pre-copy content if dest_repo is a soft copy of its library instance.
76
+ # Don't use extended_repo_mapping because the source repositories are library instances.
77
+ # We want the old CV snapshot repositories here so as to not pull in excess new content.
78
+ separated_repo_map[:pulp3_yum_multicopy].each do |source_repos, dest_repo|
79
+ if dest_repo.soft_copy_of_library?
80
+ source_repos.each do |source_repo|
81
+ # remove_all flag is set to cover the case of incrementally updating more than once with different content.
82
+ # Without it, content from the previous incremental update will be copied as well due to how Pulp repo versions work.
83
+ plan_action(Pulp3::Repository::CopyContent, source_repo, SmartProxy.pulp_primary, dest_repo, copy_all: true, remove_all: true)
84
+ end
85
+ end
86
+ end
75
87
  copy_action_outputs << plan_action(Pulp3::Repository::MultiCopyUnits, extended_repo_mapping, unit_map,
76
88
  dependency_solving: dep_solve).output
77
89
  repos_to_clone.each do |source_repos|
@@ -125,10 +137,12 @@ module Actions
125
137
  source_library_repo = source_repos.first.library_instance? ? source_repos.first : source_repos.first.library_instance
126
138
 
127
139
  source_repos = [source_library_repo]
128
- if old_version_repo.version_href
129
- base_version = old_version_repo.version_href.split("/")[-1].to_i
130
- else
140
+ if old_version_repo.version_href.nil?
131
141
  base_version = 0
142
+ elsif old_version_repo.soft_copy_of_library?
143
+ base_version = nil
144
+ else
145
+ base_version = old_version_repo.version_href.split("/")[-1].to_i
132
146
  end
133
147
 
134
148
  pulp3_repo_mapping[source_repos.map(&:id)] = { dest_repo: dest_repo.id, base_version: base_version }
@@ -19,6 +19,13 @@ module Actions
19
19
  metadata: input[:metadata]
20
20
  ).create_import(input[:importer_data][:pulp_href])
21
21
  end
22
+
23
+ def rescue_strategy_for_self
24
+ # There are various reasons the importing fails, not all of them are
25
+ # fatal: when fail on import, we continue with the task ending up
26
+ # in the warning state, but not locking further imports
27
+ Dynflow::Action::Rescue::Skip
28
+ end
22
29
  end
23
30
  end
24
31
  end
@@ -15,17 +15,19 @@ module Actions
15
15
  metadata: metadata
16
16
  ).output
17
17
 
18
- import_output = plan_action(
18
+ plan_action(
19
19
  ::Actions::Pulp3::ContentViewVersion::Import,
20
20
  content_view_version_id: content_view_version.id,
21
21
  smart_proxy_id: smart_proxy.id,
22
22
  importer_data: importer_output[:importer_data],
23
23
  path: path,
24
24
  metadata: metadata
25
- ).output
26
-
27
- plan_action(Actions::Pulp3::Repository::SaveVersions, content_view_version.importable_repositories.pluck(:id),
28
- tasks: import_output[:pulp_tasks])
25
+ )
26
+ concurrence do
27
+ content_view_version.importable_repositories.each do |repo|
28
+ plan_action(Actions::Pulp3::Repository::SaveVersion, repo)
29
+ end
30
+ end
29
31
  plan_action(
30
32
  ::Actions::Pulp3::ContentViewVersion::CreateImportHistory,
31
33
  content_view_version_id: content_view_version.id,
@@ -13,7 +13,7 @@ module Actions
13
13
  target = ::Katello::Repository.find(input[:target_repository_id] || input[:target_repository])
14
14
  service = target.backend_service(smart_proxy)
15
15
  output[:pulp_tasks] = if input[:copy_all]
16
- service.copy_all(source, mirror: input[:mirror] || false)
16
+ service.copy_all(source, input)
17
17
  else
18
18
  service.copy_content_for_source(source, input)
19
19
  end
@@ -27,6 +27,7 @@ module Actions
27
27
  []
28
28
  else
29
29
  output[:pulp_tasks] = [content_backend_service.content_api_create(relative_path: input[:options][:file_name],
30
+ repository_id: repository.id,
30
31
  artifact: artifact_href,
31
32
  content_type: content_type)]
32
33
  end
@@ -184,7 +184,7 @@ module Katello
184
184
  def net_http_class
185
185
  if proxy
186
186
  uri = URI(proxy.url) #Net::HTTP::Proxy ignores port as part of the url
187
- Net::HTTP::Proxy("#{uri.host}#{uri.path}", uri.port, proxy.username, proxy.password)
187
+ Net::HTTP::Proxy("#{uri.host}", uri.port, proxy.username, proxy.password)
188
188
  else
189
189
  Net::HTTP
190
190
  end
@@ -190,7 +190,7 @@ module Katello
190
190
  service.update_model(model, generic_content_type)
191
191
  elsif self == ::Katello::Erratum
192
192
  # Errata will change pulp_hrefs if the upstream repo updates them
193
- erratum_updated_ids << service.update_model(model)
193
+ erratum_updated_ids << service.update_model(model, repository)
194
194
  else
195
195
  service.update_model(model)
196
196
  end
@@ -153,7 +153,7 @@ module Katello
153
153
  end
154
154
 
155
155
  unless params_to_query_for_delete.empty?
156
- RepositoryDockerMetaTag.where(:docker_meta_tag => DockerMetaTag.where(params_to_query_for_delete.join(" OR "))).delete_all
156
+ RepositoryDockerMetaTag.where(:repository_id => repo.id).where(:docker_meta_tag => DockerMetaTag.where(params_to_query_for_delete.join(" OR "))).delete_all
157
157
  end
158
158
 
159
159
  metatags = []
@@ -285,6 +285,11 @@ module Katello
285
285
  ::Katello::Resources::CDN::CdnResource.ca_file if ::Katello::Resources::CDN::CdnResource.redhat_cdn?(url)
286
286
  end
287
287
 
288
+ def soft_copy_of_library?
289
+ return false if self.version_href.nil?
290
+ self.version_href.starts_with?(self.library_instance.backend_service(SmartProxy.pulp_primary).repository_reference.repository_href)
291
+ end
292
+
288
293
  def archive?
289
294
  self.environment.nil?
290
295
  end
@@ -10,7 +10,7 @@ module Cert
10
10
  end
11
11
 
12
12
  def uuid
13
- drop_cn_prefix_from_subject(@cert.subject.to_s)
13
+ @uuid ||= @cert.subject.to_a.detect { |name, _, _| name == 'CN' }&.second
14
14
  end
15
15
 
16
16
  private
@@ -26,10 +26,6 @@ module Cert
26
26
  end
27
27
  end
28
28
 
29
- def drop_cn_prefix_from_subject(subject_string)
30
- subject_string.sub(/\/CN=/i, '')
31
- end
32
-
33
29
  def strip_cert(cert)
34
30
  cert = cert.to_s.gsub("-----BEGIN CERTIFICATE-----", "").gsub("-----END CERTIFICATE-----", "")
35
31
  cert.delete!(' ')
@@ -121,11 +121,20 @@ module Katello
121
121
  }
122
122
  end
123
123
 
124
+ fail _("Content View label not provided.") if metadata[:label].blank?
125
+
124
126
  cv = ::Katello::ContentView.find_by(label: metadata[:label],
125
- organization: organization,
126
- import_only: true)
127
+ organization: organization)
127
128
  if cv.blank?
128
129
  ::Katello::ContentView.create!(metadata.merge(organization: organization, import_only: true))
130
+ elsif !cv.import_only?
131
+ msg = _("Unable to import in to Content View specified in the metadata - '%{name}'. "\
132
+ "The 'import_only' attribute for the content view is set to false. "\
133
+ "To mark this Content View as importable, have your system administrator"\
134
+ " run the following command on the server. "\
135
+ % { name: cv.name })
136
+ command = "foreman-rake katello:set_content_view_import_only ID=#{cv.id}"
137
+ fail msg + "\n" + command
129
138
  else
130
139
  cv.update!(description: cv_metadata[:description]) if cv.description != metadata[:description]
131
140
  cv
@@ -26,7 +26,7 @@ module Katello
26
26
  end
27
27
 
28
28
  # rubocop:disable Metrics/AbcSize
29
- def update_model(model)
29
+ def update_model(model, repository = nil)
30
30
  updated = false
31
31
  keys = %w(title id severity issued_date type description reboot_suggested solution updated_date summary)
32
32
  custom_json = backend_data.slice(*keys)
@@ -55,6 +55,14 @@ module Katello
55
55
  update_packages(model, backend_data['pkglist']) unless backend_data['pkglist'].blank?
56
56
  update_modules(model, backend_data['pkglist']) unless backend_data['pkglist'].blank?
57
57
 
58
+ if !updated && repository.present?
59
+ backend_identifier = backend_data.dig(self.class.backend_unit_identifier)
60
+ if Katello::RepositoryErratum.where(repository_id: repository.id, erratum_id: model.id).where.not(erratum_pulp3_href: backend_identifier).any?
61
+ # Pulp has created a new record for this erratum because it has been updated so we need to update repo association too
62
+ updated = true
63
+ end
64
+ end
65
+
58
66
  return model.id if updated
59
67
  end
60
68
  # rubocop:enable Metrics/AbcSize
@@ -13,7 +13,8 @@ module Katello
13
13
  end
14
14
 
15
15
  def self.content_api(repository_type, content_type)
16
- repository_type.content_types.find { |type| type.content_type == content_type }.pulp3_api.new(repository_type.pulp3_api_class.new(SmartProxy.pulp_primary!, repository_type).api_client)
16
+ label = content_type.is_a?(String) ? content_type : content_type.label
17
+ repository_type.content_types.find { |type| type.content_type == label }.pulp3_api.new(repository_type.pulp3_api_class.new(SmartProxy.pulp_primary!, repository_type).api_client)
17
18
  end
18
19
 
19
20
  def update_model(model, content_type)
@@ -116,30 +116,28 @@ module Katello
116
116
  content_unit_list page_opts
117
117
  end
118
118
 
119
- # rubocop:disable Lint/UselessAssignment
120
119
  def self.find_duplicate_unit(repository, unit_type_id, file, checksum)
121
- filter_label = 'sha256'
120
+ filter_label = :sha256
122
121
  if unit_type_id == 'ostree_ref'
123
- filter_label = 'checksum'
122
+ filter_label = :checksum
124
123
  end
125
124
  content_backend_service = SmartProxy.pulp_primary.content_service(unit_type_id)
126
125
  duplicates_allowed = ::Katello::RepositoryTypeManager.find_content_type(unit_type_id).try(:duplicates_allowed)
127
126
  if repository.generic? && duplicates_allowed
128
127
  filename_key = ::Katello::RepositoryTypeManager.find_content_type(unit_type_id).filename_key
129
128
  duplicate_sha_path_content_list = content_backend_service.content_api(repository.repository_type, unit_type_id).list(
130
- filter_label: checksum,
129
+ filter_label => checksum,
131
130
  filename_key => file[:filename])
132
131
  elsif repository.generic?
133
132
  duplicate_sha_path_content_list = content_backend_service.content_api(repository.repository_type, unit_type_id).list(
134
- filter_label: checksum)
133
+ filter_label => checksum)
135
134
  else
136
135
  duplicate_sha_path_content_list = content_backend_service.content_api.list(
137
- filter_label: checksum,
136
+ filter_label => checksum,
138
137
  "relative_path": file[:filename])
139
138
  end
140
139
  duplicate_sha_path_content_list
141
140
  end
142
- # rubocop:enable Lint/UselessAssignment
143
141
  end
144
142
  end
145
143
  end
@@ -95,6 +95,7 @@ module Katello
95
95
  "/pulp/content/#{repo.relative_path}/".sub('//', '/')
96
96
  end
97
97
 
98
+ # rubocop:disable Metrics/MethodLength
98
99
  def multi_copy_units(repo_id_map, dependency_solving)
99
100
  tasks = []
100
101
 
@@ -107,14 +108,20 @@ module Katello
107
108
  dest_repo_href = ::Katello::Pulp3::Repository::Yum.new(dest_repo, SmartProxy.pulp_primary).repository_reference.repository_href
108
109
  content_unit_hrefs = dest_repo_id_map[:content_unit_hrefs]
109
110
  # Not needed during incremental update due to dest_base_version
111
+ # -> Unless incrementally updating a CV repo that is a soft copy of its library instance.
112
+ # -> I.e. no filters and not an incremental version.
110
113
  unless dest_repo_id_map[:base_version]
111
114
  source_repo_for_package_envs = ::Katello::Repository.find(source_repo_ids.first)
112
115
  unless source_repo_for_package_envs.library_instance?
113
116
  source_repo_for_package_envs = source_repo_for_package_envs.library_instance
114
117
  end
115
118
  package_env_hrefs = packageenvironments({ :repository_version => source_repo_for_package_envs.version_href }).map(&:pulp_href).sort
116
- tasks << remove_all_content_from_repo(dest_repo_href)
117
- tasks << add_content_for_repo(dest_repo_href, package_env_hrefs) unless package_env_hrefs.empty?
119
+ # Don't perform extra content actions if the repo is a soft copy of its library instance.
120
+ # Taken care of by the IncrementalUpdate action.
121
+ unless dest_repo.soft_copy_of_library?
122
+ tasks << remove_all_content_from_repo(dest_repo_href)
123
+ tasks << add_content_for_repo(dest_repo_href, package_env_hrefs) unless package_env_hrefs.empty?
124
+ end
118
125
  end
119
126
  source_repo_ids.each do |source_repo_id|
120
127
  source_repo_version = ::Katello::Repository.find(source_repo_id).version_href
@@ -129,6 +136,7 @@ module Katello
129
136
  end
130
137
  tasks.flatten
131
138
  end
139
+ # rubocop:enable Metrics/MethodLength
132
140
 
133
141
  def copy_api_data_dup(data)
134
142
  data_dup = PulpRpmClient::Copy.new
@@ -330,19 +330,26 @@ module Katello
330
330
  tasks
331
331
  end
332
332
 
333
- def copy_all(source_repository, mirror: false)
334
- if mirror
333
+ def copy_all(source_repository, options = {})
334
+ tasks = []
335
+ if options[:remove_all]
336
+ tasks << api.repositories_api.modify(repository_reference.repository_href, remove_content_units: ['*'])
337
+ end
338
+
339
+ if options[:mirror]
335
340
  data = api.class.add_remove_content_class.new(
336
341
  base_version: source_repository.version_href)
337
342
 
338
- [api.repositories_api.modify(repository_reference.repository_href, data)]
343
+ tasks << api.repositories_api.modify(repository_reference.repository_href, data)
344
+ tasks
339
345
  elsif api.respond_to? :copy_api
340
346
  data = api.class.copy_class.new
341
347
  data.config = [{
342
348
  source_repo_version: source_repository.version_href,
343
349
  dest_repo: repository_reference.repository_href
344
350
  }]
345
- [api.copy_api.copy_content(data)]
351
+ tasks << api.copy_api.copy_content(data)
352
+ tasks
346
353
  else
347
354
  copy_content_for_source(source_repository)
348
355
  end
@@ -2,25 +2,22 @@
2
2
  kind: job_template
3
3
  name: Install Errata - Katello SSH Default
4
4
  job_category: Katello
5
- description_format: 'Install errata %{Errata search query}'
5
+ description_format: 'Install errata %{errata}'
6
6
  feature: katello_errata_install
7
7
  provider_type: SSH
8
8
  template_inputs:
9
- - name: Errata search query
10
- description: Filter criteria for errata to be installed.
9
+ - name: errata
10
+ description: A comma-separated list of errata to install
11
11
  input_type: user
12
- required: false
12
+ required: true
13
13
  foreign_input_sets:
14
14
  - template: Package Action - SSH Default
15
15
  exclude: action,package
16
16
  %>
17
-
18
17
  <% if @host.operatingsystem.family == 'Suse' -%>
19
18
  <% advisories = input(:errata).split(',').join(' ') %>
20
19
  <%= render_template('Package Action - SSH Default', :action => 'install -n -t patch', :package => advisories) %>
21
20
  <% else %>
22
- <% advisory_ids = @host.advisory_ids(search: input("Errata search query")) %>
23
-
24
- <% advisories = advisory_ids.map { |e| "--advisory=#{e}" }.join(' ') %>
21
+ <% advisories = input(:errata).split(',').map { |e| "--advisory=#{e}" }.join(' ') %>
25
22
  <%= render_template('Package Action - SSH Default', :action => 'update-minimal', :package => advisories) %>
26
- <% end %>
23
+ <% end %>
@@ -0,0 +1,26 @@
1
+ <%#
2
+ kind: job_template
3
+ name: Install errata by search query - Katello SSH Default
4
+ job_category: Katello
5
+ description_format: 'Install errata %{Errata search query}'
6
+ feature: katello_errata_install_by_search
7
+ provider_type: SSH
8
+ template_inputs:
9
+ - name: Errata search query
10
+ description: Filter criteria for errata to be installed.
11
+ input_type: user
12
+ required: false
13
+ foreign_input_sets:
14
+ - template: Package Action - SSH Default
15
+ exclude: action,package
16
+ %>
17
+
18
+ <% if @host.operatingsystem.family == 'Suse' -%>
19
+ <% advisories = @host.advisory_ids(search: input("Errata search query")).join(' ') %>
20
+ <%= render_template('Package Action - SSH Default', :action => 'install -n -t patch', :package => advisories) %>
21
+ <% else %>
22
+ <% advisory_ids = @host.advisory_ids(search: input("Errata search query")) %>
23
+
24
+ <% advisories = advisory_ids.map { |e| "--advisory=#{e}" }.join(' ') %>
25
+ <%= render_template('Package Action - SSH Default', :action => 'update-minimal', :package => advisories) %>
26
+ <% end %>
@@ -1,4 +1,8 @@
1
1
  class CreateCdnConfiguration < ActiveRecord::Migration[6.0]
2
+ class FakeCdnConfiguration < Katello::Model
3
+ self.table_name = 'katello_cdn_configurations'
4
+ end
5
+
2
6
  def up
3
7
  create_table :katello_cdn_configurations do |t|
4
8
  t.integer :organization_id
@@ -14,17 +18,22 @@ class CreateCdnConfiguration < ActiveRecord::Migration[6.0]
14
18
  add_foreign_key :katello_cdn_configurations, :taxonomies, name: 'katello_cdn_configurations_organization_id', column: :organization_id
15
19
  add_foreign_key :katello_cdn_configurations, :katello_content_credentials, name: 'katello_cdn_configurations_ssl_ca_credential_id', column: :ssl_ca_credential_id
16
20
 
21
+ FakeCdnConfiguration.reset_column_information
22
+
17
23
  ::Organization.all.each do |org|
18
- Katello::CdnConfiguration.where(
19
- organization: org,
24
+ FakeCdnConfiguration.where(
25
+ organization_id: org.id,
20
26
  url: org.redhat_provider.repository_url || ::Katello::Resources::CDN::CdnResource.redhat_cdn_url
21
27
  ).first_or_create!
22
28
  end
23
29
 
24
30
  remove_column :katello_providers, :repository_url
31
+ ::Katello::Provider.reset_column_information
25
32
  end
26
33
 
27
34
  def down
35
+ add_column :katello_providers, :repository_url, :string
36
+ ::Katello::Provider.reset_column_information
28
37
  drop_table :katello_cdn_configurations
29
38
  end
30
39
  end
@@ -6,6 +6,7 @@ UpgradeTask.define_tasks(:katello) do
6
6
  {:name => 'katello:upgrades:4.1:sync_noarch_content'},
7
7
  {:name => 'katello:upgrades:4.1:fix_invalid_pools'},
8
8
  {:name => 'katello:upgrades:4.1:reupdate_content_import_export_perms'},
9
- {:name => 'katello:upgrades:4.2:remove_checksum_values'}
9
+ {:name => 'katello:upgrades:4.2:remove_checksum_values'},
10
+ {:name => 'katello:upgrades:4.4:publish_import_cvvs'}
10
11
  ]
11
12
  end
@@ -21,6 +21,7 @@ angular.module('Bastion.packages').controller('PackagesController',
21
21
  var nutupane, params = {
22
22
  'organization_id': CurrentOrganization,
23
23
  'search': $location.search().search || "",
24
+ 'repository_id': $location.search().repositoryId || null,
24
25
  'paged': true
25
26
  };
26
27
 
@@ -13,7 +13,6 @@
13
13
  * @requires DockerManifest
14
14
  * @requires DockerManifestList
15
15
  * @requires DockerTag
16
- * @requires OstreeBranch
17
16
  * @requires File
18
17
  * @requires Deb
19
18
  * @requires ModuleStream
@@ -25,8 +24,8 @@
25
24
  * Provides the functionality for the repository details pane.
26
25
  */
27
26
  angular.module('Bastion.repositories').controller('RepositoryManageContentController',
28
- ['$scope', '$state', 'translate', 'Notification', 'Nutupane', 'Repository', 'Package', 'PackageGroup', 'DockerManifest', 'DockerManifestList', 'DockerTag', 'OstreeBranch', 'File', 'Deb', 'ModuleStream', 'AnsibleCollection', 'GenericContent', 'RepositoryTypesService',
29
- function ($scope, $state, translate, Notification, Nutupane, Repository, Package, PackageGroup, DockerManifest, DockerManifestList, DockerTag, OstreeBranch, File, Deb, ModuleStream, AnsibleCollection, GenericContent, RepositoryTypesService) {
27
+ ['$scope', '$state', 'translate', 'Notification', 'Nutupane', 'Repository', 'Package', 'PackageGroup', 'DockerManifest', 'DockerManifestList', 'DockerTag', 'File', 'Deb', 'ModuleStream', 'AnsibleCollection', 'GenericContent', 'RepositoryTypesService',
28
+ function ($scope, $state, translate, Notification, Nutupane, Repository, Package, PackageGroup, DockerManifest, DockerManifestList, DockerTag, File, Deb, ModuleStream, AnsibleCollection, GenericContent, RepositoryTypesService) {
30
29
  var contentTypes, nutupaneParams;
31
30
 
32
31
  function success(response, selected) {
@@ -309,6 +309,7 @@ Foreman::Plugin.register :katello do
309
309
  RemoteExecutionFeature.register(:katello_group_update, N_("Katello: Update Package Group"), :description => N_("Update package group via Katello interface"), :provided_inputs => ['package'])
310
310
  RemoteExecutionFeature.register(:katello_group_remove, N_("Katello: Remove Package Group"), :description => N_("Remove package group via Katello interface"), :provided_inputs => ['package'])
311
311
  RemoteExecutionFeature.register(:katello_errata_install, N_("Katello: Install Errata"), :description => N_("Install errata via Katello interface"), :provided_inputs => ['errata'])
312
+ RemoteExecutionFeature.register(:katello_errata_install_by_search, N_("Katello: Install errata by search query"), :description => N_("Install errata using scoped search query"), :provided_inputs => ['Errata search query'])
312
313
  RemoteExecutionFeature.register(:katello_service_restart, N_("Katello: Service Restart"), :description => N_("Restart Services via Katello interface"), :provided_inputs => ['helpers'])
313
314
  RemoteExecutionFeature.register(:katello_host_tracer_resolve, N_("Katello: Resolve Traces"), :description => N_("Resolve traces via Katello interface"), :provided_inputs => ['ids'])
314
315
  RemoteExecutionFeature.register(:katello_module_stream_action, N_("Katello: Module Stream Actions"),
@@ -21,12 +21,14 @@ Katello::RepositoryTypeManager.register('ostree') do
21
21
  url_description N_("URL of an OSTree repository.")
22
22
 
23
23
  generic_content_type 'ostree_ref',
24
+ pluralized_name: "OSTree Refs",
24
25
  model_class: Katello::GenericContentUnit,
25
26
  pulp3_api: PulpOstreeClient::ContentRefsApi,
26
27
  pulp3_service_class: Katello::Pulp3::GenericContentUnit,
27
28
  model_name: lambda { |pulp_unit| pulp_unit["name"] },
28
29
  model_version: lambda { |pulp_unit| pulp_unit["checksum"] },
29
30
  uploadable: true,
31
+ generic_browser: true,
30
32
  repository_import_on_upload: true
31
33
 
32
34
  import_attribute :ref, :content_type => 'ostree_ref',
@@ -0,0 +1,34 @@
1
+ namespace :katello do
2
+ desc <<-DESCRIPTION
3
+ Marks a content view import only or otherwise. Only 'import_only' Content Views can import content via import/export process.
4
+ Options:
5
+ ID - ID of the content view that will be marked import
6
+ VALUE - If true the provided content view will be marked as import_only. This is the default.
7
+ If false the import_only flag of provided content view will be reset.
8
+ DESCRIPTION
9
+
10
+ task :set_content_view_import_only => ["environment"] do
11
+ def fetch_content_view
12
+ if ENV['ID'].blank?
13
+ fail 'Content view `ID` required.'
14
+ end
15
+ ::Katello::ContentView.find_by(id: ENV['ID'])
16
+ end
17
+
18
+ def mark_import_only(value: true)
19
+ User.current = User.anonymous_admin
20
+ content_view = fetch_content_view
21
+ fail('Composite content views cannot be marked import_only. Check the content view id.') if content_view.composite?
22
+ fail('Default Organization View cannot be marked import_only. Check the content view id.') if content_view.default?
23
+ content_view.import_only = value
24
+ if content_view.save(validate: false)
25
+ $stdout.print("Content View '#{content_view.name}'s import_only value updated to #{content_view.import_only} ")
26
+ else
27
+ $stderr.print("Unable to set the content view import_only to #{value}. Check the content view id.")
28
+ $stderr.print(content_view.errors.inspect)
29
+ end
30
+ end
31
+ value = ENV['VALUE'].blank? || ::Foreman::Cast.to_bool(ENV['VALUE'])
32
+ mark_import_only(value: value)
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ namespace :katello do
2
+ namespace :upgrades do
3
+ namespace '4.4' do
4
+ desc "Republish imported CVs that aren't published"
5
+ task :publish_import_cvvs => ["environment"] do
6
+ ::ForemanTasks.dynflow.config.remote = true
7
+ ::ForemanTasks.dynflow.initialize!
8
+
9
+ User.current = User.anonymous_admin
10
+
11
+ Katello::Repository.in_content_views(Katello::ContentView.where(:import_only => true)).where(:publication_href => nil).pluck(:content_view_version_id).uniq.each do |cvv_id|
12
+ ForemanTasks.async_task(Actions::Katello::ContentViewVersion::RepublishRepositories, ::Katello::ContentViewVersion.find(cvv_id))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "4.3.0".freeze
2
+ VERSION = "4.3.1".freeze
3
3
  end
@@ -1,3 +1,4 @@
1
+ /* eslint-disable react/jsx-indent */
1
2
  import React, { Component } from 'react';
2
3
  import PropTypes from 'prop-types';
3
4
  import { bindActionCreators } from 'redux';
@@ -38,7 +38,7 @@ const katelloHostErrataInstallParams = ({
38
38
  }) => baseParams({
39
39
  hostname,
40
40
  inputs: { [ERRATA_SEARCH_QUERY]: search },
41
- feature: REX_FEATURES.KATELLO_HOST_ERRATA_INSTALL,
41
+ feature: REX_FEATURES.KATELLO_HOST_ERRATA_INSTALL_BY_SEARCH,
42
42
  });
43
43
 
44
44
  export const installPackage = ({ hostname, packageName }) => post({
@@ -75,7 +75,7 @@ export const installErrata = ({
75
75
  hostname, search,
76
76
  }),
77
77
  handleSuccess: response => renderTaskStartedToast({
78
- humanized: { action: `Install Errata on ${hostname}` },
78
+ humanized: { action: `Install errata on ${hostname}` },
79
79
  id: response?.data?.dynflow_task?.id,
80
80
  }),
81
81
  errorToast: error => errorToast(error),