katello 3.18.0 → 3.18.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of katello might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +2 -1
- data/app/lib/actions/katello/capsule_content/sync_capsule.rb +7 -2
- data/app/lib/actions/katello/content_view_version/incremental_update.rb +19 -3
- data/app/lib/actions/middleware/record_smart_proxy_sync_history.rb +24 -4
- data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +4 -2
- data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +0 -4
- data/app/models/katello/concerns/pulp_database_unit.rb +7 -0
- data/app/models/katello/host/subscription_facet.rb +4 -0
- data/app/models/katello/subscription_status.rb +3 -2
- data/app/services/katello/applicability/applicable_content_helper.rb +12 -1
- data/app/services/katello/pulp3/content_view_version/import_validator.rb +0 -30
- data/app/views/katello/api/v2/content_views/show.json.rabl +6 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/deletion/content-view-version-deletion-activation-keys.controller.js +8 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/deletion/content-view-version-deletion-content-hosts.controller.js +9 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-details.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-publish.html +4 -0
- data/lib/katello/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78239ba1e921e408588db439d4b929151e1a9c10408e23c63f0ec5c76a23c66b
|
4
|
+
data.tar.gz: f945779353ab8cedce6a30e33f5ac4a264f6790e486a00126f15d3862babdfce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5526ccfbae423e0315e89349253756acf60bb920c9e3f1e2b7f581f677312e19d0141a185f58adeea0b08dc4d1a2d323bd051404c6c0d54faedd06ed5667427
|
7
|
+
data.tar.gz: 5f7d476d2061439219dc468b5ead1291835fe68bfacf1396b54db46f3e9afe3ca13c3383e5d5ce92f1d07c76ab5a0f59cffa78cda0c9500345dc5813c6ea24dc
|
@@ -267,8 +267,9 @@ module Katello
|
|
267
267
|
api :POST, "/hosts/bulk/available_incremental_updates", N_("Given a set of hosts and errata, lists the content view versions" \
|
268
268
|
" and environments that need updating.")
|
269
269
|
param_group :bulk_params
|
270
|
-
param :errata_ids, Array, :desc => N_("List of Errata ids")
|
270
|
+
param :errata_ids, Array, :desc => N_("List of Errata ids"), :required => true
|
271
271
|
def available_incremental_updates
|
272
|
+
fail HttpErrors::BadRequest, _("errata_ids is a required parameter") if params[:errata_ids].empty?
|
272
273
|
version_environments = {}
|
273
274
|
content_facets = Katello::Host::ContentFacet.with_non_installable_errata(@errata, @hosts)
|
274
275
|
|
@@ -19,9 +19,14 @@ module Actions
|
|
19
19
|
Actions::Pulp3::CapsuleContent::Sync],
|
20
20
|
repo, smart_proxy,
|
21
21
|
skip_metadata_check: skip_metadata_check)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
concurrence do
|
26
|
+
repo_batch.each do |repo|
|
22
27
|
if repo.is_a?(::Katello::Repository) &&
|
23
|
-
|
24
|
-
|
28
|
+
repo.distribution_bootable? &&
|
29
|
+
repo.download_policy == ::Runcible::Models::YumImporter::DOWNLOAD_ON_DEMAND
|
25
30
|
plan_action(Katello::Repository::FetchPxeFiles,
|
26
31
|
id: repo.id,
|
27
32
|
capsule_id: smart_proxy.id)
|
@@ -352,20 +352,36 @@ module Actions
|
|
352
352
|
end
|
353
353
|
|
354
354
|
def copy_yum_content(new_repo, dep_solve, package_ids, errata_ids)
|
355
|
+
return [] unless new_repo.content_type == ::Katello::Repository::YUM_TYPE
|
356
|
+
|
355
357
|
copy_outputs = []
|
356
|
-
|
357
|
-
|
358
|
+
|
359
|
+
unless errata_ids.blank?
|
360
|
+
content_present_in_this_repo = new_repo
|
361
|
+
.library_instance
|
362
|
+
.errata
|
363
|
+
.with_identifiers(errata_ids)
|
364
|
+
.exists?
|
365
|
+
if content_present_in_this_repo
|
358
366
|
copy_outputs << plan_action(Pulp::Repository::CopyUnits, new_repo.library_instance, new_repo,
|
359
367
|
::Katello::Erratum.with_identifiers(errata_ids),
|
360
368
|
incremental_update: dep_solve).output
|
361
369
|
end
|
370
|
+
end
|
362
371
|
|
363
|
-
|
372
|
+
unless package_ids.blank?
|
373
|
+
content_present_in_this_repo = new_repo
|
374
|
+
.library_instance
|
375
|
+
.rpms
|
376
|
+
.with_identifiers(package_ids)
|
377
|
+
.exists?
|
378
|
+
if content_present_in_this_repo
|
364
379
|
copy_outputs << plan_action(Pulp::Repository::CopyUnits, new_repo.library_instance, new_repo,
|
365
380
|
::Katello::Rpm.with_identifiers(package_ids),
|
366
381
|
incremental_update: dep_solve).output
|
367
382
|
end
|
368
383
|
end
|
384
|
+
|
369
385
|
copy_outputs
|
370
386
|
end
|
371
387
|
|
@@ -1,12 +1,32 @@
|
|
1
1
|
module Actions
|
2
2
|
module Middleware
|
3
3
|
class RecordSmartProxySyncHistory < Dynflow::Middleware
|
4
|
-
def
|
4
|
+
def save_smart_proxy_sync_history
|
5
5
|
if (action.input[:repository_id] && (action.input[:smart_proxy_id] || action.input[:capsule_id]) && !self.action.output[:smart_proxy_history_id])
|
6
|
-
|
6
|
+
repo_id = action.input[:repository_id]
|
7
|
+
repo = ::Katello::Repository.find_by(id: repo_id)
|
7
8
|
smart_proxy_id = action.input[:smart_proxy_id] || action.input[:capsule_id]
|
8
|
-
smart_proxy = ::SmartProxy.
|
9
|
-
|
9
|
+
smart_proxy = ::SmartProxy.find_by(id: smart_proxy_id)
|
10
|
+
|
11
|
+
#skip pulp2 puppet syncs
|
12
|
+
if (repo_pulp_id = action.input[:repo_pulp_id])
|
13
|
+
return if ::Katello::ContentViewPuppetEnvironment.find_by(pulp_id: repo_pulp_id)
|
14
|
+
end
|
15
|
+
|
16
|
+
if repo && smart_proxy
|
17
|
+
self.action.output[:smart_proxy_history_id] = repo.create_smart_proxy_sync_history(smart_proxy)
|
18
|
+
else
|
19
|
+
fail "Smart Proxy could not be found with id #{smart_proxy_id}" if smart_proxy.nil?
|
20
|
+
fail "Repository could not be found with id #{repo_id}" if repo.nil?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def run(*args)
|
26
|
+
begin
|
27
|
+
save_smart_proxy_sync_history
|
28
|
+
rescue => error
|
29
|
+
Rails.logger.error("Error saving smart proxy history: #{error.message}")
|
10
30
|
end
|
11
31
|
pass(*args)
|
12
32
|
end
|
@@ -76,8 +76,10 @@ module Actions
|
|
76
76
|
content_view_version: cvv,
|
77
77
|
smart_proxy: smart_proxy,
|
78
78
|
from_content_view_version: from_cvv).generate_metadata
|
79
|
-
|
80
|
-
|
79
|
+
|
80
|
+
toc_path_info = output[:exported_file_checksum].find { |item| item.first.end_with?("toc.json") }
|
81
|
+
export_metadata[:toc] = File.basename(toc_path_info.first)
|
82
|
+
|
81
83
|
history = ::Katello::ContentViewVersionExportHistory.create!(
|
82
84
|
content_view_version_id: input[:content_view_version_id],
|
83
85
|
destination_server: input[:destination_server],
|
@@ -91,6 +91,13 @@ module Katello
|
|
91
91
|
service_class.pulp_units_batch_all(pulp_ids).each do |units|
|
92
92
|
units.each do |unit|
|
93
93
|
unit = unit.with_indifferent_access
|
94
|
+
if content_type == 'rpm' && repository
|
95
|
+
rpms_to_disassociate = ::Katello::Rpm.where(name: unit[:name], version: unit[:version], release: unit[:release],
|
96
|
+
epoch: unit[:epoch], arch: unit[:arch]).select(:id)
|
97
|
+
if rpms_to_disassociate.any?
|
98
|
+
::Katello::RepositoryRpm.where(rpm_id: rpms_to_disassociate, repository_id: repository.id).destroy_all
|
99
|
+
end
|
100
|
+
end
|
94
101
|
model = Katello::Util::Support.active_record_retry do
|
95
102
|
self.where(:pulp_id => unit[service_class.unit_identifier]).first_or_create
|
96
103
|
end
|
@@ -282,6 +282,10 @@ module Katello
|
|
282
282
|
name.gsub('_', '-').chomp('.').downcase
|
283
283
|
end
|
284
284
|
|
285
|
+
def unsubscribed_hypervisor?
|
286
|
+
self.hypervisor && !self.candlepin_consumer.entitlements?
|
287
|
+
end
|
288
|
+
|
285
289
|
def candlepin_consumer
|
286
290
|
@candlepin_consumer ||= Katello::Candlepin::Consumer.new(self.uuid, self.host.organization.label)
|
287
291
|
end
|
@@ -43,9 +43,10 @@ module Katello
|
|
43
43
|
|
44
44
|
def to_status(options = {})
|
45
45
|
return UNKNOWN unless host.subscription_facet.try(:uuid)
|
46
|
-
|
46
|
+
return DISABLED if host.organization.simple_content_access?
|
47
|
+
status_override = 'unsubscribed_hypervisor' if host.subscription_facet.unsubscribed_hypervisor?
|
47
48
|
status_override ||= options.fetch(:status_override, nil)
|
48
|
-
status = status_override ||
|
49
|
+
status = status_override || host.subscription_facet.candlepin_consumer.entitlement_status
|
49
50
|
|
50
51
|
case status
|
51
52
|
when Katello::Candlepin::Consumer::ENTITLEMENTS_DISABLED
|
@@ -78,7 +78,8 @@ module Katello
|
|
78
78
|
joins("INNER JOIN katello_installed_packages ON
|
79
79
|
katello_rpms.name = katello_installed_packages.name AND
|
80
80
|
katello_rpms.arch = katello_installed_packages.arch AND
|
81
|
-
katello_rpms.evr > katello_installed_packages.evr
|
81
|
+
katello_rpms.evr > katello_installed_packages.evr AND
|
82
|
+
katello_installed_packages.id in (#{newest_distinct_installed_packages_query})").
|
82
83
|
joins("LEFT JOIN katello_module_stream_rpms ON
|
83
84
|
katello_rpms.id = katello_module_stream_rpms.rpm_id").
|
84
85
|
joins("INNER JOIN katello_host_installed_packages ON
|
@@ -92,6 +93,16 @@ module Katello
|
|
92
93
|
:enabled_module_streams => enabled_module_stream_ids).pluck(:id).uniq
|
93
94
|
end
|
94
95
|
|
96
|
+
def newest_distinct_installed_packages_query
|
97
|
+
"SELECT DISTINCT ON (katello_installed_packages.name) katello_installed_packages.id " \
|
98
|
+
"FROM katello_installed_packages INNER JOIN " \
|
99
|
+
"katello_host_installed_packages ON " \
|
100
|
+
"katello_installed_packages.id = " \
|
101
|
+
"katello_host_installed_packages.installed_package_id " \
|
102
|
+
"WHERE katello_host_installed_packages.host_id = " \
|
103
|
+
"#{content_facet.host.id} ORDER BY katello_installed_packages.name, katello_installed_packages.evr DESC"
|
104
|
+
end
|
105
|
+
|
95
106
|
def applicable_differences
|
96
107
|
consumer_ids = content_facet.send(applicable_units).pluck("#{content_unit_class.table_name}.id")
|
97
108
|
content_ids = fetch_content_ids
|
@@ -2,7 +2,6 @@ module Katello
|
|
2
2
|
module Pulp3
|
3
3
|
module ContentViewVersion
|
4
4
|
class ImportValidator
|
5
|
-
BASEDIR = '/var/lib/pulp'.freeze
|
6
5
|
attr_accessor :metadata, :path, :content_view
|
7
6
|
def initialize(content_view:, path:, metadata:)
|
8
7
|
self.content_view = content_view
|
@@ -11,7 +10,6 @@ module Katello
|
|
11
10
|
end
|
12
11
|
|
13
12
|
def check!
|
14
|
-
check_permissions!
|
15
13
|
unless content_view.default?
|
16
14
|
ensure_importing_cvv_does_not_exist!
|
17
15
|
ensure_from_cvv_exists!
|
@@ -71,34 +69,6 @@ module Katello
|
|
71
69
|
end
|
72
70
|
end
|
73
71
|
|
74
|
-
def check_permissions!
|
75
|
-
fail _("Invalid path specified.") if path.blank? || !File.directory?(path)
|
76
|
-
fail _("The import path must be in a subdirectory under '%s'." % BASEDIR) unless path.starts_with?(BASEDIR)
|
77
|
-
fail _("Pulp user or group unable to read content in '%s'." % path) unless pulp_user_accessible?(path)
|
78
|
-
|
79
|
-
Dir.glob("#{path}/*").each do |file|
|
80
|
-
fail _("Pulp user or group unable to read '%s'." % file) unless pulp_user_accessible?(file)
|
81
|
-
end
|
82
|
-
toc_path = "#{path}/#{metadata[:toc]}"
|
83
|
-
fail _("The TOC file specified in the metadata does not exist. %s " % toc_path) unless File.exist?(toc_path)
|
84
|
-
end
|
85
|
-
|
86
|
-
def pulp_user_accessible?(path)
|
87
|
-
pulp_info = fetch_pulp_user_info
|
88
|
-
return false if pulp_info.blank?
|
89
|
-
|
90
|
-
stat = File.stat(path)
|
91
|
-
stat.gid.to_s == pulp_info.gid ||
|
92
|
-
stat.uid.to_s == pulp_info.uid ||
|
93
|
-
stat.mode.to_s(8)[-1].to_i >= 4
|
94
|
-
end
|
95
|
-
|
96
|
-
def fetch_pulp_user_info
|
97
|
-
pulp_user = nil
|
98
|
-
Etc.passwd { |u| pulp_user = u if u.name == 'pulp' }
|
99
|
-
pulp_user
|
100
|
-
end
|
101
|
-
|
102
72
|
def generate_product_repo_i18n_string(product_repos)
|
103
73
|
# product_repos look like [["prod1", "repo1", false], ["prod2", "repo2", false]]
|
104
74
|
product_repos.map do |product, repo, redhat|
|
@@ -4,6 +4,12 @@ extends "katello/api/v2/content_views/base"
|
|
4
4
|
|
5
5
|
attributes :content_host_count
|
6
6
|
|
7
|
+
node :errors do
|
8
|
+
unless @resource.valid?
|
9
|
+
attribute :messages => @resource.errors.full_messages
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
child :duplicate_repositories_to_publish => :duplicate_repositories_to_publish do
|
8
14
|
attributes :id, :name
|
9
15
|
node :components do |repo|
|
@@ -16,16 +16,20 @@
|
|
16
16
|
angular.module('Bastion.content-views').controller('ContentViewVersionDeletionActivationKeysController',
|
17
17
|
['$scope', '$location', 'Organization', 'CurrentOrganization', 'Nutupane', 'ActivationKey',
|
18
18
|
function ($scope, $location, Organization, CurrentOrganization, Nutupane, ActivationKey) {
|
19
|
-
var params, nutupane;
|
19
|
+
var params, nutupane, nutupaneParams;
|
20
20
|
|
21
21
|
$scope.validateEnvironmentSelection();
|
22
22
|
params = {
|
23
23
|
'organization_id': CurrentOrganization,
|
24
|
-
'content_view_id': $scope.contentView.id,
|
25
24
|
'sort_by': 'name',
|
26
25
|
'sort_order': 'ASC'
|
27
26
|
};
|
28
|
-
|
27
|
+
|
28
|
+
nutupaneParams = {
|
29
|
+
'disableAutoLoad': true
|
30
|
+
};
|
31
|
+
|
32
|
+
nutupane = new Nutupane(ActivationKey, params, undefined, nutupaneParams);
|
29
33
|
$scope.controllerName = 'katello_activation_keys';
|
30
34
|
|
31
35
|
nutupane.searchTransform = function (term) {
|
@@ -43,6 +47,7 @@ angular.module('Bastion.content-views').controller('ContentViewVersionDeletionAc
|
|
43
47
|
|
44
48
|
return term + " AND " + addition;
|
45
49
|
};
|
50
|
+
nutupane.load();
|
46
51
|
|
47
52
|
$scope.table = nutupane.table;
|
48
53
|
$scope.table.closeItem = function () {};
|
@@ -17,16 +17,20 @@ angular.module('Bastion.content-views').controller('ContentViewVersionDeletionCo
|
|
17
17
|
['$scope', '$location', 'Organization', 'CurrentOrganization', 'Nutupane', 'Host',
|
18
18
|
function ($scope, $location, Organization, CurrentOrganization, Nutupane, Host) {
|
19
19
|
|
20
|
-
var params, nutupane;
|
20
|
+
var params, nutupane, nutupaneParams;
|
21
21
|
|
22
22
|
$scope.validateEnvironmentSelection();
|
23
23
|
params = {
|
24
24
|
'organization_id': CurrentOrganization,
|
25
|
-
'content_view_id': $scope.contentView.id,
|
26
25
|
'sort_by': 'name',
|
27
26
|
'sort_order': 'ASC'
|
28
27
|
};
|
29
|
-
|
28
|
+
|
29
|
+
nutupaneParams = {
|
30
|
+
'disableAutoLoad': true
|
31
|
+
};
|
32
|
+
|
33
|
+
nutupane = new Nutupane(Host, params, undefined, nutupaneParams);
|
30
34
|
$scope.controllerName = 'hosts';
|
31
35
|
|
32
36
|
nutupane.searchTransform = function (term) {
|
@@ -44,6 +48,8 @@ angular.module('Bastion.content-views').controller('ContentViewVersionDeletionCo
|
|
44
48
|
|
45
49
|
return term + " AND " + addition;
|
46
50
|
};
|
51
|
+
|
52
|
+
nutupane.load();
|
47
53
|
$scope.table = nutupane.table;
|
48
54
|
$scope.table.closeItem = function () {};
|
49
55
|
|
@@ -13,7 +13,7 @@
|
|
13
13
|
</div>
|
14
14
|
|
15
15
|
<nav data-block="item-actions">
|
16
|
-
<button type="button" class="btn btn-primary" ng-hide="denied('publish_content_views', contentView) || contentView.import_only"
|
16
|
+
<button type="button" class="btn btn-primary" ng-hide="denied('publish_content_views', contentView) || contentView.import_only"
|
17
17
|
ui-sref="content-view.publish">
|
18
18
|
<span translate>Publish New Version</span>
|
19
19
|
</button>
|
@@ -7,6 +7,10 @@
|
|
7
7
|
It can be promoted to other environments from the Versions tab of this Content View.
|
8
8
|
</p>
|
9
9
|
|
10
|
+
<div bst-alert="warning" ng-show="contentView.errors['messages'].length > 0">
|
11
|
+
<span translate>{{contentView.errors['messages'][0]}}</span>
|
12
|
+
</div>
|
13
|
+
|
10
14
|
<header class="details-header">
|
11
15
|
<h3 translate>Version Details</h3>
|
12
16
|
</header>
|
data/lib/katello/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: katello
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.18.
|
4
|
+
version: 3.18.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- N/A
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|