katello 3.16.0.rc4.1 → 3.16.1.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/registry/registry_proxies_controller.rb +39 -23
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
  4. data/app/controllers/katello/api/v2/content_view_filters_controller.rb +5 -1
  5. data/app/controllers/katello/api/v2/host_tracer_controller.rb +0 -5
  6. data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +15 -0
  7. data/app/controllers/katello/api/v2/repositories_controller.rb +10 -1
  8. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -5
  9. data/app/helpers/katello/content_view_helper.rb +15 -0
  10. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +1 -1
  11. data/app/lib/actions/katello/capsule_content/sync.rb +3 -2
  12. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +17 -3
  13. data/app/lib/actions/katello/content_view/incremental_updates.rb +3 -1
  14. data/app/lib/actions/katello/content_view/publish.rb +55 -16
  15. data/app/lib/actions/katello/content_view_version/incremental_update.rb +81 -51
  16. data/app/lib/actions/katello/host/attach_subscriptions.rb +5 -1
  17. data/app/lib/actions/katello/product/destroy.rb +25 -4
  18. data/app/lib/actions/katello/repository/destroy.rb +5 -1
  19. data/app/lib/actions/katello/repository/multi_clone_contents.rb +62 -0
  20. data/app/lib/actions/katello/repository/multi_clone_to_version.rb +30 -0
  21. data/app/lib/actions/katello/repository/sync.rb +35 -25
  22. data/app/lib/actions/katello/repository/update.rb +11 -16
  23. data/app/lib/actions/katello/repository/verify_checksum.rb +28 -0
  24. data/app/lib/actions/katello/sync_plan/run.rb +1 -1
  25. data/app/lib/actions/pulp/orchestration/repository/sync.rb +2 -1
  26. data/app/lib/actions/pulp/repository/sync.rb +2 -1
  27. data/app/lib/actions/pulp3/abstract_async_task.rb +62 -58
  28. data/app/lib/actions/pulp3/capsule_content/refresh_content_guard.rb +17 -0
  29. data/app/lib/actions/pulp3/capsule_content/sync.rb +3 -1
  30. data/app/lib/actions/pulp3/{ContentGuard → content_guard}/refresh.rb +0 -0
  31. data/app/lib/actions/pulp3/content_migration.rb +4 -0
  32. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -4
  33. data/app/lib/actions/pulp3/orchestration/repository/multi_copy_all_units.rb +36 -0
  34. data/app/lib/actions/pulp3/orchestration/repository/sync.rb +3 -1
  35. data/app/lib/actions/pulp3/orchestration/repository/trigger_update_repo_cert_guard.rb +22 -0
  36. data/app/lib/actions/pulp3/repository/copy_content.rb +0 -1
  37. data/app/lib/actions/pulp3/repository/multi_copy_content.rb +28 -0
  38. data/app/lib/actions/pulp3/repository/multi_copy_units.rb +14 -7
  39. data/app/lib/actions/pulp3/repository/presenters/content_unit_presenter.rb +1 -1
  40. data/app/lib/actions/pulp3/repository/presenters/repair_presenter.rb +85 -0
  41. data/app/lib/actions/pulp3/repository/repair.rb +29 -0
  42. data/app/lib/actions/pulp3/repository/save_version.rb +20 -8
  43. data/app/lib/actions/pulp3/repository/save_versions.rb +47 -13
  44. data/app/lib/actions/pulp3/repository/sync.rb +1 -1
  45. data/app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb +6 -2
  46. data/app/lib/actions/pulp3/repository/upload_file.rb +1 -1
  47. data/app/lib/katello/concerns/base_template_scope_extensions.rb +4 -0
  48. data/app/lib/katello/errors.rb +1 -15
  49. data/app/lib/katello/resources/cdn.rb +3 -2
  50. data/app/lib/katello/util/cdn_var_substitutor.rb +9 -6
  51. data/app/models/katello/concerns/smart_proxy_extensions.rb +14 -3
  52. data/app/models/katello/content_view.rb +18 -6
  53. data/app/models/katello/content_view_erratum_filter.rb +13 -0
  54. data/app/models/katello/content_view_filter.rb +4 -0
  55. data/app/models/katello/content_view_module_stream_filter.rb +30 -3
  56. data/app/models/katello/content_view_package_filter.rb +1 -1
  57. data/app/models/katello/host/content_facet.rb +1 -0
  58. data/app/models/katello/module_stream.rb +1 -1
  59. data/app/models/katello/ping.rb +1 -3
  60. data/app/models/katello/repository.rb +16 -0
  61. data/app/models/setting/content.rb +1 -1
  62. data/app/presenters/katello/sync_status_presenter.rb +4 -2
  63. data/app/services/cert/certs.rb +10 -2
  64. data/app/services/katello/pulp/repository/yum.rb +2 -1
  65. data/app/services/katello/pulp3/api/core.rb +4 -0
  66. data/app/services/katello/pulp3/erratum.rb +3 -1
  67. data/app/services/katello/pulp3/migration.rb +9 -4
  68. data/app/services/katello/pulp3/migration_plan.rb +6 -6
  69. data/app/services/katello/pulp3/repository.rb +13 -5
  70. data/app/services/katello/pulp3/repository/yum.rb +235 -35
  71. data/app/services/katello/pulp3/repository_mirror.rb +7 -2
  72. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  73. data/app/services/katello/pulp3/task.rb +100 -0
  74. data/app/services/katello/pulp3/task_group.rb +79 -0
  75. data/app/services/katello/smart_proxy_helper.rb +13 -16
  76. data/app/views/katello/api/v2/content_view_filters/base.json.rabl +4 -0
  77. data/config/routes/api/rhsm.rb +1 -0
  78. data/config/routes/api/v2.rb +2 -0
  79. data/db/migrate/20200709021250_add_original_modules_to_content_view_module_stream_filter.rb +5 -0
  80. data/db/migrate/20200721142707_remove_duplicate_katello_pools_index.rb +5 -0
  81. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.routes.js +1 -13
  82. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/filter-details.controller.js +17 -4
  83. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/filters/views/module-stream-filter-details.html +17 -0
  84. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/product-bulk-action.factory.js +1 -0
  85. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +6 -0
  86. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +7 -1
  87. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +1 -0
  88. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +15 -0
  89. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +6 -0
  90. data/lib/katello/permission_creator.rb +2 -2
  91. data/lib/katello/plugin.rb +0 -1
  92. data/lib/katello/tasks/pulp3_post_migration_check.rake +2 -1
  93. data/lib/katello/tasks/reports.rake +16 -0
  94. data/lib/katello/version.rb +1 -1
  95. data/webpack/redux/actions/RedHatRepositories/helpers.js +6 -6
  96. metadata +34 -14
  97. data/app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3206fcf99b7e7aa7a1fcbb9b6231173193f89ba0099c5e46f6226b5fc044bc8b
4
- data.tar.gz: c5ffbe4836c0958563e1448657a5fbc7d8a684ed2a647b19f933728e2436fe5f
3
+ metadata.gz: 0f0cbc00333e5f45573f080439a79710d656562078e54733dddbf2838202966b
4
+ data.tar.gz: 066d69fb7ba3574b68598e545be08c7fa229f9b952ce97ca7be1fabc3550e8d3
5
5
  SHA512:
6
- metadata.gz: c01c07349a208003082823e8a0b50e5d0920506a6b72db57c811c8c13d934cba35ec92f3c3b7088770e6e8f21efca6cd22560380c8838900d7c2fdf99501ebcd
7
- data.tar.gz: fc2bbb3bab3ac2e163bea0b97941e0fac8d48831d276af542a059ba03cae395c396010ec8a65e3e0a5150bb6032a9d0e1458c848c17a9e74dbd8a4d429f95729
6
+ metadata.gz: 28e6f171608b10bb8adf3531e4d336a8bf3a4df5787224de2fb58461755783551d440946ac64577890e8acae045b098a3db4c6cb16d5e3715784b4f54374cd5b
7
+ data.tar.gz: 54332104edef4e69b0062792547808299172fcf1c5f915e6d7a7d7825a3bf3599dd4dfd6c8d51ab683c1aa17ded1e595f28462f049f781cccf4ad5e34d4b0989
@@ -6,8 +6,8 @@ module Katello
6
6
  before_action :confirm_push_settings, only: [:start_upload_blob, :upload_blob, :finish_upload_blob,
7
7
  :chunk_upload_blob, :push_manifest]
8
8
  skip_before_action :authorize
9
- before_action :optional_authorize, only: [:token]
10
- before_action :registry_authorize, except: [:token, :v1_search]
9
+ before_action :optional_authorize, only: [:token, :catalog]
10
+ before_action :registry_authorize, except: [:token, :v1_search, :catalog]
11
11
  before_action :authorize_repository_read, only: [:pull_manifest, :tags_list]
12
12
  before_action :authorize_repository_write, only: [:push_manifest]
13
13
  skip_before_action :check_content_type, only: [:start_upload_blob, :upload_blob, :finish_upload_blob,
@@ -39,20 +39,7 @@ module Katello
39
39
  "scope=\"repository:registry:pull,push\""
40
40
  end
41
41
 
42
- def optional_authorize
43
- @repository = find_scope_repository
44
- if @repository && (@repository.environment.registry_unauthenticated_pull || ssl_client_authorized?(@repository.organization.label))
45
- true
46
- else
47
- authorize
48
- end
49
- end
50
-
51
- def registry_authorize
52
- @repository = find_readable_repository
53
- return true if ['GET', 'HEAD'].include?(request.method) && @repository && !require_user_authorization?
54
-
55
- token = request.headers['Authorization']
42
+ def set_user_by_token(token, redirect_on_failure = true)
56
43
  if token
57
44
  token_type, token = token.split
58
45
  if token_type == 'Bearer' && token
@@ -63,10 +50,34 @@ module Katello
63
50
  end
64
51
  elsif token_type == 'Basic' && token
65
52
  return true if authorize
66
- redirect_authorization_headers
53
+ redirect_authorization_headers if redirect_on_failure
67
54
  return false
68
55
  end
69
56
  end
57
+ false
58
+ end
59
+
60
+ def optional_authorize
61
+ @repository = find_scope_repository
62
+ if @repository && (@repository.environment.registry_unauthenticated_pull || ssl_client_authorized?(@repository.organization.label))
63
+ true
64
+ elsif params['action'] == 'catalog'
65
+ set_user_by_token(request.headers['Authorization'], false)
66
+ elsif (params['action'] == 'token' && params['scope'].blank? && params['account'].blank?)
67
+ true
68
+ else
69
+ authorize
70
+ end
71
+ end
72
+
73
+ def registry_authorize
74
+ @repository = find_readable_repository
75
+ return true if ['GET', 'HEAD'].include?(request.method) && @repository && !require_user_authorization?
76
+
77
+ is_user_set = set_user_by_token(request.headers['Authorization'])
78
+
79
+ return true if is_user_set
80
+
70
81
  redirect_authorization_headers
71
82
  render_error('unauthorized', :status => :unauthorized)
72
83
  return false
@@ -87,12 +98,8 @@ module Katello
87
98
  # Also include repositories in lifecycle environments with registry_unauthenticated_pull=true
88
99
  def readable_repositories
89
100
  table_name = Repository.table_name
90
- in_products = Repository.in_product(Katello::Product.authorized(:view_products)).select(:id)
91
- in_environments = Repository.where(:environment_id => Katello::KTEnvironment.authorized(:view_lifecycle_environments)).select(:id)
92
101
  in_unauth_environments = Repository.joins(:environment).where("#{Katello::KTEnvironment.table_name}.registry_unauthenticated_pull" => true).select(:id)
93
- in_content_views = Repository.joins(:content_view_repositories).where("#{ContentViewRepository.table_name}.content_view_id" => Katello::ContentView.readable).select(:id)
94
- in_versions = Repository.joins(:content_view_version).where("#{Katello::ContentViewVersion.table_name}.content_view_id" => Katello::ContentView.readable).select(:id)
95
- Repository.where("#{table_name}.id in (?) or #{table_name}.id in (?) or #{table_name}.id in (?) or #{table_name}.id in (?) or #{table_name}.id in (?)", in_products, in_content_views, in_versions, in_environments, in_unauth_environments)
102
+ Repository.readable.or(Repository.joins(:root).where("#{table_name}.id in (?)", in_unauth_environments))
96
103
  end
97
104
 
98
105
  def find_readable_repository
@@ -105,7 +112,8 @@ module Katello
105
112
  end
106
113
 
107
114
  def require_user_authorization?(repository = @repository)
108
- !repository || (!repository.environment.registry_unauthenticated_pull && !ssl_client_authorized?(repository.organization.label))
115
+ !(params['action'] == 'token' && params['scope'].blank? && params['account'].blank?) &&
116
+ (!repository || (!repository.environment.registry_unauthenticated_pull && !ssl_client_authorized?(repository.organization.label)))
109
117
  end
110
118
 
111
119
  def ssl_client_authorized?(org_label)
@@ -293,6 +301,14 @@ module Katello
293
301
  end
294
302
 
295
303
  def v1_search
304
+ # Checks for podman client and issues a 404 in that case. Podman
305
+ # examines the response from a /v1_search request. If the result
306
+ # is a 4XX, it will then proceed with a request to /_catalog
307
+ if request.headers['HTTP_USER_AGENT'].downcase.include?('libpod')
308
+ render json: {}, status: :not_found
309
+ return
310
+ end
311
+
296
312
  authenticate # to set current_user, not to enforce
297
313
  options = {
298
314
  resource_class: Katello::Repository
@@ -480,7 +480,7 @@ module Katello
480
480
  else
481
481
  User.consumer? || ::User.current.can?(:view_organizations, self)
482
482
  end
483
- when "rhsm_proxy_owner_servicelevels_path"
483
+ when "rhsm_proxy_owner_servicelevels_path", "rhsm_proxy_owner_system_purpose_path"
484
484
  (User.consumer? || ::User.current.can?(:view_organizations, self))
485
485
  when "rhsm_proxy_consumer_accessible_content_path", "rhsm_proxy_consumer_certificates_path",
486
486
  "rhsm_proxy_consumer_releases_path", "rhsm_proxy_certificate_serials_path",
@@ -37,6 +37,8 @@ module Katello
37
37
  param :type, String, :desc => N_("type of filter (e.g. rpm, package_group, erratum, docker, modulemd)"), :required => true
38
38
  param :original_packages, :bool, :desc => N_("add all packages without errata to the included/excluded list. " \
39
39
  "(package filter only)")
40
+ param :original_module_streams, :bool, :desc => N_("add all module streams without errata to the included/excluded list. " \
41
+ "(module stream filter only)")
40
42
  param :inclusion, :bool, :desc => N_("specifies if content should be included or excluded, default: inclusion=false")
41
43
  param :repository_ids, Array, :desc => N_("list of repository ids")
42
44
  param :description, String, :desc => N_("description of the filter")
@@ -60,6 +62,8 @@ module Katello
60
62
  param :name, String, :desc => N_("new name for the filter")
61
63
  param :original_packages, :bool, :desc => N_("add all packages without errata to the included/excluded list. " \
62
64
  "(package filter only)")
65
+ param :original_module_streams, :bool, :desc => N_("add all module streams without errata to the included/excluded list. " \
66
+ "(module stream filter only)")
63
67
  param :inclusion, :bool, :desc => N_("specifies if content should be included or excluded, default: inclusion=false")
64
68
  param :repository_ids, Array, :desc => N_("list of repository ids")
65
69
  param :description, String, :desc => N_("description of the filter"), :required => false
@@ -95,7 +99,7 @@ module Katello
95
99
  end
96
100
 
97
101
  def filter_params
98
- params.require(:content_view_filter).permit(:name, :inclusion, :original_packages, :description, :repository_ids => [])
102
+ params.require(:content_view_filter).permit(:name, :inclusion, :original_packages, :original_module_streams, :description, :repository_ids => [])
99
103
  end
100
104
  end
101
105
  end
@@ -2,11 +2,6 @@ module Katello
2
2
  class Api::V2::HostTracerController < Api::V2::ApiController
3
3
  before_action :find_host, :only => :index
4
4
 
5
- resource_description do
6
- api_version 'v2'
7
- api_base_url "/api"
8
- end
9
-
10
5
  api :GET, "/hosts/:host_id/traces", N_("List services that need restarting on the host")
11
6
  param :host_id, :number, :required => true, :desc => N_("ID of the host")
12
7
  def index
@@ -50,6 +50,21 @@ module Katello
50
50
  respond_for_async :resource => task
51
51
  end
52
52
 
53
+ api :PUT, "/products/bulk/verify_checksum", N_("Verify checksum for one or more products")
54
+ param :ids, Array, :desc => N_("List of product ids"), :required => true
55
+ def verify_checksum_products
56
+ repairable_products = @products.syncable
57
+ repairable_roots = RootRepository.where(:product_id => repairable_products).
58
+ where(:content_type => ::Katello::Repository::YUM_TYPE).has_url.select { |r| r.library_instance }.uniq
59
+
60
+ repairable_repositories = Katello::Repository.where(:root_id => repairable_roots)
61
+ task = async_task(::Actions::BulkAction,
62
+ ::Actions::Katello::Repository::VerifyChecksum,
63
+ repairable_repositories)
64
+
65
+ respond_for_async :resource => task
66
+ end
67
+
53
68
  api :PUT, "/products/bulk/http_proxy", N_("Update the HTTP proxy configuration on the repositories of one or more products.")
54
69
  param :ids, Array, :desc => N_("List of product ids"), :required => true
55
70
  param :http_proxy_policy, ::Katello::RootRepository::HTTP_PROXY_POLICIES, :desc => N_("policy for HTTP proxy for content sync")
@@ -15,7 +15,7 @@ module Katello
15
15
  before_action :find_organization_from_product, :only => [:create]
16
16
  before_action :find_repository, :only => [:show, :update, :destroy, :sync, :export,
17
17
  :remove_content, :upload_content, :republish,
18
- :import_uploads, :gpg_key_content]
18
+ :import_uploads, :gpg_key_content, :verify_checksum]
19
19
  before_action :find_content, :only => :remove_content
20
20
  before_action :find_organization_from_repo, :only => [:update]
21
21
  before_action :error_on_rh_product, :only => [:create]
@@ -294,6 +294,15 @@ module Katello
294
294
  raise HttpErrors::BadRequest, e.message
295
295
  end
296
296
 
297
+ api :POST, "/repositories/:id/verify_checksum", N_("Verify checksum of repository contents")
298
+ param :id, :number, :required => true, :desc => N_("repository ID")
299
+ def verify_checksum
300
+ task = async_task(::Actions::Katello::Repository::VerifyChecksum, @repository)
301
+ respond_for_async :resource => task
302
+ rescue Errors::InvalidActionOptionError => e
303
+ raise HttpErrors::BadRequest, e.message
304
+ end
305
+
297
306
  api :POST, "/repositories/:id/export", N_("Export a repository")
298
307
  param :id, :number, :desc => N_("Repository identifier"), :required => true
299
308
  param :export_to_iso, :bool, :desc => N_("Export to ISO format"), :required => false
@@ -19,11 +19,17 @@ module Katello
19
19
  prepend Overrides
20
20
 
21
21
  def update_multiple_taxonomies(type)
22
- registered_host = @hosts.detect { |host| host.subscription_facet }
23
- unless registered_host.nil?
24
- error _("Unregister host %s before assigning an organization") % registered_host.name
25
- redirect_back_or_to hosts_path
26
- return
22
+ if type == :organization
23
+ new_org_id = params.dig(type, 'id')
24
+
25
+ if new_org_id
26
+ registered_host = @hosts.where.not(organization_id: new_org_id).joins(:subscription_facet).first
27
+ if registered_host
28
+ error _("Unregister host %s before assigning an organization") % registered_host.name
29
+ redirect_back_or_to hosts_path
30
+ return
31
+ end
32
+ end
27
33
  end
28
34
 
29
35
  super
@@ -0,0 +1,15 @@
1
+ module Katello
2
+ module ContentViewHelper
3
+ def separated_repo_mapping(repo_mapping)
4
+ separated_mapping = { :pulp3_yum => {}, :other => {} }
5
+ repo_mapping.each do |source_repos, dest_repo|
6
+ if dest_repo.content_type == "yum" && SmartProxy.pulp_master.pulp3_support?(dest_repo)
7
+ separated_mapping[:pulp3_yum][source_repos] = dest_repo
8
+ else
9
+ separated_mapping[:other][source_repos] = dest_repo
10
+ end
11
+ end
12
+ separated_mapping
13
+ end
14
+ end
15
+ end
@@ -37,7 +37,7 @@ module Actions
37
37
  current_repos_on_capsule = smart_proxy_service.current_repositories(environment, content_view)
38
38
  current_repos_on_capsule_ids = current_repos_on_capsule.pluck(:id)
39
39
 
40
- list_of_repos_to_sync = smart_proxy_helper.repos_available_to_capsule(environment, content_view, repository)
40
+ list_of_repos_to_sync = smart_proxy_helper.combined_repos_available_to_capsule(environment, content_view, repository)
41
41
  list_of_repos_to_sync.each do |repo|
42
42
  if repo.is_a?(Katello::ContentViewPuppetEnvironment)
43
43
  repo = repo.nonpersisted_repository
@@ -31,8 +31,8 @@ module Actions
31
31
  fail _("Action not allowed for the default smart proxy.") if smart_proxy.pulp_master?
32
32
 
33
33
  smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
34
- repositories = smart_proxy_helper.repos_available_to_capsule(environment, content_view, repository)
35
- smart_proxy.ping_pulp3 if repositories.any? { |repo| smart_proxy.pulp3_support?(repo) }
34
+ repositories = smart_proxy_helper.combined_repos_available_to_capsule(environment, content_view, repository)
35
+
36
36
  smart_proxy.ping_pulp if repositories.any? { |repo| !smart_proxy.pulp3_support?(repo) }
37
37
 
38
38
  refresh_options = options.merge(content_view: content_view,
@@ -40,6 +40,7 @@ module Actions
40
40
  repository: repository)
41
41
  sequence do
42
42
  plan_action(Actions::Pulp::Orchestration::Repository::RefreshRepos, smart_proxy, refresh_options)
43
+ plan_action(Actions::Pulp3::CapsuleContent::RefreshContentGuard, smart_proxy) if repositories.any? { |repo| smart_proxy.pulp3_support?(repo) }
43
44
  plan_action(Actions::Pulp3::Orchestration::Repository::RefreshRepos, smart_proxy, refresh_options) if smart_proxy.pulp3_enabled?
44
45
  plan_action(SyncCapsule, smart_proxy, refresh_options)
45
46
  end
@@ -10,11 +10,12 @@ module Actions
10
10
  repository = options[:repository]
11
11
  skip_metadata_check = options.fetch(:skip_metadata_check, false)
12
12
 
13
- smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
14
13
  sequence do
15
- smart_proxy_helper.repos_available_to_capsule(environment, content_view, repository).in_groups_of(Setting[:foreman_proxy_content_batch_size], false) do |repos|
14
+ repos = repos_to_sync(smart_proxy, environment, content_view, repository)
15
+
16
+ repos.in_groups_of(Setting[:foreman_proxy_content_batch_size], false) do |repo_batch|
16
17
  concurrence do
17
- repos.each do |repo|
18
+ repo_batch.each do |repo|
18
19
  plan_pulp_action([Actions::Pulp::Orchestration::Repository::SmartProxySync,
19
20
  Actions::Pulp3::CapsuleContent::Sync],
20
21
  repo, smart_proxy,
@@ -33,6 +34,19 @@ module Actions
33
34
  end
34
35
  end
35
36
 
37
+ def repos_to_sync(smart_proxy, environment, content_view, repository)
38
+ smart_proxy_helper = ::Katello::SmartProxyHelper.new(smart_proxy)
39
+ smart_proxy_helper.lifecycle_environment_check(environment, repository)
40
+
41
+ if repository
42
+ [repository]
43
+ else
44
+ repositories = smart_proxy_helper.repositories_available_to_capsule(environment, content_view).by_rpm_count
45
+ puppet_envs = smart_proxy_helper.puppet_environments_available_to_capsule(environment, content_view)
46
+ repositories + puppet_envs
47
+ end
48
+ end
49
+
36
50
  def resource_locks
37
51
  :link
38
52
  end
@@ -52,7 +52,9 @@ module Actions
52
52
  action = plan_action(ContentViewVersion::IncrementalUpdate, composite_version, environments,
53
53
  :new_components => new_components, :description => description,
54
54
  :content => {:puppet_module_ids => puppet_module_ids})
55
- output_for_version_ids << {:version_id => action.new_content_view_version.id, :output => action.output}
55
+ unless SmartProxy.pulp_master.pulp3_repository_type_support?("yum")
56
+ output_for_version_ids << {:version_id => action.new_content_view_version.id, :output => action.output}
57
+ end
56
58
  end
57
59
  end
58
60
  end
@@ -3,6 +3,8 @@ module Actions
3
3
  module Katello
4
4
  module ContentView
5
5
  class Publish < Actions::EntryAction
6
+ include ::Katello::ContentViewHelper
7
+ attr_accessor :version
6
8
  # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
7
9
  def plan(content_view, description = "", options = {})
8
10
  action_subject(content_view)
@@ -21,7 +23,11 @@ module Actions
21
23
  end
22
24
  end
23
25
 
26
+ # Add non-override components back in
27
+ options[:override_components] = include_other_components(options[:override_components], content_view)
28
+
24
29
  version = version_for_publish(content_view, options)
30
+ self.version = version
25
31
  library = content_view.organization.library
26
32
  history = ::Katello::ContentViewHistory.create!(:content_view_version => version,
27
33
  :user => ::User.current.login,
@@ -32,20 +38,30 @@ module Actions
32
38
  :triggered_by => options[:triggered_by]
33
39
  )
34
40
  source_repositories = []
35
- content_view.publish_repositories do |repositories|
41
+ content_view.publish_repositories(options[:override_cvvs]) do |repositories|
36
42
  source_repositories += [repositories]
37
43
  end
38
44
 
39
45
  sequence do
40
- plan_action(ContentView::AddToEnvironment, version, library)
46
+ plan_action(ContentView::AddToEnvironment, version, library) unless options[:skip_promotion]
41
47
  repository_mapping = plan_action(ContentViewVersion::CreateRepos, version, source_repositories).repository_mapping
42
48
 
49
+ # Split Pulp 3 Yum repos out of the repository_mapping. Only Pulp 3 RPM plugin has multi repo copy support.
50
+ separated_repo_map = separated_repo_mapping(repository_mapping)
51
+
52
+ if separated_repo_map[:pulp3_yum].keys.flatten.present? &&
53
+ SmartProxy.pulp_master.pulp3_support?(separated_repo_map[:pulp3_yum].keys.flatten.first)
54
+ plan_action(Repository::MultiCloneToVersion, separated_repo_map[:pulp3_yum], version)
55
+ end
56
+
43
57
  concurrence do
44
58
  source_repositories.each do |repositories|
45
59
  sequence do
46
- plan_action(Repository::CloneToVersion, repositories, version, repository_mapping[repositories],
47
- :repos_units => options[:repos_units])
48
- plan_action(Repository::CloneToEnvironment, repository_mapping[repositories], library)
60
+ if repositories.present? && separated_repo_map[:other].keys.include?(repositories)
61
+ plan_action(Repository::CloneToVersion, repositories, version, repository_mapping[repositories],
62
+ :repos_units => options[:repos_units])
63
+ end
64
+ plan_action(Repository::CloneToEnvironment, repository_mapping[repositories], library) unless options[:skip_promotion]
49
65
  end
50
66
  end
51
67
 
@@ -55,16 +71,18 @@ module Actions
55
71
  end
56
72
  has_modules = content_view.publish_puppet_environment?
57
73
  plan_action(ContentViewPuppetEnvironment::CreateForVersion, version)
58
- plan_action(ContentViewPuppetEnvironment::Clone, version, :environment => library,
59
- :puppet_modules_present => has_modules)
60
- plan_action(Candlepin::Environment::SetContent, content_view, library, content_view.content_view_environment(library))
61
- plan_action(Katello::Foreman::ContentUpdate, library, content_view)
62
- plan_action(ContentView::ErrataMail, content_view, library)
74
+ unless options[:skip_promotion]
75
+ plan_action(ContentViewPuppetEnvironment::Clone, version, :environment => library,
76
+ :puppet_modules_present => has_modules)
77
+ end
78
+ plan_action(Candlepin::Environment::SetContent, content_view, library, content_view.content_view_environment(library)) unless options[:skip_promotion]
79
+ plan_action(Katello::Foreman::ContentUpdate, library, content_view) unless options[:skip_promotion]
80
+ plan_action(ContentView::ErrataMail, content_view, library) unless options[:skip_promotion]
63
81
  plan_self(history_id: history.id, content_view_id: content_view.id,
64
82
  auto_publish_composite_ids: auto_publish_composite_ids(content_view),
65
83
  content_view_version_name: version.name,
66
84
  content_view_version_id: version.id,
67
- environment_id: library.id, user_id: ::User.current.id)
85
+ environment_id: library.id, user_id: ::User.current.id, skip_promotion: options[:skip_promotion])
68
86
  end
69
87
  end
70
88
 
@@ -85,6 +103,7 @@ module Actions
85
103
 
86
104
  output[:content_view_id] = input[:content_view_id]
87
105
  output[:content_view_version_id] = input[:content_view_version_id]
106
+ output[:skip_promotion] = input[:skip_promotion]
88
107
  end
89
108
 
90
109
  def rescue_strategy_for_self
@@ -95,9 +114,11 @@ module Actions
95
114
  version = ::Katello::ContentViewVersion.find(input[:content_view_version_id])
96
115
  version.update_content_counts!
97
116
  # update errata applicability counts for all hosts in the CV & Library
98
- ::Katello::Host::ContentFacet.where(:content_view_id => input[:content_view_id],
99
- :lifecycle_environment_id => input[:environment_id]).each do |facet|
100
- facet.update_applicability_counts
117
+ unless input[:skip_promotion]
118
+ ::Katello::Host::ContentFacet.where(:content_view_id => input[:content_view_id],
119
+ :lifecycle_environment_id => input[:environment_id]).each do |facet|
120
+ facet.update_applicability_counts
121
+ end
101
122
  end
102
123
 
103
124
  history = ::Katello::ContentViewHistory.find(input[:history_id])
@@ -105,7 +126,7 @@ module Actions
105
126
  history.save!
106
127
  environment = ::Katello::KTEnvironment.find(input[:environment_id])
107
128
  view = ::Katello::ContentView.find(input[:content_view_id])
108
- if SmartProxy.sync_needed?(environment) && Setting[:foreman_proxy_content_auto_sync]
129
+ if SmartProxy.sync_needed?(environment) && Setting[:foreman_proxy_content_auto_sync] && !input[:skip_promotion]
109
130
  ForemanTasks.async_task(ContentView::CapsuleSync,
110
131
  view,
111
132
  environment)
@@ -115,6 +136,20 @@ module Actions
115
136
 
116
137
  private
117
138
 
139
+ def include_other_components(override_components, content_view)
140
+ if override_components.present?
141
+ content_view.components.each do |component|
142
+ component_has_override = override_components.detect do |override_component|
143
+ component.content_view_id == override_component.content_view_id
144
+ end
145
+ unless component_has_override
146
+ override_components << component
147
+ end
148
+ end
149
+ override_components
150
+ end
151
+ end
152
+
118
153
  def repos_to_delete(content_view)
119
154
  if content_view.composite?
120
155
  library_instances = content_view.repositories_to_publish.map(&:library_instance_id)
@@ -132,7 +167,11 @@ module Actions
132
167
 
133
168
  def version_for_publish(content_view, options)
134
169
  if options[:minor] && options[:major]
135
- content_view.create_new_version(options[:major], options[:minor])
170
+ if options[:override_components]
171
+ content_view.create_new_version(options[:major], options[:minor], options[:override_components])
172
+ else
173
+ content_view.create_new_version(options[:major], options[:minor])
174
+ end
136
175
  else
137
176
  content_view.create_new_version
138
177
  end