Hello community,
here is the log from the commit of package zypper-lifecycle-plugin for
openSUSE:Factory checked in at 2020-09-29 19:05:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/zypper-lifecycle-plugin (Old)
and /work/SRC/openSUSE:Factory/.zypper-lifecycle-plugin.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "zypper-lifecycle-plugin"
Tue Sep 29 19:05:00 2020 rev:6 rq:838482 version:0.6.1601367426.843fe7a
Changes:
--------
---
/work/SRC/openSUSE:Factory/zypper-lifecycle-plugin/zypper-lifecycle-plugin.changes
2020-08-10 14:57:53.815997284 +0200
+++
/work/SRC/openSUSE:Factory/.zypper-lifecycle-plugin.new.4249/zypper-lifecycle-plugin.changes
2020-09-29 19:05:19.814025177 +0200
@@ -1,0 +2,7 @@
+Tue Sep 29 08:18:45 UTC 2020 - Vladimir Nadvornik <[email protected]>
+
+- Version 0.6.1601367426.843fe7a
+- Allow wildcard matching (jsc#SLE-14168)
+- Implement successor handling (jsc#SLE-16251)
+
+-------------------------------------------------------------------
Old:
----
zypper-lifecycle-0.6.1596796104.87bdab7.tar.xz
New:
----
zypper-lifecycle-0.6.1601367426.843fe7a.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ zypper-lifecycle-plugin.spec ++++++
--- /var/tmp/diff_new_pack.AAaaOr/_old 2020-09-29 19:05:20.486025855 +0200
+++ /var/tmp/diff_new_pack.AAaaOr/_new 2020-09-29 19:05:20.490025860 +0200
@@ -23,7 +23,7 @@
Name: zypper-lifecycle-plugin
Url: https://github.com/SUSE/zypper-lifecycle
-Version: 0.6.1596796104.87bdab7
+Version: 0.6.1601367426.843fe7a
Release: 0
Requires: zypper >= 1.13.10
BuildRoot: %{_tmppath}/%{name}-%{version}-build
++++++ zypper-lifecycle-0.6.1596796104.87bdab7.tar.xz ->
zypper-lifecycle-0.6.1601367426.843fe7a.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/zypper-lifecycle-0.6.1596796104.87bdab7/test-data/SLES.lifecycle
new/zypper-lifecycle-0.6.1601367426.843fe7a/test-data/SLES.lifecycle
--- old/zypper-lifecycle-0.6.1596796104.87bdab7/test-data/SLES.lifecycle
2020-08-07 12:28:24.000000000 +0200
+++ new/zypper-lifecycle-0.6.1601367426.843fe7a/test-data/SLES.lifecycle
2020-09-29 10:17:06.000000000 +0200
@@ -1,7 +1,36 @@
# test data for SLES product
-# this should be installed in /var/lib/lifecycle/data/SLES.lifecycle
-# format: name,version,date
+# this should be installed in /usr/share/lifecycle/data/SLES.lifecycle
+# format: name,version,date,successor
+# successor is optional
+# date can be empty if successor is specified
+
# version can contain wildcard character *
aaa_base, 13.2*, 2016-05-05
-kernel-default, 3.12.51-60.25.1, 2016-05-01
+
+
+# Name can contain wildcard character *
+
+kernel-*, 3.12.51-60.25.1, 2016-05-01
+
+# or it can be specified as regexp enclosed in / /
+# See Ruby documentation for regexp syntax.
+# Typically the regexp should match whole name,
+# so ^ and $ should be used
+
+/^kernel-.*$/, 3.12.51-60.25.1, 2016-05-01
+
+# Successor specifies a package that replaces the given package
+# when available - jsc#SLE-16356
+#
+# Successor use the same syntax as name, additionally
+# it can reference matching groups from name with "<1>", "<2>" etc.
+# the groups are generated from wildcards, in regexp they must be
+# marked with ( )
+
+# the following 4 lines are equivalent
+
+hdf5_*-gnu*-hpc, *, , hdf5_*-gnu<2>-hpc
+hdf5_*-gnu*-hpc, *, , /^hdf5_(.*)-gnu<2>-hpc$/
+/^hdf5_.*-gnu(.*)-hpc$/, *, , hdf5_*-gnu<1>-hpc
+/^hdf5_.*-gnu(.*)-hpc$/, *, , /^hdf5_(.*)-gnu<1>-hpc$/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/zypper-lifecycle-0.6.1596796104.87bdab7/zypper-lifecycle
new/zypper-lifecycle-0.6.1601367426.843fe7a/zypper-lifecycle
--- old/zypper-lifecycle-0.6.1596796104.87bdab7/zypper-lifecycle
2020-08-07 12:28:24.000000000 +0200
+++ new/zypper-lifecycle-0.6.1601367426.843fe7a/zypper-lifecycle
2020-09-29 10:17:06.000000000 +0200
@@ -116,9 +116,9 @@
@installed_products[p[:name]] = p if p[:installed] == "true"
end
- package_list = Zypper::xml_call("--no-refresh -x se -s -t package",
'search-result/solvable-list')
+ @all_packages = Zypper::xml_call("--no-refresh -x se -s -t package",
'search-result/solvable-list')
@installed_package = {}
- package_list.each do |p|
+ @all_packages.each do |p|
if p[:kind] == 'package' && p[:status] == 'installed'
@installed_package[p[:name]] ||= []
@installed_package[p[:name]] << p
@@ -144,7 +144,7 @@
end
end
- package_list.each do |p|
+ @all_packages.each do |p|
p[:product] = product_by_repo[p[:repository]]
end
@@ -156,6 +156,8 @@
end
def load_lifecycle_data()
+ @lifecycle_data = []
+ @successors = {}
@installed_products.values.each do |product|
[
"/var/lib/lifecycle/data/#{product[:name]}.lifecycle",
@@ -165,20 +167,8 @@
print "trying to load #{file}... " if @verbose
begin
CSV.foreach(file, :skip_blanks => true, :skip_lines => /^\s*#/ )
do |line|
- name, version, date = line.map(&:strip)
- date = Time.parse(date).strftime("%s")
- version_re = Regexp.new( '^' +
Regexp.quote(version).gsub(/\\\*/, '.*') + '$')
- #print "match #{name} #{version_re}\n"
- (@installed_package[name] || []).each do |p|
- #print "#{p}\n"
- if version_re.match(p[:edition])
- p[:package_eol] = date
- end
- if version_re.match(p[:update_edition])
- p[:update_package_eol] = date
- end
- p[:version_specified] = version
- end
+ line.each{ |f| f = "" unless f; f.strip! }
+ @lifecycle_data.append(line)
end
print "ok\n" if @verbose
rescue Errno::ENOENT => e
@@ -189,6 +179,93 @@
end
end
end
+ parse_lifecycle_data(1)
+ # currenly we do not print successor EOL, so second pass is not needed
+ # parse_lifecycle_data(2)
+ end
+
+
+ def parse_lifecycle_data(pass)
+ if pass==1
+ target_hash = @installed_package
+ else
+ target_hash = @successors
+ end
+ @lifecycle_data.each do |line|
+ begin
+ name, version, date, successor = line
+
+ if !date || date.empty?
+ date = nil
+ else
+ date = Time.parse(date).strftime("%s")
+ end
+ version_re = Regexp.new( '^' + Regexp.quote(version).gsub(/\\\*/,
'.*') + '$')
+ #print "match #{name} #{version_re}\n"
+ name_re = nil
+ if name.start_with?("/") && name.end_with?("/")
+ name_re = Regexp.new(name[1..-2])
+ matching_names = target_hash.keys.select { |p| name_re.match(p) }
+ matching_installed = matching_names.map { |p| target_hash[p]
}.flatten(1)
+ elsif name.include? "*"
+ name_re = Regexp.new( '^' + Regexp.quote(name).gsub(/\\\*/,
'(.*)') + '$')
+ matching_names = target_hash.keys.select { |p| name_re.match(p) }
+ matching_installed = matching_names.map { |p| target_hash[p]
}.flatten(1)
+ else
+ matching_installed = target_hash[name]
+ end
+ (matching_installed || []).each do |p|
+ if version_re.match(p[:edition])
+ p[:package_eol] = date
+ end
+ if version_re.match(p[:update_edition])
+ p[:update_package_eol] = date
+ end
+ p[:version_specified] = version
+
+ if pass == 1 && successor
+ handle_successor(p, successor, name_re)
+ end
+ end
+ rescue Exception => e
+ print "\nError parsing #{line}: #{e.message}\n"
+ @retval = 2
+ end
+ end
+ end
+
+ def handle_successor(package, successor, name_re)
+ matches = [package[:name]]
+ if name_re
+ m = name_re.match(package[:name])
+ matches += m.captures if m
+ end
+ if successor.start_with?("/") && successor.end_with?("/")
+ successor_re = successor[1..-2]
+ else
+ successor_re = '^' + Regexp.quote(successor).gsub(/\\\*/, '.*') + '$'
+ end
+ for i in 0..9
+ successor_re.gsub!(/<#{i}>/, Regexp.quote(matches[i] || ''))
+ end
+ successor_re = Regexp.new(successor_re)
+ matching_successors = @all_packages.select { |s|
successor_re.match(s[:name]) && package[:name] != s[:name] && package[:arch] ==
s[:arch] }
+
+ # select the successor with highest version
+ successor_version = package[:edition]
+ successor_pkg = nil
+ matching_successors.each do |s|
+ if Gem::Version.new(s[:edition]) > Gem::Version.new(successor_version)
+ successor_pkg = s
+ successor_version = s[:edition]
+ end
+ end
+
+ if successor_pkg
+ package[:successor] = successor_pkg
+ @successors[successor_pkg[:name]] ||= []
+ @successors[successor_pkg[:name]] << successor_pkg
+ end
end
def solve_package_eol()
@@ -211,6 +288,10 @@
up_eol = p[:product][:endoflife_time_t] if !up_eol && p[:product] &&
p[:product][:endoflife_time_t] # default to product eol
p[:update_eol] = up_eol.to_i if up_eol
end
+
+ if p[:successor]
+ p[:eol] = NowTS
+ end
end
end
@@ -301,7 +382,10 @@
vendor = p[:product][:vendor] if p[:product]
eol = eol_string(p[:eol], vendor)
up = ''
- if p[:update_edition]
+ if p[:successor]
+ up = ", installed #{p[:edition]}, successor available
#{p[:successor][:name]}-#{p[:successor][:edition]}"
+ up_eol = ''
+ elsif p[:update_edition]
up = ", installed #{p[:edition]}, update available
#{p[:update_edition]}"
up_eol = ''
up_eol = eol_string(p[:update_eol], vendor) if p[:update_eol] &&
p[:update_eol] < NaTS
@@ -366,7 +450,7 @@
print ".\n"
end
- packages = @installed_package.values.flatten.select {|p|
(p[:package_eol] || p[:update_edition]) }
+ packages = @installed_package.values.flatten.select {|p|
(p[:package_eol] || p[:update_edition] || p[:successor]) }
print_packages = packages.select {|p| !p[:already_reported] }
if print_packages.length > 0
print "\nPackage end of support if different from product:\n"
@@ -415,7 +499,7 @@
print "\nNo products whose support ends before #{date_str}.\n"
end
packages = @installed_package.values.flatten.select {|p| p[:eol] &&
p[:eol] <= date_ts }
- dif_packages = packages.select {|p| (p[:package_eol] ||
p[:update_edition]) }
+ dif_packages = packages.select {|p| (p[:package_eol] ||
p[:update_edition] || p[:successor]) }
print_packages = dif_packages.select {|p| !p[:already_reported] }
if packages.length > 0
if print_packages.length > 0