Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/debian errata working #9886

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/controllers/katello/api/v2/repositories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def custom_index_relation(collection)
param :deb_releases, String, :desc => N_("whitespace-separated list of releases to be synced from deb-archive")
param :deb_components, String, :desc => N_("whitespace-separated list of repo components to be synced from deb-archive")
param :deb_architectures, String, :desc => N_("whitespace-separated list of architectures to be synced from deb-archive")
param :deb_errata_url, String, :desc => N_("URL to a deb errata service (use only on the security repositories)")
param :ignorable_content, Array, :desc => N_("List of content units to ignore while syncing a yum repository. Must be subset of %s") % RootRepository::IGNORABLE_CONTENT_UNIT_TYPES.join(",")
param :ansible_collection_requirements, String, :desc => N_("Contents of requirement yaml file to sync from URL")
param :ansible_collection_auth_url, String, :desc => N_("The URL to receive a session token from, e.g. used with Automation Hub.")
Expand Down Expand Up @@ -505,7 +506,7 @@ def repository_params
keys = [:download_policy, :mirror_on_sync, :mirroring_policy, :sync_policy, :arch, :verify_ssl_on_sync, :upstream_password,
:upstream_username, :download_concurrency, :upstream_authentication_token,
{:os_versions => []}, :deb_releases, :deb_components, :deb_architectures, :description,
:http_proxy_policy, :http_proxy_id, :retain_package_versions_count, {:ignorable_content => []}
:http_proxy_policy, :http_proxy_id, :retain_package_versions_count, {:ignorable_content => []}, :deb_errata_url
]
keys += [{:docker_tags_whitelist => []}, :docker_upstream_name] if params[:action] == 'create' || @repository&.docker?
keys += [:ansible_collection_requirements, :ansible_collection_auth_url, :ansible_collection_auth_token] if params[:action] == 'create' || @repository&.ansible_collection?
Expand Down Expand Up @@ -567,6 +568,7 @@ def construct_repo_from_params(repo_params) # rubocop:disable Metrics/AbcSize
root.deb_releases = repo_params[:deb_releases] if repo_params[:deb_releases]
root.deb_components = repo_params[:deb_components] if repo_params[:deb_components]
root.deb_architectures = repo_params[:deb_architectures] if repo_params[:deb_architectures]
root.deb_errata_url = repo_params[:deb_errata_url] if repo_params[:deb_errata_url]
end

if root.ansible_collection?
Expand Down
5 changes: 5 additions & 0 deletions app/lib/actions/katello/content_view/incremental_updates.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def total_counts(input)
total_count[:errata_count] = added_units[:erratum].try(:count)
total_count[:modulemd_count] = added_units[:modulemd].try(:count)
total_count[:rpm_count] = added_units[:rpm].try(:count)
total_count[:deb_count] = added_units[:deb].try(:count)
end
end
end
Expand Down Expand Up @@ -135,6 +136,10 @@ def content_output_collection(total_count)
if total_count[:rpm_count] && total_count[:rpm_count] > 0
rpm = _(" %{package_count} Package(s)" % {:package_count => total_count[:rpm_count]})
content << rpm
end
if total_count[:deb_count] && total_count[:deb_count] > 0
deb = _(" %{deb_package_count} Package(s)" % {:deb_package_count => total_count[:deb_count]})
content << deb
end
content
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class IncrementalUpdatesPresenter < Helpers::Presenter::Base
HUMANIZED_TYPES = {
::Katello::Erratum::CONTENT_TYPE => "Errata",
::Katello::ModuleStream::CONTENT_TYPE => "Module Streams",
::Katello::Rpm::CONTENT_TYPE => "Packages"
::Katello::Rpm::CONTENT_TYPE => "RPM Packages",
::Katello::Deb::CONTENT_TYPE => "Deb Packages",
}.freeze

def humanized_output
Expand All @@ -25,7 +26,7 @@ def humanized_content
if cvv
humanized_lines << "Content View: #{cvv.content_view.name} version #{cvv.version}"
humanized_lines << _("Added Content:")
[::Katello::Erratum, ::Katello::ModuleStream, ::Katello::Rpm].each do |content_type|
[::Katello::Erratum, ::Katello::ModuleStream, ::Katello::Rpm, ::Katello::Deb].each do |content_type|
unless output[:added_units][content_type::CONTENT_TYPE].blank?
humanized_lines << " #{HUMANIZED_TYPES[content_type::CONTENT_TYPE]}:"
humanized_lines += output[:added_units][content_type::CONTENT_TYPE].sort.map { |unit| " #{unit}" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ def calculate_components(old_version, new_components)

def generate_description(version, content)
humanized_lines = []
[::Katello::Erratum, ::Katello::Rpm].each do |content_type|
[::Katello::Erratum, ::Katello::Rpm, ::Katello::Deb].each do |content_type|
unless content[content_type::CONTENT_TYPE].blank?
humanized_lines << "#{HUMANIZED_TYPES[content_type::CONTENT_TYPE]}:"
humanized_lines += content[content_type::CONTENT_TYPE].sort.map { |unit| " #{unit}" }
Expand Down
5 changes: 5 additions & 0 deletions app/lib/actions/katello/repository/clone_contents.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ def plan(source_repositories, new_repository, options)
SmartProxy.pulp_primary,
source_repositories,
filters: filters, rpm_filenames: rpm_filenames, solve_dependencies: solve_dependencies)
source_repositories.select(&:deb?).each do |repository|
plan_action(Actions::Katello::Repository::CopyDebErratum,
source_repo_id: repository.id,
target_repo_id: new_repository.id)
end
end

matching_content = check_matching_content(new_repository, source_repositories)
Expand Down
31 changes: 31 additions & 0 deletions app/lib/actions/katello/repository/copy_deb_erratum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Actions
module Katello
module Repository
class CopyDebErratum < Actions::Base
input_format do
param :source_repo_id
param :target_repo_id
param :erratum_ids
end

def run
source_repo = ::Katello::Repository.find(input[:source_repo_id])
target_repo = ::Katello::Repository.find(input[:target_repo_id])
erratum_ids = input[:erratum_ids]

erratum_ids_to_copy = source_repo.erratum_ids
erratum_ids_to_copy &= ::Katello::Erratum.where(errata_id: erratum_ids).pluck(:id) if erratum_ids
erratum_ids_to_copy -= target_repo.erratum_ids
target_repo.erratum_ids |= erratum_ids_to_copy
target_repo.save

# fake output to make foreman task presenter happy
if erratum_ids
output[:pulp_tasks] = [{ :result => { :units_successful => ::Katello::Erratum.where(:id => erratum_ids_to_copy).pluck(:errata_id).map { |errata| { "type_id" => "erratum", "unit_key" => { id: errata } } } } }]
end
end
end
end
end
end

3 changes: 2 additions & 1 deletion app/lib/actions/katello/repository/sync.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def plan(repo, options = {})

fail ::Katello::Errors::InvalidActionOptionError, _("Unable to sync repo. This repository does not have a feed url.") if repo.url.blank? && source_url.blank?
fail ::Katello::Errors::InvalidActionOptionError, _("Cannot validate contents on non-yum/deb repositories.") if validate_contents && !repo.yum? && !repo.deb?
fail ::Katello::Errors::InvalidActionOptionError, _("Cannot skip metadata check on non-yum repositories.") if skip_metadata_check && !repo.yum?
fail ::Katello::Errors::InvalidActionOptionError, _("Cannot skip metadata check on non-yum repositories.") if skip_metadata_check && !repo.yum? && !repo.deb?

pulp_sync_options = {}
pulp_sync_options[:download_policy] = ::Katello::RootRepository::DOWNLOAD_ON_DEMAND if validate_contents && repo.yum?
Expand All @@ -51,6 +51,7 @@ def plan(repo, options = {})
plan_action(Katello::Repository::FetchPxeFiles, :id => repo.id)
plan_action(Katello::Repository::CorrectChecksum, repo)
concurrence do
plan_action(Katello::Repository::SyncDebErrata, repo, validate_contents) if repo.deb? && repo.root.deb_errata_url.present?
plan_action(Katello::Repository::ErrataMail, repo, nil, contents_changed)
plan_action(Actions::Katello::Applicability::Repository::Regenerate, :repo_ids => [repo.id]) if generate_applicability
end
Expand Down
90 changes: 90 additions & 0 deletions app/lib/actions/katello/repository/sync_deb_errata.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
module Actions
module Katello
module Repository
class SyncDebErrata < Actions::EntryAction
def plan(repo, force = false)
plan_self(repo_id: repo.id, force_download: force)
end

def run
repo = ::Katello::Repository.find(input[:repo_id]).root
proxy = repo.http_proxy
params = {}
params['releases'] = repo.deb_releases.split(',').map { |comp| comp.split('/')[0] }.join(',') if repo.deb_releases
params['components'] = repo.deb_components if repo.deb_components
params['architectures'] = repo.deb_architectures if repo.deb_architectures
RestClient::Request.execute(
method: :get,
url: repo.deb_errata_url,
proxy: proxy&.full_url,
headers: {
params: params,
'If-None-Match' => input[:force_download] ? nil : repo.deb_errata_url_etag
}
) do |response, _request, _result, &block|
case response.code
when 200
output[:etag] = response.headers[:etag] || ''
output[:modified] = true
output[:data] = response.body
Rails.logger.warn("MP sync #{response.body}")
when 304 # not modified
output[:modified] = false
else
response.return!(&block)
end
end
rescue => e
raise "Error while fetching errata information (#{e.to_s})"
end

# rubocop:disable Metrics/MethodLength
def finalize
if output[:modified]
repo = ::Katello::Repository.find(input[:repo_id])
erratum_list = JSON.parse(output[:data])
erratum_list.each do |data|
erratum = ::Katello::Erratum.find_or_initialize_by(errata_id: data['name'])
erratum.errata_id = data['name']
erratum.pulp_id = data['name']
erratum.title = data['title']
erratum.summary = data['summary'] || ''
erratum.description = data['description']
erratum.issued = data['issued']
erratum.updated = data['updated'] || data['issued']
erratum.severity = data['severity'] || ''
erratum.solution = data['solution'] || ''
erratum.reboot_suggested = data['reboot_suggested'] || false
erratum.errata_type = 'security'
erratum.save!
data['cves']&.each do |cve|
erratum.cves.find_or_initialize_by(cve_id: cve)
end
data['dbts_bugs']&.each do |dbts_bug|
erratum.dbts_bugs.find_or_initialize_by(bug_id: dbts_bug)
end
data['packages']&.each do |package|
affected_deb = erratum.deb_packages.find_or_initialize_by(name: package['name'], release: package['release'])
affected_deb.version = package['version']
affected_deb.version = package['architecture']
+ affected_deb.nva = "#{package['name']}_#{package['version']}_#{package['architecture']}"
affected_deb.save!
end
erratum.repositories |= [repo]
erratum.save!
end
repo.root.update(deb_errata_url_etag: output[:etag])
end
end

def humanized_output
output.dup.update(data: 'Trimmed')
end

def rescue_strategy
Dynflow::Action::Rescue::Skip
end
end
end
end
end
7 changes: 6 additions & 1 deletion app/models/katello/concerns/host_managed_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ def rhsm_fact_values
self.fact_values.joins(:fact_name).where("#{::FactName.table_name}.type = '#{Katello::RhsmFactName}'")
end

def debs_for_erratum(erratum_name)
erratum = Katello::Erratum.find_by errata_id: erratum_name
erratum.deb_packages.where(release: self.operatingsystem.release_name).pluck(:name).join(' ')
end

def self.available_locks
[:update]
end
Expand Down Expand Up @@ -414,7 +419,7 @@ def enabled_module_stream_inactive?(module_stream)
class ::Host::Managed::Jail < Safemode::Jail
allow :content_source, :subscription_manager_configuration_url, :rhsm_organization_label,
:host_collections, :pools, :hypervisor_host, :lifecycle_environment, :content_view,
:installed_packages, :traces_helpers, :advisory_ids
:installed_packages, :traces_helpers, :advisory_ids, :debs_for_erratum
end

class ActiveRecord::Associations::CollectionProxy::Jail < Safemode::Jail
Expand Down
10 changes: 9 additions & 1 deletion app/models/katello/erratum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ class Erratum < Katello::Model
has_many :content_facets, :through => :content_facet_errata, :class_name => "Katello::Host::ContentFacet", :source => :content_facet
has_many :content_facets_applicable, :through => :content_facet_errata, :class_name => "Katello::Host::ContentFacet", :source => :content_facet
has_many :bugzillas, :class_name => "Katello::ErratumBugzilla", :dependent => :destroy, :inverse_of => :erratum
has_many :dbts_bugs, :class_name => "Katello::ErratumDbtsBug", :dependent => :destroy, :inverse_of => :erratum
has_many :cves, :class_name => "Katello::ErratumCve", :dependent => :destroy, :inverse_of => :erratum
has_many :packages, :class_name => "Katello::ErratumPackage", :dependent => :destroy, :inverse_of => :erratum
has_many :deb_packages, :class_name => "Katello::ErratumDebPackage", :dependent => :destroy, :inverse_of => :erratum

scoped_search :on => :errata_id, :only_explicit => true
scoped_search :on => :errata_id, :rename => :id, :complete_value => true, :only_explicit => true
Expand All @@ -36,8 +38,10 @@ class Erratum < Katello::Model
scoped_search :on => :reboot_suggested, :complete_value => true
scoped_search :relation => :cves, :on => :cve_id, :rename => :cve
scoped_search :relation => :bugzillas, :on => :bug_id, :rename => :bug
scoped_search :relation => :dbts_bugs, :on => :bug_id, :rename => :bug
scoped_search :relation => :packages, :on => :nvrea, :rename => :package, :complete_value => true, :only_explicit => true
scoped_search :relation => :packages, :on => :name, :rename => :package_name, :complete_value => true, :only_explicit => true
scoped_search :relation => :deb_packages, :on => :name, :rename => :package_name, :complete_value => true, :only_explicit => true

scoped_search :on => :modular,
:only_explicit => true,
Expand Down Expand Up @@ -182,6 +186,10 @@ def content_view_filters
Katello::ContentViewErratumFilterRule.where(errata_id: self.errata_id).eager_load(:filter).map(&:filter)
end

def all_package_names
package_names + deb_packages.map { |pkg| pkg.name }
end

apipie :class, desc: "A class representing #{model_name.human} object" do
name 'Erratum'
refs 'Erratum'
Expand All @@ -198,7 +206,7 @@ def content_view_filters
property :summary, String, desc: 'Returns the errata summary, the length can very, it is usually in range of 60 to 1000 characters. It can include empty line characters.'
end
class Jail < ::Safemode::Jail
allow :errata_id, :errata_type, :issued, :created_at, :severity, :package_names, :cves, :reboot_suggested, :title, :summary
allow :errata_id, :errata_type, :issued, :created_at, :severity, :package_names, :all_package_names, :cves, :reboot_suggested, :title, :summary
end
end
end
9 changes: 9 additions & 0 deletions app/models/katello/erratum_dbts_bug.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Katello
class ErratumDbtsBug < Katello::Model
belongs_to :erratum, inverse_of: :dbts_bugs, class_name: 'Katello::Erratum'

def href
"https://bugs.debian.org/#{bug_id}"
end
end
end
5 changes: 5 additions & 0 deletions app/models/katello/erratum_deb_package.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Katello
class ErratumDebPackage < Katello::Model
belongs_to :erratum, :inverse_of => :deb_packages, :class_name => 'Katello::Erratum'
end
end
21 changes: 21 additions & 0 deletions app/models/katello/host/content_facet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,27 @@ def import_module_stream_applicability(partial)
ApplicableContentHelper.new(ModuleStream, self).import(partial)
end

def applicable_deb_errata_uuids
# find 'base-repositories'
repositories = []
self.bound_repositories.each do |repo|
if repo.library_instance.nil?
repositories << repo.id
else
repositories << repo.library_instance.id
end
end

Katello::Erratum.joins([:deb_packages, :repositories],
"INNER JOIN #{Katello::InstalledDeb.table_name} ON #{Katello::InstalledDeb.table_name}.name = #{Katello::ErratumDebPackage.table_name}.name",
"INNER JOIN #{Katello::HostInstalledDeb.table_name} ON #{Katello::HostInstalledDeb.table_name}.installed_deb_id = #{Katello::InstalledDeb.table_name}.id")
.where("deb_version_cmp(#{Katello::ErratumDebPackage.table_name}.version, #{Katello::InstalledDeb.table_name}.version) > 0")
.where("#{Katello::ErratumDebPackage.table_name}.release": self.host.operatingsystem.release_name)
.where("#{Katello::HostInstalledDeb.table_name}.host_id": self.host.id)
.where("#{Katello::RepositoryErratum.table_name}.repository_id" => repositories)
.distinct.pluck(:pulp_id)
end

def self.in_content_view_version_environments(version_environments)
#takes a structure of [{:content_view_version => ContentViewVersion, :environments => [KTEnvironment]}]
queries = version_environments.map do |version_environment|
Expand Down
12 changes: 12 additions & 0 deletions app/models/katello/root_repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ def content
Katello::Content.find_by(:cp_content_id => self.content_id, :organization_id => self.product.organization_id)
end

def repository_type
RepositoryTypeManager.find(self.content_type)
end

def docker?
self.content_type == Repository::DOCKER_TYPE
end
Expand Down Expand Up @@ -365,6 +369,14 @@ def pulp_update_needed?
changeable_attributes.any? { |key| previous_changes.key?(key) }
end

def supports_errata?
if deb?
self.deb_errata_url.present?
else
self.repository_type.supports_content_type Katello::Erratum
end
end

def raw_content_path
self.content.content_url
end
Expand Down
16 changes: 15 additions & 1 deletion app/services/katello/applicability/applicable_content_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def calculate_and_import

def fetch_content_ids
if self.content_unit_class == ::Katello::Erratum
fetch_errata_content_ids
fetch_errata_content_ids + fetch_errata_deb_content_ids
elsif self.content_unit_class == ::Katello::Deb
fetch_deb_content_ids
elsif self.content_unit_class == ::Katello::ModuleStream
Expand All @@ -31,6 +31,20 @@ def fetch_content_ids
end
end

def fetch_errata_deb_content_ids
query = 'SELECT DISTINCT katello_repository_errata.erratum_id AS id FROM katello_repository_errata
INNER JOIN katello_erratum_deb_packages
ON katello_repository_errata.erratum_id = katello_erratum_deb_packages.erratum_id
INNER JOIN katello_debs
ON katello_debs.nva = katello_erratum_deb_packages.nva
INNER JOIN katello_content_facet_applicable_debs
ON katello_content_facet_applicable_debs.deb_id = katello_debs.id
WHERE katello_content_facet_applicable_debs.content_facet_id = :content_facet_id
AND katello_repository_errata.repository_id IN (:repo_ids)'

return Katello::Erratum.find_by_sql([query, { content_facet_id: content_facet.id, repo_ids: self.bound_library_instance_repos }]).map(&:id)
end

def fetch_errata_content_ids
# Query for all Errata ids that are attached to the host's applicable packages
query = 'SELECT DISTINCT katello_repository_errata.erratum_id AS id FROM katello_repository_errata
Expand Down
Loading