katello 4.9.1 → 4.9.2
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/host_subscriptions_controller.rb +1 -1
- data/app/controllers/katello/api/v2/products_controller.rb +4 -4
- data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +12 -5
- data/app/controllers/katello/api/v2/repositories_controller.rb +10 -7
- data/app/controllers/katello/concerns/content_facet_hosts_controller_extensions.rb +7 -9
- data/app/helpers/katello/hosts_and_hostgroups_helper.rb +13 -1
- data/app/lib/actions/katello/agent_action.rb +4 -3
- data/app/lib/actions/katello/bulk_agent_action.rb +4 -1
- data/app/lib/actions/katello/content_view_environment/destroy.rb +5 -3
- data/app/lib/actions/katello/content_view_version/destroy.rb +5 -1
- data/app/lib/actions/katello/host/update_content_view.rb +4 -2
- data/app/lib/actions/katello/product/destroy.rb +15 -11
- data/app/lib/actions/katello/repository/destroy.rb +10 -2
- data/app/lib/actions/katello/repository/index_content.rb +0 -1
- data/app/lib/actions/katello/repository/sync.rb +1 -3
- data/app/lib/actions/katello/repository/verify_checksum.rb +2 -10
- data/app/lib/actions/pulp3/orchestration/repository/generate_metadata.rb +12 -5
- data/app/models/katello/candlepin/repository_mapper.rb +1 -0
- data/app/models/katello/concerns/host_managed_extensions.rb +55 -3
- data/app/models/katello/content_view.rb +16 -2
- data/app/models/katello/docker_meta_tag.rb +3 -1
- data/app/models/katello/host/content_facet.rb +3 -1
- data/app/models/katello/kt_environment.rb +1 -1
- data/app/models/katello/product_content.rb +14 -1
- data/app/models/katello/repository.rb +1 -0
- data/app/views/katello/api/v2/products/show.json.rabl +3 -0
- data/app/views/katello/api/v2/repositories/base.json.rabl +18 -0
- data/app/views/katello/api/v2/repository_sets/show.json.rabl +2 -2
- data/app/views/overrides/activation_keys/_host_environment_select.html.erb +4 -5
- data/db/migrate/20220228173251_remove_drpm_from_ignorable_content.rb +1 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/katello-agent-notice.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +0 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +0 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +0 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-installed.html +0 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +4 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +4 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-details.html +1 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +4 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-details.controller.js +2 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +17 -4
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +55 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +2 -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/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +4 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/views/product-details.html +5 -0
- data/lib/katello/version.rb +1 -1
- data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +4 -0
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +4 -0
- data/webpack/components/extensions/HostDetails/common/KatelloAgentDeprecationAlert.js +23 -0
- data/webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js +1 -1
- data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js +1 -1
- data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareConfig.js +1 -1
- data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +0 -8
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +0 -8
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: feee4d277c7c10e872fb0a6b78e3b1c3c774f108b5c6d2dd715bfc5519e9e2be
|
4
|
+
data.tar.gz: 91fa39a6da658fa21bb51ca6eab3c4080d8098654ae731194861457f7e7ce9cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70fc4051a751c9f8df528de6a4acf4ca9588a60cecc7297dd7a826b01adfc22f5ea3994457a535e4b8405f5873d7307e4e6e126c8413e4f061c7cc39a11aa926
|
7
|
+
data.tar.gz: '09b5eb9678d9028bfb96fe4a293ecad609b2d01b9889a1f4dda6002f27bb8db0259229560bc7b42f18a9ea7e2a52404f9b6f2c5e295c74a00bc515e9eb7ec5f6'
|
@@ -81,7 +81,7 @@ module Katello
|
|
81
81
|
def create
|
82
82
|
rhsm_params = params_to_rhsm_params
|
83
83
|
|
84
|
-
host = Katello::RegistrationManager.process_registration(rhsm_params, @content_view_environment)
|
84
|
+
host = Katello::RegistrationManager.process_registration(rhsm_params, [@content_view_environment])
|
85
85
|
host.reload
|
86
86
|
::Katello::Host::SubscriptionFacet.update_facts(host, rhsm_params[:facts]) unless rhsm_params[:facts].blank?
|
87
87
|
|
@@ -17,10 +17,10 @@ module Katello
|
|
17
17
|
|
18
18
|
def_param_group :product do
|
19
19
|
param :description, String, :desc => N_("Product description")
|
20
|
-
param :gpg_key_id, :number, :desc => N_("Identifier of the GPG key")
|
21
|
-
param :ssl_ca_cert_id, :number, :desc => N_("Idenifier of the SSL CA Cert")
|
22
|
-
param :ssl_client_cert_id, :number, :desc => N_("Identifier of the SSL Client Cert")
|
23
|
-
param :ssl_client_key_id, :number, :desc => N_("Identifier of the SSL Client Key")
|
20
|
+
param :gpg_key_id, :number, :desc => N_("Identifier of the GPG key"), :allow_nil => true
|
21
|
+
param :ssl_ca_cert_id, :number, :desc => N_("Idenifier of the SSL CA Cert"), :allow_nil => true
|
22
|
+
param :ssl_client_cert_id, :number, :desc => N_("Identifier of the SSL Client Cert"), :allow_nil => true
|
23
|
+
param :ssl_client_key_id, :number, :desc => N_("Identifier of the SSL Client Key"), :allow_nil => true
|
24
24
|
param :sync_plan_id, :number, :desc => N_("Plan numeric identifier"), :allow_nil => true
|
25
25
|
end
|
26
26
|
|
@@ -7,7 +7,7 @@ module Katello
|
|
7
7
|
def destroy_repositories
|
8
8
|
deletion_authorized_repositories = @repositories.deletable
|
9
9
|
unpromoted_repos = deletion_authorized_repositories.reject { |repo| repo.promoted? && repo.content_views.generated_for_none.exists? }
|
10
|
-
|
10
|
+
unpromoted_repos_non_last_affected_repo = unpromoted_repos.reject { |repo| repo.filters.any? { |filter| filter.repositories.size == 1 } }
|
11
11
|
messages1 = format_bulk_action_messages(
|
12
12
|
:success => "",
|
13
13
|
:error => _("You do not have permissions to delete %s"),
|
@@ -17,16 +17,23 @@ module Katello
|
|
17
17
|
|
18
18
|
messages2 = format_bulk_action_messages(
|
19
19
|
:success => "",
|
20
|
-
:error => _("Repository %s cannot be deleted since it has already been included in a published Content View."),
|
20
|
+
:error => _("Repository %s cannot be deleted since it has already been included in a published Content View. Use repository details page to delete"),
|
21
21
|
:models => deletion_authorized_repositories,
|
22
22
|
:authorized => unpromoted_repos
|
23
23
|
)
|
24
24
|
|
25
|
-
|
25
|
+
messages3 = format_bulk_action_messages(
|
26
|
+
:success => "",
|
27
|
+
:error => _("Repository %s cannot be deleted since it is the last affected repository in a filter. Use repository details page to delete."),
|
28
|
+
:models => unpromoted_repos,
|
29
|
+
:authorized => unpromoted_repos_non_last_affected_repo
|
30
|
+
)
|
31
|
+
|
32
|
+
errors = messages1[:error] + messages2[:error] + messages3[:error]
|
26
33
|
|
27
34
|
task = nil
|
28
|
-
if
|
29
|
-
task = async_task(::Actions::BulkAction, ::Actions::Katello::Repository::Destroy,
|
35
|
+
if unpromoted_repos_non_last_affected_repo.any?
|
36
|
+
task = async_task(::Actions::BulkAction, ::Actions::Katello::Repository::Destroy, unpromoted_repos_non_last_affected_repo)
|
30
37
|
else
|
31
38
|
status = 400
|
32
39
|
end
|
@@ -41,12 +41,12 @@ module Katello
|
|
41
41
|
|
42
42
|
def_param_group :repo do
|
43
43
|
param :url, String, :desc => N_("repository source url")
|
44
|
-
param :os_versions, Array,
|
45
|
-
|
46
|
-
param :gpg_key_id, :number, :desc => N_("id of the gpg key that will be assigned to the new repository")
|
47
|
-
param :ssl_ca_cert_id, :number, :desc => N_("Identifier of the content credential containing the SSL CA Cert")
|
48
|
-
param :ssl_client_cert_id, :number, :desc => N_("Identifier of the content credential containing the SSL Client Cert")
|
49
|
-
param :ssl_client_key_id, :number, :desc => N_("Identifier of the content credential containing the SSL Client Key")
|
44
|
+
param :os_versions, Array, :desc => N_("Identifies whether the repository should be unavailable on a client with a non-matching OS version.
|
45
|
+
Pass [] to make repo available for clients regardless of OS version. Maximum length 1; allowed tags are: %s") % Katello::RootRepository::ALLOWED_OS_VERSIONS.join(', ')
|
46
|
+
param :gpg_key_id, :number, :desc => N_("id of the gpg key that will be assigned to the new repository"), :allow_nil => true
|
47
|
+
param :ssl_ca_cert_id, :number, :desc => N_("Identifier of the content credential containing the SSL CA Cert"), :allow_nil => true
|
48
|
+
param :ssl_client_cert_id, :number, :desc => N_("Identifier of the content credential containing the SSL Client Cert"), :allow_nil => true
|
49
|
+
param :ssl_client_key_id, :number, :desc => N_("Identifier of the content credential containing the SSL Client Key"), :allow_nil => true
|
50
50
|
param :unprotected, :bool, :desc => N_("true if this repository can be published via HTTP")
|
51
51
|
param :checksum_type, String, :desc => N_("Checksum of the repository, currently 'sha1' & 'sha256' are supported")
|
52
52
|
param :docker_upstream_name, String, :desc => N_("Name of the upstream docker repository")
|
@@ -416,9 +416,12 @@ module Katello
|
|
416
416
|
api :DELETE, "/repositories/:id", N_("Destroy a custom repository")
|
417
417
|
param :id, :number, :required => true
|
418
418
|
param :remove_from_content_view_versions, :bool, :required => false, :desc => N_("Force delete the repository by removing it from all content view versions")
|
419
|
+
param :delete_empty_repo_filters, :bool, :required => false, :desc => N_("Delete content view filters that have this repository as the last associated repository. Defaults to true. If false, such filters will now apply to all repositories in the content view.")
|
419
420
|
def destroy
|
420
421
|
sync_task(::Actions::Katello::Repository::Destroy, @repository,
|
421
|
-
|
422
|
+
remove_from_content_view_versions: ::Foreman::Cast.to_bool(params.fetch(:remove_from_content_view_versions, false)),
|
423
|
+
delete_empty_repo_filters: ::Foreman::Cast.to_bool(params.fetch(:delete_empty_repo_filters, true))
|
424
|
+
)
|
422
425
|
respond_for_destroy
|
423
426
|
end
|
424
427
|
|
@@ -6,17 +6,15 @@ module Katello
|
|
6
6
|
before_action :set_up_content_view_environment, only: [:update]
|
7
7
|
|
8
8
|
def set_up_content_view_environment
|
9
|
-
return unless
|
9
|
+
return unless @host&.content_facet.present? && params[:host]&.[](:content_facet_attributes)&.present?
|
10
10
|
cv_id = params[:host][:content_facet_attributes].delete(:content_view_id)
|
11
11
|
env_id = params[:host][:content_facet_attributes].delete(:lifecycle_environment_id)
|
12
|
-
Rails.logger.info "
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
Rails.logger.info "set_up_content_view_environment: done"
|
19
|
-
end
|
12
|
+
Rails.logger.info "#{__method__}: cv_id=#{cv_id}, env_id=#{env_id}"
|
13
|
+
@host.content_facet.assign_single_environment(
|
14
|
+
lifecycle_environment_id: env_id,
|
15
|
+
content_view_id: cv_id
|
16
|
+
)
|
17
|
+
Rails.logger.info "#{__method__}: done"
|
20
18
|
end
|
21
19
|
end
|
22
20
|
end
|
@@ -4,6 +4,18 @@ module Katello
|
|
4
4
|
"kt_activation_keys"
|
5
5
|
end
|
6
6
|
|
7
|
+
def edit_action?
|
8
|
+
params[:action] == 'edit'
|
9
|
+
end
|
10
|
+
|
11
|
+
def cv_lce_disabled?
|
12
|
+
edit_action? && !using_discovered_hosts_page?
|
13
|
+
end
|
14
|
+
|
15
|
+
def using_discovered_hosts_page?
|
16
|
+
controller.controller_name == "discovered_hosts"
|
17
|
+
end
|
18
|
+
|
7
19
|
def using_hostgroups_page?
|
8
20
|
controller.controller_name == "hostgroups"
|
9
21
|
end
|
@@ -164,7 +176,7 @@ module Katello
|
|
164
176
|
|
165
177
|
views = []
|
166
178
|
if lifecycle_environment
|
167
|
-
views = Katello::ContentView.in_environment(lifecycle_environment).readable.order(:name)
|
179
|
+
views = Katello::ContentView.in_environment(lifecycle_environment).ignore_generated.readable.order(:name)
|
168
180
|
views |= [content_view] if content_view.present? && content_view.in_environment?(lifecycle_environment)
|
169
181
|
elsif content_view
|
170
182
|
views = [content_view]
|
@@ -14,8 +14,10 @@ module Actions
|
|
14
14
|
|
15
15
|
def plan(host, options)
|
16
16
|
action_subject(host, :hostname => host.name, :content => options[:content])
|
17
|
-
|
18
|
-
dispatch_history_id = options.dig(:dispatch_histories, host.id.to_s) ||
|
17
|
+
# options[:dispatch_histories] keys might be strings or integers
|
18
|
+
dispatch_history_id = options.dig(:dispatch_histories, host.id.to_s) ||
|
19
|
+
options.dig(:dispatch_histories, host.id.to_i) ||
|
20
|
+
::Katello::Agent::Dispatcher.create_histories(
|
19
21
|
host_ids: [host.id]
|
20
22
|
).first.id
|
21
23
|
|
@@ -44,7 +46,6 @@ module Actions
|
|
44
46
|
history.dynflow_execution_plan_id = suspended_action.execution_plan_id
|
45
47
|
history.dynflow_step_id = suspended_action.step_id
|
46
48
|
history.save!
|
47
|
-
|
48
49
|
dispatch_message(history) unless input[:bulk]
|
49
50
|
|
50
51
|
schedule_timeout(timeout, optional: true)
|
@@ -21,7 +21,10 @@ module Actions
|
|
21
21
|
|
22
22
|
def spawn_plans
|
23
23
|
args = input[:args].first
|
24
|
-
|
24
|
+
# args[:dispatch_histories] keys are numeric host ids; they may be integer or string
|
25
|
+
# Hash#slice will return a filtered hash only with the specified keys, and ignore keys that don't exist
|
26
|
+
possible_keys = [*current_batch.map(&:to_i), *current_batch.map(&:to_s)]
|
27
|
+
histories = ::Katello::Agent::DispatchHistory.where(id: args[:dispatch_histories].slice(*possible_keys).values)
|
25
28
|
::Katello::Agent::Dispatcher.dispatch(
|
26
29
|
args[:type].to_sym,
|
27
30
|
histories,
|
@@ -8,19 +8,20 @@ module Actions
|
|
8
8
|
content_view = cv_env.content_view
|
9
9
|
environment = cv_env.environment
|
10
10
|
content_view.check_remove_from_environment!(environment) unless organization_destroy
|
11
|
-
|
11
|
+
docker_cleanup = false
|
12
12
|
sequence do
|
13
13
|
concurrence do
|
14
14
|
unless skip_repo_destroy
|
15
15
|
content_view.repos(environment).each do |repo|
|
16
16
|
# no need to update the content view environment since it's
|
17
17
|
# getting destroyed so skip_environment_update
|
18
|
-
plan_action(Repository::Destroy, repo, skip_environment_update: true)
|
18
|
+
plan_action(Repository::Destroy, repo, skip_environment_update: true, docker_cleanup: false)
|
19
|
+
docker_cleanup ||= repo.docker?
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
22
23
|
plan_action(Candlepin::Environment::Destroy, cp_id: cv_env.cp_id) unless organization_destroy
|
23
|
-
plan_self(:id => cv_env.id)
|
24
|
+
plan_self(:id => cv_env.id, :docker_cleanup => docker_cleanup)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
@@ -31,6 +32,7 @@ module Actions
|
|
31
32
|
else
|
32
33
|
cv_env.destroy!
|
33
34
|
end
|
35
|
+
::Katello::DockerMetaTag.cleanup_tags if input[:docker_cleanup]
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
@@ -7,22 +7,26 @@ module Actions
|
|
7
7
|
|
8
8
|
destroy_env_content = !options.fetch(:skip_destroy_env_content, false)
|
9
9
|
repos = destroy_env_content ? version.repositories : version.archived_repos
|
10
|
+
docker_cleanup = false
|
10
11
|
|
11
12
|
sequence do
|
12
13
|
concurrence do
|
13
14
|
repos.each do |repo|
|
14
15
|
repo_options = options.clone
|
16
|
+
repo_options[:docker_cleanup] = false
|
15
17
|
plan_action(Repository::Destroy, repo, repo_options)
|
18
|
+
docker_cleanup ||= repo.docker?
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
20
|
-
plan_self(:id => version.id)
|
23
|
+
plan_self(:id => version.id, :docker_cleanup => docker_cleanup)
|
21
24
|
end
|
22
25
|
|
23
26
|
def finalize
|
24
27
|
version = ::Katello::ContentViewVersion.find_by(id: input[:id])
|
25
28
|
version&.destroy!
|
29
|
+
::Katello::DockerMetaTag.cleanup_tags if input[:docker_cleanup]
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -4,8 +4,10 @@ module Actions
|
|
4
4
|
class UpdateContentView < Actions::EntryAction
|
5
5
|
def plan(host, content_view_id, lifecycle_environment_id)
|
6
6
|
if host.content_facet
|
7
|
-
host.content_facet.
|
8
|
-
|
7
|
+
host.content_facet.assign_single_environment(
|
8
|
+
content_view_id: content_view_id,
|
9
|
+
lifecycle_environment_id: lifecycle_environment_id
|
10
|
+
)
|
9
11
|
host.update_candlepin_associations
|
10
12
|
plan_self(:hostname => host.name)
|
11
13
|
else
|
@@ -2,21 +2,11 @@ module Actions
|
|
2
2
|
module Katello
|
3
3
|
module Product
|
4
4
|
class Destroy < Actions::EntryAction
|
5
|
-
# rubocop:disable Metrics/MethodLength
|
6
5
|
def plan(product, options = {})
|
7
6
|
organization_destroy = options.fetch(:organization_destroy, false)
|
8
7
|
skip_environment_update = options.fetch(:skip_environment_update, false) ||
|
9
8
|
options.fetch(:organization_destroy, false)
|
10
|
-
|
11
|
-
unless organization_destroy || product.user_deletable?
|
12
|
-
if product.redhat?
|
13
|
-
fail _("Cannot delete Red Hat product: %{product}") % { :product => product.name }
|
14
|
-
elsif !product.published_content_view_versions.not_ignorable.empty?
|
15
|
-
fail _("Cannot delete product with repositories published in a content view. Product: %{product}, %{view_versions}") %
|
16
|
-
{ :product => product.name, :view_versions => view_versions(product) }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
9
|
+
check_ready_to_delete(product, organization_destroy)
|
20
10
|
action_subject(product)
|
21
11
|
|
22
12
|
# Candlepin::Product::ContentRemove is called with Katello::Repository::Destroy, so we only want to run ContentRemove
|
@@ -99,6 +89,20 @@ module Actions
|
|
99
89
|
end
|
100
90
|
results.join(', ')
|
101
91
|
end
|
92
|
+
|
93
|
+
def check_ready_to_delete(product, organization_destroy)
|
94
|
+
unless organization_destroy || product.user_deletable?
|
95
|
+
if product.redhat?
|
96
|
+
fail _("Cannot delete Red Hat product: %{product}") % { :product => product.name }
|
97
|
+
elsif !product.published_content_view_versions.not_ignorable.empty?
|
98
|
+
fail _("Cannot delete product with repositories published in a content view. Product: %{product}, %{view_versions}") %
|
99
|
+
{ :product => product.name, :view_versions => view_versions(product) }
|
100
|
+
elsif product.repositories.any? { |repo| repo.filters.any? { |filter| filter.repositories.size == 1 } }
|
101
|
+
fail _("Cannot delete product: %{product} with repositories that are the last affected repository in content view filters. Delete these repositories before deleting product.") %
|
102
|
+
{ :product => product.name }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
102
106
|
end
|
103
107
|
end
|
104
108
|
end
|
@@ -15,6 +15,8 @@ module Actions
|
|
15
15
|
options.fetch(:organization_destroy, false)
|
16
16
|
destroy_content = options.fetch(:destroy_content, true)
|
17
17
|
remove_from_content_view_versions = options.fetch(:remove_from_content_view_versions, false)
|
18
|
+
delete_empty_repo_filters = options.fetch(:delete_empty_repo_filters, true)
|
19
|
+
docker_cleanup = options.fetch(:docker_cleanup, true)
|
18
20
|
action_subject(repository)
|
19
21
|
check_destroyable!(repository, remove_from_content_view_versions)
|
20
22
|
remove_generated_content_views(repository)
|
@@ -29,8 +31,9 @@ module Actions
|
|
29
31
|
|
30
32
|
handle_acs_product_removal(repository)
|
31
33
|
handle_alternate_content_sources(repository)
|
34
|
+
delete_empty_repo_filters(repository) if delete_empty_repo_filters
|
32
35
|
|
33
|
-
plan_self(:user_id => ::User.current.id, :affected_cvv_ids => affected_cvv_ids)
|
36
|
+
plan_self(:user_id => ::User.current.id, :affected_cvv_ids => affected_cvv_ids, :docker_cleanup => docker_cleanup)
|
34
37
|
sequence do
|
35
38
|
if repository.redhat?
|
36
39
|
handle_redhat_content(repository) unless skip_environment_update
|
@@ -45,7 +48,7 @@ module Actions
|
|
45
48
|
def finalize
|
46
49
|
repository = ::Katello::Repository.find_by(id: input[:repository][:id])
|
47
50
|
if repository
|
48
|
-
docker_cleanup = repository.
|
51
|
+
docker_cleanup = repository.docker? && input[:docker_cleanup]
|
49
52
|
delete_record(repository, {docker_cleanup: docker_cleanup})
|
50
53
|
|
51
54
|
if (affected_cvv_ids = input[:affected_cvv_ids]).any?
|
@@ -81,6 +84,11 @@ module Actions
|
|
81
84
|
end
|
82
85
|
end
|
83
86
|
|
87
|
+
def delete_empty_repo_filters(repository)
|
88
|
+
filters_to_delete = repository.filters.select { |filter| filter.repositories.size == 1 }
|
89
|
+
::Katello::ContentViewFilter.where(id: filters_to_delete).destroy_all
|
90
|
+
end
|
91
|
+
|
84
92
|
def handle_custom_content(repository, remove_from_content_view_versions)
|
85
93
|
#if this is the last instance of a custom repo, destroy the content
|
86
94
|
if remove_from_content_view_versions || repository.root.repositories.where.not(id: repository.id).empty?
|
@@ -20,7 +20,6 @@ module Actions
|
|
20
20
|
|
21
21
|
if input[:force_index] || (repo.last_contents_changed >= repo.last_indexed)
|
22
22
|
repo.index_content(source_repository: source_repository, full_index: input[:full_index].present?)
|
23
|
-
repo.update(:last_indexed => DateTime.now)
|
24
23
|
else
|
25
24
|
output[:index_skipped] = true
|
26
25
|
end
|
@@ -26,7 +26,6 @@ module Actions
|
|
26
26
|
|
27
27
|
validate_repo!(repo: repo,
|
28
28
|
source_url: source_url,
|
29
|
-
validate_contents: validate_contents,
|
30
29
|
skip_metadata_check: skip_metadata_check,
|
31
30
|
skip_candlepin_check: options.fetch(:skip_candlepin_check, false))
|
32
31
|
|
@@ -81,9 +80,8 @@ module Actions
|
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
84
|
-
def validate_repo!(repo:, source_url:,
|
83
|
+
def validate_repo!(repo:, source_url:, skip_metadata_check:, skip_candlepin_check:)
|
85
84
|
fail ::Katello::Errors::InvalidActionOptionError, _("Unable to sync repo. This repository does not have a feed url.") if repo.url.blank? && source_url.blank?
|
86
|
-
fail ::Katello::Errors::InvalidActionOptionError, _("Cannot validate contents on non-yum/deb repositories.") if validate_contents && !repo.yum? && !repo.deb?
|
87
85
|
fail ::Katello::Errors::InvalidActionOptionError, _("Cannot skip metadata check on non-yum/deb repositories.") if skip_metadata_check && !repo.yum? && !repo.deb?
|
88
86
|
::Katello::Util::CandlepinRepositoryChecker.check_repository_for_sync!(repo) if repo.yum? && !skip_candlepin_check
|
89
87
|
end
|
@@ -6,19 +6,11 @@ module Actions
|
|
6
6
|
|
7
7
|
def plan(repo)
|
8
8
|
action_subject(repo)
|
9
|
-
|
10
|
-
if SmartProxy.pulp_primary.pulp3_support?(repo)
|
11
|
-
plan_action(Actions::Pulp3::Repository::Repair, repo.id, SmartProxy.pulp_primary)
|
12
|
-
else
|
13
|
-
options = {}
|
14
|
-
options[:validate_contents] = true
|
15
|
-
plan_action(Actions::Katello::Repository::Sync, repo, options)
|
16
|
-
end
|
9
|
+
plan_action(Actions::Pulp3::Repository::Repair, repo.id, SmartProxy.pulp_primary)
|
17
10
|
end
|
18
11
|
|
19
12
|
def presenter
|
20
|
-
found = all_planned_actions(
|
21
|
-
found = all_planned_actions(Pulp3::Repository::Repair) if found.empty?
|
13
|
+
found = all_planned_actions(Pulp3::Repository::Repair)
|
22
14
|
Helpers::Presenter::Delegated.new(self, found)
|
23
15
|
end
|
24
16
|
end
|
@@ -14,6 +14,8 @@ module Actions
|
|
14
14
|
plan_self(source_repository_id: options[:source_repository].id, target_repository_id: repository.id, smart_proxy_id: smart_proxy.id)
|
15
15
|
elsif publication_content_type && (force_publication || repository.publication_href.nil? || !repository.using_mirrored_metadata?)
|
16
16
|
plan_action(Actions::Pulp3::Repository::CreatePublication, repository, smart_proxy, options)
|
17
|
+
elsif !publication_content_type
|
18
|
+
plan_self(target_repository_id: repository.id, contents_changed: options[:contents_changed], skip_publication: true)
|
17
19
|
end
|
18
20
|
plan_action(Actions::Pulp3::ContentGuard::Refresh, smart_proxy) unless repository.unprotected
|
19
21
|
plan_action(Actions::Pulp3::Repository::RefreshDistribution, repository, smart_proxy, :contents_changed => options[:contents_changed]) if Setting[:distribute_archived_cvv] || repository.environment
|
@@ -21,13 +23,18 @@ module Actions
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def run
|
24
|
-
#we don't have to actually generate a publication, we can reuse the old one
|
25
26
|
target_repo = ::Katello::Repository.find(input[:target_repository_id])
|
26
|
-
|
27
|
-
|
28
|
-
target_repo.clear_smart_proxy_sync_histories
|
27
|
+
if input[:skip_publication]
|
28
|
+
#Need to clear smart proxy sync histories for non-publication content_types: docker, ansible collection
|
29
|
+
target_repo.clear_smart_proxy_sync_histories if input[:contents_changed]
|
30
|
+
else
|
31
|
+
#we don't have to actually generate a publication, we can reuse the old one
|
32
|
+
source_repo = ::Katello::Repository.find(input[:source_repository_id])
|
33
|
+
if (target_repo.publication_href != source_repo.publication_href && smart_proxy.pulp_primary?)
|
34
|
+
target_repo.clear_smart_proxy_sync_histories
|
35
|
+
end
|
36
|
+
target_repo.update!(publication_href: source_repo.publication_href)
|
29
37
|
end
|
30
|
-
target_repo.update!(publication_href: source_repo.publication_href)
|
31
38
|
end
|
32
39
|
end
|
33
40
|
end
|
@@ -1,22 +1,40 @@
|
|
1
1
|
module Katello
|
2
2
|
module Concerns
|
3
|
+
# rubocop:disable Metrics/ModuleLength
|
3
4
|
module HostManagedExtensions
|
4
5
|
extend ActiveSupport::Concern
|
5
6
|
include Katello::KatelloUrlsHelper
|
6
7
|
include ForemanTasks::Concerns::ActionSubject
|
7
8
|
|
8
9
|
module Overrides
|
9
|
-
def
|
10
|
+
def check_cve_attributes(attrs)
|
10
11
|
if attrs[:content_facet_attributes]
|
11
12
|
cv_id = attrs[:content_facet_attributes].delete(:content_view_id)
|
12
13
|
lce_id = attrs[:content_facet_attributes].delete(:lifecycle_environment_id)
|
14
|
+
# Running validations on a host will clear out any existing errors, and then
|
15
|
+
# validate all attributes. As we know, running update or save will run validations.
|
16
|
+
# Since we've just removed two attributes that may
|
17
|
+
# have caused an error, we need to save those so we can explicitly validate
|
18
|
+
# them below in add_back_cve_errors.
|
19
|
+
@pending_cve_attrs = { content_view_id: cv_id, lifecycle_environment_id: lce_id }
|
13
20
|
if cv_id && lce_id
|
14
|
-
content_facet
|
21
|
+
cve = content_facet&.assign_single_environment(content_view_id: cv_id, lifecycle_environment_id: lce_id)
|
22
|
+
Rails.logger.warn "Couldn't assign content view environment; host has no content facet" if cve.blank?
|
23
|
+
@pending_cve_attrs = {}
|
15
24
|
end
|
16
25
|
if (cv_id.present? && lce_id.blank?) || (cv_id.blank? && lce_id.present?)
|
17
|
-
|
26
|
+
errors.add(:base, _("Content view and lifecycle environment must be provided together"))
|
18
27
|
end
|
19
28
|
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def attributes=(attrs)
|
32
|
+
check_cve_attributes(attrs)
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def update(attrs)
|
37
|
+
check_cve_attributes(attrs) unless self.content_facet.blank?
|
20
38
|
super
|
21
39
|
end
|
22
40
|
|
@@ -30,6 +48,28 @@ module Katello
|
|
30
48
|
inherited_attrs
|
31
49
|
end
|
32
50
|
|
51
|
+
def apply_inherited_attributes(attributes, initialized = true)
|
52
|
+
attributes = super(attributes, initialized) || {}
|
53
|
+
facet_attrs = attributes&.[]('content_facet_attributes')
|
54
|
+
return attributes if facet_attrs.blank?
|
55
|
+
cv_id = facet_attrs['content_view_id']
|
56
|
+
lce_id = facet_attrs['lifecycle_environment_id']
|
57
|
+
if initialized && (cv_id.blank? || lce_id.blank?)
|
58
|
+
if cv_id.blank?
|
59
|
+
Rails.logger.info "Hostgroup has no content view assigned; using host's existing content view"
|
60
|
+
facet_attrs['content_view_id'] = content_facet&.single_content_view&.id
|
61
|
+
end
|
62
|
+
if lce_id.blank?
|
63
|
+
Rails.logger.info "Hostgroup has no lifecycle environment assigned; using host's existing lifecycle environment"
|
64
|
+
facet_attrs['lifecycle_environment_id'] = content_facet&.single_lifecycle_environment&.id
|
65
|
+
end
|
66
|
+
attributes['content_facet_attributes'] = facet_attrs
|
67
|
+
else
|
68
|
+
Rails.logger.debug "Hostgroup has content view and lifecycle environment assigned; using those"
|
69
|
+
end
|
70
|
+
attributes
|
71
|
+
end
|
72
|
+
|
33
73
|
def smart_proxy_ids
|
34
74
|
ids = super
|
35
75
|
ids << content_source_id
|
@@ -90,6 +130,8 @@ module Katello
|
|
90
130
|
has_many :hypervisor_pools, :class_name => '::Katello::Pool', :foreign_key => :hypervisor_id, :dependent => :nullify
|
91
131
|
|
92
132
|
before_validation :correct_kickstart_repository
|
133
|
+
after_validation :add_back_cve_errors
|
134
|
+
after_update :clear_pending_cve_attributes
|
93
135
|
before_update :check_host_registration, :if => proc { organization_id_changed? }
|
94
136
|
|
95
137
|
after_validation :queue_reset_content_host_status
|
@@ -118,6 +160,16 @@ module Katello
|
|
118
160
|
|
119
161
|
scoped_search relation: :pools, on: :pools_expiring_in_days, ext_method: :find_with_expiring_pools, only_explicit: true
|
120
162
|
|
163
|
+
def add_back_cve_errors
|
164
|
+
if @pending_cve_attrs&.[](:content_view_id).present? || @pending_cve_attrs&.[](:lifecycle_environment_id).present?
|
165
|
+
check_cve_attributes({ content_facet_attributes: @pending_cve_attrs })
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def clear_pending_cve_attributes
|
170
|
+
@pending_cve_attrs = {}
|
171
|
+
end
|
172
|
+
|
121
173
|
def self.find_with_expiring_pools(_key, _operator, days_from_now)
|
122
174
|
host_ids = with_pools_expiring_in_days(days_from_now).ids
|
123
175
|
if host_ids.any?
|
@@ -794,12 +794,20 @@ module Katello
|
|
794
794
|
return last_publish_result.present? && last_publish_result == 'success'
|
795
795
|
end
|
796
796
|
|
797
|
+
def cv_repo_indexed_after_last_published?
|
798
|
+
repositories.any? { |repo| repo.last_indexed && repo.last_indexed > latest_version_object.created_at }
|
799
|
+
end
|
800
|
+
|
797
801
|
def needs_publish?
|
798
802
|
#Returns
|
799
803
|
# True:
|
800
804
|
# a) When content/repo/filter change audit records exist
|
801
805
|
# b) CV hasn't ever been published
|
802
806
|
# c) CV dependency_solving != latest_version.applied_filters.dependency_solving
|
807
|
+
# d) If repo was indexed after cv publish. This can happen under 3 cases:
|
808
|
+
# i) Index runs because last index(before publish) had failed and repo is picked up for index even if pulp publication hasn't changed.
|
809
|
+
# ii) Complete sync runs or sync adds/removes new content (Already true because new pulp publication/version gets created)
|
810
|
+
# iii) repo.index_content is run. (This doesn't necessarily indicate contents changed. Corner case where we play safe and return true)
|
803
811
|
# nil:
|
804
812
|
# a) When CV version creation audit is missing(Indicating audit cleanup)
|
805
813
|
# b) Version doesn't have audited_filters set indicating
|
@@ -814,10 +822,11 @@ module Katello
|
|
814
822
|
return nil unless last_publish_task_success?
|
815
823
|
return composite_cv_components_changed? if composite?
|
816
824
|
# return true if the audit records clearly show we have unpublished changes
|
817
|
-
return true if
|
818
|
-
audited_cv_filters_changed.present? || audited_cv_filter_rules_changed.present?)
|
825
|
+
return true if audited_changes_present?
|
819
826
|
# return true if the dependency solving changed for CV between last publish and now
|
820
827
|
return true if dependency_solving_changed?
|
828
|
+
# return true if any child repo's indexed_at > last_version.created_at
|
829
|
+
return true if cv_repo_indexed_after_last_published?
|
821
830
|
# if we didn't return `true` already, either the audit records show that we don't need to publish, or we may
|
822
831
|
# have insufficient data to make the determination (either audits were cleaned, or never got created at all).
|
823
832
|
# first, check for the `create` audit record; its absence indicates that audits were cleaned some time after
|
@@ -834,6 +843,11 @@ module Katello
|
|
834
843
|
latest_version_object.applied_filters.nil? ? nil : false
|
835
844
|
end
|
836
845
|
|
846
|
+
def audited_changes_present?
|
847
|
+
audited_cv_repositories_since_last_publish.present? || audited_cv_repository_changed.present? ||
|
848
|
+
audited_cv_filters_changed.present? || audited_cv_filter_rules_changed.present?
|
849
|
+
end
|
850
|
+
|
837
851
|
def dependency_solving_changed?
|
838
852
|
latest_version_object.applied_filters && solve_dependencies != latest_version_object.applied_filters['dependency_solving']
|
839
853
|
end
|
@@ -134,7 +134,9 @@ module Katello
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def self.cleanup_tags
|
137
|
-
|
137
|
+
#Cleanup RepositoryMetaTag for nil schema meta tags
|
138
|
+
RepositoryDockerMetaTag.where(docker_meta_tag: where(schema1: nil, schema2: nil)).delete_all
|
139
|
+
self.where.not(id: RepositoryDockerMetaTag.select(:docker_meta_tag_id)).or(where(schema1: nil, schema2: nil)).delete_all
|
138
140
|
end
|
139
141
|
|
140
142
|
def self.import_meta_tags(repositories)
|
@@ -375,7 +375,9 @@ module Katello
|
|
375
375
|
class Jail < ::Safemode::Jail
|
376
376
|
allow :applicable_deb_count, :applicable_module_stream_count, :applicable_rpm_count, :content_source, :content_source_id, :content_source_name,
|
377
377
|
:errata_counts, :id, :kickstart_repository, :kickstart_repository_id, :kickstart_repository_name,
|
378
|
-
:upgradable_deb_count, :upgradable_module_stream_count, :upgradable_rpm_count, :uuid
|
378
|
+
:upgradable_deb_count, :upgradable_module_stream_count, :upgradable_rpm_count, :uuid,
|
379
|
+
:installable_security_errata_count, :installable_bugfix_errata_count, :installable_enhancement_errata_count,
|
380
|
+
:single_content_view, :single_lifecycle_environment
|
379
381
|
end
|
380
382
|
end
|
381
383
|
end
|