katello 4.3.0.rc2.1 → 4.3.0.rc3
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.
- checksums.yaml +4 -4
- data/app/controllers/katello/api/v2/capsule_content_controller.rb +11 -3
- data/app/controllers/katello/api/v2/content_uploads_controller.rb +1 -1
- data/app/controllers/katello/api/v2/generic_content_units_controller.rb +10 -4
- data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +8 -0
- data/app/controllers/katello/api/v2/repositories_controller.rb +35 -3
- data/app/lib/actions/katello/repository/import_upload.rb +12 -2
- data/app/lib/actions/pulp3/capsule_content/reclaim_space.rb +25 -0
- data/app/lib/actions/pulp3/orchestration/repository/import_repository_upload.rb +36 -0
- data/app/lib/actions/pulp3/orchestration/repository/import_upload.rb +1 -1
- data/app/lib/actions/pulp3/repository/commit_upload.rb +3 -1
- data/app/lib/actions/pulp3/repository/import_upload.rb +4 -2
- data/app/lib/actions/pulp3/repository/reclaim_space.rb +25 -0
- data/app/lib/actions/pulp3/repository/save_artifact.rb +12 -8
- data/app/models/katello/concerns/smart_proxy_extensions.rb +1 -1
- data/app/models/katello/pulp3/repository_reference.rb +7 -0
- data/app/models/katello/root_repository.rb +0 -1
- data/app/models/setting/content.rb +2 -8
- data/app/services/katello/pulp3/api/core.rb +16 -2
- data/app/services/katello/pulp3/content.rb +4 -2
- data/app/services/katello/pulp3/pulp_content_unit.rb +9 -3
- data/app/services/katello/pulp3/repository.rb +9 -0
- data/app/services/katello/repository_type.rb +2 -1
- data/app/views/foreman/smart_proxies/_content_sync.html.erb +10 -4
- data/app/views/foreman/smart_proxies/_reclaim_space.html.erb +12 -0
- data/app/views/foreman/smart_proxies/show.html.erb +4 -2
- data/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +2 -0
- data/config/routes/api/v2.rb +5 -0
- data/db/migrate/20211129200124_remove_dependency_solving_algorithm_setting.rb +5 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion-katello-bootstrap.js +1 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion_katello.js +3 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +21 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.factory.js +2 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/sync-state.service.js +2 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-repositories.controller.js +14 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-reclaim-space-modal.controller.js +36 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +16 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details-reclaim-space-modal.html +18 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +13 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/product-repositories-reclaim-space-modal.controller.js +35 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +3 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories-reclaim-space-modal.html +18 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +7 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/pulp-primary/pulp-primary.controller.js +35 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/pulp-primary/pulp-primary.factory.js +18 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/pulp-primary/pulp-primary.module.js +14 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/pulp-primary/pulp-primary.routes.js +16 -0
- data/lib/katello/permission_creator.rb +3 -3
- data/lib/katello/plugin.rb +4 -0
- data/lib/katello/repository_types/ostree.rb +3 -1
- data/lib/katello/tasks/upgrades/4.3/fix_url_auth.rake +25 -0
- data/lib/katello/version.rb +1 -1
- data/package.json +1 -0
- data/webpack/components/AddedStatusLabel.js +2 -1
- data/webpack/components/EditableTextInput/EditableTextInput.js +76 -17
- data/webpack/components/EditableTextInput/__tests__/editableTextInput.test.js +82 -0
- data/webpack/components/EditableTextInput/editableTextInput.scss +4 -0
- data/webpack/components/RoutedTabs/index.js +3 -1
- data/webpack/components/Table/EmptyStateMessage.js +4 -2
- data/webpack/components/Table/TableWrapper.js +3 -1
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard.js +24 -30
- data/webpack/global_index.js +10 -5
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +36 -31
- data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +8 -8
- data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +1 -8
- data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +2 -2
- data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositoryTable.js +1 -4
- data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +6 -6
- data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +11 -5
- data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +6 -9
- data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +5 -8
- data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +40 -43
- data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +2 -2
- data/webpack/scenes/ContentViews/Details/Filters/ContentType.js +4 -4
- data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +6 -8
- data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +6 -1
- data/webpack/scenes/ContentViews/Details/Filters/Rules/ContainerTag/AddEditContainerTagRuleModal.js +1 -1
- data/webpack/scenes/ContentViews/Details/Filters/Rules/Package/AddEditPackageRuleModal.js +16 -22
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +7 -7
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/ContentViewPackageGroupFilter.test.js +3 -5
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +2 -1
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErrataDateFilterContent.test.js +1 -9
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErrataIDFilter.test.js +2 -4
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvModuleStreamFilter.test.js +2 -4
- data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +3 -3
- data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +4 -0
- data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +4 -7
- data/webpack/scenes/ContentViews/Details/Repositories/LastSync.js +1 -1
- data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionContent.js +44 -41
- data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionErrata.js +4 -4
- data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +6 -2
- data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js +3 -3
- data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +2 -2
- data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +2 -1
- data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +4 -4
- data/webpack/scenes/ContentViews/components/ContentViewIcon.js +6 -2
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationForm.js +185 -0
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationForm.scss +3 -0
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +95 -266
- data/webpack/scenes/Subscriptions/Manifest/__tests__/CdnConfigurationForm.test.js +114 -0
- data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +0 -29
- data/webpack/utils/helpers.js +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa69b2700d8537140c39e127e5e94f121aeead00124eeddd6c2e7fa94e9fed32
|
4
|
+
data.tar.gz: 67ff63f7def7af9ed99bf7e73d14aa6e82cb41bd65ca73d4ec0fdd8867b2285d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b8d403df79ab4e58b40d3bb675c9908f5bae448d03e410c0fb256eaa974a043c80f8bcc371ceb9e2827311cd138f8bf209f255c3a3c295f6294af6b0799b69f
|
7
|
+
data.tar.gz: 469abe1ecd5ae6ce1117c9978fa3d9a1bf3dd2ad8e775de21bc6c61ba4d394e338ccec4b12e1d6226293189dfc2965f68c4377a6a5911130f1d723da14524516
|
@@ -4,7 +4,7 @@ module Katello
|
|
4
4
|
api_base_url "/katello/api"
|
5
5
|
end
|
6
6
|
|
7
|
-
before_action :find_capsule, :except => [:sync, :cancel_sync, :add_lifecycle_environment, :remove_lifecycle_environment]
|
7
|
+
before_action :find_capsule, :except => [:sync, :cancel_sync, :add_lifecycle_environment, :remove_lifecycle_environment, :reclaim_space]
|
8
8
|
before_action :find_editable_capsule, :only => [:sync, :cancel_sync, :add_lifecycle_environment, :remove_lifecycle_environment]
|
9
9
|
before_action :find_environment, :only => [:add_lifecycle_environment, :remove_lifecycle_environment]
|
10
10
|
before_action :find_optional_organization, :only => [:sync_status]
|
@@ -86,6 +86,14 @@ module Katello
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
api :POST, '/capsules/:id/reclaim_space', N_('Reclaim space from all On Demand repositories on a smart proxy')
|
90
|
+
param :id, :number, :required => true, :desc => N_('Id of the smart proxy')
|
91
|
+
def reclaim_space
|
92
|
+
find_capsule(true)
|
93
|
+
task = async_task(::Actions::Pulp3::CapsuleContent::ReclaimSpace, @capsule)
|
94
|
+
respond_for_async :resource => task
|
95
|
+
end
|
96
|
+
|
89
97
|
protected
|
90
98
|
|
91
99
|
def respond_for_lifecycle_environments_index(environments)
|
@@ -104,9 +112,9 @@ module Katello
|
|
104
112
|
end
|
105
113
|
end
|
106
114
|
|
107
|
-
def find_capsule
|
115
|
+
def find_capsule(primary_okay = false)
|
108
116
|
@capsule = SmartProxy.unscoped.authorized(:view_capsule_content).find(params[:id])
|
109
|
-
unless @capsule&.pulp_mirror?
|
117
|
+
unless @capsule&.pulp_mirror? || primary_okay
|
110
118
|
fail _("This request may only be performed on a Smart proxy that has the Pulpcore feature with mirror=true.")
|
111
119
|
end
|
112
120
|
end
|
@@ -10,7 +10,7 @@ module Katello
|
|
10
10
|
param :repository_id, :number, :required => true, :desc => N_("repository id")
|
11
11
|
param :size, :number, :required => true, :desc => N_("Size of file to upload")
|
12
12
|
param :checksum, String, :required => false, :desc => N_("Checksum of file to upload")
|
13
|
-
param :content_type, RepositoryTypeManager.uploadable_content_types(false).map(&:label), :required => false, :desc => N_("content type ('deb', 'docker_manifest', 'file', '
|
13
|
+
param :content_type, RepositoryTypeManager.uploadable_content_types(false).map(&:label), :required => false, :desc => N_("content type ('deb', 'docker_manifest', 'file', 'ostree_ref', 'rpm', 'srpm')")
|
14
14
|
def create
|
15
15
|
fail Katello::Errors::InvalidRepositoryContent, _("Cannot upload Ansible collections.") if @repository.ansible_collection?
|
16
16
|
content_type = params[:content_type] || ::Katello::RepositoryTypeManager.find(@repository.content_type)&.default_managed_content_type&.label
|
@@ -1,10 +1,15 @@
|
|
1
1
|
module Katello
|
2
2
|
class Api::V2::GenericContentUnitsController < Api::V2::ApiController
|
3
|
+
resource_description do
|
4
|
+
name 'Content Units'
|
5
|
+
param :content_type, String, desc: N_("Possible values: #{Katello::RepositoryTypeManager.generic_content_types.join(", ")}"), required: true
|
6
|
+
end
|
7
|
+
apipie_concern_subst(:a_resource => N_("a content unit"), :resource_id => "content_units")
|
8
|
+
|
3
9
|
Katello::RepositoryTypeManager.generic_content_types(false).each do |type|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
10
|
+
api :GET, "/#{type.pluralize}", N_("List %s" % type.pluralize)
|
11
|
+
api :GET, "/#{type.pluralize}/:id", N_("Show %s" % type.gsub(/_/, ' '))
|
12
|
+
api :GET, "/repositories/:repository_id/#{type.pluralize}/:id", N_("Show %s" % type.gsub(/_/, ' '))
|
8
13
|
end
|
9
14
|
|
10
15
|
include Katello::Concerns::Api::V2::RepositoryContentController
|
@@ -14,6 +19,7 @@ module Katello
|
|
14
19
|
end
|
15
20
|
|
16
21
|
def resource_class
|
22
|
+
fail "Required param content_type is missing" unless params[:content_type]
|
17
23
|
::Katello::GenericContentUnit.where(content_type: params[:content_type].singularize)
|
18
24
|
end
|
19
25
|
|
@@ -50,6 +50,14 @@ module Katello
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
api :POST, "/repositories/bulk/reclaim_space", N_("Reclaim space from On Demand repositories")
|
54
|
+
param :ids, Array, :desc => N_("List of repository ids"), :required => true
|
55
|
+
def reclaim_space_from_repositories
|
56
|
+
task = async_task(::Actions::Pulp3::Repository::ReclaimSpace, @repositories)
|
57
|
+
|
58
|
+
respond_for_async :resource => task
|
59
|
+
end
|
60
|
+
|
53
61
|
private
|
54
62
|
|
55
63
|
def find_repositories
|
@@ -23,7 +23,7 @@ module Katello
|
|
23
23
|
before_action :find_unauthorized_katello_resource, :only => [:gpg_key_content]
|
24
24
|
before_action :find_authorized_katello_resource, :only => [:show, :update, :destroy, :sync,
|
25
25
|
:remove_content, :upload_content, :republish,
|
26
|
-
:import_uploads, :verify_checksum]
|
26
|
+
:import_uploads, :verify_checksum, :reclaim_space]
|
27
27
|
before_action :find_content, :only => :remove_content
|
28
28
|
before_action :find_organization_from_repo, :only => [:update]
|
29
29
|
before_action :error_on_rh_product, :only => [:create]
|
@@ -234,6 +234,10 @@ module Katello
|
|
234
234
|
fail HttpErrors::UnprocessableEntity, msg
|
235
235
|
end
|
236
236
|
|
237
|
+
if !repo_params[:url].nil? && URI(repo_params[:url]).userinfo
|
238
|
+
fail "Do not include the username/password in the URL. Use the username/password settings instead."
|
239
|
+
end
|
240
|
+
|
237
241
|
gpg_key = get_content_credential(repo_params, CONTENT_CREDENTIAL_GPG_KEY_TYPE)
|
238
242
|
ssl_ca_cert = get_content_credential(repo_params, CONTENT_CREDENTIAL_SSL_CA_CERT_TYPE)
|
239
243
|
ssl_client_cert = get_content_credential(repo_params, CONTENT_CREDENTIAL_SSL_CLIENT_CERT_TYPE)
|
@@ -317,6 +321,15 @@ module Katello
|
|
317
321
|
raise HttpErrors::BadRequest, e.message
|
318
322
|
end
|
319
323
|
|
324
|
+
api :POST, "/repositories/:id/reclaim_space", N_("Reclaim space from an On Demand repository")
|
325
|
+
param :id, :number, :required => true, :desc => N_("repository ID")
|
326
|
+
def reclaim_space
|
327
|
+
task = async_task(::Actions::Pulp3::Repository::ReclaimSpace, @repository)
|
328
|
+
respond_for_async :resource => task
|
329
|
+
rescue Errors::InvalidActionOptionError => e
|
330
|
+
raise HttpErrors::BadRequest, e.message
|
331
|
+
end
|
332
|
+
|
320
333
|
api :PUT, "/repositories/:id", N_("Update a repository")
|
321
334
|
param :id, :number, :required => true, :desc => N_("repository ID")
|
322
335
|
param :name, String, :required => false
|
@@ -324,6 +337,9 @@ module Katello
|
|
324
337
|
param_group :repo
|
325
338
|
def update
|
326
339
|
repo_params = repository_params
|
340
|
+
if !repo_params[:url].nil? && URI(repo_params[:url]).userinfo
|
341
|
+
fail "Do not include the username/password in the URL. Use the username/password settings instead."
|
342
|
+
end
|
327
343
|
|
328
344
|
if @repository.generic?
|
329
345
|
generic_remote_options = generic_remote_options_hash(repo_params)
|
@@ -421,10 +437,16 @@ module Katello
|
|
421
437
|
end
|
422
438
|
|
423
439
|
begin
|
440
|
+
upload_args = {
|
441
|
+
content_type: params[:content_type],
|
442
|
+
generate_metadata: generate_metadata,
|
443
|
+
sync_capsule: sync_capsule
|
444
|
+
}
|
445
|
+
upload_args.merge!(generic_content_type_import_upload_args)
|
446
|
+
|
424
447
|
respond_for_async(resource: send(
|
425
448
|
async ? :async_task : :sync_task,
|
426
|
-
::Actions::Katello::Repository::ImportUpload, @repository, uploads,
|
427
|
-
generate_metadata: generate_metadata, sync_capsule: sync_capsule, content_type: params[:content_type]))
|
449
|
+
::Actions::Katello::Repository::ImportUpload, @repository, uploads, upload_args))
|
428
450
|
rescue => e
|
429
451
|
raise HttpErrors::BadRequest, e.message
|
430
452
|
end
|
@@ -617,6 +639,16 @@ module Katello
|
|
617
639
|
generic_remote_options
|
618
640
|
end
|
619
641
|
|
642
|
+
def generic_content_type_import_upload_args
|
643
|
+
args = {}
|
644
|
+
@repository.repository_type&.import_attributes&.collect do |import_attribute|
|
645
|
+
if params[import_attribute.api_param]
|
646
|
+
args[import_attribute.api_param] = params[import_attribute.api_param]
|
647
|
+
end
|
648
|
+
end
|
649
|
+
args
|
650
|
+
end
|
651
|
+
|
620
652
|
def check_import_parameters
|
621
653
|
@repository.repository_type&.import_attributes&.each do |import_attribute|
|
622
654
|
if import_attribute.required && params[import_attribute.api_param].blank?
|
@@ -4,6 +4,7 @@ module Actions
|
|
4
4
|
module Repository
|
5
5
|
class ImportUpload < Actions::EntryAction
|
6
6
|
include Actions::Katello::PulpSelector
|
7
|
+
# rubocop:disable Metrics/MethodLength
|
7
8
|
def plan(repository, uploads, options = {})
|
8
9
|
action_subject(repository)
|
9
10
|
repository.clear_smart_proxy_sync_histories
|
@@ -21,6 +22,7 @@ module Actions
|
|
21
22
|
else
|
22
23
|
unit_type_id = SmartProxy.pulp_primary.content_service(options[:content_type])::CONTENT_TYPE
|
23
24
|
end
|
25
|
+
content_type = ::Katello::RepositoryTypeManager.find_content_type(options[:content_type])
|
24
26
|
|
25
27
|
sequence do
|
26
28
|
upload_results = concurrence do
|
@@ -34,8 +36,15 @@ module Actions
|
|
34
36
|
unit_metadata: unit_metadata
|
35
37
|
}
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
+
import_upload_args.merge!(options)
|
40
|
+
|
41
|
+
if content_type.repository_import_on_upload
|
42
|
+
action_class = ::Actions::Pulp3::Orchestration::Repository::ImportRepositoryUpload
|
43
|
+
else
|
44
|
+
action_class = ::Actions::Pulp3::Orchestration::Repository::ImportUpload
|
45
|
+
end
|
46
|
+
|
47
|
+
import_upload = plan_action(action_class, repository, SmartProxy.pulp_primary, import_upload_args)
|
39
48
|
plan_action(FinishUpload, repository, :import_upload_task => import_upload.output,
|
40
49
|
generate_metadata: false, content_type: options[:content_type])
|
41
50
|
import_upload.output
|
@@ -46,6 +55,7 @@ module Actions
|
|
46
55
|
plan_self(repository_id: repository.id, sync_capsule: sync_capsule, upload_results: upload_results)
|
47
56
|
end
|
48
57
|
end
|
58
|
+
# rubocop:enable Metrics/MethodLength
|
49
59
|
|
50
60
|
def run
|
51
61
|
repository = ::Katello::Repository.find(input[:repository_id])
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Actions
|
2
|
+
module Pulp3
|
3
|
+
module CapsuleContent
|
4
|
+
class ReclaimSpace < Pulp3::AbstractAsyncTask
|
5
|
+
def plan(smart_proxy)
|
6
|
+
if smart_proxy.pulp_primary?
|
7
|
+
repository_hrefs = ::Katello::Pulp3::RepositoryReference.default_cv_repository_hrefs(::Katello::Repository.unscoped.on_demand, ::Organization.all)
|
8
|
+
repository_hrefs.flatten!
|
9
|
+
else
|
10
|
+
if smart_proxy.download_policy != ::Katello::RootRepository::DOWNLOAD_ON_DEMAND
|
11
|
+
fail _('Only On Demand smart proxies may have space reclaimed.')
|
12
|
+
end
|
13
|
+
repository_hrefs = ::Katello::Pulp3::Api::Core.new(smart_proxy).core_repositories_list_all(fields: 'pulp_href').map(&:pulp_href)
|
14
|
+
end
|
15
|
+
plan_self(repository_hrefs: repository_hrefs, smart_proxy_id: smart_proxy.id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def invoke_external_task
|
19
|
+
output[:pulp_tasks] = ::Katello::Pulp3::Api::Core.new(SmartProxy.find(input[:smart_proxy_id])).
|
20
|
+
repositories_reclaim_space_api.reclaim(repo_hrefs: input[:repository_hrefs])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Actions
|
2
|
+
module Pulp3
|
3
|
+
module Orchestration
|
4
|
+
module Repository
|
5
|
+
#Used for a different type of uploading where you are importing an entire repository, not a single content unit
|
6
|
+
# This workflow involves never actually creating a content unit directly, but instead importing the artifact directly into the repository
|
7
|
+
class ImportRepositoryUpload < Pulp3::Abstract
|
8
|
+
def plan(repository, smart_proxy, args)
|
9
|
+
file = {:filename => args.dig(:unit_key, :name), :sha256 => args.dig(:unit_key, :checksum) }
|
10
|
+
sequence do
|
11
|
+
upload_href = "/pulp/api/v3/uploads/#{args.dig(:upload_id)}/" if args.dig(:upload_id) && args.dig(:upload_id) != 'duplicate'
|
12
|
+
commit_output = plan_action(Pulp3::Repository::CommitUpload,
|
13
|
+
repository,
|
14
|
+
smart_proxy,
|
15
|
+
upload_href,
|
16
|
+
args.dig(:unit_key, :checksum)).output
|
17
|
+
|
18
|
+
artifact_output = plan_action(Pulp3::Repository::SaveArtifact,
|
19
|
+
file,
|
20
|
+
repository,
|
21
|
+
smart_proxy,
|
22
|
+
commit_output[:pulp_tasks],
|
23
|
+
args.dig(:unit_type_id), args).output
|
24
|
+
plan_self(:artifact_output => artifact_output)
|
25
|
+
plan_action(Pulp3::Repository::SaveVersion, repository, tasks: artifact_output[:pulp_tasks])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
output[:content_unit_href] = input[:artifact_output][:content_unit_href] || input[:artifact_output][:pulp_tasks].last[:created_resources].first
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Actions
|
2
2
|
module Pulp3
|
3
3
|
module Repository
|
4
|
+
#Creates an artifacts
|
4
5
|
class CommitUpload < Pulp3::AbstractAsyncTask
|
5
6
|
def plan(repository, smart_proxy, upload_href, sha256)
|
6
7
|
plan_self(:repository_id => repository.id, :smart_proxy_id => smart_proxy.id, :upload_href => upload_href, :sha256 => sha256)
|
@@ -10,10 +11,11 @@ module Actions
|
|
10
11
|
repo = ::Katello::Repository.find(input[:repository_id])
|
11
12
|
repo_backend_service = repo.backend_service(smart_proxy)
|
12
13
|
uploads_api = repo_backend_service.core_api.uploads_api
|
14
|
+
|
13
15
|
duplicate_sha_artifact_list = ::Katello::Pulp3::Api::Core.new(smart_proxy).artifacts_api.list("sha256": input[:sha256])
|
14
16
|
duplicate_sha_artifact_href = duplicate_sha_artifact_list&.results&.first&.pulp_href
|
15
17
|
if duplicate_sha_artifact_href
|
16
|
-
uploads_api.delete(input[:upload_href])
|
18
|
+
uploads_api.delete(input[:upload_href]) if input[:upload_href]
|
17
19
|
output[:artifact_href] = duplicate_sha_artifact_href
|
18
20
|
output[:pulp_tasks] = nil
|
19
21
|
else
|
@@ -4,10 +4,11 @@ module Actions
|
|
4
4
|
module Pulp3
|
5
5
|
module Repository
|
6
6
|
class ImportUpload < Pulp3::AbstractAsyncTask
|
7
|
-
def plan(save_artifact_output, repository, smart_proxy)
|
7
|
+
def plan(save_artifact_output, repository, smart_proxy, options = {})
|
8
8
|
plan_self(:save_artifact_output => save_artifact_output,
|
9
9
|
:repository_id => repository.id,
|
10
|
-
:smart_proxy_id => smart_proxy.id
|
10
|
+
:smart_proxy_id => smart_proxy.id,
|
11
|
+
:options => options)
|
11
12
|
end
|
12
13
|
|
13
14
|
def invoke_external_task
|
@@ -19,6 +20,7 @@ module Actions
|
|
19
20
|
|
20
21
|
repo = ::Katello::Repository.find(input[:repository_id])
|
21
22
|
repo_backend_service = repo.backend_service(smart_proxy)
|
23
|
+
|
22
24
|
output[:content_unit_href] = content_unit_href
|
23
25
|
output[:pulp_tasks] = [repo_backend_service.add_content(content_unit_href)]
|
24
26
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Actions
|
2
|
+
module Pulp3
|
3
|
+
module Repository
|
4
|
+
class ReclaimSpace < Pulp3::AbstractAsyncTask
|
5
|
+
def plan(repositories, smart_proxy = SmartProxy.pulp_primary)
|
6
|
+
repositories = [repositories] if repositories.is_a?(::Katello::Repository)
|
7
|
+
if repositories.empty?
|
8
|
+
fail _("No repositories selected.")
|
9
|
+
end
|
10
|
+
repositories = repositories.select { |repo| repo.download_policy == ::Katello::RootRepository::DOWNLOAD_ON_DEMAND }
|
11
|
+
if repositories.empty?
|
12
|
+
fail _("Only On Demand repositories may have space reclaimed.")
|
13
|
+
end
|
14
|
+
repository_hrefs = ::Katello::Pulp3::RepositoryReference.default_cv_repository_hrefs(repositories, Organization.current)
|
15
|
+
plan_self(repository_hrefs: repository_hrefs, smart_proxy_id: smart_proxy.id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def invoke_external_task
|
19
|
+
output[:pulp_tasks] = ::Katello::Pulp3::Api::Core.new(SmartProxy.find(input[:smart_proxy_id])).
|
20
|
+
repositories_reclaim_space_api.reclaim(repo_hrefs: input[:repository_hrefs])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -2,6 +2,7 @@ module Actions
|
|
2
2
|
module Pulp3
|
3
3
|
module Repository
|
4
4
|
class SaveArtifact < Pulp3::AbstractAsyncTask
|
5
|
+
#This task creates a content unit and may or may not create a new repository version in the process
|
5
6
|
def plan(file, repository, smart_proxy, tasks, unit_type_id, options = {})
|
6
7
|
options[:file_name] = file[:filename]
|
7
8
|
options[:sha256] = file[:sha256] || Digest::SHA256.hexdigest(File.read(file[:path]))
|
@@ -15,17 +16,20 @@ module Actions
|
|
15
16
|
content_type = input[:unit_type_id]
|
16
17
|
content_backend_service = SmartProxy.pulp_primary.content_service(content_type)
|
17
18
|
|
18
|
-
existing_content = ::Katello::Pulp3::PulpContentUnit.find_duplicate_unit(repository, input[
|
19
|
+
existing_content = ::Katello::Pulp3::PulpContentUnit.find_duplicate_unit(repository, input[:unit_type_id], {filename: input[:options][:file_name]}, input[:options][:sha256])
|
19
20
|
existing_content_href = existing_content&.results&.first&.pulp_href
|
20
21
|
|
21
|
-
if
|
22
|
-
output[:
|
23
|
-
[]
|
22
|
+
if ::Katello::RepositoryTypeManager.find_content_type(input[:unit_type_id]).repository_import_on_upload
|
23
|
+
output[:pulp_tasks] = [repository.backend_service(smart_proxy).repository_import_content(artifact_href, input[:options])]
|
24
24
|
else
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
if existing_content_href
|
26
|
+
output[:content_unit_href] = existing_content_href
|
27
|
+
[]
|
28
|
+
else
|
29
|
+
output[:pulp_tasks] = [content_backend_service.content_api_create(relative_path: input[:options][:file_name],
|
30
|
+
artifact: artifact_href,
|
31
|
+
content_type: content_type)]
|
32
|
+
end
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
@@ -186,7 +186,7 @@ module Katello
|
|
186
186
|
end
|
187
187
|
|
188
188
|
def pulp3_ssl_configuration(config)
|
189
|
-
legacy_pulp_cert = !self.setting(PULP3_FEATURE, 'client_authentication')&.include?('
|
189
|
+
legacy_pulp_cert = !self.setting(PULP3_FEATURE, 'client_authentication')&.include?('client_certificate')
|
190
190
|
|
191
191
|
if Faraday.default_adapter == :excon
|
192
192
|
config.ssl_client_cert = ::Cert::Certs.ssl_client_cert_filename(use_admin_as_cn_cert: legacy_pulp_cert)
|
@@ -3,6 +3,13 @@ module Katello
|
|
3
3
|
class RepositoryReference < Katello::Model
|
4
4
|
belongs_to :root_repository, :class_name => 'Katello::RootRepository'
|
5
5
|
belongs_to :content_view, :class_name => 'Katello::ContentView'
|
6
|
+
|
7
|
+
def self.default_cv_repository_hrefs(repositories, organizations)
|
8
|
+
organizations = [organizations] if organizations.is_a?(::Organization)
|
9
|
+
where(content_view_id: organizations.map(&:default_content_view).compact.pluck(:id)).
|
10
|
+
where(root_repository_id: repositories.pluck(:root_id)).
|
11
|
+
select(:repository_href).pluck(:repository_href)
|
12
|
+
end
|
6
13
|
end
|
7
14
|
end
|
8
15
|
end
|
@@ -74,7 +74,6 @@ module Katello
|
|
74
74
|
validate :ensure_valid_authentication_token, :if => :yum?
|
75
75
|
validate :ensure_valid_deb_constraints, :if => :deb?
|
76
76
|
validate :ensure_no_checksum_on_demand
|
77
|
-
validates :url, presence: true, if: :ostree?
|
78
77
|
validates :checksum_type, :inclusion => {:in => CHECKSUM_TYPES}, :allow_blank => true
|
79
78
|
validates :product_id, :presence => true
|
80
79
|
validates :content_type, :inclusion => {
|
@@ -13,7 +13,6 @@ class Setting::Content < Setting
|
|
13
13
|
download_policies = proc { hashify_parameters(::Katello::RootRepository::DOWNLOAD_POLICIES) }
|
14
14
|
|
15
15
|
proxy_download_policies = proc { hashify_parameters(::SmartProxy::DOWNLOAD_POLICIES) }
|
16
|
-
dependency_solving_options = proc { hashify_parameters(['conservative', 'greedy']) }
|
17
16
|
cdn_ssl_versions = proc { hashify_parameters(Katello::Resources::CDN::SUPPORTED_SSL_VERSIONS) }
|
18
17
|
http_proxy_select = [{
|
19
18
|
name: _("HTTP Proxies"),
|
@@ -125,12 +124,6 @@ class Setting::Content < Setting
|
|
125
124
|
self.set('content_view_solve_dependencies',
|
126
125
|
N_('The default dependency solving value for new Content Views.'),
|
127
126
|
false, N_('Content View Dependency Solving Default')),
|
128
|
-
self.set('dependency_solving_algorithm',
|
129
|
-
N_("How the logic of solving dependencies in a Content View is managed. Conservative will only add " \
|
130
|
-
"packages to solve the dependencies if the package needed doesn't exist. Greedy will pull in the " \
|
131
|
-
"latest package to solve a dependency even if it already does exist in the repository."),
|
132
|
-
'conservative', N_('Content View Dependency Solving Algorithm'), nil,
|
133
|
-
:collection => dependency_solving_options),
|
134
127
|
self.set('host_dmi_uuid_duplicates',
|
135
128
|
N_("If hosts fail to register because of duplicate DMI UUIDs " \
|
136
129
|
"add their comma-separated values here. Subsequent registrations will generate a unique DMI UUID for the affected hosts."),
|
@@ -154,7 +147,8 @@ class Setting::Content < Setting
|
|
154
147
|
self.set('bulk_load_size', N_('The number of items fetched from a single paged Pulp API call.'), 2000,
|
155
148
|
N_('Pulp bulk load size')),
|
156
149
|
self.set('upload_profiles_without_dynflow', N_('Allow Katello to update host installed packages, enabled repos, and module inventory directly instead of wrapped in Dynflow tasks (try turning off if Puma processes are using too much memory)'), true,
|
157
|
-
N_('Upload profiles without Dynflow'))
|
150
|
+
N_('Upload profiles without Dynflow')),
|
151
|
+
self.set('orphan_protection_time', N_('Time in minutes to consider orphan content as orphaned.'), 1440, N_('Orphaned Content Protection Time'))
|
158
152
|
]
|
159
153
|
end
|
160
154
|
|
@@ -55,6 +55,10 @@ module Katello
|
|
55
55
|
repository_type.distributions_api_class.new(api_client)
|
56
56
|
end
|
57
57
|
|
58
|
+
def core_repositories_api
|
59
|
+
PulpcoreClient::RepositoriesApi.new(core_api_client)
|
60
|
+
end
|
61
|
+
|
58
62
|
def repositories_api
|
59
63
|
repository_type.repositories_api_class.new(api_client)
|
60
64
|
end
|
@@ -81,6 +85,10 @@ module Katello
|
|
81
85
|
end
|
82
86
|
end
|
83
87
|
|
88
|
+
def repositories_reclaim_space_api
|
89
|
+
PulpcoreClient::RepositoriesReclaimSpaceApi.new(core_api_client)
|
90
|
+
end
|
91
|
+
|
84
92
|
def exporter_api
|
85
93
|
PulpcoreClient::ExportersPulpApi.new(core_api_client)
|
86
94
|
end
|
@@ -102,7 +110,7 @@ module Katello
|
|
102
110
|
end
|
103
111
|
|
104
112
|
def orphans_api
|
105
|
-
PulpcoreClient::
|
113
|
+
PulpcoreClient::OrphansCleanupApi.new(core_api_client)
|
106
114
|
end
|
107
115
|
|
108
116
|
def artifacts_api
|
@@ -152,7 +160,7 @@ module Katello
|
|
152
160
|
end
|
153
161
|
|
154
162
|
def delete_orphans
|
155
|
-
[orphans_api.
|
163
|
+
[orphans_api.cleanup(PulpcoreClient::OrphansCleanup.new(orphan_protection_time: Setting[:orphan_protection_time]))]
|
156
164
|
end
|
157
165
|
|
158
166
|
def delete_remote(remote_href)
|
@@ -192,6 +200,12 @@ module Katello
|
|
192
200
|
ignore_404_exception { distributions_api.delete(href) }
|
193
201
|
end
|
194
202
|
|
203
|
+
def core_repositories_list_all(options = {})
|
204
|
+
self.class.fetch_from_list do |page_opts|
|
205
|
+
core_repositories_api.list(page_opts.merge(options))
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
195
209
|
def list_all(options = {})
|
196
210
|
self.class.fetch_from_list do |page_opts|
|
197
211
|
repositories_api.list(page_opts.merge(options))
|
@@ -6,10 +6,12 @@ module Katello
|
|
6
6
|
class << self
|
7
7
|
def create_upload(size = 0, checksum = nil, content_type = nil, repository = nil)
|
8
8
|
content_unit_href = nil
|
9
|
-
|
9
|
+
content_type = ::Katello::RepositoryTypeManager.find_content_type(content_type)
|
10
|
+
|
11
|
+
if checksum && !content_type.repository_import_on_upload
|
10
12
|
content_backend_service = SmartProxy.pulp_primary.content_service(content_type)
|
11
13
|
if repository&.generic?
|
12
|
-
content_list = content_backend_service.content_api(repository.repository_type, content_type).list(
|
14
|
+
content_list = content_backend_service.content_api(repository.repository_type, content_type).list('sha256': checksum)
|
13
15
|
else
|
14
16
|
content_list = content_backend_service.content_api.list("sha256": checksum)
|
15
17
|
end
|
@@ -116,24 +116,30 @@ module Katello
|
|
116
116
|
content_unit_list page_opts
|
117
117
|
end
|
118
118
|
|
119
|
+
# rubocop:disable Lint/UselessAssignment
|
119
120
|
def self.find_duplicate_unit(repository, unit_type_id, file, checksum)
|
121
|
+
filter_label = 'sha256'
|
122
|
+
if unit_type_id == 'ostree_ref'
|
123
|
+
filter_label = 'checksum'
|
124
|
+
end
|
120
125
|
content_backend_service = SmartProxy.pulp_primary.content_service(unit_type_id)
|
121
126
|
duplicates_allowed = ::Katello::RepositoryTypeManager.find_content_type(unit_type_id).try(:duplicates_allowed)
|
122
127
|
if repository.generic? && duplicates_allowed
|
123
128
|
filename_key = ::Katello::RepositoryTypeManager.find_content_type(unit_type_id).filename_key
|
124
129
|
duplicate_sha_path_content_list = content_backend_service.content_api(repository.repository_type, unit_type_id).list(
|
125
|
-
|
130
|
+
filter_label: checksum,
|
126
131
|
filename_key => file[:filename])
|
127
132
|
elsif repository.generic?
|
128
133
|
duplicate_sha_path_content_list = content_backend_service.content_api(repository.repository_type, unit_type_id).list(
|
129
|
-
|
134
|
+
filter_label: checksum)
|
130
135
|
else
|
131
136
|
duplicate_sha_path_content_list = content_backend_service.content_api.list(
|
132
|
-
|
137
|
+
filter_label: checksum,
|
133
138
|
"relative_path": file[:filename])
|
134
139
|
end
|
135
140
|
duplicate_sha_path_content_list
|
136
141
|
end
|
142
|
+
# rubocop:enable Lint/UselessAssignment
|
137
143
|
end
|
138
144
|
end
|
139
145
|
end
|
@@ -478,6 +478,15 @@ module Katello
|
|
478
478
|
end
|
479
479
|
end
|
480
480
|
|
481
|
+
def repository_import_content(artifact_href, options = {})
|
482
|
+
ostree_import = PulpOstreeClient::OstreeRepoImport.new
|
483
|
+
ostree_import.artifact = artifact_href
|
484
|
+
ostree_import.repository_name = options[:ostree_repository_name]
|
485
|
+
ostree_import.ref = options[:ostree_ref]
|
486
|
+
ostree_import.parent_commit = options[:ostree_parent_commit]
|
487
|
+
api.repositories_api.import_commits(repository_reference.repository_href, ostree_import)
|
488
|
+
end
|
489
|
+
|
481
490
|
def add_content(content_unit_href, remove_all_units = false)
|
482
491
|
content_unit_href = [content_unit_href] unless content_unit_href.is_a?(Array)
|
483
492
|
if remove_all_units
|
@@ -145,7 +145,7 @@ module Katello
|
|
145
145
|
|
146
146
|
class ContentType
|
147
147
|
attr_accessor :model_class, :priority, :pulp2_service_class, :pulp3_service_class, :index, :uploadable, :removable,
|
148
|
-
:primary_content, :index_on_pulp3, :generic_browser, :content_type
|
148
|
+
:primary_content, :index_on_pulp3, :generic_browser, :content_type, :repository_import_on_upload
|
149
149
|
|
150
150
|
def initialize(options)
|
151
151
|
self.model_class = options[:model_class]
|
@@ -159,6 +159,7 @@ module Katello
|
|
159
159
|
self.removable = options[:removable] || false
|
160
160
|
self.primary_content = options[:primary_content] || false
|
161
161
|
self.generic_browser = options[:generic_browser]
|
162
|
+
self.repository_import_on_upload = options[:repository_import_on_upload]
|
162
163
|
end
|
163
164
|
|
164
165
|
def label
|