katello 4.0.0 → 4.0.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/registry/registry_proxies_controller.rb +5 -7
- data/app/controllers/katello/api/v2/repositories_controller.rb +4 -3
- data/app/lib/actions/katello/agent_action.rb +26 -17
- data/app/lib/actions/katello/bulk_agent_action.rb +18 -5
- data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
- data/app/lib/actions/katello/capsule_content/sync_capsule.rb +44 -6
- data/app/lib/actions/katello/content_view/promote.rb +25 -0
- data/app/lib/actions/katello/content_view/publish.rb +29 -0
- data/app/lib/actions/katello/content_view_version/incremental_update.rb +14 -3
- data/app/lib/actions/katello/jail_concern/content_view.rb +30 -0
- data/app/lib/actions/katello/jail_concern/organization.rb +30 -0
- data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +2 -2
- data/app/lib/actions/katello/repository/check_matching_content.rb +3 -4
- data/app/lib/actions/katello/repository/sync.rb +59 -0
- data/app/lib/actions/pulp3/content_guard/refresh.rb +6 -10
- data/app/lib/actions/pulp3/orchestration/orphan_cleanup/remove_orphans.rb +1 -1
- data/app/lib/katello/agent/client_message_handler.rb +12 -3
- data/app/lib/katello/errors.rb +1 -1
- data/app/lib/katello/event_daemon/monitor.rb +1 -0
- data/app/lib/katello/event_daemon/services/agent_event_receiver.rb +6 -10
- data/app/lib/katello/util/hostgroup_facets_helper.rb +126 -0
- data/app/models/katello/agent/dispatch_history.rb +2 -0
- data/app/models/katello/authorization/content_view.rb +12 -0
- data/app/models/katello/authorization/repository.rb +18 -0
- data/app/models/katello/concerns/hostgroup_extensions.rb +4 -2
- data/app/models/katello/concerns/redhat_extensions.rb +23 -18
- data/app/models/katello/concerns/smart_proxy_extensions.rb +23 -0
- data/app/models/katello/content_view.rb +13 -7
- data/app/models/katello/glue/pulp/repo.rb +0 -19
- data/app/models/katello/ping.rb +3 -10
- data/app/models/katello/repository.rb +16 -2
- data/app/models/katello/root_repository.rb +1 -1
- data/app/services/cert/certs.rb +4 -0
- data/app/services/katello/agent/dispatcher.rb +18 -24
- data/app/services/katello/applicability/applicable_content_helper.rb +8 -6
- data/app/services/katello/managed_content_medium_provider.rb +3 -3
- data/app/services/katello/pulp3/api/content_guard.rb +39 -5
- data/app/services/katello/pulp3/migration.rb +4 -3
- data/app/services/katello/pulp3/repository.rb +32 -4
- data/app/services/katello/pulp3/repository/apt.rb +1 -2
- data/app/services/katello/pulp3/repository/yum.rb +1 -1
- data/app/services/katello/ui_notifications/pulp/proxy_disk_space.rb +1 -0
- data/app/views/overrides/smart_proxies/_download_policy.erb +1 -1
- data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +1 -1
- data/db/migrate/20210119162528_delete_puppet_and_ostree_repos.rb +25 -22
- data/db/migrate/20210512192745_fix_red_hat_root_repository_arch.rb +11 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/views/products-bulk-advanced-sync-modal.html +2 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +3 -4
- data/lib/katello.rb +1 -1
- data/lib/katello/engine.rb +11 -11
- data/lib/katello/plugin.rb +5 -2
- data/lib/katello/tasks/clean_backend_objects.rake +0 -25
- data/lib/katello/tasks/fix_hostgroup_facets.rake +8 -0
- data/lib/katello/version.rb +1 -1
- data/lib/proxy_api/container_gateway.rb +22 -11
- metadata +28 -10
- data/app/lib/actions/pulp3/capsule_content/refresh_content_guard.rb +0 -17
@@ -1,13 +1,13 @@
|
|
1
1
|
module Actions
|
2
2
|
module Katello
|
3
3
|
module OrphanCleanup
|
4
|
-
class RemoveOrphans <
|
4
|
+
class RemoveOrphans < Actions::Base
|
5
5
|
input_format do
|
6
6
|
param :capsule_id
|
7
7
|
end
|
8
8
|
def plan(proxy)
|
9
9
|
sequence do
|
10
|
-
plan_action(Actions::Pulp::Orchestration::OrphanCleanup::RemoveOrphans, proxy)
|
10
|
+
plan_action(Actions::Pulp::Orchestration::OrphanCleanup::RemoveOrphans, proxy) if (proxy.has_feature?(SmartProxy::PULP_FEATURE) || proxy.has_feature?(SmartProxy::PULP_NODE_FEATURE))
|
11
11
|
if proxy.pulp3_enabled?
|
12
12
|
plan_action(
|
13
13
|
Actions::Pulp3::Orchestration::OrphanCleanup::RemoveOrphans,
|
@@ -13,6 +13,7 @@ module Actions
|
|
13
13
|
def run
|
14
14
|
source_repo = ::Katello::Repository.find(input[:source_repo_id])
|
15
15
|
target_repo = ::Katello::Repository.find(input[:target_repo_id])
|
16
|
+
target_repo_published = target_repo.backend_service(SmartProxy.pulp_primary).published?
|
16
17
|
|
17
18
|
if source_repo.content_type == ::Katello::Repository::YUM_TYPE
|
18
19
|
srpms_match = srpms_match?(source_repo, target_repo)
|
@@ -23,16 +24,14 @@ module Actions
|
|
23
24
|
yum_metadata_files = yum_metadata_files_match?(source_repo, target_repo)
|
24
25
|
checksum_match = (target_repo.saved_checksum_type == source_repo.saved_checksum_type)
|
25
26
|
|
26
|
-
published = target_repo.backend_service(SmartProxy.pulp_primary).published?
|
27
|
-
|
28
27
|
output[:checksum_match] = checksum_match
|
29
|
-
output[:matching_content] = yum_metadata_files && srpms_match && rpms && errata && package_groups && distributions &&
|
28
|
+
output[:matching_content] = yum_metadata_files && srpms_match && rpms && errata && package_groups && distributions && target_repo_published && checksum_match
|
30
29
|
end
|
31
30
|
|
32
31
|
if source_repo.content_type == ::Katello::Repository::DEB_TYPE
|
33
32
|
debs = debs_match?(source_repo, target_repo)
|
34
33
|
|
35
|
-
output[:matching_content] = debs &&
|
34
|
+
output[:matching_content] = debs && target_repo_published
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
@@ -3,8 +3,10 @@ module Actions
|
|
3
3
|
module Katello
|
4
4
|
module Repository
|
5
5
|
class Sync < Actions::EntryAction
|
6
|
+
extend ApipieDSL::Class
|
6
7
|
include Helpers::Presenter
|
7
8
|
include Actions::Katello::PulpSelector
|
9
|
+
include ::Actions::ObservableAction
|
8
10
|
middleware.use Actions::Middleware::ExecuteIfContentsChanged
|
9
11
|
|
10
12
|
input_format do
|
@@ -124,6 +126,63 @@ module Actions
|
|
124
126
|
def rescue_strategy
|
125
127
|
Dynflow::Action::Rescue::Skip
|
126
128
|
end
|
129
|
+
|
130
|
+
def repository_id
|
131
|
+
input['repository']['id']
|
132
|
+
end
|
133
|
+
|
134
|
+
def repository_name
|
135
|
+
input['repository']['name']
|
136
|
+
end
|
137
|
+
|
138
|
+
def repository_label
|
139
|
+
input['repository']['label']
|
140
|
+
end
|
141
|
+
|
142
|
+
def product_id
|
143
|
+
input['product']['id']
|
144
|
+
end
|
145
|
+
|
146
|
+
def product_name
|
147
|
+
input['product']['name']
|
148
|
+
end
|
149
|
+
|
150
|
+
def product_label
|
151
|
+
input['product']['label']
|
152
|
+
end
|
153
|
+
|
154
|
+
def contents_changed
|
155
|
+
input['contents_changed']
|
156
|
+
end
|
157
|
+
|
158
|
+
def sync_result
|
159
|
+
input['sync_result']
|
160
|
+
end
|
161
|
+
|
162
|
+
apipie :class, "A class representing #{self} object" do
|
163
|
+
desc 'This object is available as **@object** variable in
|
164
|
+
webhook templates when a corresponding event occures.
|
165
|
+
The following properties can be used to retrieve the needed information.'
|
166
|
+
name "#{class_scope}"
|
167
|
+
refs "#{class_scope}"
|
168
|
+
sections only: %w[all webhooks]
|
169
|
+
property :task, object_of: 'Task', desc: 'Returns the task to which this action belongs'
|
170
|
+
property :repository_id, Integer, desc: 'Returns synced repository id'
|
171
|
+
property :repository_name, String, desc: 'Returns synced repository name'
|
172
|
+
property :repository_label, String, desc: 'Returns synced repository label'
|
173
|
+
property :product_id, Integer, desc: 'Returns product id the synced repository belongs to'
|
174
|
+
property :product_name, String, desc: 'Returns product name the synced repository belongs to'
|
175
|
+
property :product_label, String, desc: 'Returns product label the synced repository belongs to'
|
176
|
+
property :sync_result, Hash, desc: 'Returns Hash object with sync result'
|
177
|
+
property :contents_changed, one_of: [true, false], desc: 'Returns true if repository content was changed due to sync, false otherwise'
|
178
|
+
end
|
179
|
+
include Actions::Katello::JailConcern::Organization
|
180
|
+
class Jail < ::Actions::ObservableAction::Jail
|
181
|
+
allow :organization_id, :organization_name, :organization_label,
|
182
|
+
:repository_id, :repository_name, :repository_label,
|
183
|
+
:product_id, :product_name, :product_label,
|
184
|
+
:sync_result, :contents_changed
|
185
|
+
end
|
127
186
|
end
|
128
187
|
end
|
129
188
|
end
|
@@ -2,16 +2,12 @@ module Actions
|
|
2
2
|
module Pulp3
|
3
3
|
module ContentGuard
|
4
4
|
class Refresh < Pulp3::Abstract
|
5
|
-
def plan(smart_proxy
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
else
|
12
|
-
content_guard_api.create
|
13
|
-
::Katello::Pulp3::ContentGuard.import(smart_proxy)
|
14
|
-
end
|
5
|
+
def plan(smart_proxy)
|
6
|
+
plan_self(smart_proxy_id: smart_proxy.id)
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
::Katello::Pulp3::Api::ContentGuard.new(smart_proxy).refresh
|
15
11
|
end
|
16
12
|
end
|
17
13
|
end
|
@@ -8,6 +8,7 @@ module Katello
|
|
8
8
|
@dispatch_history = Katello::Agent::DispatchHistory.find_by_id(dispatch_history_id)
|
9
9
|
|
10
10
|
unless @dispatch_history
|
11
|
+
logger.error("Invalid client message: #{@json}")
|
11
12
|
fail("No valid dispatch history in client message")
|
12
13
|
end
|
13
14
|
end
|
@@ -33,9 +34,17 @@ module Katello
|
|
33
34
|
private
|
34
35
|
|
35
36
|
def handle_dynflow_event
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
return unless accepted? || result
|
38
|
+
|
39
|
+
task = ForemanTasks::Task.find_by_external_id(@dispatch_history.dynflow_execution_plan_id)
|
40
|
+
|
41
|
+
unless task
|
42
|
+
logger.info("Task external_id=#{@dispatch_history.dynflow_execution_plan_id} wasn't found. Skipping dynflow event dispatch")
|
43
|
+
return
|
44
|
+
end
|
45
|
+
|
46
|
+
unless task.result == 'pending'
|
47
|
+
logger.info("Task is no longer pending. Skipping dynflow event dispatch. task_result=#{task.result} external_id=#{@dispatch_history.dynflow_execution_plan_id} dispatch_history_id=#{@dispatch_history.id}")
|
39
48
|
return
|
40
49
|
end
|
41
50
|
|
data/app/lib/katello/errors.rb
CHANGED
@@ -53,7 +53,7 @@ module Katello
|
|
53
53
|
|
54
54
|
class PulpcoreMissingCapabilities < StandardError
|
55
55
|
def message
|
56
|
-
_("A smart proxy seems to have been refreshed without pulpcore being running.
|
56
|
+
_("A smart proxy seems to have been refreshed without pulpcore being running. Please refresh the smart proxy after ensuring that pulpcore services are running.")
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -2,8 +2,6 @@ module Katello
|
|
2
2
|
module EventDaemon
|
3
3
|
module Services
|
4
4
|
class AgentEventReceiver
|
5
|
-
STATUS_CACHE_KEY = 'katello_agent_events'.freeze
|
6
|
-
|
7
5
|
class Handler
|
8
6
|
attr_accessor :processed, :failed
|
9
7
|
|
@@ -48,14 +46,12 @@ module Katello
|
|
48
46
|
@agent_connection&.open? && @thread&.status.present?
|
49
47
|
end
|
50
48
|
|
51
|
-
def self.status
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
}
|
58
|
-
end
|
49
|
+
def self.status
|
50
|
+
{
|
51
|
+
running: running?,
|
52
|
+
processed_count: @handler&.processed || 0,
|
53
|
+
failed_count: @handler&.failed || 0
|
54
|
+
}
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# Used exclusively by fix_hostgroup_facets.rake task
|
2
|
+
module Katello
|
3
|
+
module Util
|
4
|
+
class HostgroupFacetsHelper
|
5
|
+
def initialize
|
6
|
+
@logger = Logger.new($stdout)
|
7
|
+
end
|
8
|
+
|
9
|
+
def interested_hostgroups
|
10
|
+
groups = ::Hostgroup.unscoped.where(
|
11
|
+
id: Katello::Hostgroup::ContentFacet.
|
12
|
+
where(content_source_id: nil,
|
13
|
+
kickstart_repository_id: nil,
|
14
|
+
content_view_id: nil,
|
15
|
+
lifecycle_environment_id: nil).select(:hostgroup_id))
|
16
|
+
parents = groups.select { |group| group.parent.blank? }
|
17
|
+
children = groups.reject { |group| group.parent.blank? }
|
18
|
+
# we want the parents to get created before the children
|
19
|
+
# hence the order
|
20
|
+
parents + children
|
21
|
+
end
|
22
|
+
|
23
|
+
def pick_facet_values(hg)
|
24
|
+
# This call looks at the audit logs for a host group.
|
25
|
+
# Pries out information related to lce, ks, cv and content_source_id from the audit logs.
|
26
|
+
# The audit logs typically only contain updates.
|
27
|
+
# So if the user changed just the content_view_id, then that is the only thing marked as audited_changes.
|
28
|
+
# Hence we need to go through all the audit logs until we have information on lce, ks, cv and cs.
|
29
|
+
# If there was only one audit log and that was during the creation of hostgroup
|
30
|
+
# the audited changes look like this
|
31
|
+
# ```ruby
|
32
|
+
# {
|
33
|
+
# content_view_id: 10,
|
34
|
+
# kickstart_repository_id: 1000
|
35
|
+
# ......
|
36
|
+
# }
|
37
|
+
# ```
|
38
|
+
# However if you updated the hostgroup and set the kickstart_repository_id, or
|
39
|
+
# content_view_id then audited changes look like
|
40
|
+
# ```ruby
|
41
|
+
# {
|
42
|
+
# content_view_id: [10, 11],
|
43
|
+
# kickstart_repository_id: [1000, 1200]
|
44
|
+
# ......
|
45
|
+
# }
|
46
|
+
# ```
|
47
|
+
# So the code says "if the attribute value is an array pick the last value else just keep the value as it is "
|
48
|
+
|
49
|
+
# Further along it is to be noted that `hostgroup.audits` returns the audits ordered by the version number in ascending order, so the latest audit will be `hostgroup.audits.last`
|
50
|
+
|
51
|
+
# We want to iterate though each audit from latest audit to start, and as soon as we find a content_view_id key or kickstart_repository_id key or lifecycle environment_id key or content_source_id key we want it to be set once.
|
52
|
+
|
53
|
+
# So if I had an audit history like
|
54
|
+
# ``` ruby
|
55
|
+
# {
|
56
|
+
# content_view_id: 10,
|
57
|
+
# kickstart_repository_id: 1000,
|
58
|
+
# version:1
|
59
|
+
# ......
|
60
|
+
# },
|
61
|
+
# {
|
62
|
+
# content_view_id: [10, 11],
|
63
|
+
# kickstart_repository_id: [1000, 1200],
|
64
|
+
# version: 2
|
65
|
+
# ......
|
66
|
+
# }
|
67
|
+
# ```
|
68
|
+
|
69
|
+
# The code would start at version 2, notice that cv_id and ks_repo were set there
|
70
|
+
# and keep them as the final.
|
71
|
+
# So when it goes to version 1 since cv_id and ks_repo are already set,
|
72
|
+
# it will ignore. It will finally
|
73
|
+
# return {content_view_id: 11, kickstart_repository_id: 1200}
|
74
|
+
facet_values = {}
|
75
|
+
hg.audits.reverse_each do |audit|
|
76
|
+
hg_changes = audit.audited_changes.slice("lifecycle_environment_id",
|
77
|
+
"kickstart_repository_id",
|
78
|
+
"content_view_id",
|
79
|
+
"content_source_id")
|
80
|
+
facet_values = hg_changes.merge(facet_values)
|
81
|
+
end
|
82
|
+
|
83
|
+
values = facet_values.map do |k, v|
|
84
|
+
v = v[-1] if v.is_a? Array
|
85
|
+
[k, v]
|
86
|
+
end
|
87
|
+
values.to_h.with_indifferent_access
|
88
|
+
end
|
89
|
+
|
90
|
+
def main
|
91
|
+
bad_hgs = []
|
92
|
+
good_hgs = []
|
93
|
+
|
94
|
+
groups = interested_hostgroups.each do |hg|
|
95
|
+
facet = hg.content_facet
|
96
|
+
values = pick_facet_values(hg)
|
97
|
+
if !values.empty? && facet.update(values)
|
98
|
+
good_hgs << { hostgroup: hg, facet_values: values }
|
99
|
+
else
|
100
|
+
bad_hgs << { hostgroup: hg, facet_values: values }
|
101
|
+
facet.save(validate: false)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
unless bad_hgs.empty?
|
106
|
+
@logger.warn "Some of the hostgroups reported a validation error. "\
|
107
|
+
"The hostgroups have been updated. "\
|
108
|
+
"Check via the Web UI."
|
109
|
+
|
110
|
+
bad_hgs.each do |bad_group|
|
111
|
+
@logger.warn "Hostgroup #{bad_group[:hostgroup]}"
|
112
|
+
@logger.warn "Facet Values #{bad_group[:facet_values]}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
unless good_hgs.empty?
|
116
|
+
@logger.info "Following hostgroups were succesfully updated."
|
117
|
+
good_hgs.each do |good_group|
|
118
|
+
@logger.info "Hostgroup #{good_group[:hostgroup]}"
|
119
|
+
@logger.info "Facet Values #{good_group[:facet_values]}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
@logger.info("#{groups.count} Hostgroup(s) were updated.")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -33,6 +33,18 @@ module Katello
|
|
33
33
|
authorized(:view_content_views)
|
34
34
|
end
|
35
35
|
|
36
|
+
def creatable
|
37
|
+
authorized(:view_content_views)
|
38
|
+
end
|
39
|
+
|
40
|
+
def importable?
|
41
|
+
creatable? && publishable?
|
42
|
+
end
|
43
|
+
|
44
|
+
def readable_as(user)
|
45
|
+
authorized_as(user, :view_content_views)
|
46
|
+
end
|
47
|
+
|
36
48
|
def readable?
|
37
49
|
::User.current.can?(:view_content_views)
|
38
50
|
end
|
@@ -27,6 +27,24 @@ module Katello
|
|
27
27
|
joins(:root).where("#{Repository.table_name}.id in (?) or #{self.table_name}.id in (?) or #{self.table_name}.id in (?) or #{self.table_name}.id in (?)", in_products, in_content_views, in_versions, in_environments)
|
28
28
|
end
|
29
29
|
|
30
|
+
def readable_as(user)
|
31
|
+
in_products = Repository.in_product(Katello::Product.authorized_as(user, :view_products)).select(:id)
|
32
|
+
in_environments = Repository.where(:environment_id => Katello::KTEnvironment.authorized_as(user, :view_lifecycle_environments)).select(:id)
|
33
|
+
in_content_views = Repository.joins(:content_view_repositories).where("#{ContentViewRepository.table_name}.content_view_id" => Katello::ContentView.readable_as(user)).select(:id)
|
34
|
+
in_versions = Repository.joins(:content_view_version).where("#{Katello::ContentViewVersion.table_name}.content_view_id" => Katello::ContentView.readable_as(user)).select(:id)
|
35
|
+
joins(:root).where("#{Repository.table_name}.id in (?) or #{self.table_name}.id in (?) or #{self.table_name}.id in (?) or #{self.table_name}.id in (?)", in_products, in_content_views, in_versions, in_environments)
|
36
|
+
end
|
37
|
+
|
38
|
+
def readable_docker_catalog
|
39
|
+
readable_docker_catalog_as(User.current)
|
40
|
+
end
|
41
|
+
|
42
|
+
def readable_docker_catalog_as(user)
|
43
|
+
table_name = Repository.table_name
|
44
|
+
in_unauth_environments = Repository.joins(:environment).where("#{Katello::KTEnvironment.table_name}.registry_unauthenticated_pull" => true).select(:id)
|
45
|
+
Repository.readable_as(user).or(Repository.joins(:root).where("#{table_name}.id in (?)", in_unauth_environments)).non_archived.docker_type
|
46
|
+
end
|
47
|
+
|
30
48
|
def exportable
|
31
49
|
in_product(Katello::Product.exportable)
|
32
50
|
end
|
@@ -107,7 +107,9 @@ module Katello
|
|
107
107
|
return true unless operatingsystem
|
108
108
|
|
109
109
|
if operatingsystem.respond_to? :kickstart_repos
|
110
|
-
|
110
|
+
operatingsystem.kickstart_repos(self, content_facet: content_facet).any? do |repo|
|
111
|
+
repo[:id] == (content_facet&.kickstart_repository_id || content_facet&.kickstart_repository&.id)
|
112
|
+
end
|
111
113
|
end
|
112
114
|
end
|
113
115
|
|
@@ -126,7 +128,7 @@ module Katello
|
|
126
128
|
facet_model = Facets.registered_facets[facet].hostgroup_configuration.model
|
127
129
|
value = facet_model.where.not(attribute => nil).joins(:hostgroup).merge(
|
128
130
|
::Hostgroup.where(id: self.ancestor_ids).reorder(ancestry: :desc)
|
129
|
-
).limit(1).pluck(attribute)
|
131
|
+
).limit(1).pluck(attribute).first
|
130
132
|
end
|
131
133
|
value
|
132
134
|
end
|
@@ -10,8 +10,15 @@ module Katello
|
|
10
10
|
minor ||= '' # treat minor versions as empty string to not confuse with nil
|
11
11
|
os = ::Redhat.where(:name => os_name, :major => major, :minor => minor).try(:first)
|
12
12
|
return os if os
|
13
|
-
|
14
|
-
|
13
|
+
|
14
|
+
if ::Redhat.where(:title => "#{os_name} #{repo.distribution_version}").present?
|
15
|
+
description = "#{os_name} #{repo.distribution_version} #{SecureRandom.uuid}"
|
16
|
+
create_os = lambda do
|
17
|
+
::Redhat.create!(:name => os_name, :major => major, :minor => minor, :description => description)
|
18
|
+
end
|
19
|
+
else
|
20
|
+
create_os = lambda { ::Redhat.create!(:name => os_name, :major => major, :minor => minor) }
|
21
|
+
end
|
15
22
|
|
16
23
|
begin
|
17
24
|
create_os.call
|
@@ -42,33 +49,31 @@ module Katello
|
|
42
49
|
end
|
43
50
|
end
|
44
51
|
|
45
|
-
def kickstart_repos(host)
|
46
|
-
distros = distribution_repositories(host).where(distribution_bootable: true)
|
47
|
-
|
48
|
-
|
52
|
+
def kickstart_repos(host, content_facet: nil)
|
53
|
+
distros = distribution_repositories(host, content_facet: content_facet).where(distribution_bootable: true)
|
54
|
+
content_facet ||= host.content_facet
|
55
|
+
if distros && content_facet&.content_source
|
56
|
+
distros.map { |distro| distro.to_hash(content_facet.content_source) }
|
49
57
|
else
|
50
58
|
[]
|
51
59
|
end
|
52
60
|
end
|
53
61
|
|
54
|
-
def
|
62
|
+
def variant_repos(host, variant)
|
55
63
|
if variant && host.content_source
|
56
64
|
product_id = host.try(:content_facet).try(:kickstart_repository).try(:product_id) || host.try(:kickstart_repository).try(:product_id)
|
57
|
-
|
65
|
+
distros = distribution_repositories(host)
|
58
66
|
.joins(:product)
|
59
|
-
.where(
|
60
|
-
|
61
|
-
|
62
|
-
).first
|
63
|
-
|
64
|
-
distro&.to_hash(host.content_source)
|
67
|
+
.where("#{Katello::Repository.table_name}.distribution_variant LIKE :variant", { variant: "%#{variant}%" })
|
68
|
+
.where("#{Katello::Product.table_name}.id": product_id).collect { |repo| repo.to_hash(host.content_source, true) }
|
69
|
+
distros
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
68
|
-
def distribution_repositories(host)
|
69
|
-
|
70
|
-
|
71
|
-
|
73
|
+
def distribution_repositories(host, content_facet: nil)
|
74
|
+
content_facet ||= host.content_facet
|
75
|
+
content_view = content_facet.try(:content_view) || host.try(:content_view)
|
76
|
+
lifecycle_environment = content_facet.try(:lifecycle_environment) || host.try(:lifecycle_environment)
|
72
77
|
if content_view && lifecycle_environment && host.os && host.architecture
|
73
78
|
Katello::Repository.in_environment(lifecycle_environment).in_content_views([content_view]).
|
74
79
|
where(:distribution_arch => host.architecture.name).
|