Module: Katello::Util::Package

Defined in:
app/lib/katello/util/package.rb

Constant Summary collapse

SUFFIX_RE =
/\.(rpm)$/.freeze
ARCH_RE =
/\.([^.\-]*)$/.freeze
NVRE_RE =
/^(.*)-(?:([0-9]+):)?([^-]*)-([^-]*)$/.freeze
EVR_RE =
/^(?:([0-9]+):)?(.*?)(?:-([^-]*))?$/.freeze
SUPPORTED_ARCHS =
%w(noarch i386 i686 ppc64 s390x x86_64 ia64).freeze

Class Method Summary collapse

Class Method Details

.build_nvra(package) ⇒ Object



84
85
86
87
88
89
90
# File 'app/lib/katello/util/package.rb', line 84

def self.build_nvra(package)
  package = package.with_indifferent_access
  nvra = "#{package[:name]}-#{package[:version]}-#{package[:release]}"
  nvra = "#{nvra}.#{package[:arch]}" unless package[:arch].nil?
  nvra = "#{nvra}.#{package[:suffix]}" unless package[:suffix].nil?
  nvra
end

.build_nvrea(package, include_zero_epoch = true) ⇒ Object



70
71
72
# File 'app/lib/katello/util/package.rb', line 70

def self.build_nvrea(package, include_zero_epoch = true)
  [package[:name], build_vrea(package, include_zero_epoch)].compact.reject(&:empty?).join('-')
end

.build_vrea(package, include_zero_epoch = true) ⇒ Object



74
75
76
77
78
79
80
81
82
# File 'app/lib/katello/util/package.rb', line 74

def self.build_vrea(package, include_zero_epoch = true)
  vrea =  [package[:version], package[:release]].compact.join('-')
  vrea = vrea + '.' + package[:arch] unless package[:arch].nil?
  vrea = vrea + '.' + package[:suffix] unless package[:suffix].nil?
  unless package[:epoch].nil?
    vrea = package[:epoch] + ':' + vrea if package[:epoch].to_i != 0 || include_zero_epoch
  end
  vrea
end

.extract_arch(name) ⇒ Object



57
58
59
# File 'app/lib/katello/util/package.rb', line 57

def self.extract_arch(name)
  return name.split(ARCH_RE)
end

.extract_suffix(name) ⇒ Object



53
54
55
# File 'app/lib/katello/util/package.rb', line 53

def self.extract_suffix(name)
  return name.split(SUFFIX_RE)
end

.find_latest_packages(packages) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'app/lib/katello/util/package.rb', line 92

def self.find_latest_packages(packages)
  latest_pack = nil
  selected_packs = []

  packages.each do |pack|
    next if pack.nil?

    pack = pack.with_indifferent_access
    if latest_pack.nil? ||
       (pack[:epoch].to_i > latest_pack[:epoch].to_i) ||
       (pack[:epoch].to_i == latest_pack[:epoch].to_i &&
        pack[:version_sortable] > latest_pack[:version_sortable]) ||
       (pack[:epoch].to_i == latest_pack[:epoch].to_i &&
        pack[:version_sortable] == latest_pack[:version_sortable] &&
        pack[:release_sortable] > latest_pack[:release_sortable])
      latest_pack = pack
      selected_packs = [pack]

    elsif (pack[:epoch].to_i == latest_pack[:epoch].to_i &&
           pack[:version_sortable] == latest_pack[:version_sortable] &&
           pack[:release_sortable] == latest_pack[:release_sortable])
      selected_packs << pack
    end
  end

  selected_packs
end

.format_requires(requires) ⇒ Object



61
62
63
64
65
66
67
68
# File 'app/lib/katello/util/package.rb', line 61

def self.format_requires(requires)
  flags = {'GT' => '>', 'LT' => '<', 'EQ' => '=', 'GE' => '>=', 'LE' => '<='}
  if requires['flags']
    "#{requires['name']} #{flags[requires['flags']]} #{build_vrea(requires, false)}"
  else
    build_nvrea(requires, false)
  end
end

.parse_dependencies(dependencies) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'app/lib/katello/util/package.rb', line 174

def self.parse_dependencies(dependencies)
  # dependencies is either 'requires' or 'provides' metadata attribute of rpm package in pulp
  results = []
  flags = {'GT' => '>', 'LT' => '<', 'EQ' => '=', 'GE' => '>=', 'LE' => '<='}

  dependencies&.each do |dependency|
    dependencies_str = ""
    if dependency.count < 3
      dependencies_str = dependency.first
      results << dependencies_str
    else
      dependency[1] = flags[dependency[1]]
      dependency[0...2].each { |dependency_piece| dependencies_str += "#{dependency_piece} " }
      dependencies_str += "#{dependency[2]}:" unless dependency[2] == "0" # epoch
      dependencies_str += "#{dependency[3]}-" # version
      dependency[4...-1].each { |dependency_piece| dependencies_str += "#{dependency_piece}." }
      results << dependencies_str[0...-1]
    end
  end
  results.uniq
end

.parse_evr(evr) ⇒ Object



45
46
47
48
49
50
51
# File 'app/lib/katello/util/package.rb', line 45

def self.parse_evr(evr)
  if (match = EVR_RE.match(evr))
    {:epoch => match[1],
     :version => match[2],
     :release => match[3]}.delete_if { |_k, v| v.nil? }
  end
end

.parse_nvre(name) ⇒ Object

parses package nvre and stores it in a hash name-epoch:ve.rs.ion-rel.e.ase.rpm



33
34
35
36
37
38
39
40
41
42
43
# File 'app/lib/katello/util/package.rb', line 33

def self.parse_nvre(name)
  name, suffix = extract_suffix(name)

  if (match = NVRE_RE.match(name))
    {:suffix => suffix,
     :name => match[1],
     :epoch => match[2],
     :version => match[3],
     :release => match[4]}.delete_if { |_k, v| v.nil? }
  end
end

.parse_nvrea(name) ⇒ Object

parses package nvrea and stores it in a hash name-epoch:ve.rs.ion-rel.e.ase.arch.rpm



22
23
24
25
26
27
28
29
# File 'app/lib/katello/util/package.rb', line 22

def self.parse_nvrea(name)
  name, suffix = extract_suffix(name)
  name, arch = extract_arch(name)

  if (nvre = parse_nvre(name))
    nvre.merge(:suffix => suffix, :arch => arch).delete_if { |_k, v| v.nil? }
  end
end

.parse_nvrea_nvre(name) ⇒ Object

is able to take both nvre and nvrea and parse it correctly



11
12
13
14
15
16
17
18
# File 'app/lib/katello/util/package.rb', line 11

def self.parse_nvrea_nvre(name)
  package = self.parse_nvrea(name)
  if package && SUPPORTED_ARCHS.include?(package[:arch])
    return package
  else
    return self.parse_nvre(name)
  end
end

.setup_shared_unique_filter(repoids, search_mode, search_results) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'app/lib/katello/util/package.rb', line 141

def self.setup_shared_unique_filter(repoids, search_mode, search_results)
  repo_filter_ids = repoids.collect do |repo|
    {:term => {:repoids => [repo]}}
  end
  case search_mode
  when :shared
    search_results.filter :and, repo_filter_ids
  when :unique
    search_results.filter :or, repo_filter_ids
    search_results.filter :not, :filter => {:and => repo_filter_ids}
  else
    search_results.filter :or, repo_filter_ids
  end
end

.sortable_version(version) ⇒ String

Converts a package version to a sortable string

See the Fedora docs for what chars are accepted fedoraproject.org/wiki/Archive:Tools/RPM/VersionComparison

See Pulp’s documentation for more info about this algorithm pulp-rpm-dev-guide.readthedocs.org/en/latest/sort-index.html



166
167
168
169
170
171
172
# File 'app/lib/katello/util/package.rb', line 166

def self.sortable_version(version)
  return "" if version.blank?
  pieces = version.scan(/([A-Za-z]+|\d+)/).flatten.map do |chunk|
    chunk =~ /\d+/ ? "#{"%02d" % chunk.length}-#{chunk}" : "$#{chunk}"
  end
  pieces.join(".")
end

.valid_package_charactersObject



137
138
139
# File 'app/lib/katello/util/package.rb', line 137

def self.valid_package_characters
  /[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\-\.\_\+\,]+/
end

.valid_package_name_format(package) ⇒ Object



133
134
135
# File 'app/lib/katello/util/package.rb', line 133

def self.valid_package_name_format(package)
  return (package =~ valid_package_characters)
end

.validate_package_list_format(packages) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
# File 'app/lib/katello/util/package.rb', line 120

def self.validate_package_list_format(packages)
  # validate the format of the comma-separated package list provided
  packages = packages.split(/ *, */)

  packages.each do |package_name|
    unless valid_package_name_format(package_name).nil?
      return false
    end
  end

  return packages
end