katello 3.9.1 → 3.10.0.rc1
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/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js +28 -12
- data/app/controllers/katello/api/rhsm/candlepin_dynflow_proxy_controller.rb +12 -3
- data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +4 -13
- data/app/controllers/katello/api/v2/content_credentials_controller.rb +1 -1
- data/app/controllers/katello/api/v2/content_view_filter_rules_controller.rb +1 -1
- data/app/controllers/katello/api/v2/content_view_versions_controller.rb +6 -4
- data/app/controllers/katello/api/v2/content_views_controller.rb +8 -3
- data/app/controllers/katello/api/v2/gpg_keys_controller.rb +2 -1
- data/app/controllers/katello/api/v2/host_module_streams_controller.rb +39 -0
- data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +20 -11
- data/app/controllers/katello/api/v2/module_streams_controller.rb +2 -1
- data/app/controllers/katello/api/v2/repository_sets_controller.rb +17 -8
- data/app/controllers/katello/application_controller.rb +0 -2
- data/app/controllers/katello/concerns/hosts_controller_extensions.rb +5 -2
- data/app/lib/actions/candlepin/consumer/attach_subscription.rb +0 -2
- data/app/lib/actions/candlepin/consumer/remove_subscription.rb +0 -2
- data/app/lib/actions/katello/capsule_content/create_repos.rb +1 -25
- data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
- data/app/lib/actions/katello/content_view/promote.rb +2 -5
- data/app/lib/actions/katello/content_view/promote_to_environment.rb +2 -5
- data/app/lib/actions/katello/content_view/publish.rb +1 -4
- data/app/lib/actions/katello/content_view_puppet_environment/create.rb +6 -10
- data/app/lib/actions/katello/content_view_version/export.rb +0 -2
- data/app/lib/actions/katello/content_view_version/incremental_update.rb +19 -1
- data/app/lib/actions/katello/environment/publish_repositories.rb +2 -1
- data/app/lib/actions/katello/gpg_key/update.rb +17 -0
- data/app/lib/actions/katello/host/attach_subscriptions.rb +0 -2
- data/app/lib/actions/katello/host/erratum/install.rb +6 -0
- data/app/lib/actions/katello/host/generate_applicability.rb +0 -2
- data/app/lib/actions/katello/host/hypervisors_update.rb +11 -6
- data/app/lib/actions/katello/host/package/install.rb +6 -0
- data/app/lib/actions/katello/host/package/remove.rb +6 -0
- data/app/lib/actions/katello/host/package/update.rb +7 -1
- data/app/lib/actions/katello/host/package_group/install.rb +6 -0
- data/app/lib/actions/katello/host/package_group/remove.rb +6 -0
- data/app/lib/actions/katello/host/recalculate_errata_status.rb +0 -2
- data/app/lib/actions/katello/host/remove_subscriptions.rb +0 -2
- data/app/lib/actions/katello/host/update.rb +1 -0
- data/app/lib/actions/katello/host/update_content_overrides.rb +0 -2
- data/app/lib/actions/katello/host/upload_package_profile.rb +13 -12
- data/app/lib/actions/katello/host/upload_profiles.rb +70 -0
- data/app/lib/actions/katello/product/reindex_subscriptions.rb +0 -2
- data/app/lib/actions/katello/product/repositories_certs_reset.rb +4 -4
- data/app/lib/actions/katello/product/repositories_gpg_reset.rb +2 -2
- data/app/lib/actions/katello/repository/check_matching_content.rb +18 -6
- data/app/lib/actions/katello/repository/clone_deb_content.rb +1 -1
- data/app/lib/actions/katello/repository/clone_to_environment.rb +3 -5
- data/app/lib/actions/katello/repository/clone_to_version.rb +2 -3
- data/app/lib/actions/katello/repository/clone_yum_content.rb +1 -2
- data/app/lib/actions/katello/repository/clone_yum_metadata.rb +2 -2
- data/app/lib/actions/katello/repository/create.rb +1 -31
- data/app/lib/actions/katello/repository/destroy.rb +1 -2
- data/app/lib/actions/katello/repository/export.rb +0 -2
- data/app/lib/actions/katello/repository/fetch_pxe_files.rb +0 -2
- data/app/lib/actions/katello/repository/filtered_index_content.rb +0 -2
- data/app/lib/actions/katello/repository/finish_upload.rb +0 -2
- data/app/lib/actions/katello/repository/import_upload.rb +0 -2
- data/app/lib/actions/katello/repository/index_content.rb +0 -1
- data/app/lib/actions/katello/repository/index_package_groups.rb +0 -2
- data/app/lib/actions/katello/repository/instance_update.rb +21 -0
- data/app/lib/actions/katello/repository/remove_content.rb +0 -2
- data/app/lib/actions/katello/repository/sync.rb +0 -1
- data/app/lib/actions/katello/repository/update.rb +0 -2
- data/app/lib/actions/katello/upstream_subscriptions/bind_entitlement.rb +0 -2
- data/app/lib/actions/katello/upstream_subscriptions/bind_entitlements.rb +0 -2
- data/app/lib/actions/katello/upstream_subscriptions/remove_entitlement.rb +0 -1
- data/app/lib/actions/katello/upstream_subscriptions/remove_entitlements.rb +0 -2
- data/app/lib/actions/katello/upstream_subscriptions/update_entitlement.rb +0 -1
- data/app/lib/actions/katello/upstream_subscriptions/update_entitlements.rb +0 -2
- data/app/lib/actions/pulp/abstract.rb +13 -14
- data/app/lib/actions/pulp/repository/create.rb +13 -211
- data/app/lib/actions/pulp/repository/create_in_plan.rb +4 -18
- data/app/lib/actions/pulp/repository/refresh.rb +7 -70
- data/app/lib/actions/pulp/repository/sync.rb +1 -2
- data/app/lib/katello/capsule_content.rb +3 -3
- data/app/lib/katello/resources/candlepin/consumer.rb +1 -1
- data/app/lib/katello/resources/candlepin/product.rb +1 -1
- data/app/lib/katello/validators/hostgroup_kickstart_repository_validator.rb +1 -1
- data/app/models/katello/available_module_stream.rb +11 -0
- data/app/models/katello/concerns/content_facet_host_extensions.rb +1 -0
- data/app/models/katello/concerns/host_managed_extensions.rb +56 -0
- data/app/models/katello/concerns/hostgroup_extensions.rb +17 -0
- data/app/models/katello/concerns/redhat_extensions.rb +20 -6
- data/app/models/katello/concerns/search_by_repository_name.rb +0 -1
- data/app/models/katello/concerns/smart_proxy_extensions.rb +26 -12
- data/app/models/katello/content_facet_applicable_module_stream.rb +7 -0
- data/app/models/katello/content_view_puppet_environment.rb +14 -35
- data/app/models/katello/erratum.rb +54 -24
- data/app/models/katello/erratum_package.rb +6 -0
- data/app/models/katello/glue/pulp/repo.rb +5 -228
- data/app/models/katello/gpg_key.rb +1 -0
- data/app/models/katello/host/content_facet.rb +38 -83
- data/app/models/katello/host_available_module_stream.rb +47 -0
- data/app/models/katello/module_stream.rb +18 -0
- data/app/models/katello/module_stream_erratum_package.rb +6 -0
- data/app/models/katello/product.rb +0 -2
- data/app/models/katello/product_content.rb +1 -0
- data/app/models/katello/repository.rb +15 -6
- data/app/models/katello/root_repository.rb +1 -1
- data/app/models/katello/rpm.rb +5 -17
- data/app/services/katello/applicable_content_helper.rb +111 -0
- data/app/services/katello/managed_content_medium_provider.rb +7 -0
- data/app/services/katello/pulp/consumer.rb +13 -7
- data/app/services/katello/pulp/repository.rb +157 -4
- data/app/services/katello/pulp/repository/deb.rb +47 -0
- data/app/services/katello/pulp/repository/docker.rb +43 -0
- data/app/services/katello/pulp/repository/file.rb +31 -0
- data/app/services/katello/pulp/repository/ostree.rb +40 -0
- data/app/services/katello/pulp/repository/puppet.rb +43 -0
- data/app/services/katello/pulp/repository/yum.rb +61 -0
- data/app/services/katello/repository_type.rb +1 -1
- data/app/views/katello/api/v2/content_facet/base.json.rabl +1 -0
- data/app/views/katello/api/v2/content_view_versions/base.json.rabl +0 -1
- data/app/views/katello/api/v2/errata/_counts.json.rabl +0 -1
- data/app/views/katello/api/v2/errata/show.json.rabl +9 -3
- data/app/views/katello/api/v2/host_collections/delta_activation_keys.rabl +0 -1
- data/app/views/katello/api/v2/host_module_streams/base.json.rabl +8 -0
- data/app/views/katello/api/v2/host_module_streams/index.json.rabl +7 -0
- data/app/views/katello/api/v2/packages/backend.json.rabl +0 -1
- data/app/views/katello/api/v2/repositories/show.json.rabl +6 -6
- data/app/views/katello/layouts/react.html.erb +2 -2
- data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +0 -1
- data/config/routes/api/rhsm.rb +1 -0
- data/config/routes/overrides.rb +4 -0
- data/db/migrate/20181008201422_add_modules_to_errata_packages.rb +29 -0
- data/db/migrate/20181017181806_available_module_streams.rb +34 -0
- data/db/migrate/20181027014323_add_applicable_modules.rb +24 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/module-stream-actions.service.js +2 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-info.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/views/new-content-credential.html +1 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-host-bulk-module-streams-modal.html +2 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-errata-modal.html +37 -22
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +4 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +27 -7
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-module-streams.html +29 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/errata-details.html +15 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-promotion.controller.js +0 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-publish.controller.js +1 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/content-view-versions.controller.js +3 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/histories/content-view-history.controller.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-promotion.html +0 -15
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-publish.html +0 -14
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum.controller.js +19 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-info.html +0 -12
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-packages.html +36 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum.html +7 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/errata.routes.js +9 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-module-streams.factory.js +18 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +4 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +2 -2
- data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +13 -0
- data/lib/katello/permissions/host_permissions.rb +3 -0
- data/lib/katello/repository_types/deb.rb +3 -1
- data/lib/katello/repository_types/docker.rb +3 -1
- data/lib/katello/repository_types/file.rb +1 -0
- data/lib/katello/repository_types/ostree.rb +3 -1
- data/lib/katello/repository_types/puppet.rb +3 -1
- data/lib/katello/repository_types/yum.rb +3 -1
- data/lib/katello/tasks/delete_orphaned_content.rake +1 -1
- data/lib/katello/tasks/reset.rake +1 -0
- data/lib/katello/tasks/test.rake +14 -0
- data/lib/katello/tasks/unify_hosts.rake +2 -0
- data/lib/katello/tasks/virt_who_report.rake +2 -1
- data/lib/katello/version.rb +1 -1
- data/locale/Makefile +52 -17
- data/locale/update-i18n +22 -0
- data/package.json +11 -1
- data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +8 -0
- data/webpack/move_to_foreman/components/common/table/components/Table.js +2 -1
- data/webpack/move_to_pf/react-bootstrap-select/index.js +4 -2
- data/webpack/move_to_pf/test-utils/testHelpers.js +9 -0
- data/webpack/redux/OrganizationProducts/OrganizationProductsActions.js +24 -0
- data/webpack/redux/OrganizationProducts/OrganizationProductsConstants.js +5 -0
- data/webpack/redux/OrganizationProducts/OrganizationProductsReducer.js +38 -0
- data/webpack/redux/OrganizationProducts/OrganizationProductsSelectors.js +7 -0
- data/webpack/redux/OrganizationProducts/__tests__/OrganizationProductsActions.test.js +47 -0
- data/webpack/redux/OrganizationProducts/__tests__/OrganizationProductsReducer.test.js +33 -0
- data/webpack/redux/OrganizationProducts/__tests__/OrganizationProductsSelectors.test.js +19 -0
- data/webpack/redux/OrganizationProducts/__tests__/__snapshots__/OrganizationProductsActions.test.js.snap +49 -0
- data/webpack/redux/OrganizationProducts/__tests__/__snapshots__/OrganizationProductsReducer.test.js.snap +36 -0
- data/webpack/redux/OrganizationProducts/__tests__/__snapshots__/OrganizationProductsSelectors.test.js.snap +9 -0
- data/webpack/redux/OrganizationProducts/index.js +13 -0
- data/webpack/redux/actions/RedHatRepositories/enabled.js +7 -1
- data/webpack/redux/actions/RedHatRepositories/helpers.js +4 -0
- data/webpack/redux/actions/RedHatRepositories/sets.js +2 -0
- data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +8 -2
- data/webpack/redux/reducers/RedHatRepositories/enabled.js +1 -1
- data/webpack/redux/reducers/RedHatRepositories/sets.fixtures.js +12 -3
- data/webpack/redux/reducers/index.js +2 -0
- data/webpack/scenes/RedHatRepositories/components/SearchBar.js +68 -33
- data/webpack/scenes/RedHatRepositories/index.js +13 -2
- data/webpack/scenes/RedHatRepositories/index.scss +26 -0
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +1 -1
- data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +1 -1
- data/webpack/scenes/Subscriptions/SubscriptionActions.js +18 -2
- data/webpack/scenes/Subscriptions/SubscriptionConstants.js +8 -0
- data/webpack/scenes/Subscriptions/SubscriptionHelpers.js +15 -0
- data/webpack/scenes/Subscriptions/SubscriptionReducer.js +22 -14
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +39 -90
- data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +14 -0
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +1 -3
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +0 -1
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionHelpers.test.js +84 -0
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +26 -1
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +5 -0
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +177 -75
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsSelectors.test.js +29 -0
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionHelpers.test.js.snap +31 -0
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +32 -0
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +18 -96
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsReducer.test.js.snap +511 -0
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsSelectors.test.js.snap +26 -0
- data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +6 -1
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +3 -21
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +113 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.test.js +47 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap +504 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/index.js +1 -0
- data/webpack/scenes/Subscriptions/index.js +15 -4
- metadata +59 -14
- data/app/lib/actions/pulp/repository/associate_distributor.rb +0 -20
- data/app/lib/actions/pulp/repository/associate_importer.rb +0 -23
- data/app/lib/actions/pulp/repository/delete_distributor.rb +0 -18
- data/app/lib/actions/pulp/repository/refresh_distributor.rb +0 -19
- data/app/lib/actions/pulp/repository/update_importer.rb +0 -33
- data/app/lib/katello/bulk_actions.rb +0 -63
- data/webpack/move_to_foreman/components/common/EmptyState/index.js +0 -68
@@ -0,0 +1,47 @@
|
|
1
|
+
module Katello
|
2
|
+
class HostAvailableModuleStream < Katello::Model
|
3
|
+
belongs_to :host, :inverse_of => :host_available_module_streams, :class_name => '::Host::Managed'
|
4
|
+
belongs_to :available_module_stream, :inverse_of => :host_available_module_streams, :class_name => 'Katello::AvailableModuleStream'
|
5
|
+
serialize :installed_profiles
|
6
|
+
|
7
|
+
scope :installed, -> { enabled.where.not(installed_profiles: []) }
|
8
|
+
scope :enabled, -> { where(status: ENABLED) }
|
9
|
+
scope :disabled, -> { where(status: DISABLED) }
|
10
|
+
scope :unknown, -> { where(status: UNKNOWN) }
|
11
|
+
|
12
|
+
ENABLED = "enabled".freeze
|
13
|
+
DISABLED = "disabled".freeze
|
14
|
+
UNKNOWN = "unknown".freeze
|
15
|
+
INSTALLED = "installed".freeze
|
16
|
+
UPGRADABLE = "upgradable".freeze
|
17
|
+
|
18
|
+
STATUS = [ENABLED, DISABLED, UNKNOWN].freeze
|
19
|
+
|
20
|
+
API_STATES = {
|
21
|
+
ENABLED => :enabled,
|
22
|
+
DISABLED => :disabled,
|
23
|
+
UNKNOWN => :unknown,
|
24
|
+
INSTALLED => :installed,
|
25
|
+
UPGRADABLE => :upgradable
|
26
|
+
}.with_indifferent_access
|
27
|
+
|
28
|
+
scoped_search :on => :name, :relation => :available_module_stream, :complete_value => true
|
29
|
+
scoped_search :on => :stream, :relation => :available_module_stream, :complete_value => false
|
30
|
+
scoped_search :on => :status, :complete_value => STATUS
|
31
|
+
|
32
|
+
def upgradable?
|
33
|
+
return false if status != ENABLED
|
34
|
+
|
35
|
+
ApplicableContentHelper.new(ModuleStream).installable_for_hosts([host_id]).
|
36
|
+
where(ModuleStream.table_name => {:name => available_module_stream.name,
|
37
|
+
:stream => available_module_stream.stream}).exists?
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.upgradable(host)
|
41
|
+
upgradable_module_name_streams = ApplicableContentHelper.new(ModuleStream).installable_for_hosts([host]).select(:name, :stream)
|
42
|
+
|
43
|
+
enabled.joins(:available_module_stream).where(:host_id => host).
|
44
|
+
where("(#{AvailableModuleStream.table_name}.name, #{AvailableModuleStream.table_name}.stream) in (#{upgradable_module_name_streams.to_sql})")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -7,6 +7,12 @@ module Katello
|
|
7
7
|
has_many :repositories, through: :repository_module_streams, class_name: "Katello::Repository"
|
8
8
|
has_many :profiles, class_name: "Katello::ModuleProfile", dependent: :destroy, inverse_of: :module_stream
|
9
9
|
has_many :artifacts, class_name: "Katello::ModuleStreamArtifact", dependent: :destroy, inverse_of: :module_stream
|
10
|
+
has_many :module_stream_errata_packages, class_name: "Katello::ModuleStreamErratumPackage", dependent: :destroy, inverse_of: :module_stream
|
11
|
+
has_many :erratum_packages, class_name: "Katello::ErratumPackage", :through => :module_stream_errata_packages
|
12
|
+
|
13
|
+
has_many :content_facet_applicable_module_streams, :class_name => "Katello::ContentFacetApplicableModuleStream",
|
14
|
+
:dependent => :destroy, :inverse_of => :module_stream
|
15
|
+
has_many :content_facets, :through => :content_facet_applicable_module_streams, :class_name => "Katello::Host::ContentFacet"
|
10
16
|
|
11
17
|
scoped_search on: :name, complete_value: true
|
12
18
|
scoped_search on: :uuid, complete_value: true
|
@@ -36,6 +42,14 @@ module Katello
|
|
36
42
|
RepositoryModuleStream
|
37
43
|
end
|
38
44
|
|
45
|
+
def self.content_facet_association_class
|
46
|
+
ContentFacetApplicableModuleStream
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.installable_for_hosts(hosts = nil)
|
50
|
+
ApplicableContentHelper.new(ModuleStream).installable_for_hosts(hosts)
|
51
|
+
end
|
52
|
+
|
39
53
|
def update_from_json(json)
|
40
54
|
shared_attributes = json.keys & self.class.column_names
|
41
55
|
shared_json = json.select { |key, _v| shared_attributes.include?(key) }
|
@@ -83,6 +97,10 @@ module Katello
|
|
83
97
|
items.join(":")
|
84
98
|
end
|
85
99
|
|
100
|
+
def module_spec_hash
|
101
|
+
{:name => name, :stream => stream, :version => version, :context => context, :arch => arch, :id => id}.compact
|
102
|
+
end
|
103
|
+
|
86
104
|
def self.parse_module_spec(module_spec)
|
87
105
|
# NAME:STREAM:VERSION:CONTEXT:ARCH/PROFILE
|
88
106
|
spec = module_spec.split("/").first
|
@@ -0,0 +1,6 @@
|
|
1
|
+
module Katello
|
2
|
+
class ModuleStreamErratumPackage < Katello::Model
|
3
|
+
belongs_to :module_stream, class_name: "Katello::ModuleStream", inverse_of: :module_stream_errata_packages
|
4
|
+
belongs_to :erratum_package, class_name: "Katello::ErratumPackage", inverse_of: :module_stream_errata_packages
|
5
|
+
end
|
6
|
+
end
|
@@ -22,6 +22,7 @@ module Katello
|
|
22
22
|
scoped_search :on => :content_type, :relation => :content
|
23
23
|
scoped_search :on => :label, :relation => :content
|
24
24
|
scoped_search :on => :name, :relation => :product, :rename => :product_name
|
25
|
+
scoped_search :on => :id, :relation => :product, :rename => :product_id, :only_explicit => true
|
25
26
|
|
26
27
|
def self.content_table_name
|
27
28
|
Katello::Content.table_name
|
@@ -96,7 +96,10 @@ module Katello
|
|
96
96
|
|
97
97
|
validates_with Validators::ContainerImageNameValidator, :attributes => :container_repository_name, :allow_blank => false, :if => :docker?
|
98
98
|
validates :pulp_id, :presence => true, :uniqueness => true, :if => proc { |r| r.name.present? }
|
99
|
-
validates :container_repository_name, :
|
99
|
+
validates :container_repository_name, :if => :docker?, :uniqueness => {message: ->(object, _data) do
|
100
|
+
_("for repository '%{name}' is not unique and cannot be created in '%{env}'. Its Container Repository Name (%{container_name}) conflicts with an existing repository. Consider changing the Lifecycle Environment's Registry Name Pattern to something more specific.") %
|
101
|
+
{name: object.name, container_name: object.container_repository_name, :env => object.environment.name}
|
102
|
+
end}
|
100
103
|
|
101
104
|
before_validation :set_pulp_id
|
102
105
|
before_validation :set_container_repository_name, :if => :docker?
|
@@ -134,12 +137,14 @@ module Katello
|
|
134
137
|
scoped_search :on => :redhat, :complete_value => { :true => true, :false => false }, :ext_method => :search_by_redhat
|
135
138
|
scoped_search :on => :container_repository_name, :complete_value => true
|
136
139
|
scoped_search :on => :description, :relation => :root, :only_explicit => true
|
140
|
+
scoped_search :on => :name, :relation => :product, :rename => :product_name
|
141
|
+
scoped_search :on => :id, :relation => :product, :rename => :product_id, :only_explicit => true
|
137
142
|
|
138
143
|
delegate :product, :redhat?, :custom?, :to => :root
|
139
144
|
delegate :yum?, :docker?, :puppet?, :deb?, :file?, :ostree?, :to => :root
|
140
145
|
delegate :name, :label, :docker_upstream_name, :url, :to => :root
|
141
146
|
|
142
|
-
delegate :name, :created_at, :updated_at, :major, :minor, :gpg_key_id, :content_id, :arch, :label, :url, :unprotected,
|
147
|
+
delegate :name, :created_at, :updated_at, :major, :minor, :gpg_key_id, :gpg_key, :content_id, :arch, :label, :url, :unprotected,
|
143
148
|
:content_type, :product_id, :checksum_type, :docker_upstream_name, :mirror_on_sync, :"mirror_on_sync?",
|
144
149
|
:download_policy, :verify_ssl_on_sync, :"verify_ssl_on_sync?", :upstream_username, :upstream_password,
|
145
150
|
:ostree_upstream_sync_policy, :ostree_upstream_sync_depth, :deb_releases, :deb_components, :deb_architectures,
|
@@ -150,6 +155,10 @@ module Katello
|
|
150
155
|
joins(:root).where("#{RootRepository.table_name}.content_type" => content_type)
|
151
156
|
end
|
152
157
|
|
158
|
+
def backend_service(smart_proxy)
|
159
|
+
@service ||= Katello::Pulp::Repository.instance_for_type(self, smart_proxy)
|
160
|
+
end
|
161
|
+
|
153
162
|
def organization
|
154
163
|
if self.environment
|
155
164
|
self.environment.organization
|
@@ -278,6 +287,10 @@ module Katello
|
|
278
287
|
all_instances
|
279
288
|
end
|
280
289
|
|
290
|
+
def to_hash(content_source = nil)
|
291
|
+
{id: id, name: label, url: full_path(content_source)}
|
292
|
+
end
|
293
|
+
|
281
294
|
#is the repo cloned in the specified environment
|
282
295
|
def cloned_in?(env)
|
283
296
|
!get_clone(env).nil?
|
@@ -481,10 +494,6 @@ module Katello
|
|
481
494
|
self.ostree_branches.map(&:name)
|
482
495
|
end
|
483
496
|
|
484
|
-
def ostree_capsule_sync_depth
|
485
|
-
-1
|
486
|
-
end
|
487
|
-
|
488
497
|
def units_for_removal(ids)
|
489
498
|
table_name = removable_unit_association.table_name
|
490
499
|
is_integer = Integer(ids.first) rescue false #assume all ids are either integers or not
|
@@ -235,7 +235,7 @@ module Katello
|
|
235
235
|
changeable_attributes = %w(url unprotected checksum_type docker_upstream_name download_policy mirror_on_sync verify_ssl_on_sync
|
236
236
|
upstream_username upstream_password ostree_upstream_sync_policy ostree_upstream_sync_depth ignore_global_proxy ignorable_content)
|
237
237
|
changeable_attributes += %w(name container_repository_name) if docker?
|
238
|
-
changeable_attributes += %w(deb_releases deb_components deb_architectures) if deb?
|
238
|
+
changeable_attributes += %w(deb_releases deb_components deb_architectures gpg_key_id) if deb?
|
239
239
|
changeable_attributes.any? { |key| previous_changes.key?(key) }
|
240
240
|
end
|
241
241
|
|
data/app/models/katello/rpm.rb
CHANGED
@@ -31,6 +31,10 @@ module Katello
|
|
31
31
|
RepositoryRpm
|
32
32
|
end
|
33
33
|
|
34
|
+
def self.content_facet_association_class
|
35
|
+
ContentFacetApplicableRpm
|
36
|
+
end
|
37
|
+
|
34
38
|
def self.scoped_search_version(_key, operator, value)
|
35
39
|
self.scoped_search_sortable('version', operator, value)
|
36
40
|
end
|
@@ -222,23 +226,7 @@ module Katello
|
|
222
226
|
end
|
223
227
|
|
224
228
|
def self.installable_for_hosts(hosts = nil)
|
225
|
-
|
226
|
-
|
227
|
-
query = Katello::Rpm.joins(:content_facet_applicable_rpms).
|
228
|
-
joins("INNER JOIN #{Katello::ContentFacetRepository.table_name} on \
|
229
|
-
#{Katello::ContentFacetRepository.table_name}.content_facet_id = #{Katello::ContentFacetApplicableRpm.table_name}.content_facet_id").
|
230
|
-
joins("INNER JOIN #{Katello::RepositoryRpm.table_name} AS host_repo_rpm ON \
|
231
|
-
host_repo_rpm.rpm_id = #{Katello::Rpm.table_name}.id AND \
|
232
|
-
#{Katello::ContentFacetRepository.table_name}.repository_id = host_repo_rpm.repository_id")
|
233
|
-
|
234
|
-
if hosts
|
235
|
-
query = query.where("#{Katello::ContentFacetRepository.table_name}.content_facet_id" => hosts.joins(:content_facet)
|
236
|
-
.select("#{Katello::Host::ContentFacet.table_name}.id"))
|
237
|
-
else
|
238
|
-
query = query.joins(:content_facet_applicable_rpms)
|
239
|
-
end
|
240
|
-
|
241
|
-
query
|
229
|
+
ApplicableContentHelper.new(Rpm).installable_for_hosts(hosts)
|
242
230
|
end
|
243
231
|
|
244
232
|
def self.applicable_to_hosts(hosts)
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Katello
|
2
|
+
class ApplicableContentHelper
|
3
|
+
attr_accessor :content_facet, :content_unit_class
|
4
|
+
|
5
|
+
def initialize(content_unit_class, content_facet = nil)
|
6
|
+
self.content_facet = content_facet
|
7
|
+
self.content_unit_class = content_unit_class
|
8
|
+
end
|
9
|
+
|
10
|
+
def import(partial)
|
11
|
+
to_add, to_remove = applicable_differences(partial)
|
12
|
+
content_facet_association_class.where(:content_facet_id => content_facet.id).delete_all unless partial
|
13
|
+
ActiveRecord::Base.transaction do
|
14
|
+
insert(to_add) unless to_add.blank?
|
15
|
+
remove(to_remove) unless to_remove.blank?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def installable(env = nil, content_view = nil)
|
20
|
+
repos = if env && content_view
|
21
|
+
Katello::Repository.in_environment(env).in_content_views([content_view])
|
22
|
+
else
|
23
|
+
content_facet.bound_repositories.pluck(:id)
|
24
|
+
end
|
25
|
+
content_facet.send(applicable_units).in_repositories(repos)
|
26
|
+
end
|
27
|
+
|
28
|
+
def installable_for_hosts(hosts = nil)
|
29
|
+
# Main goal of this query
|
30
|
+
# 1) Get me the applicable content units for these set of hosts
|
31
|
+
# 2) Now further prune this list. Only include units from repos that have been "enabled" on those hosts.
|
32
|
+
# In other words, prune the list to only include the units in the "bound" repositories signified by
|
33
|
+
# the inner join between ContentFacetRepository and Repository<Unit>
|
34
|
+
|
35
|
+
facet_repos = Katello::ContentFacetRepository.joins(:content_facet => :host).select(:repository_id)
|
36
|
+
facet_content_units = content_facet_association_class.joins(:content_facet => :host).select(content_unit_association_id)
|
37
|
+
|
38
|
+
if hosts
|
39
|
+
hosts = ::Host.where(id: hosts) if hosts.is_a?(Array)
|
40
|
+
facet_repos = facet_repos.merge(hosts).reorder(nil)
|
41
|
+
facet_content_units = facet_content_units.merge(hosts).reorder(nil)
|
42
|
+
end
|
43
|
+
|
44
|
+
content_unit_class.joins(repository_association_units).
|
45
|
+
where(repository_association_class.table_name => {:repository_id => facet_repos,
|
46
|
+
content_unit_association_id => facet_content_units}).distinct
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def content_units
|
52
|
+
content_unit_class.name.demodulize.pluralize.underscore.to_sym
|
53
|
+
end
|
54
|
+
|
55
|
+
def applicable_units
|
56
|
+
"applicable_#{content_units}".to_sym
|
57
|
+
end
|
58
|
+
|
59
|
+
def content_unit_association_id
|
60
|
+
"#{content_unit_class.name.demodulize.underscore}_id".to_sym
|
61
|
+
end
|
62
|
+
|
63
|
+
def content_type
|
64
|
+
content_unit_class.const_get(:CONTENT_TYPE)
|
65
|
+
end
|
66
|
+
|
67
|
+
def content_facet_association_class
|
68
|
+
# Example: ContentFacetErratum
|
69
|
+
self.content_unit_class.content_facet_association_class
|
70
|
+
end
|
71
|
+
|
72
|
+
def content_facet_association_units
|
73
|
+
content_facet_association_class.name.demodulize.pluralize.underscore.to_sym
|
74
|
+
end
|
75
|
+
|
76
|
+
def repository_association_class
|
77
|
+
content_unit_class.repository_association_class
|
78
|
+
end
|
79
|
+
|
80
|
+
def repository_association_units
|
81
|
+
repository_association_class.name.demodulize.pluralize.underscore.to_sym
|
82
|
+
end
|
83
|
+
|
84
|
+
def applicable_differences(partial)
|
85
|
+
content_uuids = ::Katello::Pulp::Consumer.new(content_facet.uuid).applicable_ids(content_type)
|
86
|
+
if partial
|
87
|
+
consumer_uuids = content_facet.send(applicable_units).pluck("#{content_unit_class.table_name}.uuid")
|
88
|
+
to_remove = consumer_uuids - content_uuids
|
89
|
+
to_add = content_uuids - consumer_uuids
|
90
|
+
else
|
91
|
+
to_add = content_uuids
|
92
|
+
to_remove = nil
|
93
|
+
end
|
94
|
+
[to_add, to_remove]
|
95
|
+
end
|
96
|
+
|
97
|
+
def insert(uuids)
|
98
|
+
applicable_ids = content_unit_class.where(:uuid => uuids).pluck(:id)
|
99
|
+
unless applicable_ids.empty?
|
100
|
+
inserts = applicable_ids.map { |applicable_id| "(#{applicable_id.to_i}, #{content_facet.id.to_i})" }
|
101
|
+
sql = "INSERT INTO #{content_facet_association_class.table_name} (#{content_unit_association_id}, content_facet_id) VALUES #{inserts.join(', ')}"
|
102
|
+
ActiveRecord::Base.connection.execute(sql)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def remove(uuids)
|
107
|
+
applicable_ids = content_unit_class.where(:uuid => uuids).pluck(:id)
|
108
|
+
content_facet_association_class.where(:content_facet_id => content_facet.id, content_unit_association_id => applicable_ids).delete_all
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -14,6 +14,13 @@ module Katello
|
|
14
14
|
URI.parse(url)
|
15
15
|
end
|
16
16
|
|
17
|
+
# If there is an 'AppStream' variant, we need to make it
|
18
|
+
# available to Anaconda
|
19
|
+
def additional_media
|
20
|
+
appstream = entity.operatingsystem.variant_repo(entity, 'AppStream')
|
21
|
+
super + (appstream ? [appstream] : [])
|
22
|
+
end
|
23
|
+
|
17
24
|
def unique_id
|
18
25
|
@unique_id ||= begin
|
19
26
|
"#{kickstart_repo.name.parameterize}-#{kickstart_repo.id}"
|
@@ -20,16 +20,22 @@ module Katello
|
|
20
20
|
Katello.pulp_server.extensions.consumer.upload_profile(self.uuid, 'rpm', profile)
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
return [] if response.empty?
|
26
|
-
response[0]['applicability']['erratum'] || []
|
23
|
+
def upload_module_stream_profile(profile)
|
24
|
+
Katello.pulp_server.extensions.consumer.upload_profile(self.uuid, 'modulemd', profile)
|
27
25
|
end
|
28
26
|
|
29
|
-
def
|
30
|
-
|
27
|
+
def applicable_ids(content_unit_type)
|
28
|
+
consumer_method = case content_unit_type
|
29
|
+
when ::Katello::Erratum::CONTENT_TYPE
|
30
|
+
:applicable_errata
|
31
|
+
when ::Katello::ModuleStream::CONTENT_TYPE
|
32
|
+
:applicable_module_streams
|
33
|
+
else
|
34
|
+
:applicable_rpms
|
35
|
+
end
|
36
|
+
response = Katello.pulp_server.extensions.consumer.send(consumer_method, [self.uuid])
|
31
37
|
return [] if response.empty?
|
32
|
-
response[0]['applicability'][
|
38
|
+
response[0]['applicability'][content_unit_type] || []
|
33
39
|
end
|
34
40
|
|
35
41
|
def bind_yum_repositories(ids)
|
@@ -1,21 +1,174 @@
|
|
1
1
|
module Katello
|
2
2
|
module Pulp
|
3
3
|
class Repository < ::Actions::Pulp::Abstract
|
4
|
-
attr_accessor :repo
|
4
|
+
attr_accessor :repo, :input, :pulp_api
|
5
|
+
attr_accessor :smart_proxy
|
6
|
+
delegate :root, to: :repo
|
5
7
|
|
6
|
-
def initialize(repo, smart_proxy
|
8
|
+
def initialize(repo, smart_proxy)
|
7
9
|
@repo = repo
|
8
10
|
@smart_proxy = smart_proxy
|
9
11
|
end
|
10
12
|
|
13
|
+
def backend_data(force = false)
|
14
|
+
return smart_proxy.pulp_api.extensions.repository.retrieve_with_details(repo.pulp_id) if (repo.pulp_id && force)
|
15
|
+
@backend_data ||= smart_proxy.pulp_api.extensions.repository.retrieve_with_details(repo.pulp_id) if repo.pulp_id
|
16
|
+
rescue RestClient::ResourceNotFound
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.instance_for_type(repo, smart_proxy)
|
21
|
+
Katello::RepositoryTypeManager.repository_types[repo.root.content_type].service_class.new(repo, smart_proxy)
|
22
|
+
end
|
23
|
+
|
24
|
+
def partial_repo_path
|
25
|
+
fail NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
def importer_class
|
29
|
+
fail NotImplementedError
|
30
|
+
end
|
31
|
+
|
32
|
+
def master_importer_configuration
|
33
|
+
fail NotImplementedError
|
34
|
+
end
|
35
|
+
|
36
|
+
def mirror_importer_configuration
|
37
|
+
fail NotImplementedError
|
38
|
+
end
|
39
|
+
|
40
|
+
def generate_mirror_importer
|
41
|
+
fail NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
def generate_master_importer
|
45
|
+
fail NotImplementedError
|
46
|
+
end
|
47
|
+
|
48
|
+
def generate_distributors
|
49
|
+
fail NotImplementedError
|
50
|
+
end
|
51
|
+
|
11
52
|
def sync(overrides = {})
|
12
53
|
sync_options = {}
|
13
54
|
sync_options[:max_speed] = SETTINGS.dig(:katello, :pulp, :sync_KBlimit)
|
14
55
|
sync_options[:num_threads] = SETTINGS.dig(:katello, :pulp, :sync_threads)
|
15
|
-
sync_options[:feed] = overrides[:
|
56
|
+
sync_options[:feed] = overrides[:feed] if overrides[:feed]
|
16
57
|
sync_options[:validate] = !SETTINGS.dig(:katello, :pulp, :skip_checksum_validation)
|
17
58
|
sync_options.merge!(overrides[:options]) if overrides[:options]
|
18
|
-
[
|
59
|
+
[smart_proxy.pulp_api.resources.repository.sync(@repo.pulp_id, override_config: sync_options.compact!)]
|
60
|
+
end
|
61
|
+
|
62
|
+
def create
|
63
|
+
smart_proxy.pulp_api.extensions.repository.create_with_importer_and_distributors(repo.pulp_id, generate_importer,
|
64
|
+
generate_distributors, display_name: root.name)
|
65
|
+
end
|
66
|
+
|
67
|
+
def external_url(force_https = false)
|
68
|
+
uri = URI.parse(::SmartProxy.pulp_master.pulp_url)
|
69
|
+
uri.scheme = (root.unprotected && !force_https) ? 'http' : 'https'
|
70
|
+
uri.path = partial_repo_path
|
71
|
+
uri.to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
def generate_importer
|
75
|
+
if smart_proxy.pulp_mirror?
|
76
|
+
generate_mirror_importer
|
77
|
+
elsif repo.in_default_view?
|
78
|
+
generate_master_importer
|
79
|
+
else #content view repositories don't need any importer configuration
|
80
|
+
importer_class.new
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def master_importer_connection_options
|
85
|
+
options = {
|
86
|
+
proxy_host: self.proxy_host_importer_value,
|
87
|
+
basic_auth_username: root.upstream_username,
|
88
|
+
basic_auth_password: root.upstream_password,
|
89
|
+
ssl_validation: root.verify_ssl_on_sync?
|
90
|
+
}
|
91
|
+
options.merge(master_importer_ssl_options)
|
92
|
+
end
|
93
|
+
|
94
|
+
def master_importer_ssl_options
|
95
|
+
if root.redhat? && Katello::Resources::CDN::CdnResource.redhat_cdn?(root.url)
|
96
|
+
{
|
97
|
+
ssl_client_cert: root.product.certificate,
|
98
|
+
ssl_client_key: root.product.key,
|
99
|
+
ssl_ca_cert: Katello::Repository.feed_ca_cert(root.url)
|
100
|
+
}
|
101
|
+
elsif root.custom?
|
102
|
+
{
|
103
|
+
ssl_client_cert: root.ssl_client_cert&.content,
|
104
|
+
ssl_client_key: root.ssl_client_key&.content,
|
105
|
+
ssl_ca_cert: root.ssl_ca_cert&.content
|
106
|
+
}
|
107
|
+
else
|
108
|
+
{}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def mirror_importer_connection_options
|
113
|
+
ueber_cert = ::Cert::Certs.ueber_cert(root.organization)
|
114
|
+
{
|
115
|
+
ssl_client_cert: ueber_cert[:cert],
|
116
|
+
ssl_client_key: ueber_cert[:key],
|
117
|
+
ssl_ca_cert: ::Cert::Certs.ca_cert
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
def proxy_host_importer_value
|
122
|
+
root.ignore_global_proxy ? "" : nil
|
123
|
+
end
|
124
|
+
|
125
|
+
def refresh
|
126
|
+
update_or_associate_importer
|
127
|
+
update_or_associate_distributors
|
128
|
+
remove_unnecessary_distributors
|
129
|
+
end
|
130
|
+
|
131
|
+
def update_or_associate_importer
|
132
|
+
existing_importers = backend_data["importers"]
|
133
|
+
importer = generate_importer
|
134
|
+
found = existing_importers.find { |i| i['importer_type_id'] == importer.id }
|
135
|
+
|
136
|
+
if found
|
137
|
+
ssl_ca_cert = importer.config.delete('ssl_ca_cert')
|
138
|
+
ssl_client_cert = importer.config.delete('ssl_client_cert')
|
139
|
+
ssl_client_key = importer.config.delete('ssl_client_key')
|
140
|
+
importer.config['basic_auth_username'] = nil if importer.config['basic_auth_username'].blank?
|
141
|
+
importer.config['basic_auth_password'] = nil if importer.config['basic_auth_password'].blank?
|
142
|
+
# Update ssl options by themselves workaround for https://pulp.plan.io/issues/2727
|
143
|
+
smart_proxy.pulp_api.resources.repository.update_importer(repo.pulp_id, found['id'], :ssl_client_cert => ssl_client_cert,
|
144
|
+
:ssl_client_key => ssl_client_key, :ssl_ca_cert => ssl_ca_cert)
|
145
|
+
smart_proxy.pulp_api.resources.repository.update_importer(repo.pulp_id, found['id'], importer.config)
|
146
|
+
else
|
147
|
+
smart_proxy.pulp_api.resources.repository.associate_importer(repo.pulp_id, repo.importers.first['importer_type_id'], importer.config)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def update_or_associate_distributors
|
152
|
+
existing_distributors = backend_data["distributors"]
|
153
|
+
generate_distributors.each do |distributor|
|
154
|
+
found = existing_distributors.find { |i| i['distributor_type_id'] == distributor.type_id }
|
155
|
+
if found
|
156
|
+
smart_proxy.pulp_api.resources.repository.
|
157
|
+
update_distributor(repo.pulp_id, found['id'], distributor.config)
|
158
|
+
else
|
159
|
+
smart_proxy.pulp_api.resources.repository.
|
160
|
+
associate_distributor(repo.pulp_id, distributor.type_id, distributor.config, :distributor_id => distributor.id)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def remove_unnecessary_distributors
|
166
|
+
existing_distributors = backend_data["distributors"]
|
167
|
+
generated_distributors = generate_distributors
|
168
|
+
existing_distributors.each do |distributor|
|
169
|
+
found = generated_distributors.find { |dist| dist.type_id == distributor['distributor_type_id'] }
|
170
|
+
smart_proxy.pulp_api.resources.repository.delete_distributor(repo.pulp_id, distributor['id']) unless found
|
171
|
+
end
|
19
172
|
end
|
20
173
|
end
|
21
174
|
end
|