Skip to content

Commit

Permalink
Fixes #35713 - Host details tab for Debian packages
Browse files Browse the repository at this point in the history
  • Loading branch information
nadjaheitmann committed Oct 26, 2023
1 parent 586f2fe commit 51969bb
Show file tree
Hide file tree
Showing 25 changed files with 1,500 additions and 10 deletions.
4 changes: 4 additions & 0 deletions app/controllers/katello/api/v2/debs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,13 @@ def available_for_content_view_version(version)
def custom_index_relation(collection)
applicable = ::Foreman::Cast.to_bool(params[:packages_restrict_applicable]) || params[:host_id]
upgradable = ::Foreman::Cast.to_bool(params[:packages_restrict_upgradable])
not_installed = ::Foreman::Cast.to_bool(params[:packages_restrict_not_installed])

if upgradable
collection = collection.installable_for_hosts(@hosts)
elsif not_installed && params[:host_id]
host = @hosts.first
collection = Katello::Deb.deb_installable_for_host(host)
elsif applicable
collection = collection.applicable_to_hosts(@hosts)
end
Expand Down
14 changes: 13 additions & 1 deletion app/controllers/katello/api/v2/host_debs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,26 @@ class Api::V2::HostDebsController < Api::V2::ApiController

api :GET, "/hosts/:host_id/debs", N_("List deb packages installed on the host")
param :host_id, :number, :required => true, :desc => N_("ID of the host")
param :include_latest_upgradable, :boolean, :desc => N_("Also include the latest upgradable package version for each host package")
param :status, String, :desc => N_("Return only packages of a particular status (upgradable or up-to-date)"), :required => false
param_group :search, Api::V2::ApiController
add_scoped_search_description_for(Katello::InstalledDeb)
def index
collection = scoped_search(index_relation, :name, :asc, :resource_class => ::Katello::InstalledDeb)
collection[:results] = HostDebPresenter.with_latest(collection[:results], @host) if ::Foreman::Cast.to_bool(params[:include_latest_upgradable])
respond_for_index(:collection => collection)
end

def index_relation
@host.installed_debs
packages = @host.installed_debs
upgradable_packages = ::Katello::Deb.installable_for_hosts([@host]).select(:name)
if params[:status].present?
packages = case params[:status]
when 'up-to-date' then packages.where.not(name: upgradable_packages)
when 'upgradable' then packages.where(name: upgradable_packages)
end
end
packages
end

def resource_class
Expand Down
20 changes: 19 additions & 1 deletion app/models/katello/concerns/host_managed_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,24 @@ def package_names_for_job_template(action:, search:, versions: nil)
end
end

def deb_names_for_job_template(action:, search:)
actions = %w(install remove update).freeze
case action
when 'install'
::Katello::Deb.deb_installable_for_host(self).search_for(search).distinct.pluck(:name)
when 'remove'
return [] if search.empty?

installed_debs.search_for(search).distinct.pluck(:name)
when 'update'
return [] if search.empty?

installed_debs.search_for(search).distinct.pluck(:name)
else
fail ::Foreman::Exception.new(N_("package_names_for_job_template: Action must be one of %s"), actions.join(', '))
end
end

def advisory_ids(search:)
::Katello::Erratum.installable_for_hosts([self]).search_for(search).pluck(:errata_id)
end
Expand Down Expand Up @@ -590,7 +608,7 @@ class ::Host::Managed::Jail < Safemode::Jail
:installed_packages, :traces_helpers, :advisory_ids, :package_names_for_job_template,
:filtered_entitlement_quantity_consumed, :bound_repositories,
:single_content_view, :single_lifecycle_environment, :purpose_role, :purpose_usage, :release_version,
:purpose_role_status_label, :purpose_usage_status_label
:purpose_role_status_label, :purpose_usage_status_label, :deb_names_for_job_template
end

class ActiveRecord::Associations::CollectionProxy::Jail < Safemode::Jail
Expand Down
8 changes: 8 additions & 0 deletions app/models/katello/deb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Deb < Katello::Model
:dependent => :destroy, :inverse_of => :deb
has_many :content_facets, :through => :content_facet_applicable_debs, :class_name => "Katello::Host::ContentFacet"

scoped_search :on => :id, :complete_value => true
scoped_search :on => :name, :complete_value => true
scoped_search :on => :version, :complete_value => true
scoped_search :on => :architecture, :complete_value => true
Expand Down Expand Up @@ -95,6 +96,13 @@ def self.applicable_to_hosts(hosts)
where("#{Katello::Host::ContentFacet.table_name}.host_id" => hosts).distinct
end

# Return deb packages that are not installed on a host, but could be installed
# the word 'installable' has a different meaning here than elsewhere
def self.deb_installable_for_host(host)
repos = host.content_facet.bound_repositories.pluck(:id)
Katello::Deb.in_repositories(repos).where.not(name: host.installed_debs.pluck(:name)).order(:name)
end

def self.latest(_relation)
fail 'NotImplemented'
end
Expand Down
1 change: 1 addition & 0 deletions app/models/katello/installed_deb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class InstalledDeb < Katello::Model
has_many :host_installed_debs, :class_name => "Katello::HostInstalledDeb", :dependent => :destroy, :inverse_of => :installed_deb
has_many :hosts, :through => :host_installed_debs, :class_name => "::Host"

scoped_search :on => :id, :complete_value => true
scoped_search :on => :name, :complete_value => true
scoped_search :on => :version
scoped_search :on => :architecture
Expand Down
23 changes: 23 additions & 0 deletions app/presenters/katello/host_deb_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module Katello
class HostDebPresenter < SimpleDelegator
attr_accessor :installed_package, :upgradable_versions, :deb_id

def initialize(installed_package, upgradable_versions, deb_id)
@installed_package = installed_package
@upgradable_versions = upgradable_versions
@deb_id = deb_id
super(@installed_package)
end

def self.with_latest(packages, host)
upgradable_packages_map = ::Katello::Deb.installable_for_hosts([host]).select(:id, :name, :architecture, :version).order(version: :desc).group_by { |i| [i.name, i.architecture] }
installed_packages_map = ::Katello::Deb.where(version: packages.map(&:version)).select(:id, :architecture, :name).group_by { |i| [i.name, i.architecture] }

packages.map do |p|
upgrades = upgradable_packages_map[[p.name, p.architecture]]&.pluck(:version)
installed = installed_packages_map[[p.name, p.architecture]]&.first&.id
HostDebPresenter.new(p, upgrades, installed)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ template_inputs:
input_type: user
required: false
%>
<% package_names = @host.package_names_for_job_template(
<% if @host.operatingsystem.family == 'Debian'
package_names = @host.deb_names_for_job_template(
action: 'install',
search: input('Package search query')
) -%>
)
else
package_names = @host.package_names_for_job_template(
action: 'install',
search: input('Package search query')
)
end -%>

<%= render_template('Package Action - Script Default', :action => 'install', :package => package_names.join(' ')) %>
<%= render_template('Package Action - Script Default', :action => 'install', :package => package_names.join(' ')) %>
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ template_inputs:
input_type: user
required: true
%>
<% package_names = @host.package_names_for_job_template(
<% if @host.operatingsystem.family == 'Debian'
package_names = @host.deb_names_for_job_template(
action: 'remove',
search: input('Packages search query')
) -%>
)
else
package_names = @host.package_names_for_job_template(
action: 'remove',
search: input('Packages search query')
)
end -%>

<%= render_template('Package Action - Script Default', :action => 'remove', :package => package_names.join(' ')) %>
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@ template_inputs:
required: false
value_type: plain
%>
<% package_names = @host.package_names_for_job_template(
<% if @host.operatingsystem.family == 'Debian'
package_names = @host.deb_names_for_job_template(
action: 'update',
search: input('Packages search query')
)
else
package_names = @host.package_names_for_job_template(
action: 'update',
search: input('Packages search query'),
versions: input('Selected update versions')
) -%>
)
end -%>

<%= render_template('Package Action - Script Default', :action => 'update', :package => package_names.join(' ')) %>
2 changes: 2 additions & 0 deletions app/views/katello/api/v2/host_debs/base.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ object @resource

attributes :id, :name
attributes :version, :architecture
attributes :upgradable_versions
attributes :deb_id
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { PackagesTab } from '../PackagesTab/PackagesTab.js';
import { DebsTab } from '../DebsTab/DebsTab.js';
import { ErrataTab } from '../ErrataTab/ErrataTab.js';
import { ModuleStreamsTab } from '../ModuleStreamsTab/ModuleStreamsTab';
import RepositorySetsTab from '../RepositorySetsTab/RepositorySetsTab';
Expand All @@ -11,6 +12,9 @@ const SecondaryTabRoutes = () => (
<Route path={route('packages')}>
<PackagesTab />
</Route>
<Route path={route('debs')}>
<DebsTab />
</Route>
<Route path={route('errata')}>
<ErrataTab />
</Route>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { translate as __ } from 'foremanReact/common/I18n';
import { hideRepoSetsTab } from '../RepositorySetsTab/RepositorySetsTab';
import { hideModuleStreamsTab } from '../ModuleStreamsTab/ModuleStreamsTab';
import { hideDebsTab } from '../DebsTab/DebsTab';
import { hidePackagesTab } from '../PackagesTab/PackagesTab';

const SECONDARY_TABS = [
{ key: 'packages', title: __('Packages') },
{ key: 'debs', hideTab: hideDebsTab, title: __('Packages') },
{ key: 'packages', hideTab: hidePackagesTab, title: __('Packages') },
{ key: 'errata', title: __('Errata') },
{ key: 'module-streams', hideTab: hideModuleStreamsTab, title: __('Module streams') },
{ key: 'Repository sets', hideTab: hideRepoSetsTab, title: __('Repository sets') },
Expand Down
Loading

0 comments on commit 51969bb

Please sign in to comment.