Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package transactional-update for openSUSE:Factory checked in at 2022-10-27 13:53:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/transactional-update (Old) and /work/SRC/openSUSE:Factory/.transactional-update.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "transactional-update" Thu Oct 27 13:53:01 2022 rev:92 rq:1031369 version:4.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/transactional-update/transactional-update.changes 2022-09-06 13:00:36.938903736 +0200 +++ /work/SRC/openSUSE:Factory/.transactional-update.new.2275/transactional-update.changes 2022-10-27 13:53:15.084285646 +0200 @@ -0,0 +1,19 @@ +Fri Sep 30 12:39:17 UTC 2022 - Ignaz Forster <ifors...@suse.com> + +- Version 4.1.0 + - t-u: Add a "setup-kdump" command; implements [jsc#PED-1441] + - Export TRANSACTIONAL_UPDATE_ROOT (the path to the snapshot) in + the update environment; implements [jsc#PED-1078] + - Add support for "notify" reboot method for desktop use + [gh#openSUSE/transactional-update#93] + - Fix kdump initrd recreation detection; the check was performed in the + active snapshot instead of the target snapshot + - Document register command [bsc#1202900] + - Avoid unnecessary snapshots for register command [bsc#1202901] + - Various optimizations for register command + - Remove bogus error message when triggering reboot + - Rework /etc overlay documentation in "The Transactional Update Guide" + - Fix incorrect manpage formatting + - Remove leftover "salt" reboot method in configuration example file + - Replace deprecated std::mem_fn with lambdas + Old: ---- transactional-update-4.0.1.tar.gz New: ---- transactional-update-4.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ transactional-update.spec ++++++ --- /var/tmp/diff_new_pack.PLs5Fm/_old 2022-10-27 13:53:15.680288687 +0200 +++ /var/tmp/diff_new_pack.PLs5Fm/_new 2022-10-27 13:53:15.688288727 +0200 @@ -26,7 +26,7 @@ %{!?_distconfdir: %global _distconfdir %{_prefix}%{_sysconfdir}} Name: transactional-update -Version: 4.0.1 +Version: 4.1.0 Release: 0 Summary: Transactional Updates with btrfs and snapshots License: GPL-2.0-or-later AND LGPL-2.1-or-later ++++++ transactional-update-4.0.1.tar.gz -> transactional-update-4.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/NEWS new/transactional-update-4.1.0/NEWS --- old/transactional-update-4.0.1/NEWS 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/NEWS 2022-10-26 16:50:43.000000000 +0200 @@ -2,6 +2,27 @@ Copyright (C) 2016-2022 Thorsten Kukuk, Ignaz Forster et al. +Version 4.1.0 +* t-u: Add a "setup-kdump" command; implements [jsc#PED-1441] +* Add support for ULP (Userspace Live Patching) [jsc#PED-1078]: + * Export TRANSACTIONAL_UPDATE_ROOT (the path to the snapshot) in + the update environment + * Unfortunately requires a separate bind mount in /tmp again for the + update environment, as libpulp has to be able to access the snapshot + directly, without it being bind mounted on itself +* Add support for "notify" reboot method for desktop use + [gh#openSUSE/transactional-update#93] +* Fix kdump initrd recreation detection; the check was performed in the + active snapshot instead of the target snapshot +* Document register command [bsc#1202900] +* Avoid unnecessary snapshots for register command [bsc#1202901] +* Various optimizations for register command +* Remove bogus error message when triggering reboot +* Rework /etc overlay documentation in "The Transactional Update Guide" +* Fix incorrect manpage formatting +* Remove leftover "salt" reboot method in configuration example file +* Replace deprecated std::mem_fn with lambdas + Version 4.0.1 * create_dirs_from_rpmdb: Just warn if no default SELinux context found [gh#openSUSE/transactional-update#88], [bsc#1188215] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/configure.ac new/transactional-update-4.1.0/configure.ac --- old/transactional-update-4.0.1/configure.ac 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/configure.ac 2022-10-26 16:50:43.000000000 +0200 @@ -1,11 +1,11 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(transactional-update, 4.0.1) +AC_INIT(transactional-update, 4.1.0) # Increase on any interface change and reset revision LIBTOOL_CURRENT=4 -# Increase or reset on any VERSION update -LIBTOOL_REVISION=0 -# Increase if interface change is backwards compatible, reset otherwise +# On interface change increase if backwards compatible, reset otherwise LIBTOOL_AGE=0 +# Increase on *any* C/C++ library code change, reset at interface change +LIBTOOL_REVISION=1 AC_CANONICAL_SYSTEM AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_FILES([tukit.pc]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/doc/transactional-update.xml new/transactional-update-4.1.0/doc/transactional-update.xml --- old/transactional-update-4.0.1/doc/transactional-update.xml 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/doc/transactional-update.xml 2022-10-26 16:50:43.000000000 +0200 @@ -163,7 +163,7 @@ For these systems transactional-updates provides automatic updates; snapshots with failed updates will be automatically removed. Automatic reboots can be triggered using a variety of different reboot - methods (e.g. rebootmgr, kured or systemd), making the appliance of + methods (e.g. rebootmgr, notify, kured or systemd), making the appliance of the updates cluster aware. </para> <para> @@ -485,56 +485,117 @@ <title>/etc</title> <para> <emphasis remap='B'>transactional-update</emphasis> also supports - write support to <filename class='directory'>/etc</filename> on an + write operations to <filename class='directory'>/etc</filename> on an otherwise read-only file system. To do so an <emphasis>overlayfs</emphasis> layer is put on top of the system's <filename class='directory'>/etc</filename> directory. All modified configuration files will end up in the current snapshot's overlay in - <filename class='directory'>/var/lib/overlay/<snapshotnum>/etc</filename>. + <filename class='directory'>/var/lib/overlay/<snapshotnum>/etc</filename>, + with each snapshot having one associated overlay directory. </para> <para> - Each snapshot will have one associated overlay directory. On creating - a new snapshot the previous snapshot's - <filename class='directory'>/etc</filename> state will be sychronized - into the new snapshot and used as a base. The overlay directories of - the current and the new snapshot are then mounted using overlay - stacking, i.e. the new snapshot's overlay will be mounted as the - <option>upperdir</option> and the current snapshot's overlay as - <option>lowerdir</option>. This way changes applied to - <filename class='directory'>/etc</filename> after the snapshot was - taken, but before the reboot takes place, will still be visible to the - new snapshot (Exception: If the file has been modified both in the - current and the new snapshot, then the file state of the new snapshot - will be visible). + The mounted <filename class='directory'>/etc</filename> directory will + typically consist of three (or more) layers. In + <filename>/etc/fstab</filename> this may look similar as the following + entry: + <programlisting>overlay /etc overlay defaults,upperdir=/sysroot/var/lib/overlay/82/etc,lowerdir=/sysroot/var/lib/overlay/81/etc:/sysroot/var/lib/overlay/76/etc:/sysroot/etc,workdir=/sysroot/var/lib/overlay/work-etc,x-systemd.requires-mounts-for=/var,x-systemd.requires-mounts-for=/var/lib/overlay,x-systemd.requires-mounts-for=/sysroot/var,x-systemd.requires-mounts-for=/sysroot/var/lib/overlay,x-initrd.mount 0 0</programlisting> </para> <para> + The important options are <option>upperdir</option> and + <option>lowerdir</option>. <option>upperdir</option> references the + write layer, i.e. the directory the system is currently writing to. If + a file in <filename class='directory'>/etc</filename> is opened for + read access, it will first try to open the file from this directory. + If the file is not present in this layer, then overlayfs will search + in the <option>lowerdir</option>s from left to right until it finds + the file, i.e. the layers are <emphasis>transparent</emphasis>. The + last layer is the reference layer and always has to have a complete + copy of <filename class='directory'>/etc</filename>, all the layers + above just contain changes to that base layer. + </para> + <example> + <title>/etc layers</title> + <programlisting> +upperdir (/var/lib/overlay/x/etc) | | file2 | file3 | file4 | | +lowerdir1 (/var/lib/overlay/x-1/etc) | | | file3 | | file5 | file6 +lowerdir2 (/etc of snapshot x-2) | file1 | file2 | file3 | | | file6 + </programlisting> + <para> + Let's have another look from the perspective while an update is + running. <replaceable>x</replaceable> is the id of the new snapshot + where the update is currently be performed in, + <replaceable>x-1</replaceable> is the id of the currently running + snapshot, and <replaceable>x-2</replaceable> is the id of the + snapshot before the currently running one. + </para> + <para> + <filename>file1</filename> is an old file that hasn't been + changed in the last two snapshots. Therefore it is only present in the + base / lowest overlay. As the file cannot be found in the first two + layers, the version from the base layer will be used.</para> + <para><filename>file2</filename> has been changed during the update. + The currently running system still sees the old version of the file + from the base layer, the updated system will see the new version of + the file. + </para> + <para> + <filename>file3</filename> has been changed during the update, + but there is also a modification in the currently running system. See + the Warning below for details. + </para> + <para> + <filename>file4</filename> was only added in the new snapshot + and will be only available there. The currently running system doesn't + know anything about it. + </para> + <para> + <filename>file5</filename> was added in the current snapshot. + It will also be visible in the new snapshot. + </para> + <para> + <filename>file6</filename> was modified in the current snapshot. + It will also be visible in the new snapshot. Basically the same case + as <filename>file5</filename>. + </para> + </example> + <para> + To reduce the number of overlays the contents of the overlays are + merged into the base layer if a new snapshot is created. Caveat: + the state of <filename class='directory'>/etc</filename> that is + synced into the new snapshot is not the one from the currently + running system, but the previous one: the files in the current + system could still be changed before the reboot, and we want these + changes (e.g. by the admin or a configuration management software) + to be visible in the new system. + </para> + <warning> + <para> + If a file has been modified both in the new snapshot and in the + currently running system <emphasis>after the snapshot was + created</emphasis>, then the changes done in the currently running + system will be lost in the new snapshot (see the + <filename>file3</filename> case from the example above). + </para> + <para> + When the new snapshot is booted for the first time the systemd + service <command>transactional-update-etc-cleaner</command> will + check for these conflicts and print the results to the journal. + </para> + </warning> + <para> If the <option>--continue</option> is used multiple times to extend a new snapshot while the system has not been rebooted, and if that snapshot is based on the currently active system, then the - synchronization will only run for the first snapshot; the additional - snapshot layers will be added to <option>lowerdir</option>. Again - this is to make sure that changes to the running system will still be + merge will only run for the first snapshot; the additional + snapshot layers will be added to <option>lowerdir</option>. This is + to make sure that changes to the running system will still be visible after booting into the new system. </para> <para> - Let's have a look at an example <filename>fstab</filename> entry: - <programlisting>overlay /etc overlay defaults,upperdir=/sysroot/var/lib/overlay/82/etc,lowerdir=/sysroot/var/lib/overlay/81/etc:/sysroot/var/lib/overlay/76/etc:/sysroot/etc,workdir=/sysroot/var/lib/overlay/work-etc,x-systemd.requires-mounts-for=/var,x-systemd.requires-mounts-for=/var/lib/overlay,x-systemd.requires-mounts-for=/sysroot/var,x-systemd.requires-mounts-for=/sysroot/var/lib/overlay,x-initrd.mount 0 0</programlisting> - </para> - <itemizedlist> - <listitem><para> - We are currently in snapshot <emphasis>82</emphasis> as indicated by the - <option>upperdir</option> directory. This can be confirmed by typing - <command>snapper list</command> or - <command>btrfs subvolume get-default /</command>. All changes to - <filename class='directory'>/etc</filename> will end up in this - directory. - </para></listitem> - <listitem><para> - <option>lowerdir</option> contains two numbered overlay directories. - The later directory with number <emphasis>76</emphasis> indicates the - snapshot which was used as a base. This snapshot's - <filename class='directory'>/etc</filename> state was also synchronized - into the read-only root file system of snapshot 82. As the + The above <filename>/etc/fstab</filename> example is showing such a + case: <option>lowerdir</option> contains two numbered overlay + directories. The later directory with number <emphasis>76</emphasis> + indicates the snapshot which was used as a base. As the <option>lowerdir</option> contains a second entry with number <emphasis>81</emphasis> it means that the <option>--continue</option> has been used before the system was rebooted. Gaps in the number such @@ -542,15 +603,14 @@ rollback to snapshot 76 was performed. The lowest snapshot is always <filename class='directory'>/sysroot/etc</filename>, containing the root file system's contents. - </para></listitem> - <listitem><para> + </para> + <para> As <filename class='directory'>/etc</filename> is mounted by <application>dracut</application> during early boot the options have to be prefixed with <emphasis>/sysroot</emphasis>. The <command>x-systemd.</command> options are setting up the volume's <application>systemd</application> dependencies correctly. - </para></listitem> - </itemizedlist> + </para> <para> Overlays no longer referenced by any snapshots will be deleted during the <command>transactional-update cleanup-overlays</command> run. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/etc/transactional-update.conf new/transactional-update-4.1.0/etc/transactional-update.conf --- old/transactional-update-4.0.1/etc/transactional-update.conf 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/etc/transactional-update.conf 2022-10-26 16:50:43.000000000 +0200 @@ -2,7 +2,7 @@ # See transactional-update.conf(5) for details # Reboot method -# Valid values: auto salt rebootmgr systemd kexec none +# Valid values: auto rebootmgr notify systemd kexec kured none #REBOOT_METHOD=auto # zypper update method diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/lib/Reboot.cpp new/transactional-update-4.1.0/lib/Reboot.cpp --- old/transactional-update-4.0.1/lib/Reboot.cpp 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/lib/Reboot.cpp 2022-10-26 16:50:43.000000000 +0200 @@ -29,6 +29,8 @@ if (method == "rebootmgr") { command = "/usr/sbin/rebootmgrctl reboot"; + } else if (method == "notify") { + command = "/usr/bin/transactional-update-notifier client"; } else if (method == "systemd") { command = "sync;"; command += "systemctl reboot;"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/lib/Transaction.cpp new/transactional-update-4.1.0/lib/Transaction.cpp --- old/transactional-update-4.0.1/lib/Transaction.cpp 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/lib/Transaction.cpp 2022-10-26 16:50:43.000000000 +0200 @@ -46,6 +46,7 @@ int inotifyRead(); std::unique_ptr<SnapshotManager> snapshotMgr; std::unique_ptr<Snapshot> snapshot; + std::string bindDir; std::vector<std::unique_ptr<Mount>> dirsToMount; Supplements supplements; pid_t pidCmd; @@ -67,6 +68,13 @@ close(inotifyFd); pImpl->dirsToMount.clear(); + if (!pImpl->bindDir.empty()) { + try { + fs::remove(fs::path{pImpl->bindDir}); + } catch (const std::exception &e) { + tulog.error("ERROR: ", e.what()); + } + } try { if (isInitialized() && !getSnapshot().empty() && fs::exists(getRoot())) { tulog.info("Discarding snapshot ", pImpl->snapshot->getUid(), "."); @@ -96,7 +104,9 @@ // GRUB needs to have an actual mount point for the root partition, so // mount the snapshot directory on a temporary mount point - std::unique_ptr<BindMount> mntBind{new BindMount{snapshot->getRoot(), MS_PRIVATE}}; + char bindTemplate[] = "/tmp/transactional-update-XXXXXX"; + bindDir = mkdtemp(bindTemplate); + std::unique_ptr<BindMount> mntBind{new BindMount{bindDir, MS_PRIVATE}}; mntBind->setSource(snapshot->getRoot()); mntBind->mount(); @@ -164,14 +174,14 @@ dirsToMount.push_back(std::make_unique<BindMount>("/.snapshots")); for (auto it = dirsToMount.begin(); it != dirsToMount.end(); ++it) { - it->get()->mount(snapshot->getRoot()); + it->get()->mount(bindDir); } dirsToMount.push_back(std::move(mntBind)); } void Transaction::impl::addSupplements() { - supplements = Supplements(snapshot->getRoot()); + supplements = Supplements(bindDir); Mount mntVar{"/var"}; if (mntVar.isMount()) { @@ -329,11 +339,11 @@ } if (inChroot) { - if (chdir(snapshot->getRoot().c_str()) < 0) { + if (chdir(bindDir.c_str()) < 0) { tulog.info("Warning: Couldn't set working directory: ", std::string(strerror(errno))); } - if (chroot(snapshot->getRoot().c_str()) < 0) { - throw std::runtime_error{"Chrooting to " + std::string(snapshot->getRoot()) + " failed: " + std::string(strerror(errno))}; + if (chroot(bindDir.c_str()) < 0) { + throw std::runtime_error{"Chrooting to " + bindDir + " failed: " + std::string(strerror(errno))}; } // Prevent mounts from within the chroot environment influence the tukit organized mounts if (unshare(CLONE_NEWNS) < 0) { @@ -346,7 +356,13 @@ // Set indicator for RPM pre/post sections to detect whether we run in a // transactional update - setenv("TRANSACTIONAL_UPDATE", "true", 1); + if (setenv("TRANSACTIONAL_UPDATE", "true", 1) < 0) { + throw std::runtime_error{"Setting environment variable TRANSACTIONAL_UPDATE failed: " + std::string(strerror(errno))}; + } + if (setenv("TRANSACTIONAL_UPDATE_ROOT", snapshot->getRoot().c_str(), 1)) { + throw std::runtime_error{"Setting environment variable TRANSACTIONAL_UPDATE_ROOT failed: " + std::string(strerror(errno))}; + } + if (execvp(argv[0], (char* const*)argv) < 0) { throw std::runtime_error{"Calling " + std::string(argv[0]) + " failed: " + std::string(strerror(errno))}; } @@ -395,7 +411,7 @@ for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += getRoot().string().length()) - s.replace(pos, from.size(), getRoot()); + s.replace(pos, from.size(), this->pImpl->bindDir); argv[i] = strdup(s.c_str()); } return this->pImpl->runCommand(argv, false, output); @@ -420,7 +436,7 @@ // in /etc may be applied immediately, so merge them back into the running system. std::unique_ptr<Mount> mntEtc{new Mount{"/etc"}}; if (mntEtc->isMount() && mntEtc->getFilesystem() == "overlay") { - Util::exec("rsync --archive --inplace --xattrs --acls --exclude 'fstab' --delete --quiet '" + std::string(getRoot()) + "/etc/' /etc"); + Util::exec("rsync --archive --inplace --xattrs --acls --exclude 'fstab' --delete --quiet '" + this->pImpl->bindDir + "/etc/' /etc"); } return; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/lib/Util.cpp new/transactional-update-4.1.0/lib/Util.cpp --- old/transactional-update-4.0.1/lib/Util.cpp 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/lib/Util.cpp 2022-10-26 16:50:43.000000000 +0200 @@ -46,13 +46,13 @@ // trim from start (in place) void Util::ltrim(string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), - std::not1(std::ptr_fun<int, int>(std::isspace)))); + [](char a) { return !std::isspace(a); })); } // trim from end (in place) void Util::rtrim(string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), - std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); + [](char a) { return !std::isspace(a); }).base(), s.end()); } void Util::stub(string option) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/man/transactional-update.8.xml new/transactional-update-4.1.0/man/transactional-update.8.xml --- old/transactional-update-4.0.1/man/transactional-update.8.xml 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/man/transactional-update.8.xml 2022-10-26 16:50:43.000000000 +0200 @@ -267,6 +267,24 @@ </listitem> </varlistentry> <varlistentry> + <term><option>setup-kdump</option> <optional>--crashkernel=<replaceable>low</replaceable>,<replaceable>high</replaceable></optional></term> + <listitem> + <para> + Sets up kdump on the system; if no <option>--crashkernel</option> + option is specified then it will use the values determined by + <command>kdumptool calibrate</command>, otherwise the values of + <replaceable>low</replaceable> and <replaceable>high</replaceable> + (numbers in Megabytes) will be used for the corresponding + <command>crashkernel</command> kernel parameters. + </para> + <para> + This command can not be combined with any + <link linkend='pkg_commands'>Package Command</link> other than + <option>install</option>. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><option>setup-selinux</option></term> <listitem> <para> @@ -350,6 +368,26 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term><option>register</option> <replaceable>arguments</replaceable></term> + <listitem> + <para> + Register a (commercial) system. This is a simple wrapper for + <command>SUSEConnect</command>, as some commands may require access + to the root file system (e.g. to add a new key to the RPM database). + Any arguments will just be forwarded to <command>SUSEConnect</command>. + </para> + <para> + This command implies the <option>--drop-if-no-change</option> option + to avoid creation of unnecessary snapshots, as many of the + <command>SUSEConnect</command> options are read-only or only require + access to <filename class='directory'>/etc</filename>. + </para> + <para> + <command>SUSEConnect</command> is always a non-interactive command. + </para> + </listitem> + </varlistentry> </variablelist> </refsect3> <refsect3 id='i_pkg_commands'><title>Interactive Package Commands</title> @@ -445,10 +483,12 @@ <term><option>status</option></term> <listitem> <warning> - This command is under development and will change in the - future. The status command is currently using a non-stable - feature of MicroOS, the control.xml file, that will change the - scope and location in future releases. + <para> + This command is under development and will change in the + future. The status command is currently using a non-stable + feature of MicroOS, the control.xml file, that will change the + scope and location in future releases. + </para> </warning> <para> Shows the status of current and older snapshots. The status diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/sbin/transactional-update.in new/transactional-update-4.1.0/sbin/transactional-update.in --- old/transactional-update-4.0.1/sbin/transactional-update.in 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/sbin/transactional-update.in 2022-10-26 16:50:43.000000000 +0200 @@ -46,6 +46,7 @@ REBOOT_METHOD="auto" RUN_CMD="" RUN_SHELL=0 +SETUP_KDUMP=0 SETUP_SELINUX=0 USE_TELEMETRICS=0 TELEM_PAYLOAD="PACKAGE_NAME=transactional-update\nPACKAGE_VERSION=@VERSION@" @@ -141,6 +142,7 @@ echo "shell Open rw shell in new snapshot before exiting" echo "reboot Reboot after update" echo "run <cmd> Run a command in a new snapshot" + echo "setup-kdump [--crashkernel=<low>,<high>] Configure and enable kdump" echo "setup-selinux Install targeted SELinux policy and enable it" echo "" echo "Package Commands:" @@ -152,6 +154,7 @@ echo "pkg install ... Install individual packages (i)" echo "pkg remove ... Remove individual packages (i)" echo "pkg update ... Updates individual packages (i)" + echo "register ... Register system via SUSEConnect (implies -d)" echo "" echo "Standalone Commands:" echo "rollback [<number>] Set the current or given snapshot as default snapshot" @@ -234,8 +237,8 @@ } rebuild_kdump_initrd() { - test -f /usr/lib/systemd/system/kdump.service || return - systemctl is-enabled --quiet kdump.service + test -f "/.snapshots/$1/snapshot/usr/lib/systemd/system/kdump.service" || return 0 + tukit -q call "$1" systemctl is-enabled --quiet kdump.service if [ $? = 0 -a -x "/.snapshots/$1/snapshot/usr/sbin/tu-rebuild-kdump-initrd" ]; then tukit ${TUKIT_OPTS} call "$1" /usr/sbin/tu-rebuild-kdump-initrd |& tee -a ${LOGFILE} 1>&${origstdout} fi @@ -298,6 +301,11 @@ tukit reboot rebootmgr |& tee -a ${LOGFILE} } +reboot_via_notify() { + TELEM_PAYLOAD="${TELEM_PAYLOAD}\nreboot=transactional-update-notify client" + tukit reboot notify |& tee -a ${LOGFILE} +} + reboot_via_systemd() { TELEM_PAYLOAD="${TELEM_PAYLOAD}\nreboot=systemctl reboot" tukit reboot systemd |& tee -a ${LOGFILE} @@ -892,6 +900,20 @@ RUN_CMD=("$@") break ;; + setup-kdump) + test -z "$TELEM_CLASS" && TELEM_CLASS="setup-kdump" + SETUP_KDUMP=1 + shift + if [[ $1 == --crashkernel* ]]; then + if ! [[ $1 =~ ^--crashkernel=[[:digit:]]+,[[:digit:]]+ ]]; then + echo "Invalid --crashkernel syntax" + usage 1 + fi + KDUMP_LOW="$(echo "$1" | cut -d '=' -f 2 | cut -d ',' -f 1)" + KDUMP_HIGH="$(echo "$1" | cut -d '=' -f 2 | cut -d ',' -f 2)" + shift + fi + ;; setup-selinux) test -z "$TELEM_CLASS" && TELEM_CLASS="selinux" SETUP_SELINUX=1 @@ -951,19 +973,19 @@ DO_REGISTRATION=1 shift - # Collect arguments for Registration if [ $# -eq 0 ]; then usage 1 fi + if ! command -v SUSEConnect >/dev/null; then + echo "SUSEConnect does not exist on this system." + exit 1 + fi - while [ 1 ]; do - if [ $# -eq 0 ]; then - break; - else - REGISTRATION_ARGS="${REGISTRATION_ARGS} $1"; - shift - fi - done + REGISTRATION_ARGS="$*"; + shift $# + + # A lot of commands won't change anything; discard snapshot then + TUKIT_OPTS="${TUKIT_OPTS} --discard" ;; -h|--help) usage 0 @@ -1019,6 +1041,22 @@ test -d /var/lib/selinux || mkdir -p /var/lib/selinux fi +# Setup kdump +if [ ${SETUP_KDUMP} -eq 1 ]; then + if [ -n "${ZYPPER_ARG}" -a "${ZYPPER_ARG}" != "install" ]; then + log_error "ERROR: Cannot combine 'setup-kdump' with zypper command '${ZYPPER_ARG}'" + exit 1 + fi + # Check if we need to install packages + for pkg in kdump; do + rpm -q --quiet ${pkg} || ZYPPER_ARG_PKGS+=("${pkg}") + done + if [ ${#ZYPPER_ARG_PKGS[@]} -ne 0 ]; then + ZYPPER_ARG="install" + fi + REBUILD_KDUMP_INITRD=1 +fi + # If no commands were given, assume "up" if [ -z "${ZYPPER_ARG}" -a -z "${TELEM_CLASS}" -a "${REBOOT_AFTERWARDS}" -eq 0 \ -a "${DO_REGISTRATION}" -eq 0 -a "${DO_CLEANUP_OVERLAYS}" -eq 0 \ @@ -1398,6 +1436,19 @@ test -f ${SNAPSHOT_DIR}/.autorelabel && mv ${SNAPSHOT_DIR}/.autorelabel ${ETC_BASE}/etc/selinux/.autorelabel fi + if [ ${SETUP_KDUMP} -eq 1 ]; then + if [ -z "${KDUMP_LOW}" ]; then + KDUMP_CALIBRATION="$(tukit -q call "${SNAPSHOT_ID}" kdumptool calibrate)" + KDUMP_LOW="$(echo "$KDUMP_CALIBRATION" | grep ^Low: | cut -d ' ' -f 2)" + KDUMP_HIGH="$(echo "$KDUMP_CALIBRATION" | grep ^High: | cut -d ' ' -f 2)" + fi + + tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" sed -i -e '/^GRUB_CMDLINE_LINUX_DEFAULT=/s/ *crashkernel[^ "]\+//g' -e 's|\(^GRUB_CMDLINE_LINUX_DEFAULT=.*\)"|\1 crashkernel='${KDUMP_LOW}'M,low crashkernel='${KDUMP_HIGH}'M,high"|g' "/etc/default/grub" + REWRITE_GRUB_CFG=1 + + tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" systemctl enable kdump + fi + if [ ${REWRITE_INITRD} -eq 1 ]; then log_info "Creating new initrd" tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" dracut ${DRACUT_OPTS} --force --regenerate-all |& tee -a ${LOGFILE} 1>&${origstdout} @@ -1411,7 +1462,11 @@ if [ ${REBUILD_KDUMP_INITRD} -eq 1 ]; then log_info "Trying to rebuild kdump initrd" - rebuild_kdump_initrd ${SNAPSHOT_ID} + rebuild_kdump_initrd ${SNAPSHOT_ID} + if [ $? -ne 0 ]; then + log_error "ERROR: kdump initrd creation failed!" + EXITCODE=1 + fi fi if [ ${REWRITE_GRUB_CFG} -eq 1 ]; then @@ -1533,6 +1588,9 @@ rebootmgr) reboot_via_rebootmgr ;; + notify) + reboot_via_notify + ;; systemd) reboot_via_systemd ;; @@ -1547,8 +1605,6 @@ reboot_autodetect ;; esac - log_error "The system couldn't be rebooted using method '${REBOOT_METHOD}'. Please reboot the system" - log_error "manually." fi fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/systemd/transactional-update.timer new/transactional-update-4.1.0/systemd/transactional-update.timer --- old/transactional-update-4.0.1/systemd/transactional-update.timer 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/systemd/transactional-update.timer 2022-10-26 16:50:43.000000000 +0200 @@ -7,6 +7,7 @@ OnCalendar=daily AccuracySec=1m RandomizedDelaySec=2h +Persistent=true [Install] WantedBy=timers.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.0.1/tukit/tukit.cpp new/transactional-update-4.1.0/tukit/tukit.cpp --- old/transactional-update-4.0.1/tukit/tukit.cpp 2022-08-22 17:09:42.000000000 +0200 +++ new/transactional-update-4.1.0/tukit/tukit.cpp 2022-10-26 16:50:43.000000000 +0200 @@ -64,7 +64,7 @@ cout << " List of fields to print\n"; cout << "\n"; cout << "Reboot Commands:\n"; - cout << "reboot [auto|rebootmgr|systemd|kured|kexec]\n"; + cout << "reboot [auto|rebootmgr|notify|systemd|kured|kexec]\n"; cout << "\tReboot the system using the given method; Default: auto\n"; cout << "\n"; cout << "Generic Options:\n";