Class: Katello::Applicability::ApplicableContentHelper

Inherits:
Object
  • Object
show all
Defined in:
app/services/katello/applicability/applicable_content_helper.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content_facet, content_unit_class, bound_library_instance_repos) ⇒ ApplicableContentHelper

Returns a new instance of ApplicableContentHelper.



6
7
8
9
10
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 6

def initialize(content_facet, content_unit_class, bound_library_instance_repos)
  self.content_facet = content_facet
  self.content_unit_class = content_unit_class
  self.bound_library_instance_repos = bound_library_instance_repos
end

Instance Attribute Details

#bound_library_instance_reposObject

Returns the value of attribute bound_library_instance_repos.



4
5
6
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 4

def bound_library_instance_repos
  @bound_library_instance_repos
end

#content_facetObject

Returns the value of attribute content_facet.



4
5
6
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 4

def content_facet
  @content_facet
end

#content_unit_classObject

Returns the value of attribute content_unit_class.



4
5
6
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 4

def content_unit_class
  @content_unit_class
end

Instance Method Details

#applicable_differencesObject



145
146
147
148
149
150
151
152
153
154
155
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 145

def applicable_differences
  ActiveRecord::Base.connection.uncached do
    consumer_ids = content_facet.send(applicable_units).pluck("#{content_unit_class.table_name}.id")
    content_ids = fetch_content_ids

    to_remove = consumer_ids - content_ids
    to_add = content_ids - consumer_ids

    [to_add, to_remove]
  end
end

#applicable_unitsObject



183
184
185
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 183

def applicable_units
  "applicable_#{content_units}".to_sym
end

#calculate_and_importObject



12
13
14
15
16
17
18
19
20
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 12

def calculate_and_import
  if self.bound_library_instance_repos.any?
    to_add, to_remove = applicable_differences
    ActiveRecord::Base.transaction do
      insert(to_add) unless to_add.blank?
      remove(to_remove) unless to_remove.blank?
    end
  end
end

#content_facet_association_classObject



174
175
176
177
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 174

def content_facet_association_class
  # Example: ContentFacetErratum
  self.content_unit_class.content_facet_association_class
end

#content_unit_association_idObject



170
171
172
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 170

def content_unit_association_id
  "#{content_unit_class.name.demodulize.underscore}_id".to_sym
end

#content_unitsObject



179
180
181
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 179

def content_units
  content_unit_class.name.demodulize.pluralize.underscore.to_sym
end

#fetch_content_idsObject



22
23
24
25
26
27
28
29
30
31
32
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 22

def fetch_content_ids
  if self.content_unit_class == ::Katello::Erratum
    fetch_errata_content_ids
  elsif self.content_unit_class == ::Katello::Deb
    fetch_deb_content_ids
  elsif self.content_unit_class == ::Katello::ModuleStream
    fetch_module_stream_content_ids
  else
    fetch_rpm_content_ids
  end
end

#fetch_deb_content_idsObject



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 64

def fetch_deb_content_ids
  repo_deb = ::Katello::RepositoryDeb.arel_table
  deb = ::Katello::Deb.arel_table
  installed_deb = Katello::InstalledDeb.arel_table
  host_installed_deb = Katello::HostInstalledDeb.arel_table
  deb_version_compare = Arel::Nodes::NamedFunction.new('deb_version_cmp', [deb[:version], installed_deb[:version]]).gt(0)

  content = deb.join(repo_deb).on(repo_deb[:deb_id].eq(deb[:id]))
               .join(installed_deb).on(installed_deb[:name].eq(deb[:name]))
               .join(host_installed_deb).on(host_installed_deb[:installed_deb_id].eq(installed_deb[:id]))
               .where(deb_version_compare)
               .where(host_installed_deb[:host_id].eq(self.content_facet.host.id))
               .distinct
               .project(deb[Arel.star])

  ::Katello::Deb.find_by_sql(content.to_sql).pluck(:id)
end

#fetch_enabled_module_stream_idsObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 109

def fetch_enabled_module_stream_ids
  # Query for applicable RPM ids
  # -> Include all non-modular rpms or rpms that exist within installed module streams
  ::Katello::ModuleStream.
    joins("inner join katello_available_module_streams on
      katello_module_streams.name = katello_available_module_streams.name and
      katello_module_streams.stream = katello_available_module_streams.stream and
      katello_module_streams.context = katello_available_module_streams.context").
    joins("inner join katello_host_available_module_streams on
      katello_available_module_streams.id = katello_host_available_module_streams.available_module_stream_id").
    where("katello_host_available_module_streams.host_id = :content_facet_id and
      katello_host_available_module_streams.status = 'enabled'",
      :content_facet_id => self.content_facet.host.id).select(:id)
end

#fetch_errata_content_idsObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 34

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
               INNER JOIN katello_erratum_packages
                  ON katello_repository_errata.erratum_id = katello_erratum_packages.erratum_id
               INNER JOIN katello_rpms
                  ON katello_rpms.nvra = katello_erratum_packages.nvrea
               INNER JOIN katello_content_facet_applicable_rpms
                  ON katello_content_facet_applicable_rpms.rpm_id = katello_rpms.id
               WHERE katello_content_facet_applicable_rpms.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

#fetch_module_stream_content_idsObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 49

def fetch_module_stream_content_ids
  # Query for all applicable module stream ids
  query = 'SELECT DISTINCT katello_repository_module_streams.module_stream_id AS id FROM katello_repository_module_streams
               INNER JOIN katello_module_stream_rpms
                  ON katello_repository_module_streams.module_stream_id = katello_module_stream_rpms.module_stream_id
               INNER JOIN katello_rpms
                  ON katello_rpms.id = katello_module_stream_rpms.rpm_id
               INNER JOIN katello_content_facet_applicable_rpms
                  ON katello_content_facet_applicable_rpms.rpm_id = katello_rpms.id
               WHERE katello_content_facet_applicable_rpms.content_facet_id = :content_facet_id
                  AND katello_repository_module_streams.repository_id IN (:repo_ids)'

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

#fetch_rpm_content_idsObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 82

def fetch_rpm_content_ids
  enabled_module_stream_ids = fetch_enabled_module_stream_ids

  ::Katello::Rpm.
    joins("INNER JOIN katello_repository_rpms ON
      katello_rpms.id = katello_repository_rpms.rpm_id").
    joins("INNER JOIN katello_installed_packages ON
      katello_rpms.name = katello_installed_packages.name AND
      katello_rpms.arch = katello_installed_packages.arch AND
      katello_rpms.evr > katello_installed_packages.evr AND
      katello_installed_packages.id in (#{newest_distinct_installed_packages_query})").
    joins("LEFT JOIN katello_module_stream_rpms ON
      katello_rpms.id = katello_module_stream_rpms.rpm_id").
    joins("INNER JOIN katello_host_installed_packages ON
      katello_installed_packages.id = katello_host_installed_packages.installed_package_id").
    where("katello_repository_rpms.repository_id in (:bound_library_repos)",
      :bound_library_repos => self.bound_library_instance_repos).
    where("katello_host_installed_packages.host_id = :content_facet_id",
      :content_facet_id => self.content_facet.host.id).
    where("(katello_module_stream_rpms.module_stream_id IS NULL AND
      katello_installed_packages.id NOT IN (:locked_modular_installed_packages)) OR
      (katello_module_stream_rpms.module_stream_id IN (:enabled_module_streams)
      AND katello_installed_packages.id IN (:locked_modular_installed_packages))",
      :enabled_module_streams => enabled_module_stream_ids,
      :locked_modular_installed_packages => locked_modular_installed_packages(enabled_module_stream_ids)).pluck(:id).uniq
end

#insert(applicable_ids) ⇒ Object



157
158
159
160
161
162
163
164
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 157

def insert(applicable_ids)
  unless applicable_ids.empty?
    upserts = applicable_ids.collect do |applicable_id|
      { content_unit_association_id => applicable_id, :content_facet_id => content_facet.id }
    end
    content_facet_association_class.upsert_all(upserts, unique_by: [content_unit_association_id, :content_facet_id])
  end
end

#locked_modular_installed_packages(enabled_module_streams) ⇒ Object

Installed packages that are locked for the host due to enabled module stream membership



125
126
127
128
129
130
131
132
133
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 125

def locked_modular_installed_packages(enabled_module_streams)
  rpms_in_enabled_module_streams = ::Katello::Rpm.
    joins("INNER JOIN katello_module_stream_rpms ON katello_rpms.id = katello_module_stream_rpms.rpm_id").
    where("katello_module_stream_rpms.module_stream_id IN (:enabled_module_streams)",
          :enabled_module_streams => enabled_module_streams).select(:nvra, :epoch)

  ::Katello::InstalledPackage.where(nvra: rpms_in_enabled_module_streams.map(&:nvra),
                                    epoch: rpms_in_enabled_module_streams.map(&:epoch)).select(:id)
end

#newest_distinct_installed_packages_queryObject



135
136
137
138
139
140
141
142
143
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 135

def newest_distinct_installed_packages_query
  "SELECT DISTINCT ON (katello_installed_packages.name) katello_installed_packages.id " \
    "FROM katello_installed_packages INNER JOIN " \
    "katello_host_installed_packages ON " \
    "katello_installed_packages.id = " \
    "katello_host_installed_packages.installed_package_id " \
    "WHERE katello_host_installed_packages.host_id = " \
    "#{content_facet.host.id} ORDER BY katello_installed_packages.name, katello_installed_packages.evr DESC"
end

#remove(applicable_ids) ⇒ Object



166
167
168
# File 'app/services/katello/applicability/applicable_content_helper.rb', line 166

def remove(applicable_ids)
  content_facet_association_class.where(:content_facet_id => content_facet.id, content_unit_association_id => applicable_ids).delete_all
end