katello 4.2.0.rc1 → 4.2.0.rc2

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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/rhsm/candlepin_dynflow_proxy_controller.rb +20 -2
  3. data/app/controllers/katello/api/v2/content_uploads_controller.rb +2 -1
  4. data/app/controllers/katello/api/v2/repositories_controller.rb +1 -0
  5. data/app/lib/actions/katello/content_view_version/create_repos.rb +1 -1
  6. data/app/lib/actions/katello/host/upload_package_profile.rb +7 -21
  7. data/app/lib/actions/katello/host/upload_profiles.rb +6 -52
  8. data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +2 -0
  9. data/app/lib/actions/katello/repository/clone_to_environment.rb +1 -1
  10. data/app/lib/actions/katello/repository/create.rb +8 -4
  11. data/app/lib/actions/katello/repository/create_root.rb +1 -1
  12. data/app/lib/actions/katello/repository/import_upload.rb +6 -1
  13. data/app/lib/actions/katello/repository/upload_files.rb +6 -8
  14. data/app/lib/actions/katello/repository_set/enable_repository.rb +1 -1
  15. data/app/lib/actions/pulp3/orchestration/repository/create.rb +2 -2
  16. data/app/lib/actions/pulp3/orchestration/repository/import_upload.rb +25 -4
  17. data/app/lib/actions/pulp3/orchestration/repository/upload_content.rb +17 -5
  18. data/app/lib/actions/pulp3/repository/commit_upload.rb +25 -2
  19. data/app/lib/actions/pulp3/repository/create.rb +4 -3
  20. data/app/lib/actions/pulp3/repository/refresh_distribution.rb +5 -2
  21. data/app/lib/actions/pulp3/repository/save_artifact.rb +8 -1
  22. data/app/lib/actions/pulp3/repository/update_remote.rb +7 -4
  23. data/app/lib/actions/pulp3/repository/upload_file.rb +29 -3
  24. data/app/models/katello/concerns/host_managed_extensions.rb +14 -1
  25. data/app/models/katello/content_view.rb +1 -1
  26. data/app/models/katello/content_view_repository.rb +3 -2
  27. data/app/models/katello/content_view_version.rb +5 -3
  28. data/app/models/katello/erratum.rb +2 -2
  29. data/app/models/katello/host/content_facet.rb +7 -2
  30. data/app/models/katello/repository.rb +1 -1
  31. data/app/models/katello/root_repository.rb +10 -6
  32. data/app/models/setting/content.rb +3 -1
  33. data/app/services/katello/applicability/applicable_content_helper.rb +2 -1
  34. data/app/services/katello/host/package_profile_uploader.rb +41 -0
  35. data/app/services/katello/host/profiles_uploader.rb +74 -0
  36. data/app/services/katello/pulp3/api/core.rb +4 -0
  37. data/app/services/katello/pulp3/repository/ansible_collection.rb +5 -9
  38. data/app/services/katello/pulp3/repository/yum.rb +17 -4
  39. data/app/services/katello/pulp3/repository.rb +42 -8
  40. data/app/services/katello/pulp3/repository_mirror.rb +1 -1
  41. data/app/views/katello/api/v2/repositories/show.json.rabl +1 -0
  42. data/app/views/smart_proxies/plugins/_pulpcore.html.erb +1 -1
  43. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +1 -1
  44. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/apply-errata-confirm.html +1 -2
  45. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +7 -0
  46. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +2 -2
  47. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +6 -0
  48. data/lib/katello/tasks/repository.rake +4 -3
  49. data/lib/katello/version.rb +1 -1
  50. data/locale/bn/katello.po +1 -1
  51. data/locale/bn/katello.po.time_stamp +0 -0
  52. data/locale/cs/katello.po +1 -1
  53. data/locale/cs/katello.po.time_stamp +0 -0
  54. data/locale/de/katello.po +1 -1
  55. data/locale/de/katello.po.time_stamp +0 -0
  56. data/locale/en/katello.po +1 -1
  57. data/locale/en/katello.po.time_stamp +0 -0
  58. data/locale/es/katello.po +1 -1
  59. data/locale/es/katello.po.time_stamp +0 -0
  60. data/locale/fr/katello.po +1 -1
  61. data/locale/fr/katello.po.time_stamp +0 -0
  62. data/locale/gu/katello.po +1 -1
  63. data/locale/gu/katello.po.time_stamp +0 -0
  64. data/locale/hi/katello.po +1 -1
  65. data/locale/hi/katello.po.time_stamp +0 -0
  66. data/locale/it/katello.po +1 -1
  67. data/locale/it/katello.po.time_stamp +0 -0
  68. data/locale/ja/katello.po +1 -1
  69. data/locale/ja/katello.po.time_stamp +0 -0
  70. data/locale/katello.pot +1 -1
  71. data/locale/kn/katello.po +1 -1
  72. data/locale/kn/katello.po.time_stamp +0 -0
  73. data/locale/ko/katello.po +1 -1
  74. data/locale/ko/katello.po.time_stamp +0 -0
  75. data/locale/mr/katello.po +1 -1
  76. data/locale/mr/katello.po.time_stamp +0 -0
  77. data/locale/or/katello.po +1 -1
  78. data/locale/or/katello.po.time_stamp +0 -0
  79. data/locale/pa/katello.po +1 -1
  80. data/locale/pa/katello.po.time_stamp +0 -0
  81. data/locale/pt/katello.po +1 -1
  82. data/locale/pt/katello.po.time_stamp +0 -0
  83. data/locale/pt_BR/katello.po +1 -1
  84. data/locale/pt_BR/katello.po.time_stamp +0 -0
  85. data/locale/ru/katello.po +1 -1
  86. data/locale/ru/katello.po.time_stamp +0 -0
  87. data/locale/ta/katello.po +1 -1
  88. data/locale/ta/katello.po.time_stamp +0 -0
  89. data/locale/te/katello.po +1 -1
  90. data/locale/te/katello.po.time_stamp +0 -0
  91. data/locale/zh_CN/katello.po +1 -1
  92. data/locale/zh_CN/katello.po.time_stamp +0 -0
  93. data/locale/zh_TW/katello.po +1 -1
  94. data/locale/zh_TW/katello.po.time_stamp +0 -0
  95. data/webpack/components/AddedStatusLabel.js +5 -0
  96. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +1 -1
  97. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +1 -1
  98. metadata +26 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8aa0f375342de9345f09a8a5b1cd5d7ab68af3282a4b8863cf9b63c33130fbcd
4
- data.tar.gz: 871e47ae53fdd69760c042278b9feb68a1b0d81599db67cfae9ee375a270034e
3
+ metadata.gz: '0888b27382889ee155584abcf025ee49161afc59cd18d578a7fd517d5a50dae5'
4
+ data.tar.gz: 5e488c438f3a561d2b76eaf6d657842ec117efb95d887af8f7dfa040d265e5ae
5
5
  SHA512:
6
- metadata.gz: 11757b1ba7c279ca6a6b70760996c8e81d0be8fc935ba0da3dd531beb69d00a4dadd9b113a7dd8f036ecd9d035c71a7f8ce2a5bebf4e53e8f0d9b80cccef4b92
7
- data.tar.gz: 4c9337e95fda3f0e010f9fc11c3e838f15aea5f10fae1dd17312ea067c2bb20d5f5d2b05c36fee9ce274c3916db2c866d10e321c7b9a278eb2c8543983a7e3b4
6
+ metadata.gz: 7572571d4da028a2c7d8f1822632b1629a274ad6f0f21746f345f994ae60d04c4e5f8e22f3f2c848df6c809ba497d49487ccd491b4748ca31978926ee8ec9e9f
7
+ data.tar.gz: 6ef52bd64650d97097a29590bd8602045ec9e0c72978047be9e5f998bff112314f6be1028dc06f977682daea13ca1d270c4d0d13587e56dbabba8f5ea3e66c08
@@ -15,7 +15,16 @@ module Katello
15
15
  #param :id, String, :desc => N_("UUID of the consumer"), :required => true
16
16
  def upload_package_profile
17
17
  User.as_anonymous_admin do
18
- async_task(::Actions::Katello::Host::UploadPackageProfile, @host, request.raw_post)
18
+ if Setting['upload_profiles_without_dynflow']
19
+ uploader = ::Katello::Host::PackageProfileUploader.new(
20
+ host: @host,
21
+ profile_string: request.raw_post
22
+ )
23
+ uploader.upload
24
+ uploader.trigger_applicability_generation
25
+ else
26
+ async_task(::Actions::Katello::Host::UploadPackageProfile, @host, request.raw_post)
27
+ end
19
28
  end
20
29
  render :json => Resources::Candlepin::Consumer.get(@host.subscription_facet.uuid)
21
30
  end
@@ -24,7 +33,16 @@ module Katello
24
33
  param :id, String, :desc => N_("UUID of the consumer"), :required => true
25
34
  def upload_profiles
26
35
  User.as_anonymous_admin do
27
- async_task(::Actions::Katello::Host::UploadProfiles, @host, request.raw_post)
36
+ if Setting['upload_profiles_without_dynflow']
37
+ uploader = ::Katello::Host::ProfilesUploader.new(
38
+ host: @host,
39
+ profile_string: request.raw_post
40
+ )
41
+ uploader.upload
42
+ uploader.trigger_applicability_generation
43
+ else
44
+ async_task(::Actions::Katello::Host::UploadProfiles, @host, request.raw_post)
45
+ end
28
46
  end
29
47
  render :json => Resources::Candlepin::Consumer.get(@host.subscription_facet.uuid)
30
48
  end
@@ -12,7 +12,8 @@ module Katello
12
12
  param :checksum, String, :required => false, :desc => N_("Checksum of file to upload")
13
13
  param :content_type, RepositoryTypeManager.uploadable_content_types(false).map(&:label), :required => false, :desc => N_("content type ('deb', 'docker_manifest', 'file', 'ostree', 'rpm', 'srpm')")
14
14
  def create
15
- content_type = params[:content_type] || ::Katello::RepositoryTypeManager.find(@repository.content_type).default_managed_content_type.label
15
+ fail Katello::Errors::InvalidRepositoryContent, _("Cannot upload Ansible collections.") if @repository.ansible_collection?
16
+ content_type = params[:content_type] || ::Katello::RepositoryTypeManager.find(@repository.content_type)&.default_managed_content_type&.label
16
17
  RepositoryTypeManager.check_content_matches_repo_type!(@repository, content_type)
17
18
 
18
19
  unit_type_id = SmartProxy.pulp_primary.content_service(content_type).content_type
@@ -360,6 +360,7 @@ module Katello
360
360
  param :content_type, RepositoryTypeManager.uploadable_content_types(false).map(&:label), :required => false, :desc => N_("content type ('deb', 'docker_manifest', 'file', 'ostree', 'rpm', 'srpm')")
361
361
  def upload_content
362
362
  fail Katello::Errors::InvalidRepositoryContent, _("Cannot upload Container Image content.") if @repository.docker?
363
+ fail Katello::Errors::InvalidRepositoryContent, _("Cannot upload Ansible collections.") if @repository.ansible_collection?
363
364
 
364
365
  filepaths = Array.wrap(params[:content]).compact.collect do |content|
365
366
  {path: content.path, filename: content.original_filename}
@@ -10,7 +10,7 @@ module Actions
10
10
  source_repositories.each do |repositories|
11
11
  new_repository = repositories.first.build_clone(content_view: version.content_view,
12
12
  version: version)
13
- plan_action(Repository::Create, new_repository, true)
13
+ plan_action(Repository::Create, new_repository, clone: true)
14
14
  repository_mapping[repositories] = new_repository
15
15
  end
16
16
  end
@@ -30,28 +30,14 @@ module Actions
30
30
  Dynflow::Action::Rescue::Skip
31
31
  end
32
32
 
33
- def self.upload(host_id, profile)
34
- host = ::Host.find_by(:id => host_id)
35
- if host.nil?
36
- Rails.logger.warn("Host with ID %s not found, continuing" % host_id)
37
- elsif host.content_facet.nil? || host.content_facet.uuid.nil?
38
- Rails.logger.warn("Host with ID %s has no content facet, continuing" % host_id)
39
- else
40
- begin
41
- simple_packages = profile.map { |item| ::Katello::Pulp::SimplePackage.new(item) }
42
- host.import_package_profile(simple_packages)
43
- rescue ActiveRecord::InvalidForeignKey # this happens if the host gets deleted in between the "find_by" and "import_package_profile"
44
- Rails.logger.warn("Host installed package list with ID %s was not able to be written to the DB (host likely is deleted), continuing" % host_id)
45
- end
46
- end
47
- end
48
-
49
33
  def run
50
- profile = JSON.parse(input[:profile_string])
51
- #free the huge string from the memory
52
- input[:profile_string] = 'TRIMMED'.freeze
53
- UploadPackageProfile.upload(input[:host_id], profile)
54
- ::Katello::Host::ContentFacet.trigger_applicability_generation(input[:host_id])
34
+ host = ::Host.find_by(:id => input[:host_id])
35
+ uploader = ::Katello::Host::PackageProfileUploader.new(
36
+ host: host,
37
+ profile_string: input[:profile_string]
38
+ )
39
+ uploader.upload
40
+ uploader.trigger_applicability_generation
55
41
  end
56
42
  end
57
43
  end
@@ -32,60 +32,14 @@ module Actions
32
32
  Dynflow::Action::Rescue::Skip
33
33
  end
34
34
 
35
- def import_module_streams(payload, host)
36
- enabled_payload = payload.map do |profile|
37
- profile.slice("name", "stream", "version", "context", "arch").with_indifferent_access if profile["status"] == "enabled"
38
- end
39
- enabled_payload.compact!
40
-
41
- host.import_module_streams(payload)
42
- end
43
-
44
- def import_deb_package_profile(host, profile)
45
- installed_deb_ids = profile.map do |item|
46
- ::Katello::InstalledDeb.find_or_create_by(name: item['name'], architecture: item['architecture'], version: item['version']).id
47
- end
48
- host.installed_deb_ids = installed_deb_ids
49
- host.save!
50
- rescue ActiveRecord::InvalidForeignKey # this happens if the host gets deleted in between the "find_by" and "import_package_profile"
51
- Rails.logger.warn("Host installed package list with ID %s was not able to be written to the DB (host likely is deleted), continuing" % host.id)
52
- end
53
-
54
35
  def run
55
- profiles = JSON.parse(input[:profile_string])
56
- #free the huge string from the memory
57
- input[:profile_string] = 'TRIMMED'.freeze
58
36
  host = ::Host.find_by(:id => input[:host_id])
59
- if host.nil?
60
- Rails.logger.warn("Host with ID %s not found, continuing" % input[:host_id])
61
- elsif host.content_facet.nil? || host.content_facet.uuid.nil?
62
- Rails.logger.warn("Host with ID %s has no content facet, continuing" % input[:host_id])
63
- elsif profiles.try(:has_key?, "deb_package_profile")
64
- # remove this when deb_package_profile API is removed
65
- payload = profiles.dig("deb_package_profile", "deb_packages") || []
66
- import_deb_package_profile(host, payload)
67
- else
68
- module_streams = []
69
- profiles.each do |profile|
70
- payload = profile["profile"]
71
- case profile["content_type"]
72
- when "rpm"
73
- UploadPackageProfile.upload(input[:host_id], payload)
74
- when "deb"
75
- import_deb_package_profile(host, payload)
76
- when "enabled_repos"
77
- host.import_enabled_repositories(payload)
78
- else
79
- module_streams << payload
80
- end
81
- end
82
-
83
- module_streams.each do |module_stream_payload|
84
- import_module_streams(module_stream_payload, host)
85
- end
86
-
87
- ::Katello::Host::ContentFacet.trigger_applicability_generation(host.id)
88
- end
37
+ uploader = ::Katello::Host::ProfilesUploader.new(
38
+ host: host,
39
+ profile_string: input[:profile_string]
40
+ )
41
+ uploader.upload
42
+ uploader.trigger_applicability_generation
89
43
  end
90
44
  end
91
45
  end
@@ -27,6 +27,8 @@ module Actions
27
27
  models.each do |model|
28
28
  model.joins("left join katello_#{model.repository_association} on #{model.table_name}.id = katello_#{model.repository_association}.#{model.unit_id_field}").where("katello_#{model.repository_association}.#{model.unit_id_field} IS NULL").destroy_all
29
29
  end
30
+
31
+ ::Katello::RootRepository.orphaned.destroy_all
30
32
  end
31
33
  end
32
34
  end
@@ -9,7 +9,7 @@ module Actions
9
9
 
10
10
  sequence do
11
11
  if clone.new_record?
12
- plan_action(Repository::Create, clone, true)
12
+ plan_action(Repository::Create, clone, clone: true)
13
13
  end
14
14
 
15
15
  plan_action(::Actions::Katello::Repository::CloneContents, [repository], clone, :copy_contents => !clone.yum?)
@@ -2,7 +2,9 @@ module Actions
2
2
  module Katello
3
3
  module Repository
4
4
  class Create < Actions::EntryAction
5
- def plan(repository, clone = false)
5
+ def plan(repository, args = {})
6
+ clone = args[:clone] || false
7
+ force_repo_create = args[:force_repo_create] || false
6
8
  repository.save!
7
9
  root = repository.root
8
10
 
@@ -11,7 +13,7 @@ module Actions
11
13
  org = repository.organization
12
14
  sequence do
13
15
  create_action = plan_action(Pulp3::Orchestration::Repository::Create,
14
- repository, SmartProxy.pulp_primary)
16
+ repository, SmartProxy.pulp_primary, force_repo_create)
15
17
 
16
18
  return if create_action.error
17
19
 
@@ -22,8 +24,10 @@ module Actions
22
24
  if repository.product.redhat?
23
25
  plan_action(Actions::Candlepin::Environment::AddContentToEnvironment, :view_env_cp_id => view_env.cp_id, :content_id => repository.content_id)
24
26
  else
25
- content_create = plan_action(Katello::Product::ContentCreate, root)
26
- plan_action(Actions::Candlepin::Environment::AddContentToEnvironment, :view_env_cp_id => view_env.cp_id, :content_id => content_create.input[:content_id])
27
+ unless root.content
28
+ content_create = plan_action(Katello::Product::ContentCreate, root)
29
+ plan_action(Actions::Candlepin::Environment::AddContentToEnvironment, :view_env_cp_id => view_env.cp_id, :content_id => content_create.input[:content_id])
30
+ end
27
31
  end
28
32
  end
29
33
 
@@ -10,7 +10,7 @@ module Actions
10
10
  repository.relative_path = repository.custom_repo_path
11
11
  repository.save!
12
12
  action_subject(repository)
13
- plan_action(::Actions::Katello::Repository::Create, repository, false)
13
+ plan_action(::Actions::Katello::Repository::Create, repository)
14
14
  end
15
15
 
16
16
  def humanized_name
@@ -63,7 +63,7 @@ module Actions
63
63
  def results_to_json(results)
64
64
  json_results = []
65
65
  results.each do |result|
66
- result[:pulp_tasks].each do |task|
66
+ result[:pulp_tasks]&.each do |task|
67
67
  details = task ? task.dig(:result, :details, :unit) : nil
68
68
  if details && details.dig('type_id') == 'docker_manifest'
69
69
  manifest = ::Katello::DockerManifest.find_by(:pulp_id => details.dig(:metadata, :id))
@@ -79,6 +79,11 @@ module Actions
79
79
  json_results << {:type => 'file'}
80
80
  end
81
81
  end
82
+ unless json_results.size
83
+ if result[:content_unit_href]
84
+ json_results << {:type => 'file'}
85
+ end
86
+ end
82
87
  end
83
88
  json_results
84
89
  end
@@ -21,14 +21,12 @@ module Actions
21
21
  generate_applicability = options.fetch(:generate_applicability, repository.yum?)
22
22
 
23
23
  sequence do
24
- concurrence do
25
- tmp_files.each do |file|
26
- sequence do
27
- upload_action = plan_action(Pulp3::Orchestration::Repository::UploadContent,
28
- repository, SmartProxy.pulp_primary!, file, unit_type_id)
29
-
30
- upload_actions << upload_action.output
31
- end
24
+ tmp_files.each do |file|
25
+ sequence do
26
+ upload_action = plan_action(Pulp3::Orchestration::Repository::UploadContent,
27
+ repository, SmartProxy.pulp_primary!, file, unit_type_id)
28
+
29
+ upload_actions << upload_action.output
32
30
  end
33
31
  end
34
32
 
@@ -15,7 +15,7 @@ module Actions
15
15
  fail ::Katello::Errors::ConflictException, _("The repository is already enabled")
16
16
  end
17
17
  repository = mapper.build_repository
18
- plan_action(Repository::Create, repository, false)
18
+ plan_action(Repository::Create, repository, clone: false)
19
19
  action_subject(repository)
20
20
  plan_self
21
21
  end
@@ -3,9 +3,9 @@ module Actions
3
3
  module Orchestration
4
4
  module Repository
5
5
  class Create < Pulp3::Abstract
6
- def plan(repository, smart_proxy)
6
+ def plan(repository, smart_proxy, force = false)
7
7
  sequence do
8
- create_action = plan_action(Actions::Pulp3::Repository::Create, repository, smart_proxy)
8
+ create_action = plan_action(Actions::Pulp3::Repository::Create, repository, smart_proxy, force)
9
9
  plan_action(Actions::Pulp3::Repository::SaveVersion, repository, repository_details: create_action.output[:response])
10
10
 
11
11
  if repository.content_view.default? || !smart_proxy.pulp_primary?
@@ -4,15 +4,36 @@ module Actions
4
4
  module Orchestration
5
5
  module Repository
6
6
  class ImportUpload < Pulp3::Abstract
7
+ # rubocop:disable Metrics/AbcSize
7
8
  def plan(repository, smart_proxy, args)
8
- file = {:filename => args.dig(:unit_key, :name)}
9
+ file = {:filename => args.dig(:unit_key, :name), :sha256 => args.dig(:unit_key, :checksum) }
9
10
  content_unit_href = args.dig(:unit_key, :content_unit_id)
10
11
  docker_tag = (args.dig(:unit_type_id) == "docker_tag")
11
12
  sequence do
12
13
  if content_unit_href
13
- plan_self(:commit_output => [], :content_unit_href => content_unit_href)
14
- action_output = plan_action(Pulp3::Repository::ImportUpload, content_unit_href, repository, smart_proxy).output
15
- plan_action(Pulp3::Repository::SaveVersion, repository, tasks: action_output[:pulp_tasks]).output
14
+ content_backend_service = SmartProxy.pulp_primary.content_service(args.dig(:unit_type_id))
15
+ duplicate_sha_path_content_list = content_backend_service.content_api.list(
16
+ "sha256": file[:sha256],
17
+ "relative_path": file[:filename])
18
+ duplicate_content_href = duplicate_sha_path_content_list&.results&.first&.pulp_href
19
+ if duplicate_content_href
20
+ plan_self(:commit_output => [], :content_unit_href => duplicate_content_href)
21
+ action_output = plan_action(Pulp3::Repository::ImportUpload, duplicate_content_href, repository, smart_proxy).output
22
+ plan_action(Pulp3::Repository::SaveVersion, repository, tasks: action_output[:pulp_tasks]).output
23
+ else
24
+ duplicate_sha_artifact_list = ::Katello::Pulp3::Api::Core.new(smart_proxy).artifacts_api.list("sha256": file[:sha256])
25
+ duplicate_sha_artifact_href = duplicate_sha_artifact_list&.results&.first&.pulp_href
26
+ if duplicate_sha_artifact_href
27
+ artifact_output = plan_action(Pulp3::Repository::SaveArtifact,
28
+ file, repository, smart_proxy,
29
+ nil, args.dig(:unit_type_id),
30
+ artifact_href: duplicate_sha_artifact_href).output
31
+ content_unit_href = artifact_output[:pulp_tasks]
32
+ plan_self(:commit_output => nil, :artifact_output => artifact_output[:pulp_tasks])
33
+ action_output = plan_action(Pulp3::Repository::ImportUpload, content_unit_href, repository, smart_proxy).output
34
+ plan_action(Pulp3::Repository::SaveVersion, repository, tasks: action_output[:pulp_tasks]).output
35
+ end
36
+ end
16
37
  elsif docker_tag
17
38
  tag_manifest_output = plan_action(Pulp3::Repository::UploadTag,
18
39
  repository,
@@ -7,14 +7,26 @@ module Actions
7
7
  def plan(repository, smart_proxy, file, unit_type_id)
8
8
  sequence do
9
9
  content_backend_service = SmartProxy.pulp_primary.content_service(unit_type_id)
10
- content_list = content_backend_service.content_api.list("sha256": Digest::SHA256.hexdigest(File.read(file[:path])))
11
- content_href = content_list&.results&.first&.pulp_href
10
+ duplicate_sha_path_content_list = content_backend_service.content_api.list(
11
+ "sha256": Digest::SHA256.hexdigest(File.read(file[:path])),
12
+ "relative_path": file[:filename])
13
+ duplicate_content_href = duplicate_sha_path_content_list&.results&.first&.pulp_href
12
14
 
13
- unless content_href
14
- upload_action_output = plan_action(Pulp3::Repository::UploadFile, repository, smart_proxy, file[:path]).output
15
- artifact_action_output = plan_action(Pulp3::Repository::SaveArtifact, file, repository, smart_proxy, upload_action_output[:pulp_tasks], unit_type_id).output
15
+ unless duplicate_content_href
16
+ duplicate_sha_artifact_list = ::Katello::Pulp3::Api::Core.new(smart_proxy).artifacts_api.list("sha256": Digest::SHA256.hexdigest(File.read(file[:path])))
17
+ duplicate_sha_artifact_href = duplicate_sha_artifact_list&.results&.first&.pulp_href
18
+ end
19
+
20
+ unless duplicate_content_href
21
+ if duplicate_sha_artifact_href
22
+ artifact_action_output = plan_action(Pulp3::Repository::SaveArtifact, file, repository, smart_proxy, nil, unit_type_id, artifact_href: duplicate_sha_artifact_href).output
23
+ else
24
+ upload_action_output = plan_action(Pulp3::Repository::UploadFile, repository, smart_proxy, file[:path]).output
25
+ artifact_action_output = plan_action(Pulp3::Repository::SaveArtifact, file, repository, smart_proxy, upload_action_output[:pulp_tasks], unit_type_id).output
26
+ end
16
27
  content_href = artifact_action_output[:pulp_tasks]
17
28
  end
29
+ content_href ||= duplicate_content_href
18
30
  action_output = plan_action(Pulp3::Repository::ImportUpload, content_href, repository, smart_proxy).output
19
31
  plan_action(Pulp3::Repository::SaveVersion, repository, tasks: action_output[:pulp_tasks]).output
20
32
  plan_self(:subaction_output => action_output)
@@ -10,8 +10,31 @@ module Actions
10
10
  repo = ::Katello::Repository.find(input[:repository_id])
11
11
  repo_backend_service = repo.backend_service(smart_proxy)
12
12
  uploads_api = repo_backend_service.core_api.uploads_api
13
- upload_commit = repo_backend_service.core_api.upload_commit_class.new(sha256: input[:sha256])
14
- output[:pulp_tasks] = [uploads_api.commit(input[:upload_href], upload_commit)]
13
+ duplicate_sha_artifact_list = ::Katello::Pulp3::Api::Core.new(smart_proxy).artifacts_api.list("sha256": input[:sha256])
14
+ duplicate_sha_artifact_href = duplicate_sha_artifact_list&.results&.first&.pulp_href
15
+ if duplicate_sha_artifact_href
16
+ uploads_api.delete(upload_href)
17
+ output[:artifact_href] = duplicate_sha_artifact_href
18
+ output[:pulp_tasks] = nil
19
+ else
20
+ output[:artifact_href] = nil
21
+ upload_commit = repo_backend_service.core_api.upload_commit_class.new(sha256: input[:sha256])
22
+ output[:pulp_tasks] = [uploads_api.commit(input[:upload_href], upload_commit)]
23
+ end
24
+ end
25
+
26
+ def check_for_errors
27
+ combined_tasks.each do |task|
28
+ if unique_error task.error
29
+ warn _("Duplicate artifact detected")
30
+ else
31
+ super
32
+ end
33
+ end
34
+ end
35
+
36
+ def unique_error(message)
37
+ message&.include?("code='unique'")
15
38
  end
16
39
  end
17
40
  end
@@ -2,13 +2,14 @@ module Actions
2
2
  module Pulp3
3
3
  module Repository
4
4
  class Create < Pulp3::Abstract
5
- def plan(repository, smart_proxy)
6
- plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id)
5
+ def plan(repository, smart_proxy, force = false)
6
+ plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id, :force => force)
7
7
  end
8
8
 
9
9
  def run
10
10
  repo = ::Katello::Repository.find(input[:repository_id])
11
- output[:response] = repo.backend_service(smart_proxy).with_mirror_adapter.create
11
+ force = input[:force] || false
12
+ output[:response] = repo.backend_service(smart_proxy).with_mirror_adapter.create(force)
12
13
  end
13
14
  end
14
15
  end
@@ -6,13 +6,16 @@ module Actions
6
6
  middleware.use Actions::Middleware::ExecuteIfContentsChanged
7
7
 
8
8
  def plan(repository, smart_proxy, options = {})
9
- smart_proxy = SmartProxy.find_by(id: smart_proxy) #support bulk actions
9
+ smart_proxy = SmartProxy.unscoped.find_by(id: smart_proxy) #support bulk actions
10
10
  sequence do
11
11
  if !repository.unprotected && !options[:assume_content_guard_exists]
12
12
  plan_action(::Actions::Pulp3::ContentGuard::Refresh, smart_proxy)
13
13
  end
14
14
 
15
- refresh_options = {:repository_id => repository.id, :smart_proxy_id => smart_proxy.id}
15
+ refresh_options = {
16
+ :repository_id => repository.id,
17
+ :smart_proxy_id => smart_proxy.id
18
+ }
16
19
  refresh_options[:contents_changed] if options.key?(:contents_changed)
17
20
  action = plan_self(refresh_options)
18
21