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 2023-11-22 18:54:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/transactional-update (Old)
 and      /work/SRC/openSUSE:Factory/.transactional-update.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "transactional-update"

Wed Nov 22 18:54:28 2023 rev:102 rq:1127927 version:4.5.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/transactional-update/transactional-update.changes    
    2023-09-22 21:46:42.667329112 +0200
+++ 
/work/SRC/openSUSE:Factory/.transactional-update.new.25432/transactional-update.changes
     2023-11-22 18:54:46.987960406 +0100
@@ -1,0 +2,19 @@
+Mon Nov 20 17:12:20 UTC 2023 - Ignaz Forster <[email protected]>
+
+- Version 4.5.0
+  - libtukit: Use permissions of real /etc when creating overlay
+    [bsc#1215878]
+  - libtukit, tukit: Support "rollback" via library now
+  - tukitd: Implement Snapshot delete and rollback methods
+  - tukit: Check for missing arguments with "close" and "abort"
+    commands
+  - t-u: Warn user when using "kdump" if it isn't configured to
+    avoid confusion with "setup-kdump" [boo#1215725]
+  - t-u: Abort if mkdumprd run is not successful
+  - t-u: Use defaut from config file if t-u is called without
+    arguments [gh#openSUSE/transactional-update#101]
+  - Improved README.md [gh#openSUSE/transactional-update#59] and
+    API docs
+  - Code cleanup
+
+-------------------------------------------------------------------
@@ -11 +30 @@
-    run.
+    run. [gh#openSUSE/transactional-update#62]

Old:
----
  transactional-update-4.4.0.tar.gz

New:
----
  transactional-update-4.5.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ transactional-update.spec ++++++
--- /var/tmp/diff_new_pack.y9mziK/_old  2023-11-22 18:54:47.651984776 +0100
+++ /var/tmp/diff_new_pack.y9mziK/_new  2023-11-22 18:54:47.651984776 +0100
@@ -26,7 +26,7 @@
 %{!?_distconfdir: %global _distconfdir %{_prefix}%{_sysconfdir}}
 
 Name:           transactional-update
-Version:        4.4.0
+Version:        4.5.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.4.0.tar.gz -> transactional-update-4.5.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/NEWS 
new/transactional-update-4.5.0/NEWS
--- old/transactional-update-4.4.0/NEWS 2023-09-11 15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/NEWS 2023-11-20 18:09:46.000000000 +0100
@@ -1,6 +1,20 @@
 transactional-update NEWS -- history of user-visible changes.
 
-Copyright (C) 2016-2022 Thorsten Kukuk, Ignaz Forster et al.
+Copyright (C) 2016-2023 Thorsten Kukuk, Ignaz Forster et al.
+
+Version 4.5.0 (2023-11-20)
+* libtukit: Use permissions of real /etc when creating overlay
+  [bsc#1215878]
+* libtukit, tukit: Support "rollback" via library now
+* tukitd: Implement Snapshot delete and rollback methods
+* tukit: Check for missing arguments with "close" and "abort" commands
+* t-u: Warn user when using "kdump" if it isn't configured to avoid
+  confusion with "setup-kdump" [boo#1215725]
+* t-u: Abort if mkdumprd run is not successful
+* t-u: Use defaut from config file if t-u is called without arguments
+  [gh#openSUSE/transactional-update#101]
+* Improved README.md [gh#openSUSE/transactional-update#59] and API docs
+* Code cleanup
 
 Version 4.4.0
 * t-u: Introduce setup-fips command [jsc#SMO-194]
@@ -8,7 +22,7 @@
   D-Bus interface or tukit the snapshots will be automatically cleaned up
   by snapper after some time now; in the past only snapshots created by
   the transactional-update shell script would be cleanup after, and only
-  after a `t-u cleanup` run.
+  after a `t-u cleanup` run. [gh#openSUSE/transactional-update#62]
 * tukit: enable kexec's syscall detection feature
 * tukit: Don't throw exceptions from the child process after fork
 * tukitd: Rename service file to org.opensuse.tukit.service
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/README.md 
new/transactional-update-4.5.0/README.md
--- old/transactional-update-4.4.0/README.md    2023-09-11 15:49:37.000000000 
+0200
+++ new/transactional-update-4.5.0/README.md    2023-11-20 18:09:46.000000000 
+0100
@@ -1,37 +1,54 @@
 # transactional-update
 ## Update the operating system in an atomic way
-This project provides an application and library to update a Linux operating 
system in a transactional way, i.e. the update will be performed in the 
background while the system continues running as it is. Only if the update was 
the successful the system will boot into the new snapshot.
+transactional-update provides an application and library to update a Linux 
operating system in a transactional way, i.e. the update will be performed in 
the background while the system continues running as it is. Only if the update 
was the successful as a whole the system will boot into the new snapshot.
 
-Originally developed for the openSUSE project as the update mechanism for all 
transactional / read-only systems (openSUSE MicroOS, SLE Micro, SLES / openSUSE 
Leap / openSUSE Tumbleweed "Transactional Server" role) the original 
*transactional-update* Bash script has since been split into several components:
+It consists of the following components:
 
 * **libtukit**: A generic library for atomic system updates.
-* **tukit**: A command line application to access the library functionality.
-* **tukitd**: A D-Bus service to access the library functionality.
-* **transactional-update**: An (open)SUSE specific tukit wrapper to call 
common tasks, e.g. updating the system or installing the boot loader.
+* **tukit**: A command line application to access the library's functionality 
directly.
+* **tukitd**: A D-Bus service to access the library's functionality.
+* **transactional-update**: An (open)SUSE specific tukit wrapper to call 
common tasks, e.g. updating the system, installing RPM packages or refreshing 
the boot loader.
+
+## What's a "transaction" when thinking about OS updates?
+You may be familiar with the term "transaction" in the context of a classical 
database transaction: Only if all the single changes to the database tables 
could be applied successfully, then a final COMMIT will activate them, 
otherwise a ROLLBACK will just discard everything again.
+
+In the context of operating system updates this is equivalent: Only if all 
updates (or other changes) could be applied successfully, then the system will 
switch into that new updated state. If any error occured - think about failed 
package post scripts or running out of disk space - the updated system will 
just be discarded again. All of this is happening in the background, i.e. the 
currently running system just continues to run all the time.
+
+Or in a more formal way: A transactional update is an update that
+* is atomic
+  * Either fully applied, or not applied at all
+  * Update does not influence the running system
+* can be rolled back
+  * A failed or incompatible update can be quickly discarded to restore the 
previous system condition
 
 ## Supported Systems
-Currently only systems running **Btrfs with Snapper** are supported, however 
the API is intentionally generic and able to support a wider range of backends 
for atomic / transactional systems.
+* **Btrfs with Snapper**: Creates a new snapshot of the system and applies the 
update there. In contrast to classical A/B partitioning mechanisms snapper can 
handle a large number of snapshots, and snapshot handling of Btrfs is very fast 
and space efficient.
+* The API is intentionally generic and able to support a wider range of 
backends for atomic / transactional systems.
 
 ## How does this work?
-First a new snapshot of the system is created. Afterwards, this snapshot is 
changed from read-only to read-write and several special directories such as 
/dev, /sys and /proc are mounted. The proposed change(s) can the be performed 
in that snapshot in a chroot environment, on (open)SUSE systems for example 
zypper is wrapped in a *tukit* call to install, update or remove RPMs. If the 
update did succeed switch the snapshot to read-only (on ro systems) and make 
the subvolume the new default. On next boot, the system will boot the new 
snapshot. If the updated system should not boot (see also 
[health-checker](https://github.com/openSUSE/health-checker)), the system can 
simply be rolled back to the old snapshot.
+With the Snapper implementation, first a new snapshot of the system is 
created. Afterwards, this snapshot is changed from read-only to read-write and 
several special directories such as /dev, /sys and /proc are mounted. The 
proposed change(s) will be performed in that snapshot in a chroot environment; 
on (open)SUSE systems for example *zypper* is wrapped into a *tukit* call to 
install, update or remove RPMs. If the update did succeed, then switch the 
snapshot to read-only (on ro systems) and make the subvolume the new default. 
On next boot, the system will boot the new snapshot. If the updated system 
should not boot (see also 
[health-checker](https://github.com/openSUSE/health-checker)), the system can 
simply be rolled back to the old snapshot.
 
 ## How to update an atomic system
-Applications can integrate support directly (such as dnf or Cockpit - see 
below), otherwise any command can be wrapped with `tukit execute` (e.g. zypper).
+Applications can integrate support directly (such as dnf or Cockpit - see 
[Known Users](#known-users) below), otherwise any command can be wrapped with 
`tukit execute` (e.g. zypper).
 
 ## User Documentation
 * [The Transactional Update 
Guide](https://kubic.opensuse.org/documentation/transactional-update-guide/transactional-update.html)
 provides general information on the concept of transactional-update.
+* [Various talks](https://media.ccc.de/search/?q=transactional-update) are 
available online.
 
 ## API Documentation
 Developers that want to integrate support for transactional updates may be 
interested in the following official API ressources:
-* C++: [Transaction.hpp](lib/Transaction.hpp) / 
[SnapshotManager](lib/SnapshotManager.hpp)
+* C++: [Transaction.hpp](lib/Transaction.hpp) / 
[SnapshotManager.hpp](lib/SnapshotManager.hpp)
 * C: [libtukit.h](lib/Bindings/libtukit.h) (C binding - see the C++ header 
files for documentation)
 * D-Bus interface: 
[org.opensuse.tukit.Transaction.xml](dbus/org.opensuse.tukit.Transaction.xml) / 
[org.opensuse.tukit.Snapshot.xml](dbus/org.opensuse.tukit.Snapshot.xml)
 
-## Known users
+## Known Users
+transactional-update was originally developed for the **openSUSE project** as 
the update mechanism for all transactional / read-only systems ([openSUSE 
MicroOS](https://microos.opensuse.org/), [SUSE Linux Enterprise 
Micro](https://www.suse.com/products/micro/), SUSE Linux Enterprise Server / 
openSUSE Leap / openSUSE Tumbleweed "Transactional Server" role) and is used as 
the update mechanism there.
+
+Additionally the following components support transactional-update directly:
 * **dnf**, Fedora's package management system, supports transactional systems 
directly via the 
[libdnf-plugin-txnupd](https://code.opensuse.org/microos/libdnf-plugin-txnupd) 
plugin (libtukit).
 * **Cockpit** can update transactional systems via the 
[cockpit-tukit](https://github.com/openSUSE/cockpit-tukit) plugin (tukitd).
 * **Salt** contains the [salt.modules.transactional\_update 
module](https://docs.saltproject.io/en/3004/ref/modules/all/salt.modules.transactional_update.html)
 module (transactional-update).
 * **Ansible** also supports transactional-update via the the 
[community.general.zypper](https://docs.ansible.com/ansible/latest/collections/community/general/zypper_module.html)
 module (transactional-update).
 
 ## Caveats
-* A transactional system needs strict separation of applications, 
configuration and user data. Data in /var must not be available during the 
update, as changes in there would necessarily modify the state of the currently 
running system.
+* A transactional system needs strict separation of applications, 
configuration and user data. Data in /var must not be available during the 
update, as changes in there would necessarily modify the state of the currently 
running system. For better handling of package and admin configuration files 
see the UAPI Group's [Configuration File 
Specification](https://uapi-group.org/specifications/specs/configuration_files_specification/).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/configure.ac 
new/transactional-update-4.5.0/configure.ac
--- old/transactional-update-4.4.0/configure.ac 2023-09-11 15:49:37.000000000 
+0200
+++ new/transactional-update-4.5.0/configure.ac 2023-11-20 18:09:46.000000000 
+0100
@@ -1,11 +1,11 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT(transactional-update, 4.4.0)
+AC_INIT(transactional-update, 4.5.0)
 # Increase on any interface change and reset revision
-LIBTOOL_CURRENT=4
+LIBTOOL_CURRENT=5
 # On interface change increase if backwards compatible, reset otherwise
-LIBTOOL_AGE=0
+LIBTOOL_AGE=1
 # Increase on *any* C/C++ library code change, reset at interface change
-LIBTOOL_REVISION=7
+LIBTOOL_REVISION=0
 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.4.0/dbus/README.md 
new/transactional-update-4.5.0/dbus/README.md
--- old/transactional-update-4.4.0/dbus/README.md       2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/dbus/README.md       2023-11-20 
18:09:46.000000000 +0100
@@ -1,6 +1,5 @@
 # Tukit DBUS Service
-The tukitd service provides an DBUS interface which supports the same 
functionality as
-the command line interface "tukit".
+The tukitd service provides a DBUS interface for the libtukit API.
 
 ## Starting/Stopping Servive
 ### Starting
@@ -13,14 +12,18 @@
 This `systemctl` call stops the service:
 > systemctl stop tukitd.service
 
+## Monitoring
+For debugging purposes the transferred messages can be monitored via
+> busctl --system monitor org.opensuse.tukit
+
 ## DBUS API
-The following sections describe each call which is available via DBUS.
-The command line program `busctl` can be used for demonstrating the API calls
-and showing the results.
+### API Documentation
+The complete API documentation can be found in the 
org.opensuse.tukit.Transaction.xml and
+org.opensuse.tukit.Snapshot.xml interface files.
 
-### Transaction
+### Examples
 
-#### open
+#### Open
 Creates a new transaction and returns its unique ID.
 
 Parameter:
@@ -37,9 +40,9 @@
 
 `busctl` example:
 
-> busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction open "s" "default"
+> busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction Open "s" "default"
 
-### call
+### Call
 Executes the given command from within the transaction's **chroot 
environment**, resuming the
 transaction with the given ID; returns the exit status and the result of the 
given command.
 In case of errors the snapshot will not be deleted.
@@ -58,12 +61,12 @@
 `busctl` example:
 
 * call `ls` in open transaction with ID `536`:
-  > busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction call "ss" "536" "bash -c 'ls'"
-  
+  > busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction Call "ss" "536" "bash -c 'ls'"
+
   The returned signal can be monitored by:
   > busctl --system --match "path\_namespace='/org/opensuse/tukit'" monitor
 
-### callext
+### CallExt
 Executes the given command. The command is **not** executed in a **chroot 
environment**, but instead runs
 in the current system, replacing '{}' with the mount directory of the given 
snapshot.
 In case of errors the snapshot will not be deleted.
@@ -82,33 +85,33 @@
 `busctl` example:
 
 * copy file from active system into transaction with ID `536`:
-  > busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction callext "ss" "536" "bash -c 'mv /tmp/mylib 
{}/usr/lib'"
+  > busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction CallExt "ss" "536" "bash -c 'mv /tmp/mylib 
{}/usr/lib'"
 
   The returned signal can be monitored by:
   > busctl --system --match "path\_namespace='/org/opensuse/tukit'" monitor
 
-### close
+### Close
 Closes the given transaction and sets the snapshot as the new default snapshot.
 
 Parameter:
 * unique ID (string)
 
 Return value:
-* return integer; 0 on success
+* None
 
 `busctl` Example:
 
-> busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction close "s" "420"
+> busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction Close "s" "420"
 
-### abort
-Deletes the given snapshot.
+### Abort
+Cancel an open transaction so the snapshot will be deleted again.
 
 Parameter:
 * unique ID (string)
 
 Return value:
-* return integer; 0 on success
+* None
 
 `busctl` Example:
 
-> busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction abort "s" "420"
+> busctl call org.opensuse.tukit /org/opensuse/tukit/Transaction 
org.opensuse.tukit.Transaction Abort "s" "420"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transactional-update-4.4.0/dbus/org.opensuse.tukit.Snapshot.xml 
new/transactional-update-4.5.0/dbus/org.opensuse.tukit.Snapshot.xml
--- old/transactional-update-4.4.0/dbus/org.opensuse.tukit.Snapshot.xml 
2023-09-11 15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/dbus/org.opensuse.tukit.Snapshot.xml 
2023-11-20 18:09:46.000000000 +0100
@@ -8,11 +8,10 @@
      <doc:para>
       Retrieve a list of snapshots present on the system, including their 
properties. For
       performance reasons only the properties explicity requested via the 
"columns" arg
-      are queried. the desired snapshots's properties (such as the snapshot id,
-      description or whether it is the default snapshot) have to be queried 
explicitly.
+      are queried.
      </doc:para>
      <doc:example language="shell" title="Query some fields">
-      <doc:para>Request of common fields:</doc:para>
+      <doc:para>Request several common fields:</doc:para>
       <doc:code>busctl call org.opensuse.tukit /org/opensuse/tukit/Snapshot 
org.opensuse.tukit.Snapshot List "s" 
"number,description,default,active,userdata,cleanup,date,user"</doc:code>
       <doc:para>Example output on bus:</doc:para>
       <doc:code>
@@ -201,10 +200,10 @@
      <doc:error name="org.opensuse.tukit.Error">if an error 
occured.</doc:error>
    </doc:errors>
    <arg type="s" name="columns" direction="in">
-    <doc:doc><doc:summary>A comma separated list of fields to query such as 
the snapshot
+    <doc:doc><doc:summary>A comma separated list of fields to query, such as 
the snapshot
      id, the description or whether it is the default snapshot. The accepted 
field names
-     currently match the  ...   If the list is empty, an
-     empty map array will be returned; this can be used to query the number of
+     currently match the accepted fields of the "snapper list" command. If the 
list is
+     empty, an empty map array will be returned; this can be used to query the 
number of
      snapshots.</doc:summary></doc:doc>
    </arg>
    <arg type="aa{ss}" name="list" direction="out">
@@ -215,4 +214,4 @@
    </arg>
   </method>
  </interface>
-</node>
\ No newline at end of file
+</node>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/dbus/tukitd.c 
new/transactional-update-4.5.0/dbus/tukitd.c
--- old/transactional-update-4.4.0/dbus/tukitd.c        2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/dbus/tukitd.c        2023-11-20 
18:09:46.000000000 +0100
@@ -763,6 +763,53 @@
     return ret;
 }
 
+static int snapshot_delete(sd_bus_message *m, void *userdata, sd_bus_error 
*ret_error) {
+    char *snapshot;
+    int ret = 0;
+    sd_bus_message *message = NULL;
+
+    if (sd_bus_message_read(m, "s", &snapshot) < 0) {
+        sd_bus_error_set_const(ret_error, "org.opensuse.tukit.Error", "Could 
not read D-Bus parameters.");
+        return -1;
+    }
+
+    ret = lockSnapshot(userdata, snapshot, ret_error);
+    if (ret != 0) {
+        return ret;
+    }
+
+    fprintf(stdout, "Deleting snapshot %s...\n", snapshot);
+    if ((ret = tukit_sm_deletesnap(snapshot)) < 0) {
+        sd_bus_error_set_const(ret_error, "org.opensuse.tukit.Error", 
tukit_get_errmsg());
+        sd_bus_message_unref(message);
+        unlockSnapshot(userdata, snapshot);
+        return ret;
+    }
+
+    unlockSnapshot(userdata, snapshot);
+    return sd_bus_reply_method_return(m, "");
+}
+
+static int snapshot_rollback(sd_bus_message *m, void *userdata, sd_bus_error 
*ret_error) {
+    char *snapshot;
+    int ret = 0;
+    sd_bus_message *message = NULL;
+
+    if (sd_bus_message_read(m, "s", &snapshot) < 0) {
+        sd_bus_error_set_const(ret_error, "org.opensuse.tukit.Error", "Could 
not read D-Bus parameters.");
+        return -1;
+    }
+
+    if ((ret = tukit_sm_rollbackto(snapshot)) < 0) {
+        sd_bus_error_set_const(ret_error, "org.opensuse.tukit.Error", 
tukit_get_errmsg());
+        sd_bus_message_unref(message);
+        return ret;
+    }
+
+    fprintf(stdout, "Rollback to snapshot %s.\n", snapshot);
+    return sd_bus_reply_method_return(m, "");
+}
+
 int event_handler(sd_event_source *s, const struct signalfd_siginfo *si, void 
*userdata) {
     TransactionEntry* activeTransaction = userdata;
     if (activeTransaction->id != NULL) {
@@ -801,6 +848,8 @@
 static const sd_bus_vtable tukit_snapshot_vtable[] = {
     SD_BUS_VTABLE_START(0),
     SD_BUS_METHOD_WITH_ARGS("List", SD_BUS_ARGS("s", columns), 
SD_BUS_RESULT("aa{ss}", list), snapshot_list, 0),
+    SD_BUS_METHOD_WITH_ARGS("Delete", SD_BUS_ARGS("s", snapshot), 
SD_BUS_NO_RESULT, snapshot_delete, 0),
+    SD_BUS_METHOD_WITH_ARGS("RollbackTo", SD_BUS_ARGS("s", snapshot), 
SD_BUS_NO_RESULT, snapshot_rollback, 0),
     SD_BUS_VTABLE_END
 };
 
@@ -843,7 +892,7 @@
                                    "/org/opensuse/tukit/Snapshot",
                                    "org.opensuse.tukit.Snapshot",
                                    tukit_snapshot_vtable,
-                                   NULL);
+                                   activeTransactions);
     if (ret < 0) {
         fprintf(stderr, "Failed to issue method call: %s\n", strerror(-ret));
         goto finish;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transactional-update-4.4.0/etc/transactional-update.conf 
new/transactional-update-4.5.0/etc/transactional-update.conf
--- old/transactional-update-4.4.0/etc/transactional-update.conf        
2023-09-11 15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/etc/transactional-update.conf        
2023-11-20 18:09:46.000000000 +0100
@@ -5,7 +5,7 @@
 # Valid values: auto rebootmgr notify systemd kexec kured none
 #REBOOT_METHOD=auto
 
-# zypper update method
+# Default zypper update method
 # Valid values: dup up
 UPDATE_METHOD=dup
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transactional-update-4.4.0/lib/Bindings/CBindings.cpp 
new/transactional-update-4.5.0/lib/Bindings/CBindings.cpp
--- old/transactional-update-4.4.0/lib/Bindings/CBindings.cpp   2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/lib/Bindings/CBindings.cpp   2023-11-20 
18:09:46.000000000 +0100
@@ -249,6 +249,18 @@
     }
 }
 
+int tukit_sm_rollbackto(const char* id) {
+    try {
+        std::unique_ptr<TransactionalUpdate::SnapshotManager> snapshotMgr = 
TransactionalUpdate::SnapshotFactory::get();
+        snapshotMgr->rollbackTo(id);
+        return 0;
+    } catch (const std::exception &e) {
+        fprintf(stderr, "ERROR: %s\n", e.what());
+        errmsg = e.what();
+        return -1;
+    }
+}
+
 int tukit_reboot(const char* method) {
     try {
         auto rebootmgr = Reboot{method};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/lib/Bindings/libtukit.h 
new/transactional-update-4.5.0/lib/Bindings/libtukit.h
--- old/transactional-update-4.4.0/lib/Bindings/libtukit.h      2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/lib/Bindings/libtukit.h      2023-11-20 
18:09:46.000000000 +0100
@@ -43,6 +43,7 @@
 const char* tukit_sm_get_list_value(tukit_sm_list list, size_t row, char* 
columns);
 void tukit_free_sm_list(tukit_sm_list list);
 int tukit_sm_deletesnap(const char* id);
+int tukit_sm_rollbackto(const char* id);
 int tukit_reboot(const char* method);
 
 #ifdef __cplusplus
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/lib/Overlay.cpp 
new/transactional-update-4.5.0/lib/Overlay.cpp
--- old/transactional-update-4.4.0/lib/Overlay.cpp      2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/lib/Overlay.cpp      2023-11-20 
18:09:46.000000000 +0100
@@ -17,6 +17,7 @@
 #include <selinux/selinux.h>
 #include <selinux/context.h>
 #include <sstream>
+#include <sys/stat.h>
 #include <unistd.h>
 
 using std::exception;
@@ -185,7 +186,16 @@
 
     // Remove overlay directory if it already exists (e.g. after the snapshot 
was deleted)
     fs::remove_all(upperdir);
-    fs::create_directories(upperdir);
+    fs::create_directory(upperdir, "/etc");
+    // Explicitly copy the current /etc permissions, even if the umask was 
more restrictive
+    struct stat status;
+    tulog.info(parent.upperdir.string());
+    if (stat(parent.upperdir.c_str(), &status) != 0) {
+        throw std::runtime_error{"could not get permissions of /etc: " + 
std::string(strerror(errno))};
+    }
+    if (chmod(upperdir.c_str(), status.st_mode) != 0) {
+        throw std::runtime_error{"could not set permissions of " + 
upperdir.string() + ": " + std::string(strerror(errno))};
+    }
 
     char* context = NULL;
     if (getfilecon("/etc", &context) > 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/lib/Snapshot/Snapper.cpp 
new/transactional-update-4.5.0/lib/Snapshot/Snapper.cpp
--- old/transactional-update-4.4.0/lib/Snapshot/Snapper.cpp     2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/lib/Snapshot/Snapper.cpp     2023-11-20 
18:09:46.000000000 +0100
@@ -125,6 +125,10 @@
     callSnapper("delete " + id);
 }
 
+void Snapper::rollbackTo(std::string id) {
+    callSnapper("rollback " + id);
+}
+
 bool Snapper::isInProgress() {
     std::string desc = callSnapper("--csvout list --columns number,userdata");
     std::smatch match;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/lib/Snapshot/Snapper.hpp 
new/transactional-update-4.5.0/lib/Snapshot/Snapper.hpp
--- old/transactional-update-4.4.0/lib/Snapshot/Snapper.hpp     2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/lib/Snapshot/Snapper.hpp     2023-11-20 
18:09:46.000000000 +0100
@@ -37,6 +37,7 @@
     std::string getCurrent() override;
     std::string getDefault() override;
     void deleteSnap(std::string id) override;
+    void rollbackTo(std::string id) override;
 private:
     std::string callSnapper(std::string);
     inline static bool snapperNoDbus;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/lib/Snapshot.hpp 
new/transactional-update-4.5.0/lib/Snapshot.hpp
--- old/transactional-update-4.4.0/lib/Snapshot.hpp     2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/lib/Snapshot.hpp     2023-11-20 
18:09:46.000000000 +0100
@@ -10,7 +10,6 @@
 #define T_U_SNAPSHOT_H
 
 #include <filesystem>
-#include <memory>
 #include <string>
 
 namespace TransactionalUpdate {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/lib/SnapshotManager.hpp 
new/transactional-update-4.5.0/lib/SnapshotManager.hpp
--- old/transactional-update-4.4.0/lib/SnapshotManager.hpp      2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/lib/SnapshotManager.hpp      2023-11-20 
18:09:46.000000000 +0100
@@ -58,12 +58,18 @@
     virtual std::string getDefault() = 0;
 
     /**
-     * @brief deleteSnap Deletes the given snapshot; note that the method may 
not fail if the snapshot
+     * @brief deleteSnap Deletes the given snapshot; note that the method may 
fail if the snapshot
      * cannot be deleted because it is currently in use or set as the default 
snapshot, so
      * getCurrent() and getDefault() should be used beforehand.
      * @param id ID of the snapshot to be deleted.
      */
     virtual void deleteSnap(std::string id) = 0;
+
+    /**
+     * @brief Set the given snapshot ID as the default snapshot ID
+     * @param id ID of the snapshot to be rolled back to.
+     */
+    virtual void rollbackTo(std::string id) = 0;
 };
 
 class SnapshotFactory {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/lib/Transaction.cpp 
new/transactional-update-4.5.0/lib/Transaction.cpp
--- old/transactional-update-4.4.0/lib/Transaction.cpp  2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/lib/Transaction.cpp  2023-11-20 
18:09:46.000000000 +0100
@@ -17,7 +17,6 @@
 #include "Supplement.hpp"
 #include "Util.hpp"
 #include <cerrno>
-#include <chrono>
 #include <cstdlib>
 #include <cstring>
 #include <fstream>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transactional-update-4.4.0/man/transactional-update.8.xml 
new/transactional-update-4.5.0/man/transactional-update.8.xml
--- old/transactional-update-4.4.0/man/transactional-update.8.xml       
2023-09-11 15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/man/transactional-update.8.xml       
2023-11-20 18:09:46.000000000 +0100
@@ -144,8 +144,10 @@
 
 <refsect1 id='commands'><title>COMMANDS</title>
 <para>
-  If none of the following commands is given <option>up</option> will be
-  assumed.
+  If none of the following commands is given, the value of
+  <option>UPDATE_METHOD</option> in
+  
<citerefentry><refentrytitle>transactional-update.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+  will be assumed.
 </para>
 <refsect2 id='general_commands'><title>General Commands</title>
 <para>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transactional-update-4.4.0/man/transactional-update.conf.5.xml 
new/transactional-update-4.5.0/man/transactional-update.conf.5.xml
--- old/transactional-update-4.4.0/man/transactional-update.conf.5.xml  
2023-09-11 15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/man/transactional-update.conf.5.xml  
2023-11-20 18:09:46.000000000 +0100
@@ -165,7 +165,9 @@
         <listitem>
           <para>
            Specify the zypper update method to use. This value is used for
-           
<citerefentry><refentrytitle>transactional-update.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+           
<citerefentry><refentrytitle>transactional-update.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+           and in case no command is specified when calling
+           <literal>transactional-update</literal>.
          </para>
           <variablelist>
             <varlistentry>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transactional-update-4.4.0/sbin/transactional-update.in 
new/transactional-update-4.5.0/sbin/transactional-update.in
--- old/transactional-update-4.4.0/sbin/transactional-update.in 2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/sbin/transactional-update.in 2023-11-20 
18:09:46.000000000 +0100
@@ -50,6 +50,7 @@
 SETUP_FIPS=0
 SETUP_KDUMP=0
 SETUP_SELINUX=0
+UPDATE_METHOD="up"
 USE_TELEMETRICS=0
 TELEM_PAYLOAD="PACKAGE_NAME=transactional-update\nPACKAGE_VERSION=@VERSION@"
 TELEM_CLASS=""
@@ -247,11 +248,14 @@
 }
 
 rebuild_kdump_initrd() {
-    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/sbin/mkdumprd" ]; then
+    if tukit -q call "$1" systemctl is-enabled --quiet kdump.service; then
        tukit ${TUKIT_OPTS} call "$1" /sbin/mkdumprd |& tee -a ${LOGFILE} 
1>&${origstdout}
+       return ${PIPESTATUS[0]}
+    elif [ ${SETUP_KDUMP} -ge 1 ]; then
+       log_info "INFO: Requested rebuild of kdump initrd, but kdump is not 
enabled."
+       log_info "      Did you mean 'setup-kdump'?"
     fi
+    return 0;
 }
 
 # start telemetry system if installed
@@ -854,270 +858,274 @@
 
 ORIG_ARGS=("$@")
 
-while [ 1 ]; do
-    if [ $# -eq 0 ]; then
-       break
-    fi
-
-    case "$1" in
-       cleanup)
-           DO_CLEANUP_OVERLAYS=1
-           DO_CLEANUP_SNAPSHOTS=1
-           shift
-           ;;
-       cleanup-snapshots)
-           DO_CLEANUP_SNAPSHOTS=1
-           shift
-           ;;
-       cleanup-overlays)
-           DO_CLEANUP_OVERLAYS=1
-           shift
-           ;;
-       dist-upgrade|dup)
-           DO_DUP=1
-           ZYPPER_ARG="--no-cd dup"
-           shift
-           TELEM_CLASS="upgrade"
-           ;;
-        update|up)
-           ZYPPER_ARG=up
-           shift
-           TELEM_CLASS="update"
-           ;;
-        patch)
-           ZYPPER_ARG="--non-interactive-include-reboot-patches patch"
-           shift
-           TELEM_CLASS="patch"
-           ;;
-       ptf|pkg|package)
-           TELEM_CLASS="package"
-           shift
-           if [ $# -eq 0 ]; then
-               usage 1
-           fi
-            # Interactively run installing PTFs
-            ZYPPER_NONINTERACTIVE="${FORCE_NONINTERACTIVE:-}"
-           case "$1" in
-               install|in)
-                   ZYPPER_ARG="install"
-                   shift
-                   ;;
-               remove|rm)
-                   ZYPPER_ARG="remove"
-                   if [ -n "${ZYPPER_NONINTERACTIVE}" ]; then
-                       ZYPPER_NONINTERACTIVE="-y"
-                   fi
-                   shift
-                   ;;
-               update|up)
-                   ZYPPER_ARG="up"
-                   shift
-                   ;;
-               *)
-                   usage 1;
-                   ;;
-           esac
-           DO_CALLEXT=1
+parse_args() {
+    while [ 1 ]; do
+       if [ $# -eq 0 ]; then
+           break
+       fi
 
-           if [ $# -eq 0 ]; then
-               usage 1
-           fi
+       case "$1" in
+           cleanup)
+               DO_CLEANUP_OVERLAYS=1
+               DO_CLEANUP_SNAPSHOTS=1
+               shift
+               ;;
+           cleanup-snapshots)
+               DO_CLEANUP_SNAPSHOTS=1
+               shift
+               ;;
+           cleanup-overlays)
+               DO_CLEANUP_OVERLAYS=1
+               shift
+               ;;
+           dist-upgrade|dup)
+               DO_DUP=1
+               ZYPPER_ARG="--no-cd dup"
+               shift
+               TELEM_CLASS="upgrade"
+               ;;
+           update|up)
+               ZYPPER_ARG=up
+               shift
+               TELEM_CLASS="update"
+               ;;
+           patch)
+               ZYPPER_ARG="--non-interactive-include-reboot-patches patch"
+               shift
+               TELEM_CLASS="patch"
+               ;;
+           ptf|pkg|package)
+               TELEM_CLASS="package"
+               shift
+               if [ $# -eq 0 ]; then
+                   usage 1
+               fi
+               # Interactively run installing PTFs
+               ZYPPER_NONINTERACTIVE="${FORCE_NONINTERACTIVE:-}"
+               case "$1" in
+                   install|in)
+                       ZYPPER_ARG="install"
+                       shift
+                       ;;
+                   remove|rm)
+                       ZYPPER_ARG="remove"
+                       if [ -n "${ZYPPER_NONINTERACTIVE}" ]; then
+                   ZYPPER_NONINTERACTIVE="-y"
+                       fi
+                       shift
+                       ;;
+                   update|up)
+                       ZYPPER_ARG="up"
+                       shift
+                       ;;
+                   *)
+                       usage 1;
+                       ;;
+               esac
+               DO_CALLEXT=1
 
-           while [ 1 ]; do
                if [ $# -eq 0 ]; then
-                   break;
+                   usage 1
+               fi
+
+               while [ 1 ]; do
+                   if [ $# -eq 0 ]; then
+                       break;
+                   else
+                       ZYPPER_ARG_PKGS+=("$1");
+                       shift
+                   fi
+               done
+               ;;
+           migration)
+               TELEM_CLASS="migration"
+               __NO_RESET=0
+               DO_MIGRATION=1
+               ZYPPER_ARG="migration --no-snapshots --no-selfupdate"
+               if [ -n "${FORCE_NONINTERACTIVE}" ]; then
+                   # non interative option is named different for
+                   # different commands ...
+                   ZYPPER_NONINTERACTIVE="--non-interactive 
--auto-agree-with-licenses"
                else
-                   ZYPPER_ARG_PKGS+=("$1");
+                   ZYPPER_NONINTERACTIVE=""
+               fi
+               shift
+               ;;
+           bootloader)
+               test -z "$TELEM_CLASS" && TELEM_CLASS="bootloader"
+               REWRITE_BOOTLOADER=1
+               REWRITE_GRUB_CFG=1
+               shift
+               ;;
+           grub.cfg)
+               test -z "$TELEM_CLASS" && TELEM_CLASS="bootloader"
+               REWRITE_GRUB_CFG=1
+               shift
+               ;;
+           shell)
+               test -z "$TELEM_CLASS" && TELEM_CLASS="shell"
+               RUN_SHELL=1
+               shift
+               if [ "$1" = "-c" ]; then
+                   if [ -z "$2" ]; then
+                       SHELL_CMD="-"
+                   else
+                       SHELL_CMD="$2"
+                       shift
+                   fi
                    shift
                fi
-           done
-           ;;
-       migration)
-           TELEM_CLASS="migration"
-           __NO_RESET=0
-           DO_MIGRATION=1
-           ZYPPER_ARG="migration --no-snapshots --no-selfupdate"
-           if [ -n "${FORCE_NONINTERACTIVE}" ]; then
-               # non interative option is named different for
-               # different commands ...
-               ZYPPER_NONINTERACTIVE="--non-interactive 
--auto-agree-with-licenses"
-           else
-               ZYPPER_NONINTERACTIVE=""
-           fi
-           shift
-           ;;
-       bootloader)
-           test -z "$TELEM_CLASS" && TELEM_CLASS="bootloader"
-           REWRITE_BOOTLOADER=1
-           REWRITE_GRUB_CFG=1
-           shift
-           ;;
-       grub.cfg)
-           test -z "$TELEM_CLASS" && TELEM_CLASS="bootloader"
-           REWRITE_GRUB_CFG=1
-           shift
-           ;;
-       shell)
-           test -z "$TELEM_CLASS" && TELEM_CLASS="shell"
-           RUN_SHELL=1
-           shift
-           if [ "$1" = "-c" ]; then
-               if [ -z "$2" ]; then
-                   SHELL_CMD="-"
-               else
-                   SHELL_CMD="$2"
+               ;;
+           initrd)
+               test -z "$TELEM_CLASS" && TELEM_CLASS="initrd"
+               REWRITE_INITRD=1
+               REBUILD_KDUMP_INITRD=1
+               shift
+               ;;
+           kdump)
+               test -z "$TELEM_CLASS" && TELEM_CLASS="kdump"
+               REBUILD_KDUMP_INITRD=1
+               SETUP_KDUMP=2
+               shift
+               ;;
+           reboot)
+               REBOOT_AFTERWARDS=1
+               shift
+               ;;
+           rollback)
+               TELEM_CLASS="rollback"
+               DO_ROLLBACK=1
+               DO_SELF_UPDATE=0
+               shift
+               if [ $# -eq 1 ]; then
+                   ROLLBACK_SNAPSHOT=$1
                    shift
                fi
+               ;;
+           apply)
+               DO_APPLY=1
                shift
-           fi
-           ;;
-       initrd)
-           test -z "$TELEM_CLASS" && TELEM_CLASS="initrd"
-           REWRITE_INITRD=1
-           REBUILD_KDUMP_INITRD=1
-           shift
-           ;;
-       kdump)
-           test -z "$TELEM_CLASS" && TELEM_CLASS="kdump"
-           REBUILD_KDUMP_INITRD=1
-           shift
-           ;;
-       reboot)
-           REBOOT_AFTERWARDS=1
-           shift
-           ;;
-       rollback)
-           TELEM_CLASS="rollback"
-           DO_ROLLBACK=1
-           DO_SELF_UPDATE=0
-           shift
-           if [ $# -eq 1 ]; then
-               ROLLBACK_SNAPSHOT=$1
+               ;;
+           run)
+               test -z "$TELEM_CLASS" && TELEM_CLASS="shell"
+               DO_RUN=1
                shift
-           fi
-           ;;
-       apply)
-           DO_APPLY=1
-           shift
-           ;;
-       run)
-           test -z "$TELEM_CLASS" && TELEM_CLASS="shell"
-           DO_RUN=1
-           shift
-
-           # Collect arguments for run
-           if [ $# -eq 0 ]; then
-               usage 1
-           fi
 
-           RUN_CMD=("$@")
-           break
-           ;;
-       setup-fips)
-           test -z "$TELEM_CLASS" && TELEM_CLASS="fips"
-           SETUP_FIPS=1
-           shift
-           ;;
-       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"
+               # Collect arguments for run
+               if [ $# -eq 0 ]; then
                    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)"
+
+               RUN_CMD=("$@")
+               break
+               ;;
+           setup-fips)
+               test -z "$TELEM_CLASS" && TELEM_CLASS="fips"
+               SETUP_FIPS=1
                shift
-           fi
-           ;;
-       setup-selinux)
-           test -z "$TELEM_CLASS" && TELEM_CLASS="selinux"
-           SETUP_SELINUX=1
-           shift
-           ;;
-       status)
-           DO_STATUS=1
-           DO_SELF_UPDATE=0
-           shift
-           while [ 1 ]; do
-               [ $# -eq 0 ] && break
-               case "$1" in
-                   last)
-                       DO_STATUS_LAST=1
-                       shift
-                       ;;
-                   *)
-                       usage 1;
-                       ;;
-               esac
-           done
-           ;;
-       -i|--interactive)
-           ZYPPER_NONINTERACTIVE=""
-           shift
-           ;;
-       -n|--non-interactive)
-           FORCE_NONINTERACTIVE="${ZYPPER_NONINTERACTIVE}"
-           shift
-           ;;
-       -c|--continue)
-           # Check whether we got an optional snapshot number argument
-           if [[ $2 =~ ^[0-9]+$ ]]; then
-               BASE_SNAPSHOT_ID="$2"
+               ;;
+           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
+               shift
+               ;;
+           status)
+               DO_STATUS=1
+               DO_SELF_UPDATE=0
+               shift
+               while [ 1 ]; do
+                   [ $# -eq 0 ] && break
+                   case "$1" in
+                       last)
+                   DO_STATUS_LAST=1
+                   shift
+                   ;;
+                       *)
+                   usage 1;
+                   ;;
+                   esac
+               done
+               ;;
+           -i|--interactive)
+               ZYPPER_NONINTERACTIVE=""
+               shift
+               ;;
+           -n|--non-interactive)
+               FORCE_NONINTERACTIVE="${ZYPPER_NONINTERACTIVE}"
+               shift
+               ;;
+           -c|--continue)
+               # Check whether we got an optional snapshot number argument
+               if [[ $2 =~ ^[0-9]+$ ]]; then
+                   BASE_SNAPSHOT_ID="$2"
+                   shift
+               else
+                   BASE_SNAPSHOT_ID="default"
+               fi
+               shift
+               ;;
+           --no-selfupdate)
+               DO_SELF_UPDATE=0
+               shift
+               ;;
+           -d|--drop-if-no-change)
+               TUKIT_OPTS="${TUKIT_OPTS} --discard"
+               shift
+               ;;
+           --quiet)
+               VERBOSITY=1
+               TUKIT_OPTS="${TUKIT_OPTS} --quiet"
+               DRACUT_OPTS="${DRACUT_OPTS} --quiet"
+               # ZYPPER_ARG handled below
+               shift
+               ;;
+           register)
+               DO_REGISTRATION=1
                shift
-           else
-               BASE_SNAPSHOT_ID="default"
-           fi
-           shift
-           ;;
-       --no-selfupdate)
-           DO_SELF_UPDATE=0
-           shift
-           ;;
-       -d|--drop-if-no-change)
-           TUKIT_OPTS="${TUKIT_OPTS} --discard"
-           shift
-           ;;
-       --quiet)
-           VERBOSITY=1
-           TUKIT_OPTS="${TUKIT_OPTS} --quiet"
-           DRACUT_OPTS="${DRACUT_OPTS} --quiet"
-           # ZYPPER_ARG handled below
-           shift
-           ;;
-       register)
-           DO_REGISTRATION=1
-           shift
 
-           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
+               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
 
-           REGISTRATION_ARGS="$*";
-           shift $#
+               REGISTRATION_ARGS="$*";
+               shift $#
 
-           # A lot of commands won't change anything; discard snapshot then
-           TUKIT_OPTS="${TUKIT_OPTS} --discard"
-           ;;
-       -h|--help)
-           usage 0
-           ;;
-       --version)
-           print_version
-           ;;
-       *)
-           if [ $# -ge 1 ]; then
-               usage 1;
-           fi
-           ;;
-    esac
-done
+               # A lot of commands won't change anything; discard snapshot then
+               TUKIT_OPTS="${TUKIT_OPTS} --discard"
+               ;;
+           -h|--help)
+               usage 0
+               ;;
+           --version)
+               print_version
+               ;;
+           *)
+               if [ $# -ge 1 ]; then
+                   usage 1;
+               fi
+               ;;
+       esac
+    done
+}
+parse_args "${ORIG_ARGS[@]}"
 
 # Duplicate stdout before creating custom handlers
 exec {origstdout}>&1
@@ -1193,12 +1201,11 @@
     REBUILD_KDUMP_INITRD=1
 fi
 
-# If no commands were given, assume "up"
+# If no commands were given, use default from config
 if [ -z "${ZYPPER_ARG}" -a -z "${TELEM_CLASS}" -a "${REBOOT_AFTERWARDS}" -eq 0 
\
        -a "${DO_REGISTRATION}" -eq 0 -a "${DO_CLEANUP_OVERLAYS}" -eq 0 \
        -a "${DO_CLEANUP_SNAPSHOTS}" -eq 0 -a "${DO_APPLY}" -eq 0 ]; then
-    ZYPPER_ARG="up"
-    TELEM_CLASS="update"
+    parse_args "${UPDATE_METHOD}"
 fi
 
 # Prevent running transactional-update inside transactional-update
@@ -1313,7 +1320,7 @@
 
     log_info "Rollback to snapshot ${ROLLBACK_SNAPSHOT}..."
 
-    snapper rollback "${ROLLBACK_SNAPSHOT}"
+    tukit rollback "${ROLLBACK_SNAPSHOT}"
     if [ $? -ne 0 ]; then
        log_error "ERROR: Rollback to snapshot $ROLLBACK_SNAPSHOT failed!"
        quit 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-4.4.0/tukit/tukit.cpp 
new/transactional-update-4.5.0/tukit/tukit.cpp
--- old/transactional-update-4.4.0/tukit/tukit.cpp      2023-09-11 
15:49:37.000000000 +0200
+++ new/transactional-update-4.5.0/tukit/tukit.cpp      2023-11-20 
18:09:46.000000000 +0100
@@ -49,6 +49,8 @@
     cout << "\tCloses the given transaction and sets the snapshot as the new 
default snapshot\n";
     cout << "abort <ID>\n";
     cout << "\tDeletes the given snapshot again\n";
+    cout << "rollback <ID>\n";
+    cout << "\tRoll back to given snapshot\n";
     cout << "\n";
     cout << "Transaction Options:\n";
     cout << "--continue[=<ID>], -c[<ID>]  Use latest or given snapshot as 
base\n";
@@ -181,16 +183,33 @@
         return status;
     }
     else if (arg == "close") {
+        if (argv[1] == nullptr) {
+            displayHelp();
+            throw invalid_argument{"Missing argument for 'close'"};
+        }
         TransactionalUpdate::Transaction transaction{};
         transaction.resume(argv[1]);
         transaction.finalize();
         return 0;
     }
     else if (arg == "abort") {
+        if (argv[1] == nullptr) {
+            displayHelp();
+            throw invalid_argument{"Missing argument for 'abort'"};
+        }
         TransactionalUpdate::Transaction transaction{};
         transaction.resume(argv[1]);
         return 0;
     }
+    else if (arg == "rollback") {
+        if (argv[1] == nullptr) {
+            displayHelp();
+            throw invalid_argument{"Missing argument for 'rollback'"};
+        }
+        unique_ptr<TransactionalUpdate::SnapshotManager> snapshotMgr = 
TransactionalUpdate::SnapshotFactory::get();
+        snapshotMgr->rollbackTo(argv[1]);
+        return 0;
+    }
     else if (arg == "snapshots") {
         unique_ptr<TransactionalUpdate::SnapshotManager> snapshotMgr = 
TransactionalUpdate::SnapshotFactory::get();
         if (fields.empty()) {

Reply via email to