Hello community, here is the log from the commit of package yast2-update for openSUSE:Factory checked in at 2018-11-01 18:59:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-update (Old) and /work/SRC/openSUSE:Factory/.yast2-update.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-update" Thu Nov 1 18:59:00 2018 rev:124 rq:642416 version:4.1.4 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-update/yast2-update.changes 2018-09-04 22:50:18.855797576 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-update.new/yast2-update.changes 2018-11-01 18:59:02.485988731 +0100 @@ -1,0 +2,23 @@ +Tue Oct 16 16:37:07 CEST 2018 - [email protected] + +- Added license file to spec. + +------------------------------------------------------------------- +Wed Sep 19 16:52:02 CEST 2018 - [email protected] + +- Fixed crash while writing backup (bsc#1108934) +- 4.1.4 + +------------------------------------------------------------------- +Mon Sep 17 12:20:58 UTC 2018 - [email protected] + +- Avoid to restore old backups when upgrade fails (bsc#1097297) +- 4.1.3 + +------------------------------------------------------------------- +Tue Sep 11 15:34:53 CEST 2018 - [email protected] + +- do not translate snapshot description (bsc#1092757) +- 4.1.2 + +------------------------------------------------------------------- Old: ---- yast2-update-4.1.1.tar.bz2 New: ---- yast2-update-4.1.4.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-update.spec ++++++ --- /var/tmp/diff_new_pack.TJe1US/_old 2018-11-01 18:59:02.953988773 +0100 +++ /var/tmp/diff_new_pack.TJe1US/_new 2018-11-01 18:59:02.953988773 +0100 @@ -17,7 +17,7 @@ Name: yast2-update -Version: 4.1.1 +Version: 4.1.4 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -131,5 +131,6 @@ %{yast_controldir}/update.xml %{yast_clientdir}/update.rb %{yast_clientdir}/run_update.rb +%license COPYING %changelog ++++++ yast2-update-4.1.1.tar.bz2 -> yast2-update-4.1.4.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-4.1.1/package/yast2-update.changes new/yast2-update-4.1.4/package/yast2-update.changes --- old/yast2-update-4.1.1/package/yast2-update.changes 2018-08-23 10:03:34.000000000 +0200 +++ new/yast2-update-4.1.4/package/yast2-update.changes 2018-10-16 17:43:56.000000000 +0200 @@ -1,4 +1,27 @@ ------------------------------------------------------------------- +Tue Oct 16 16:37:07 CEST 2018 - [email protected] + +- Added license file to spec. + +------------------------------------------------------------------- +Wed Sep 19 16:52:02 CEST 2018 - [email protected] + +- Fixed crash while writing backup (bsc#1108934) +- 4.1.4 + +------------------------------------------------------------------- +Mon Sep 17 12:20:58 UTC 2018 - [email protected] + +- Avoid to restore old backups when upgrade fails (bsc#1097297) +- 4.1.3 + +------------------------------------------------------------------- +Tue Sep 11 15:34:53 CEST 2018 - [email protected] + +- do not translate snapshot description (bsc#1092757) +- 4.1.2 + +------------------------------------------------------------------- Wed Aug 22 09:55:27 CEST 2018 - [email protected] - Switched license in spec file from SPDX2 to SPDX3 format. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-4.1.1/package/yast2-update.spec new/yast2-update-4.1.4/package/yast2-update.spec --- old/yast2-update-4.1.1/package/yast2-update.spec 2018-08-23 10:03:34.000000000 +0200 +++ new/yast2-update-4.1.4/package/yast2-update.spec 2018-10-16 17:43:56.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-update -Version: 4.1.1 +Version: 4.1.4 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -131,3 +131,4 @@ %{yast_controldir}/update.xml %{yast_clientdir}/update.rb %{yast_clientdir}/run_update.rb +%license COPYING diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-4.1.1/src/modules/RootPart.rb new/yast2-update-4.1.4/src/modules/RootPart.rb --- old/yast2-update-4.1.1/src/modules/RootPart.rb 2018-08-23 10:03:34.000000000 +0200 +++ new/yast2-update-4.1.4/src/modules/RootPart.rb 2018-10-16 17:43:56.000000000 +0200 @@ -1677,8 +1677,8 @@ # enter the mount points of the newly mounted partitions update_staging! if Yast2::FsSnapshot.configured? - # TRANSLATORS: label for filesystem snapshot taken before system update - snapshot = Yast2::FsSnapshot.create_pre(_("before update"), cleanup: :number, important: true) + # as of bsc #1092757 snapshot descriptions are not translated + snapshot = Yast2::FsSnapshot.create_pre("before update", cleanup: :number, important: true) Yast2::FsSnapshotStore.save("update", snapshot.number) end Update.clean_backup diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-4.1.1/src/modules/Update.rb new/yast2-update-4.1.4/src/modules/Update.rb --- old/yast2-update-4.1.1/src/modules/Update.rb 2018-08-23 10:03:34.000000000 +0200 +++ new/yast2-update-4.1.4/src/modules/Update.rb 2018-10-16 17:43:56.000000000 +0200 @@ -285,7 +285,7 @@ found = Builtins.find(to_install) { |u| u == i } found != nil end - @_products_compatible = equal_product != nil + @_products_compatible = equal_product != nil # no product name found # bugzilla #218720, valid without testing according to comment #10 else @@ -430,7 +430,7 @@ # Remove 'Beta...' from product release if Builtins.regexpmatch(old_name, "Beta") - old_name = Builtins.regexpsub(old_name, "^(.*)[ \t]+Beta.*$", "\\1") + old_name = Builtins.regexpsub(old_name, "^(.*)[ \t]+Beta.*$", "\\1") # Remove 'Alpha...' from product release elsif Builtins.regexpmatch(old_name, "Alpha") old_name = Builtins.regexpsub(old_name, "^(.*)[ \t]+Alpha.*$", "\\1") @@ -467,7 +467,7 @@ Installation.installedVersion, "major", Builtins.tointeger(inst_ver) - ) + ) # openSUSE elsif Builtins.regexpmatch(inst_ver, "^[0123456789]+.[0123456789]+$") Ops.set( @@ -550,7 +550,7 @@ Ops.subtract(num, 1), 0 ) - end + end # default for !Stage::normal else update_to_source = Packages.GetBaseSourceID @@ -624,7 +624,7 @@ Installation.updateVersion, "major", Builtins.tointeger(new_ver) - ) + ) # openSUSE elsif Builtins.regexpmatch(new_ver, "^[0123456789]+.[0123456789]$") Ops.set( @@ -773,47 +773,104 @@ end BACKUP_DIR = "var/adm/backup/system-upgrade" - # Creates backup with name based on `name` contaings everything - # matching globs in `paths`. - # @param name[String] name for backup file. Use a number prefix to run - # the restore scripts in the expected order. Use a bash friendly name ;) + + # Creates the backup with name based on `name` containing everything matching globs in `paths` + # # @note Can be called only after target root is mounted. # + # @param name [String] name for backup file. Use a number prefix to run the restore scripts in + # the expected order. Use a bash friendly name ;) + # @param paths [Array<String>] paths to files that must be included + # # @example to store repos file and credentials directory - # Update.create_backup("0100-repos", ["/etc/zypp/repos.d/*", "/etc/zypp/credentials"]) + # Yast::Update.create_backup("0100-repos", ["/etc/zypp/repos.d/*", "/etc/zypp/credentials"]) def create_backup(name, paths) - log.info "Creating tarball for #{name} including #{paths}" mounted_root = Installation.destdir + # ensure directory exists + backup_dir = Pathname.new("#{mounted_root}/#{BACKUP_DIR}") + ::FileUtils.mkdir_p(backup_dir) unless backup_dir.exist? + + # Copy the os-release file (bsc#1097297) + log.info "Copying the os-release file" + copy_os_release + + log.info "Creating the tarball for #{name} including #{paths}" tarball_path = File.join(BACKUP_DIR, "#{name}.tar.gz") root_tarball_path = File.join(mounted_root, tarball_path) create_tarball(root_tarball_path, mounted_root, paths) + log.info "Creating the restore script for #{name}" script_path = File.join(mounted_root, BACKUP_DIR, "restore-#{name}.sh") create_restore_script(script_path, tarball_path, paths) end - # clean backup content. Usefull to clean up all content before creating new backup + # Removes the backup content + # + # Usefull to clean up **ALL** content in BACKUP_DIR before creating a new backup. def clean_backup log.info "Cleaning backup dir" - mounted_root = Installation.destdir - ::FileUtils.rm_r(File.join(mounted_root, BACKUP_DIR), - :force => true, :secure => true) + ::FileUtils.rm_r(File.join(Installation.destdir, BACKUP_DIR), :force => true, :secure => true) end - # restores backup + # Restores the available backup(s) + # + # If the ID and VERSION_ID in the backup os-release file matches with the values stored in + # /etc/os-release (see bsc#1097297), the available backup scripts (restores-*.sh) will be + # executed **in the expected order** (see bsc#1089643). + # + # @see #restore_backup? def restore_backup - log.info "Restoring backup" - mounted_root = Installation.destdir - script_glob = File.join(mounted_root, BACKUP_DIR,"restore-*.sh") - # sort the scripts to execute them in the expected order - ::Dir.glob(script_glob).sort.each do |path| - cmd = "sh #{path} #{File.join("/", mounted_root)}" - res = SCR.Execute(path(".target.bash_output"), cmd) - log.info "Restoring with script #{cmd} result: #{res}" + log.info "Restoring the backup" + + if restore_backup? + mounted_root = Installation.destdir + available_restore_scripts = ::Dir.glob(File.join(mounted_root, BACKUP_DIR, "restore-*.sh")) + + available_restore_scripts.sort.each do |path| + cmd = "sh #{path} #{File.join("/", mounted_root)}" + res = SCR.Execute(path(".target.bash_output"), cmd) + + log.info "Restoring with script #{cmd} result: #{res}" + end + else + log.error "Backup was not restored because its version info does not match" end end + # Check if backup must be restored, based on the version info (bsc#1097297) + # + # @see #version_from + # + # @return [Boolean] true when versions matches; false otherwise + def restore_backup? + current_release = Pathname.new("#{Installation.destdir}/etc/os-release") + backed_release = Pathname.new("#{Installation.destdir}/#{BACKUP_DIR}/os-release") + current_version = version_from(current_release) + backed_version = version_from(backed_release) + + log.info "Version expected: #{current_version}. Backup version: #{backed_version}" + + version_from(current_release) == version_from(backed_release) + end + + # Returns the ID and VERSION_ID from given file + # + # @see https://www.freedesktop.org/software/systemd/man/os-release.html + # + # @param file [File|Pathname] Operating system identification file + # + # @return [String] a string holding the ID and VERSION_ID or empty if something went wrong + def version_from(file) + content = file.read + id = content[/^ID=.*/].split("=", 2).last.tr('"', '') + version_id = content[/^VERSION_ID=.*/].split("=", 2).last.tr('"', '') + + "#{id}-#{version_id}" + rescue SystemCallError + "" + end + publish :variable => :packages_to_install, :type => "integer" publish :variable => :packages_to_update, :type => "integer" publish :variable => :packages_to_remove, :type => "integer" @@ -850,14 +907,23 @@ private + # Includes the os-release file to backup + # + # @see https://www.freedesktop.org/software/systemd/man/os-release.html + def copy_os_release + ::FileUtils.cp( + Pathname.new("#{Installation.destdir}/etc/os-release"), + Pathname.new("#{Installation.destdir}/#{BACKUP_DIR}") + ) + rescue SystemCallError + nil + end + def create_tarball(tarball_path, root, paths) # tar reports an error if a file does not exist. # So we have to check this before. existing_paths = paths.select { |p| File.exist?(File.join(root, p)) } - # ensure directory exists - ::FileUtils.mkdir_p(File.dirname(tarball_path)) - paths_without_prefix = existing_paths.map {|p| p.start_with?("/") ? p[1..-1] : p } command = "tar cv -C '#{root}'" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-4.1.1/test/data/etc/leap-15-os-release new/yast2-update-4.1.4/test/data/etc/leap-15-os-release --- old/yast2-update-4.1.1/test/data/etc/leap-15-os-release 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-update-4.1.4/test/data/etc/leap-15-os-release 2018-10-16 17:43:56.000000000 +0200 @@ -0,0 +1,11 @@ +NAME="openSUSE Leap" +VERSION="15.0" +ID="opensuse-leap" +ID_LIKE="suse opensuse" +VERSION_ID="15.0" +PRETTY_NAME="openSUSE Leap 15.0" +ANSI_COLOR="0;32" +CPE_NAME="cpe:/o:opensuse:leap:15.0" +BUG_REPORT_URL="https://bugs.opensuse.org" +HOME_URL="https://www.opensuse.org/" + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-4.1.1/test/data/etc/tw-os-release new/yast2-update-4.1.4/test/data/etc/tw-os-release --- old/yast2-update-4.1.1/test/data/etc/tw-os-release 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-update-4.1.4/test/data/etc/tw-os-release 2018-10-16 17:43:56.000000000 +0200 @@ -0,0 +1,11 @@ +NAME="openSUSE Tumbleweed" +VERSION="20180911" +ID="opensuse-tumbleweed" +ID_LIKE="opensuse suse" +VERSION_ID="20180911" +PRETTY_NAME="openSUSE Tumbleweed" +ANSI_COLOR="0;32" +CPE_NAME="cpe:/o:opensuse:tumbleweed:20180911" +BUG_REPORT_URL="https://bugs.opensuse.org" +HOME_URL="https://www.opensuse.org/" + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-4.1.1/test/update_test.rb new/yast2-update-4.1.4/test/update_test.rb --- old/yast2-update-4.1.1/test/update_test.rb 2018-08-23 10:03:34.000000000 +0200 +++ new/yast2-update-4.1.4/test/update_test.rb 2018-10-16 17:43:56.000000000 +0200 @@ -62,14 +62,62 @@ describe "#create_backup" do before(:each) do + allow(::FileUtils).to receive(:cp) allow(::FileUtils).to receive(:mkdir_p) allow(::File).to receive(:write) allow(::FileUtils).to receive(:chmod) allow(::File).to receive(:exist?).and_return(true) + allow(Pathname).to receive(:new).and_return(double("Pathname", exist?: true)) allow(Yast::SCR).to receive(:Execute).with(Yast::Path.new(".target.bash_output"), /^tar /). and_return({"exit" => 0}) end + let(:backup_dir) { "#{Yast::Installation.destdir}/#{Yast::UpdateClass::BACKUP_DIR}" } + let(:backup_dir_pathname) { double("Pathname") } + let(:os_release_pathname) { double } + + context "when backup directory does not exit yet" do + before do + allow(Pathname).to receive(:new).with(backup_dir).and_return(backup_dir_pathname) + allow(backup_dir_pathname).to receive(:exist?).and_return(false) + end + + it "creates it" do + expect(::FileUtils).to receive(:mkdir_p).with(backup_dir_pathname) + + Yast::Update.create_backup("test", []) + end + end + + context "when backup directory is alreday present" do + before do + allow(Pathname).to receive(:new).with(backup_dir).and_return(backup_dir_pathname) + allow(backup_dir_pathname).to receive(:exist?).and_return(true) + end + + it "does not create it again" do + expect(::FileUtils).to_not receive(:mkdir_p).with(backup_dir_pathname) + + Yast::Update.create_backup("test", []) + end + end + + it "copies the release info file" do + allow(Pathname).to receive(:new) + .with("#{Yast::Installation.destdir}/etc/os-release") + .and_return(os_release_pathname) + + expect(::FileUtils).to receive(:cp).with(os_release_pathname, anything) + + Yast::Update.create_backup('testing', []) + end + + it "does not crash when os-release file does not exists" do + allow(::FileUtils).to receive(:cp).and_raise(Errno::ENOENT) + + expect { Yast::Update.create_backup('testing', []) }.to_not raise_error + end + it "create tarball including given name with all paths added" do name = "test-backup" paths = ["a", "b"] @@ -137,17 +185,77 @@ end describe "#restore_backup" do - it "call all restore scripts in backup directory" do - expect(::Dir).to receive(:glob).and_return(["restore-a.sh", "restore-b.sh"]) - expect(Yast::SCR).to receive(:Execute).with(Yast::Path.new(".target.bash_output"), /sh .*restore-a.sh \/mnt/). - and_return({"exit" => 0}) - expect(Yast::SCR).to receive(:Execute).with(Yast::Path.new(".target.bash_output"), /sh .*restore-b.sh \/mnt/). - and_return({"exit" => 0}) + let(:os_release_pathname) { double } + let(:os_backup_release_pathname) { double } + let(:os_release_content) { File.new("#{DATA_DIR}/etc/leap-15-os-release").read } + let(:os_backup_release_content) { File.new("#{DATA_DIR}/etc/tw-os-release").read } + let(:backup_dir) { "#{Yast::Installation.destdir}/#{Yast::UpdateClass::BACKUP_DIR}" } + + before do + allow(Yast::Update.log).to receive(:info).and_call_original + + allow(::Dir).to receive(:glob).and_return(["restore-a.sh", "restore-b.sh"]) + + allow(Pathname).to receive(:new) + .with("#{Yast::Installation.destdir}/etc/os-release") + .and_return(os_release_pathname) + allow(Pathname).to receive(:new) + .with("#{backup_dir}/os-release") + .and_return(os_backup_release_pathname) + allow(os_release_pathname).to receive(:read).and_return(os_release_content) + allow(os_backup_release_pathname).to receive(:read).and_return(os_backup_release_content) + end + + it "check the release info files" do + expect(Pathname).to receive(:new) + .with("#{Yast::Installation.destdir}/etc/os-release") + expect(Pathname).to receive(:new) + .with("#{backup_dir}/os-release") Yast::Update.restore_backup end - end + context "when any file does not exists" do + it "does not crash" do + allow(os_backup_release_pathname).to receive(:read).and_raise(Errno::ENOENT) + + expect { Yast::Update.restore_backup }.to_not raise_error + end + end + + context "when the release info match" do + let(:os_backup_release_content) { os_release_content } + + it "call all restore scripts in backup directory" do + expect(Yast::SCR).to receive(:Execute) + .with(Yast::Path.new(".target.bash_output"), /sh .*restore-a.sh \/mnt/) + expect(Yast::SCR).to receive(:Execute) + .with(Yast::Path.new(".target.bash_output"), /sh .*restore-b.sh \/mnt/) + + Yast::Update.restore_backup + end + end + + context "when the release info does not match" do + it "logs info and error" do + expect(Yast::Update.log).to receive(:info) + .with("Version expected: opensuse-leap-15.0. Backup version: opensuse-tumbleweed-20180911") + .and_call_original + expect(Yast::Update.log).to receive(:error).with(/not restored/).and_call_original + + Yast::Update.restore_backup + end + + it "does not continue" do + expect(Yast::SCR).to_not receive(:Execute) + .with(Yast::Path.new(".target.bash_output"), /sh .*restore-a.sh \/mnt/) + expect(Yast::SCR).to_not receive(:Execute) + .with(Yast::Path.new(".target.bash_output"), /sh .*restore-b.sh \/mnt/) + + Yast::Update.restore_backup + end + end + end describe "#SetDesktopPattern" do context "if there is no definition of window manager upgrade path in control file" do
