katello 3.16.0 → 3.16.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
  3. data/app/controllers/katello/api/v2/host_tracer_controller.rb +0 -5
  4. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +15 -0
  5. data/app/controllers/katello/api/v2/repositories_controller.rb +10 -1
  6. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -5
  7. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +1 -1
  8. data/app/lib/actions/katello/capsule_content/sync.rb +3 -2
  9. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +17 -3
  10. data/app/lib/actions/katello/product/destroy.rb +25 -4
  11. data/app/lib/actions/katello/repository/destroy.rb +5 -1
  12. data/app/lib/actions/katello/repository/multi_clone_contents.rb +5 -9
  13. data/app/lib/actions/katello/repository/sync.rb +35 -25
  14. data/app/lib/actions/katello/repository/update.rb +11 -16
  15. data/app/lib/actions/katello/repository/verify_checksum.rb +28 -0
  16. data/app/lib/actions/pulp/orchestration/repository/sync.rb +2 -1
  17. data/app/lib/actions/pulp/repository/sync.rb +2 -1
  18. data/app/lib/actions/pulp3/capsule_content/refresh_content_guard.rb +17 -0
  19. data/app/lib/actions/pulp3/capsule_content/sync.rb +3 -1
  20. data/app/lib/actions/pulp3/{ContentGuard → content_guard}/refresh.rb +0 -0
  21. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +1 -2
  22. data/app/lib/actions/pulp3/orchestration/repository/sync.rb +3 -1
  23. data/app/lib/actions/pulp3/orchestration/repository/trigger_update_repo_cert_guard.rb +22 -0
  24. data/app/lib/actions/pulp3/repository/copy_content.rb +0 -1
  25. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +1 -1
  26. data/app/lib/actions/pulp3/repository/presenters/repair_presenter.rb +85 -0
  27. data/app/lib/actions/pulp3/repository/repair.rb +29 -0
  28. data/app/lib/actions/pulp3/repository/save_version.rb +20 -16
  29. data/app/lib/actions/pulp3/repository/sync.rb +1 -1
  30. data/app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb +6 -2
  31. data/app/lib/actions/pulp3/repository/upload_file.rb +1 -1
  32. data/app/lib/katello/concerns/base_template_scope_extensions.rb +4 -0
  33. data/app/lib/katello/resources/cdn.rb +3 -2
  34. data/app/lib/katello/util/cdn_var_substitutor.rb +9 -6
  35. data/app/models/katello/concerns/smart_proxy_extensions.rb +14 -3
  36. data/app/models/katello/content_view_package_filter.rb +1 -1
  37. data/app/models/katello/host/content_facet.rb +1 -0
  38. data/app/models/katello/ping.rb +1 -3
  39. data/app/models/katello/repository.rb +5 -0
  40. data/app/models/setting/content.rb +1 -1
  41. data/app/services/cert/certs.rb +10 -2
  42. data/app/services/katello/pulp3/repository.rb +7 -8
  43. data/app/services/katello/pulp3/repository/yum.rb +73 -6
  44. data/app/services/katello/pulp3/repository_mirror.rb +7 -2
  45. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  46. data/app/services/katello/smart_proxy_helper.rb +13 -16
  47. data/config/routes/api/rhsm.rb +1 -0
  48. data/config/routes/api/v2.rb +2 -0
  49. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/product-bulk-action.factory.js +1 -0
  50. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +6 -0
  51. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +7 -1
  52. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -0
  53. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +15 -0
  54. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +6 -0
  55. data/lib/katello/permission_creator.rb +2 -2
  56. data/lib/katello/plugin.rb +0 -1
  57. data/lib/katello/version.rb +1 -1
  58. data/webpack/redux/actions/RedHatRepositories/helpers.js +1 -1
  59. metadata +14 -4
  60. data/app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb +0 -17
@@ -0,0 +1,17 @@
1
+ module Actions
2
+ module Pulp3
3
+ module CapsuleContent
4
+ class RefreshContentGuard < Pulp3::AbstractAsyncTask
5
+ def plan(smart_proxy, options = {})
6
+ content_guard_api = ::Katello::Pulp3::Api::ContentGuard.new(smart_proxy)
7
+ content_guard_href = content_guard_api.list&.results&.first&.pulp_href
8
+ if content_guard_href && options.try(:[], :update)
9
+ content_guard_api.partial_update content_guard_href
10
+ else
11
+ content_guard_api.create
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -11,7 +11,9 @@ module Actions
11
11
 
12
12
  def invoke_external_task
13
13
  repo = ::Katello::Repository.find(input[:repository_id])
14
- output[:pulp_tasks] = repo.backend_service(smart_proxy).with_mirror_adapter.sync
14
+ sync_options = {}
15
+ sync_options[:optimize] = false if sync_options[:skip_metadata_check]
16
+ output[:pulp_tasks] = repo.backend_service(smart_proxy).with_mirror_adapter.sync(sync_options)
15
17
  end
16
18
 
17
19
  def rescue_strategy_for_self
@@ -16,8 +16,7 @@ module Actions
16
16
  copy_action = plan_action(Actions::Pulp3::Repository::CopyContent, source_repositories.first, smart_proxy, target_repo,
17
17
  filter_ids: filter_ids, solve_dependencies: solve_dependencies,
18
18
  rpm_filenames: rpm_filenames)
19
- plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo,
20
- repository_details: { latest_version_href: copy_action.output[:latest_version_href] }, tasks: copy_action.output[:pulp_tasks])
19
+ plan_action(Actions::Pulp3::Repository::SaveVersion, target_repo, tasks: copy_action.output[:pulp_tasks])
21
20
  else
22
21
  #if we are not filtering, copy the version to the cv repository, and the units for each additional repo
23
22
  action = plan_action(Actions::Pulp3::Repository::CopyVersion, source_repositories.first, smart_proxy, target_repo)
@@ -7,7 +7,9 @@ module Actions
7
7
  def plan(repository, smart_proxy, options)
8
8
  sequence do
9
9
  action_output = plan_action(Actions::Pulp3::Repository::Sync, repository, smart_proxy, options).output
10
- version_output = plan_action(Pulp3::Repository::SaveVersion, repository, tasks: action_output[:pulp_tasks]).output
10
+
11
+ force_fetch_version = true if options[:optimize] == false
12
+ version_output = plan_action(Pulp3::Repository::SaveVersion, repository, tasks: action_output[:pulp_tasks], :force_fetch_version => force_fetch_version).output
11
13
  plan_action(Pulp3::Orchestration::Repository::GenerateMetadata, repository, smart_proxy, :contents_changed => version_output[:contents_changed])
12
14
  plan_self(:subaction_output => version_output)
13
15
  end
@@ -0,0 +1,22 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Orchestration
4
+ module Repository
5
+ class TriggerUpdateRepoCertGuard < Pulp3::Abstract
6
+ def plan(repository, smart_proxy)
7
+ plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id)
8
+ end
9
+
10
+ def run
11
+ repository = ::Katello::Repository.find(input[:repository_id])
12
+ ForemanTasks.async_task(::Actions::Pulp3::Repository::UpdateCVRepositoryCertGuard, repository, smart_proxy)
13
+ end
14
+
15
+ def humanized_name
16
+ _("Updating repository authentication configuration")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -11,7 +11,6 @@ module Actions
11
11
  def invoke_external_task
12
12
  source = ::Katello::Repository.find(input[:source_repository_id])
13
13
  target = ::Katello::Repository.find(input[:target_repository_id] || input[:target_repository])
14
- output[:latest_version_href] = target.backend_service(smart_proxy).read.latest_version_href
15
14
  output[:pulp_tasks] = target.backend_service(smart_proxy).copy_content_for_source(source, input)
16
15
  end
17
16
  end
@@ -17,7 +17,7 @@ module Actions
17
17
  repo_id_map = {}
18
18
 
19
19
  input[:repo_id_map].each do |source_repo_ids, dest_repo_map|
20
- repo_id_map[JSON.parse(source_repo_ids)] = dest_repo_map
20
+ repo_id_map[JSON.parse(source_repo_ids)] = dest_repo_map.deep_dup
21
21
  end
22
22
 
23
23
  output[:pulp_tasks] = ::Katello::Repository.find(repo_id_map.values.first[:dest_repo]).backend_service(smart_proxy).copy_content_from_mapping(repo_id_map, input)
@@ -0,0 +1,85 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ module Presenters
5
+ class RepairPresenter < Helpers::Presenter::Base
6
+ def humanized_output
7
+ if action.external_task
8
+ humanized_details
9
+ end
10
+ end
11
+
12
+ def progress
13
+ total_units == 0 ? 0.1 : finished_units.to_f / total_units
14
+ end
15
+
16
+ private
17
+
18
+ def repair_task
19
+ tasks = action.external_task.select do |task|
20
+ if task.key? 'name'
21
+ task['name'].include?("repair_version")
22
+ end
23
+ end
24
+ tasks.first
25
+ end
26
+
27
+ def cancelled?
28
+ repair_task && repair_task['state'] == 'cancelled'
29
+ end
30
+
31
+ def task_result
32
+ repair_task['result']
33
+ end
34
+
35
+ def task_result_details
36
+ task_result && task_result['details']
37
+ end
38
+
39
+ def humanized_details
40
+ ret = []
41
+ ret << _("Cancelled.") if cancelled?
42
+ ret << _("Total steps: ") + "#{finished_units}/#{total_units}"
43
+ ret << "--------------------------------"
44
+ progress_reports = repair_task.try(:[], 'progress_reports') || []
45
+ progress_reports = progress_reports.sort_by { |pr| pr.try(:[], 'message') }
46
+ progress_reports.each do |pr|
47
+ done = pr.try(:[], 'done')
48
+ total = pr.try(:[], 'total') || pr.try(:[], 'done')
49
+ unless done.nil? || total.nil?
50
+ ret << _(pr.try(:[], 'message') + ": #{done}/#{total}")
51
+ end
52
+ end
53
+
54
+ ret.join("\n")
55
+ end
56
+
57
+ def total_units
58
+ total_unit = 0
59
+ progress_reports = repair_task.try(:[], 'progress_reports') || []
60
+ progress_reports.each do |pr|
61
+ total = pr.try(:[], 'total')
62
+ total = pr.try(:[], 'done') if total.nil?
63
+ unless total.nil?
64
+ total_unit += total.to_i
65
+ end
66
+ end
67
+ total_unit
68
+ end
69
+
70
+ def finished_units
71
+ finished_unit = 0
72
+ progress_reports = repair_task.try(:[], 'progress_reports') || []
73
+ progress_reports.each do |pr|
74
+ done = pr.try(:[], 'done')
75
+ unless done.nil?
76
+ finished_unit += done.to_i
77
+ end
78
+ end
79
+ finished_unit
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,29 @@
1
+ module Actions
2
+ module Pulp3
3
+ module Repository
4
+ class Repair < Pulp3::AbstractAsyncTask
5
+ include Helpers::Presenter
6
+ def plan(repository_id, smart_proxy)
7
+ plan_self(:repository_id => repository_id, :smart_proxy_id => smart_proxy.id)
8
+ end
9
+
10
+ def invoke_external_task
11
+ repo = ::Katello::Repository.find(input[:repository_id])
12
+ output[:response] = repo.backend_service(smart_proxy).repair(repo.version_href)
13
+ end
14
+
15
+ def run_progress
16
+ presenter.progress
17
+ end
18
+
19
+ def run_progress_weight
20
+ 10
21
+ end
22
+
23
+ def presenter
24
+ Presenters::RepairPresenter.new(self)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,35 +3,39 @@ module Actions
3
3
  module Repository
4
4
  class SaveVersion < Pulp3::Abstract
5
5
  def plan(repository, options)
6
- plan_self(:repository_id => repository.id, :tasks => options[:tasks], :repository_details => options[:repository_details])
6
+ fail "Cannot accept tasks and repository_details into Save Version." if options[:tasks].present? && options[:repository_details].present?
7
+ plan_self(:repository_id => repository.id, :tasks => options[:tasks], :repository_details => options[:repository_details], :force_fetch_version => options.fetch(:force_fetch_version, false))
7
8
  end
8
9
 
9
10
  def run
10
11
  repo = ::Katello::Repository.find(input[:repository_id])
11
12
 
12
- if input[:tasks].present?
13
+ if input[:force_fetch_version]
14
+ version_href = fetch_version_href(repo)
15
+ elsif input[:repository_details].present?
16
+ version_href = input[:repository_details][:latest_version_href]
17
+ elsif input[:tasks].present?
13
18
  version_href = input[:tasks].last[:created_resources].first
14
- end
15
-
16
- unless version_href
17
- if input[:repository_details]
18
- version_href = input[:repository_details][:latest_version_href]
19
- elsif repo.version_href.nil?
20
- # Fetch latest Pulp 3 repo version
21
- repo_backend_service = repo.backend_service(SmartProxy.pulp_master)
22
- version_href ||= repo_backend_service.api.
23
- repositories_api.read(repo_backend_service.
24
- repository_reference.repository_href).latest_version_href
25
- end
19
+ else
20
+ version_href = fetch_version_href(repo)
26
21
  end
27
22
 
28
23
  if version_href
29
- repo.update(:version_href => version_href)
30
- output[:contents_changed] = true
24
+ if repo.version_href != version_href || input[:force_fetch_version]
25
+ output[:contents_changed] = true
26
+ repo.update(:version_href => version_href)
27
+ end
31
28
  else
32
29
  output[:contents_changed] = false
33
30
  end
34
31
  end
32
+
33
+ def fetch_version_href(repo)
34
+ # Fetch latest Pulp 3 repo version
35
+ repo_backend_service = repo.backend_service(SmartProxy.pulp_master)
36
+ repo_href = repo_backend_service.repository_reference.repository_href
37
+ repo_backend_service.api.repositories_api.read(repo_href).latest_version_href
38
+ end
35
39
  end
36
40
  end
37
41
  end
@@ -10,7 +10,7 @@ module Actions
10
10
 
11
11
  def invoke_external_task
12
12
  repo = ::Katello::Repository.find(input[:repo_id])
13
- output[:pulp_tasks] = repo.backend_service(::SmartProxy.unscoped.find(input[:smart_proxy_id])).sync
13
+ output[:pulp_tasks] = repo.backend_service(::SmartProxy.unscoped.find(input[:smart_proxy_id])).sync(input[:options])
14
14
  end
15
15
 
16
16
  def external_task=(tasks)
@@ -2,13 +2,17 @@ module Actions
2
2
  module Pulp3
3
3
  module Repository
4
4
  class UpdateCVRepositoryCertGuard < Pulp3::Abstract
5
- def plan(repository, _smart_proxy)
5
+ def plan(repository, smart_proxy)
6
6
  root = repository.root
7
7
  cv_repositories = root.repositories - [root.library_instance]
8
8
  cv_repositories.each do |repo|
9
- plan_action(::Actions::Pulp3::Repository::RefreshDistribution, repo, SmartProxy.pulp_master)
9
+ plan_action(::Actions::Pulp3::Repository::RefreshDistribution, repo, smart_proxy)
10
10
  end
11
11
  end
12
+
13
+ def humanized_name
14
+ _("Updating repository authentication configuration")
15
+ end
12
16
  end
13
17
  end
14
18
  end
@@ -25,7 +25,7 @@ module Actions
25
25
  filechunk.flush
26
26
  actual_chunk_size = File.size(filechunk)
27
27
  response = uploads_api.update(upload_href, content_range(offset, offset + actual_chunk_size - 1, total_size), filechunk)
28
- offset += actual_chunk_size - 1
28
+ offset += actual_chunk_size
29
29
  ensure
30
30
  filechunk.close
31
31
  filechunk.unlink
@@ -154,6 +154,10 @@ module Katello
154
154
  end
155
155
  # rubocop:enable Metrics/MethodLength
156
156
 
157
+ def sortable_version(version)
158
+ Util::Package.sortable_version(version)
159
+ end
160
+
157
161
  private
158
162
 
159
163
  def host_subscription_facet(host)
@@ -18,7 +18,7 @@ module Katello
18
18
  class CdnResource
19
19
  CDN_DOCKER_CONTAINER_LISTING = "CONTAINER_REGISTRY_LISTING".freeze
20
20
 
21
- attr_reader :url, :product, :options
21
+ attr_reader :url, :product, :options, :proxy
22
22
 
23
23
  def substitutor(logger = nil)
24
24
  @logger = logger
@@ -26,6 +26,7 @@ module Katello
26
26
  end
27
27
 
28
28
  def initialize(url, options = {})
29
+ @proxy = ::HttpProxy.default_global_content_proxy
29
30
  @ssl_version = Setting[:cdn_ssl_version]
30
31
  if @ssl_version && !SUPPORTED_SSL_VERSIONS.include?(@ssl_version)
31
32
  fail("Invalid SSL version specified. Check the 'CDN SSL Version' setting")
@@ -140,7 +141,7 @@ module Katello
140
141
  end
141
142
 
142
143
  def net_http_class
143
- if (proxy = ::HttpProxy.default_global_content_proxy)
144
+ if self.proxy
144
145
  uri = URI(proxy.url) #Net::HTTP::Proxy ignores port as part of the url
145
146
  Net::HTTP::Proxy("#{uri.host}#{uri.path}", uri.port, proxy.username, proxy.password)
146
147
  else
@@ -59,14 +59,17 @@ module Katello
59
59
 
60
60
  return resolved if to_resolve.empty?
61
61
 
62
- futures = to_resolve.map do |path_with_substitution|
63
- Concurrent::Promises.future do
64
- path_with_substitution.resolve_substitutions(@resource)
62
+ to_resolve.in_groups_of(8) do |group|
63
+ futures = group.map do |path_with_substitution|
64
+ Concurrent::Promises.future do
65
+ path_with_substitution.resolve_substitutions(@resource)
66
+ end
65
67
  end
66
- end
67
68
 
68
- futures.each do |future|
69
- resolved << future.value
69
+ futures.each do |future|
70
+ resolved << future.value
71
+ Rails.logger.error("Failed at scanning for repository: #{future.reason}") if future.rejected?
72
+ end
70
73
  end
71
74
 
72
75
  find_substitutions(resolved.compact.flatten)
@@ -120,8 +120,7 @@ module Katello
120
120
  uri = pulp3_uri!
121
121
  config.host = uri.host
122
122
  config.scheme = uri.scheme
123
- config.ssl_client_cert = ::Cert::Certs.ssl_client_cert
124
- config.ssl_client_key = ::Cert::Certs.ssl_client_key
123
+ pulp3_ssl_configuration(config)
125
124
  config.debugging = true
126
125
  config.logger = ::Foreman::Logging.logger('katello/pulp_rest')
127
126
  config.username = self.setting(PULP3_FEATURE, 'username')
@@ -129,6 +128,18 @@ module Katello
129
128
  end
130
129
  end
131
130
 
131
+ def pulp3_ssl_configuration(config)
132
+ if Faraday.default_adapter == :excon
133
+ config.ssl_client_cert = ::Cert::Certs.ssl_client_cert_filename
134
+ config.ssl_client_key = ::Cert::Certs.ssl_client_key_filename
135
+ elsif Faraday.default_adapter == :net_http
136
+ config.ssl_client_cert = ::Cert::Certs.ssl_client_cert
137
+ config.ssl_client_key = ::Cert::Certs.ssl_client_key
138
+ else
139
+ fail "Unexpected faraday default_adapter #{Faraday.default_adapter}! Cannot continue, this is likely a bug."
140
+ end
141
+ end
142
+
132
143
  def backend_service_type(repository)
133
144
  if pulp3_support?(repository)
134
145
  Actions::Pulp3::Abstract::BACKEND_SERVICE_TYPE
@@ -142,7 +153,7 @@ module Katello
142
153
  end
143
154
 
144
155
  def pulp3_support?(repository)
145
- pulp3_repository_type_support?(repository.content_type)
156
+ repository ? pulp3_repository_type_support?(repository.try(:content_type)) : false
146
157
  end
147
158
 
148
159
  def pulp2_preferred_for_type?(repository_type)
@@ -37,7 +37,7 @@ module Katello
37
37
  self.package_rules.each do |rule|
38
38
  package_filenames.concat(query_rpms(repo, rule))
39
39
  end
40
-
40
+ package_filenames.concat(repo.packages_without_errata.map(&:filename)) if self.original_packages
41
41
  rpms = Rpm.in_repositories(repo)
42
42
  rpms.where(filename: package_filenames).where(:modular => false).pluck(:pulp_id).flatten.uniq
43
43
  end
@@ -126,6 +126,7 @@ module Katello
126
126
  ::Katello::Applicability::ApplicableContentHelper.new(self, ::Katello::Erratum, bound_repos).calculate_and_import
127
127
  ::Katello::Applicability::ApplicableContentHelper.new(self, ::Katello::ModuleStream, bound_repos).calculate_and_import
128
128
  update_applicability_counts
129
+ self.update_errata_status
129
130
  end
130
131
 
131
132
  def import_applicability(partial = false)
@@ -31,9 +31,7 @@ module Katello
31
31
 
32
32
  # set overall status result code
33
33
  result = {:services => result}
34
- result[:services].each_value do |v|
35
- result[:status] = v[:status] == OK_RETURN_CODE ? OK_RETURN_CODE : FAIL_RETURN_CODE
36
- end
34
+ result[:status] = result[:services].each_value.any? { |v| v[:status] == FAIL_RETURN_CODE } ? FAIL_RETURN_CODE : OK_RETURN_CODE
37
35
  result
38
36
  end
39
37
 
@@ -133,6 +133,7 @@ module Katello
133
133
  scope :in_published_environments, -> { in_content_views(Katello::ContentView.non_default).where.not(:environment_id => nil) }
134
134
  scope :order_by_root, ->(attr) { joins(:root).order("#{Katello::RootRepository.table_name}.#{attr}") }
135
135
  scope :with_content, ->(content) { joins(Katello::RepositoryTypeManager.find_content_type(content).model_class.repository_association_class.name.demodulize.underscore.pluralize.to_sym).distinct }
136
+ scope :by_rpm_count, -> { left_joins(:repository_rpms).group(:id).order("count(katello_repository_rpms.id) ASC") } # smallest count first
136
137
 
137
138
  scoped_search :on => :name, :relation => :root, :complete_value => true
138
139
  scoped_search :rename => :product, :on => :name, :relation => :product, :complete_value => true
@@ -592,6 +593,10 @@ module Katello
592
593
  environment
593
594
  end
594
595
 
596
+ def self.smart_proxy_syncable
597
+ where.not(:environment_id => nil)
598
+ end
599
+
595
600
  def exist_for_environment?(environment, content_view, attribute = nil)
596
601
  if environment.present? && content_view.in_environment?(environment)
597
602
  repos = content_view.version(environment).repos(environment)