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 2026-01-10 12:48:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/transactional-update (Old)
and /work/SRC/openSUSE:Factory/.transactional-update.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "transactional-update"
Sat Jan 10 12:48:04 2026 rev:124 rq: version:5.1.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/transactional-update/transactional-update.changes
2026-01-09 17:02:09.028586720 +0100
+++
/work/SRC/openSUSE:Factory/.transactional-update.new.1928/transactional-update.changes
2026-01-10 12:48:05.717626840 +0100
@@ -2,88 +1,0 @@
-Fri Jan 9 13:14:51 UTC 2026 - Ignaz Forster <[email protected]>
-
-- Version 6.0.3
- - Only try logging to journald when socket exists; would lead to
- messages about missing stream fds otherwise, which happened
- when running in combustion's chroot environment
-
--------------------------------------------------------------------
-Wed Jan 7 17:11:33 UTC 2026 - Ignaz Forster <[email protected]>
-
-- Version 6.0.2
- Don't print reboot hints as errors to prevent failed openQA test
- - t-u: Add new "warning" log level
- - t-u: Adjust log level of reboot hints
-
--------------------------------------------------------------------
-Fri Jan 2 15:58:12 UTC 2026 - Ignaz Forster <[email protected]>
-
-- Version 6.0.1
- Adjustments to avoid logging with error log level to the journal
- when there is no actual error
- - tukit: Adjust selinux_restorecon log levels
- - t-u: Print grub-mkconfig output to stdout
-
--------------------------------------------------------------------
-Wed Dec 10 14:32:49 UTC 2025 - Ignaz Forster <[email protected]>
-
-- Temporarily disable default soft-reboot again to unblock other
- projects while systemd 258 (required for correct console
- switching used during the openQA tests) isn't ready yet.
-
--------------------------------------------------------------------
-Sat Nov 22 08:51:56 UTC 2025 - Ignaz Forster <[email protected]>
-
-- Version 6.0.0
- - Bump major version number to fix self-update due to new .so
- library version in 5.5.0
- - t-u: Fix syntax error introduced in 5.5.1 [boo#1254253]
-
--------------------------------------------------------------------
-Tue Nov 18 10:33:33 UTC 2025 - Ignaz Forster <[email protected]>
-
-- Fix dbus dependency
-
--------------------------------------------------------------------
-Wed Nov 12 00:50:23 UTC 2025 - Ignaz Forster <[email protected]>
-
-- Version 5.5.1
- - t-u: Fix hanging t-u process when files were changed in /var
- - t-u: Don't ask for key import during self-update [bsc#1239721]
- - t-u: Fix stray output of "/etc"
-
--------------------------------------------------------------------
-Mon Sep 29 22:37:08 UTC 2025 - Ignaz Forster <[email protected]>
-
-- Version 5.5.0
- - t-u: The "run" command will return the exit status of the
- command now and if it is non-zero, the snapshot will be
- discarded. The --keep option or wrapping the command into a
- bash script can be used if the command is expected to return
- with a specific non-zero return code.
- [bsc#1216504] [gh#openSUSE/transactional-update#134]
- [gh#openSUSE/transactional-update#135]
- - t-u / tukit: The --keep option will close the snapshot now also
- in error case, but not set it as default or remove the
- in-progress attribute; with this change the snapshot can be
- used as a base for another snapshot when the changes are
- verified as good.
- - C API: rename loglevel to tukit_loglevel (API change)
- - C API: removed the experimental status
- - Rework logging to support syslog / journald:
- - Also log to journald when calling t-u manually
- - Introduce logging for libtukit: By default it will log
- syslog / journald. This will finally make it possible to see
- what happened during manual tukit calls or via the API
- - Add option to specify desired logging mechanisms ("console",
- "syslog") via tukit and API
- - Fixed --discard option on rw systems
- - Support SELinux outside /var/lib/selinux [jsc#PED-12492]
- - sync-etc-state: Detect changes in xattrs with null bytes
- - tukit: Added forgotten short option -k for tukit --keep
- - t-u: Fix shellcheck hints
- - README.md: Updated link to Salt executor
-- Enable soft-reboot by default again
-- Increase so version number because of the incompatible changes
- from above
-
--------------------------------------------------------------------
Old:
----
transactional-update-6.0.3.tar.gz
New:
----
transactional-update-5.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ transactional-update.spec ++++++
--- /var/tmp/diff_new_pack.Qd3M3B/_old 2026-01-10 12:48:06.493658737 +0100
+++ /var/tmp/diff_new_pack.Qd3M3B/_new 2026-01-10 12:48:06.493658737 +0100
@@ -1,7 +1,7 @@
#
# spec file for package transactional-update
#
-# Copyright (c) 2026 SUSE LLC and contributors
+# Copyright (c) 2025 SUSE LLC and contributors
# Copyright (c) 2021 Neal Gompa
#
# All modifications and additions to the file contributed by third parties
@@ -17,7 +17,7 @@
#
-%global somajor 8
+%global somajor 4
%global libprefix libtukit
%global libname %{libprefix}%{somajor}
%global devname %{libprefix}-devel
@@ -26,7 +26,7 @@
%{!?_distconfdir: %global _distconfdir %{_prefix}%{_sysconfdir}}
Name: transactional-update
-Version: 6.0.3
+Version: 5.1.0
Release: 0
Summary: Transactional Updates with btrfs and snapshots
License: GPL-2.0-or-later AND LGPL-2.1-or-later
@@ -149,7 +149,7 @@
License: GPL-2.0-or-later
Group: System/Libraries
Requires: %{libname} = %{version}-%{release}
-Requires: dbus-service
+Requires: dbus-1
%description -n tukitd
This package provedes the D-Bus service to access %{libname}'s
++++++ transactional-update-6.0.3.tar.gz -> transactional-update-5.1.0.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/NEWS
new/transactional-update-5.1.0/NEWS
--- old/transactional-update-6.0.3/NEWS 2026-01-09 14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/NEWS 2025-08-18 15:54:13.000000000 +0200
@@ -2,55 +2,6 @@
Copyright (C) 2016-2025 Thorsten Kukuk, Ignaz Forster et al.
-Version 6.0.3 (2026-01-09)
-* t-u: Only try logging to journald when the socket exists
-
-Version 6.0.2 (2026-01-07)
-* t-u: Add new "warning" log level
-* t-u: Adjust log level of reboot hints
-
-Version 6.0.1 (2026-01-02)
-Adjustments to avoid logging with error log level to the journal when
-there is no actual error
-* tukit: Adjust selinux_restorecon log levels
-* t-u: Print grub-mkconfig output to stdout
-
-Version 6.0.0 (2025-11-19)
-* Increase major version number to not break self-updates due to increased
- library version introduced in 5.5.0
-* t-u: Fix syntax error introduced in 5.5.1 [boo#1254253]
-
-Version 5.5.1 (2025-11-12)
-* t-u: Fix hanging t-u process when files were changed in /var
-* t-u: Don't ask for key import during self-update [bsc#1239721]
-* t-u: Fix stray output of "/etc"
-
-Version 5.5.0 (2025-09-29)
-This release contains changes incompatible with previous versions.
-* t-u: The "run" command will return the exit status of the command now and if
- it is non-zero, the snapshot will be discarded. The --keep option or
- wrapping the command into a bash script can be used if the command is
- expected to return with a specific non-zero return code.
-* t-u / tukit: The --keep option will close the snapshot now also in error
- case, but not set it as default or remove the in-progress attribute; with
- this change the snapshot can be used as a base for another snapshot when
- the changes are verified as good.
-* C API: rename loglevel to tukit_loglevel (API change)
-* C API: removed the experimental status
-* Rework logging:
- * Also log to journald when calling t-u manually
- * Introduce logging for libtukit: By default it will log syslog / journald.
- This will finally make it possible to see what happened during manual
- tukit calls or via the API
- * Add option to specify desired logging mechanisms ("console", "syslog") via
- tukit and API
-* Fixed --discard option on rw systems
-* Support SELinux outside /var/lib/selinux [jsc#PED-12492]
-* sync-etc-state: Detect changes in xattrs with null bytes
-* tukit: Added forgotten short option -k for tukit --keep
-* t-u: Fix shellcheck hints
-* README.md: Updated link to Salt executor
-
Version 5.1.0 (2025-08-18)
* tukit: signalize errors from plugins; transactions will be aborted by
default now
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/README.md
new/transactional-update-5.1.0/README.md
--- old/transactional-update-6.0.3/README.md 2026-01-09 14:08:38.000000000
+0100
+++ new/transactional-update-5.1.0/README.md 2025-08-18 15:54:13.000000000
+0200
@@ -47,7 +47,7 @@
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.executors.transactional\_update](https://docs.saltproject.io/en/latest/ref/executors/all/salt.executors.transactional_update.html)
executor (transactional-update).
+* **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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/configure.ac
new/transactional-update-5.1.0/configure.ac
--- old/transactional-update-6.0.3/configure.ac 2026-01-09 14:08:38.000000000
+0100
+++ new/transactional-update-5.1.0/configure.ac 2025-08-18 15:54:13.000000000
+0200
@@ -1,12 +1,11 @@
dnl Process this file with autoconf to produce a configure script.
-# Semantic versioning, increase major version on incompatible interface change
-AC_INIT([transactional-update],[6.0.3])
+AC_INIT([transactional-update],[5.0.7])
# Increase on any interface change and reset revision
-LIBTOOL_CURRENT=8
+LIBTOOL_CURRENT=7
# On interface change increase if backwards compatible, reset otherwise
-LIBTOOL_AGE=0
+LIBTOOL_AGE=3
# Increase on *any* C/C++ library code change, reset at interface change
-LIBTOOL_REVISION=1
+LIBTOOL_REVISION=0
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_FILES([tukit.pc])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/dbus/tukitd.c
new/transactional-update-5.1.0/dbus/tukitd.c
--- old/transactional-update-6.0.3/dbus/tukitd.c 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/dbus/tukitd.c 2025-08-18
15:54:13.000000000 +0200
@@ -860,14 +860,7 @@
sd_bus_slot *slot_snap = NULL;
sd_bus *bus = NULL;
sd_event *event = NULL;
- int ret;
-
- tukit_set_loglevel(Info);
- ret = tukit_set_logoutput("syslog");
- if (ret < 0) {
- fprintf(stderr, "Failed to start: %s\n", tukit_get_errmsg());
- return EXIT_FAILURE;
- }
+ int ret = 1;
TransactionEntry* activeTransactions = (TransactionEntry*)
malloc(sizeof(TransactionEntry));
if (activeTransactions == NULL) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/dracut/sync-etc-state.cpp
new/transactional-update-5.1.0/dracut/sync-etc-state.cpp
--- old/transactional-update-6.0.3/dracut/sync-etc-state.cpp 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/dracut/sync-etc-state.cpp 2025-08-18
15:54:13.000000000 +0200
@@ -129,7 +129,7 @@
perror("lgetxattr cmp get");
return false;
}
- if (memcmp(val_ref.get(), val_cmp.get(), vallen_ref) != 0) {
+ if (string{val_ref.get()} != string{val_cmp.get()}) {
cout << "Extended attribute value changed: " << cmp << endl;
return true;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/transactional-update-6.0.3/lib/Bindings/CBindings.cpp
new/transactional-update-5.1.0/lib/Bindings/CBindings.cpp
--- old/transactional-update-6.0.3/lib/Bindings/CBindings.cpp 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/lib/Bindings/CBindings.cpp 2025-08-18
15:54:13.000000000 +0200
@@ -18,19 +18,9 @@
const char* tukit_get_errmsg() {
return errmsg.c_str();
}
-void tukit_set_loglevel(tukit_loglevel lv) {
+void tukit_set_loglevel(loglevel lv) {
tulog.level = static_cast<TULogLevel>(lv);
}
-int tukit_set_logoutput(char* fields) {
- try {
- tulog.setLogOutput(fields);
- } catch (const std::exception &e) {
- fprintf(stderr, "ERROR: %s\n", e.what());
- errmsg = e.what();
- return -1;
- }
- return 0;
-}
tukit_tx tukit_new_tx() {
Transaction* transaction = nullptr;
try {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/lib/Bindings/libtukit.h
new/transactional-update-5.1.0/lib/Bindings/libtukit.h
--- old/transactional-update-6.0.3/lib/Bindings/libtukit.h 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/lib/Bindings/libtukit.h 2025-08-18
15:54:13.000000000 +0200
@@ -2,7 +2,8 @@
/* SPDX-FileCopyrightText: Copyright SUSE LLC */
/*
- This is the C API for libtukit.
+ This is the EXPERIMENTAL C API for tukit. For the moment it is only inteded
+ for internal use.
For documentation please see the corresponding classes in the C++ header
files.
*/
@@ -17,11 +18,10 @@
typedef enum {
None=0, Error, Info, Debug
-} tukit_loglevel;
+} loglevel;
const char* tukit_get_errmsg();
-void tukit_set_loglevel(tukit_loglevel lv);
-int tukit_set_logoutput(char *fields);
+void tukit_set_loglevel(loglevel lv);
typedef void* tukit_tx;
tukit_tx tukit_new_tx();
void tukit_free_tx(tukit_tx tx);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/lib/Log.hpp
new/transactional-update-5.1.0/lib/Log.hpp
--- old/transactional-update-6.0.3/lib/Log.hpp 2026-01-09 14:08:38.000000000
+0100
+++ new/transactional-update-5.1.0/lib/Log.hpp 2025-08-18 15:54:13.000000000
+0200
@@ -8,87 +8,35 @@
#ifndef T_U_LOG_H
#define T_U_LOG_H
-#include <exception>
#include <iomanip>
#include <iostream>
-#include <syslog.h>
enum class TULogLevel {
None=0, Error, Info, Debug
};
-struct TULogOutput {
- bool console = true;
- bool syslog = true;
-};
// There's no threading in this application, so no locking is implemented
class TULog {
public:
TULogLevel level = TULogLevel::Error;
- TULogOutput output{};
template<typename... T> void error(const T&... args) {
- if (level >=TULogLevel::Error) {
- print_to_output(LOG_ERR, args...);
- }
- print_to_syslog(LOG_ERR, args...);
+ if (level >=TULogLevel::Error)
+ log(args...);
}
template<typename... T> void info(const T&... args) {
- if (level >= TULogLevel::Info) {
- print_to_output(LOG_INFO, args...);
- }
- print_to_syslog(LOG_INFO, args...);
+ if (level >= TULogLevel::Info)
+ log(args...);
}
template<typename... T> void debug(const T&... args) {
- if (level >= TULogLevel::Debug) {
- print_to_output(LOG_DEBUG, args...);
- print_to_syslog(LOG_DEBUG, args...);
- }
+ if (level >= TULogLevel::Debug)
+ log(args...);
}
template<typename... T> void log(const T&... args) {
- print_to_output(LOG_INFO, args...);
- print_to_syslog(LOG_INFO, args...);
- }
-
- void setLogOutput(std::string outputs) {
- output.console = false;
- output.syslog = false;
- std::string field;
- std::stringstream ss(outputs);
- while (getline(ss, field, ',')) {
- if (field == "console") {
- output.console = true;
- continue;
- }
- if (field == "syslog") {
- output.syslog = true;
- continue;
- }
- throw std::invalid_argument{"Invalid log output."};
- }
- }
-
-private:
- template<typename... T> void print_to_output(int loglevel, const T&...
args) {
- if (output.console) {
- std::stringstream ss;
- ((ss << args),...);
- std::string s = ss.str();
- if (loglevel <= LOG_ERR) {
- std::cerr << s << std::endl;
- } else {
- std::cout << s << std::endl;
- }
- }
- }
- template<typename... T> void print_to_syslog(int loglevel, const T&...
args) {
- if (output.syslog) {
- std::stringstream ss;
- ((ss << args),...);
- std::string s = ss.str();
- syslog(loglevel, "%s", s.c_str());
- }
+ std::time_t now = std::time(0);
+ std::cout << std::put_time(std::localtime(&now), "%F %T ");
+ ((std::cout << args),...) << std::endl;
}
};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/lib/Snapshot/Snapper.cpp
new/transactional-update-5.1.0/lib/Snapshot/Snapper.cpp
--- old/transactional-update-6.0.3/lib/Snapshot/Snapper.cpp 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/lib/Snapshot/Snapper.cpp 2025-08-18
15:54:13.000000000 +0200
@@ -92,7 +92,7 @@
/* Snapshot methods */
void Snapper::close() {
- callSnapper("modify --userdata 'transactional-update-in-progress=' " +
snapshotId);
+ callSnapper("modify -u 'transactional-update-in-progress=' " + snapshotId);
}
void Snapper::abort() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/lib/Transaction.cpp
new/transactional-update-5.1.0/lib/Transaction.cpp
--- old/transactional-update-6.0.3/lib/Transaction.cpp 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/lib/Transaction.cpp 2025-08-18
15:54:13.000000000 +0200
@@ -42,10 +42,8 @@
public:
void addSupplements();
void snapMount();
- void closeSnapshot(bool aborted=false);
int runCommand(char* argv[], bool inChroot, std::string* buffer);
static int inotifyAdd(const char *pathname, const struct stat *sbuf, int
type, struct FTW *ftwb);
- static int selinux_logging_callback(int type, const char *fmt, ...);
int inotifyRead();
std::unique_ptr<SnapshotManager> snapshotMgr;
std::unique_ptr<Snapshot> snapshot;
@@ -82,11 +80,7 @@
try {
if (isInitialized() && !getSnapshot().empty() &&
fs::exists(getRoot())) {
tulog.info("Discarding snapshot ", pImpl->snapshot->getUid(), ".");
- if (pImpl->keepIfError) {
- pImpl->closeSnapshot(true);
- } else {
- pImpl->snapshot->abort();
- }
+ pImpl->snapshot->abort();
TransactionalUpdate::Plugins plugins{nullptr, pImpl->keepIfError};
plugins.run("abort-post", pImpl->snapshot->getUid());
}
@@ -111,28 +105,6 @@
return pImpl->bindDir;
}
-int Transaction::impl::selinux_logging_callback(int type, const char *fmt,
...) {
- va_list ap, ap_copy;
- va_start(ap, fmt);
- va_copy(ap_copy, ap);
- size_t size = vsnprintf(nullptr, 0, fmt, ap);
- va_end(ap);
- std::vector<char> se_buffer(size + 1);
- vsnprintf(se_buffer.data(), size, fmt, ap_copy);
-
- switch (type) {
- case SELINUX_ERROR:
- tulog.error("SELinux: ", se_buffer.data());
- break;
- default:
- tulog.info("SELinux: ", se_buffer.data());
- break;
- }
- va_end(ap_copy);
-
- return 0;
-}
-
void Transaction::impl::snapMount() {
if (unshare(CLONE_NEWNS) < 0) {
throw std::runtime_error{"Creating new mount namespace failed: " +
std::string(strerror(errno))};
@@ -163,10 +135,8 @@
// up in the root file system, but will always be shadowed by the
real /var mount. Due to that they
// also won't be relabelled at any time. During updates this may
cause problems if packages try to
// access those leftover directories with wrong permissions, so
they have to be relabelled manually...
- if (fs::is_directory("/var/lib/selinux")) {
- BindMount selinuxVar("/var/lib/selinux", 0, true);
- selinuxVar.mount(bindDir);
- }
+ BindMount selinuxVar("/var/lib/selinux", 0, true);
+ selinuxVar.mount(bindDir);
BindMount selinuxEtc("/etc/selinux", 0, true);
selinuxEtc.mount(bindDir);
@@ -179,10 +149,6 @@
tulog.error("Chrooting to " + bindDir.native() + " for
SELinux relabelling failed: " + std::string(strerror(errno)));
_exit(errno);
}
-
- union selinux_callback se_callback;
- se_callback.func_log = selinux_logging_callback;
- selinux_set_callback(SELINUX_CB_LOG, se_callback);
unsigned int restoreconOptions = SELINUX_RESTORECON_RECURSE |
SELINUX_RESTORECON_IGNORE_DIGEST;
if (tulog.level >= TULogLevel::Info)
restoreconOptions |= SELINUX_RESTORECON_VERBOSE;
@@ -311,7 +277,7 @@
std::unique_ptr<Snapshot> prevSnap = pImpl->snapshotMgr->open(base);
std::unique_ptr<Mount> oldEtc{new Mount{"/etc"}};
oldEtc->setTabSource(prevSnap->getRoot() / "etc" / "fstab");
- if (oldEtc->isMount() && oldEtc->getFilesystem() == "overlayfs") {
+ if (oldEtc->getFilesystem() == "overlayfs") {
tulog.info("Can not merge back changes in /etc into old overlayfs
system - ignoring 'discardIfNoChange'.");
} else {
// Flag file to indicate this snapshot was initialized with
discard flag
@@ -381,10 +347,7 @@
// Recursively register all directories of the root file system
inotifyExcludes = MountList::getList(snapshot->getRoot());
- std::unique_ptr<Mount> mntEtc{new Mount{"/etc"}};
- if (mntEtc->isMount()) {
- inotifyExcludes.push_back(snapshot->getRoot() / "etc");
- }
+ inotifyExcludes.push_back(snapshot->getRoot() / "etc");
nftw(snapshot->getRoot().c_str(), inotifyAdd, 20, FTW_MOUNT |
FTW_PHYS);
}
@@ -535,11 +498,14 @@
}
}
-void Transaction::impl::closeSnapshot(bool aborted) {
+void Transaction::finalize() {
+ TransactionalUpdate::Plugins plugins{this, pImpl->keepIfError};
+ plugins.run("finalize-pre", nullptr);
+
sync();
- if (discardIfNoChange &&
- ((inotifyFd != 0 && inotifyRead() == 0) ||
- (inotifyFd == 0 && fs::exists(snapshot->getRoot() /
"discardIfNoChange")))) {
+ if (pImpl->discardIfNoChange &&
+ ((inotifyFd != 0 && pImpl->inotifyRead() == 0) ||
+ (inotifyFd == 0 && fs::exists(getRoot() / "discardIfNoChange")))) {
tulog.info("No changes to the root file system - discarding
snapshot.");
// Even if the snapshot itself does not contain any changes, /etc may
do so. If the new snapshot is a
@@ -551,52 +517,41 @@
std::filesystem::path targetRoot = "/";
std::string base;
- std::ifstream input(snapshot->getRoot() / "discardIfNoChange");
+ std::ifstream input(getRoot() / "discardIfNoChange");
input >> base;
input.close();
std::unique_ptr<Mount> previousEtc{new Mount("/etc", 0, true)};
- if (snapshotMgr->getCurrent() == base) {
+ if (pImpl->snapshotMgr->getCurrent() == base) {
tulog.info("Merging changes in /etc into the running system.");
} else {
tulog.info("Merging changes in /etc into the previous
snapshot.");
- targetRoot = snapshotMgr->open(base)->getRoot();
+ targetRoot = pImpl->snapshotMgr->open(base)->getRoot();
}
- Util::exec("rsync --archive --inplace --xattrs --acls --exclude
'fstab' --exclude 'etc.syncpoint' --delete --quiet '" + bindDir.native() +
"/etc/' " + targetRoot.native() + "/etc");
+ Util::exec("rsync --archive --inplace --xattrs --acls --exclude
'fstab' --exclude 'etc.syncpoint' --delete --quiet '" +
this->pImpl->bindDir.native() + "/etc/' " + targetRoot.native() + "/etc");
}
- TransactionalUpdate::Plugins plugins_without_transaction{nullptr,
keepIfError};
- plugins_without_transaction.run("finalize-post", snapshot->getUid() +
" " + "discarded");
+ TransactionalUpdate::Plugins plugins_without_transaction{nullptr,
pImpl->keepIfError};
+ plugins_without_transaction.run("finalize-post",
pImpl->snapshot->getUid() + " " + "discarded");
return;
}
- if (fs::exists(snapshot->getRoot() / "discardIfNoChange")) {
- fs::remove(snapshot->getRoot() / "discardIfNoChange");
+ if (fs::exists(getRoot() / "discardIfNoChange")) {
+ fs::remove(getRoot() / "discardIfNoChange");
}
// Update /usr timestamp to support system offline update mechanism
- if (utime((snapshot->getRoot() / "usr").c_str(), nullptr) != 0)
+ if (utime((pImpl->snapshot->getRoot() / "usr").c_str(), nullptr) != 0)
throw std::runtime_error{"Updating /usr timestamp failed: " +
std::string(strerror(errno))};
- if (! aborted) {
- snapshot->close();
- }
- supplements.cleanup();
- dirsToMount.clear();
+ pImpl->snapshot->close();
+ pImpl->supplements.cleanup();
+ pImpl->dirsToMount.clear();
- std::unique_ptr<Snapshot> defaultSnap =
snapshotMgr->open(snapshotMgr->getDefault());
+ std::unique_ptr<Snapshot> defaultSnap =
pImpl->snapshotMgr->open(pImpl->snapshotMgr->getDefault());
if (defaultSnap->isReadOnly())
- snapshot->setReadOnly(true);
- if (! aborted) {
- snapshot->setDefault();
- tulog.info("New default snapshot is #" + snapshot->getUid() + " (" +
std::string(snapshot->getRoot()) + ").");
- }
-}
-
-void Transaction::finalize() {
- TransactionalUpdate::Plugins plugins{this, pImpl->keepIfError};
- plugins.run("finalize-pre", nullptr);
-
- this->pImpl->closeSnapshot();
+ pImpl->snapshot->setReadOnly(true);
+ pImpl->snapshot->setDefault();
+ tulog.info("New default snapshot is #" + pImpl->snapshot->getUid() + " ("
+ std::string(pImpl->snapshot->getRoot()) + ").");
std::string id = pImpl->snapshot->getUid();
pImpl->snapshot.reset();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/transactional-update-6.0.3/man/transactional-update.8.xml
new/transactional-update-5.1.0/man/transactional-update.8.xml
--- old/transactional-update-6.0.3/man/transactional-update.8.xml
2026-01-09 14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/man/transactional-update.8.xml
2025-08-18 15:54:13.000000000 +0200
@@ -244,22 +244,10 @@
<term><option>run</option> <replaceable>cmd</replaceable></term>
<listitem>
<para>
- Execute the command <replaceable>cmd</replaceable> inside
- a new snapshot and return the command's exit code. If the command
- returns with a non-zero exit status, the snapshot will be discarded
- again.
- </para>
- <para>
- If a non-zero exit status is expected, then the command may either be
- wrapped inside a Bash script (see the program listing below) or it can
- be combinded with the <option>--keep</option> option and checking the
- exit code of <command>transactional-update</command> itself.
- </para>
- <para>
- Note that a snapshot will be created for each call, so if the command
- only performs read-only operations it may be worth to combine it with
- <option>--drop-if-no-change</option> to discard the snapshot again when
- there are not changes in the snapshot.
+ Execute the the command <replaceable>cmd</replaceable> inside
+ a new snapshot. By default this snaphot will remain, but if
+ <option>--drop-if-no-change</option> is set, the new snapshot
+ will be dropped if there is no change in the file system.
</para>
<para>
This command consumes all the remaining parameters, so should
@@ -585,11 +573,8 @@
<term><option>--keep</option></term>
<term><option>-k</option></term>
<listitem>
- <para>Do not delete the snapshot in case of errors. This option is mainly
- meant for debugging or recovery if a tukit plugin failed, the resulting
- snapshot should be used only after verifying the contents are as
- expected.</para>
- <para>The default snapshot will not be changed.</para>
+ <para>Do not delete the snapshot in case of errors. This option is only
for debugging or recovery if a tukit
+ plugin failed - do not use this option for production snapshots!</para>
</listitem>
</varlistentry>
<varlistentry>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/transactional-update-6.0.3/sbin/transactional-update.in
new/transactional-update-5.1.0/sbin/transactional-update.in
--- old/transactional-update-6.0.3/sbin/transactional-update.in 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/sbin/transactional-update.in 2025-08-18
15:54:13.000000000 +0200
@@ -59,9 +59,7 @@
OCI_RSYNC_EXCLUDES="/etc /var /usr/local /tmp /root /home /srv /opt /sys /dev
/proc /run"
OCI_TARGET=""
DRACUT_OPTS=""
-TUKIT_OPTS="--log=console"
-FORCE_REFRESH=0
-ZYPPER_FORCE_REFRESH=0
+TUKIT_OPTS=""
IS_BLS=""
TMPDIR=${TMPDIR:-/tmp}
@@ -97,18 +95,7 @@
fi
log_info "Checking for newer version."
- # Tell zypper that we are in a read-only system, do not import keys using
rpm
- export ZYPP_READONLY_HACK=1
- local zypper_log_tmpfile
- zypper_log_tmpfile=$(mktemp "${TMPDIR}/transactional-update.XXXXXXXXXX")
- zypper --xmlout --non-interactive info transactional-update >
"$zypper_log_tmpfile"
- if grep -q "can not be imported. (READONLY MODE)" "$zypper_log_tmpfile";
then
- export ZYPPER_FORCE_REFRESH=1
- fi
- grep -q '^Status *: out-of-date' "$zypper_log_tmpfile"
- out_of_date="$?"
- rm "$zypper_log_tmpfile"
- if [ $out_of_date -eq 0 ]; then
+ if zypper --non-interactive info transactional-update | grep -q '^Status
*: out-of-date'; then
log_info "New version found - updating..."
if ! TA_UPDATE_TMPFILE="$(mktemp -d
"${TMPDIR}"/transactional-update.XXXXXXXXXX)"; then
log_error "ERROR: Couldn't create temporary directory for
self-update."
@@ -120,7 +107,6 @@
log_error "ERROR: Couldn't extract the update."
quit 1
fi
- unset ZYPP_READONLY_HACK
# Reset CWD before restart
if ! popd >/dev/null; then
log_error "popd failed during self-update"
@@ -135,7 +121,6 @@
export TA_UPDATE_TMPFILE
exec "${TA_UPDATE_TMPFILE}/usr/sbin/transactional-update" "$@"
1>&${origstdout} 2>&${origstderr}
fi
- unset ZYPP_READONLY_HACK
}
usage() {
@@ -194,64 +179,23 @@
exit 0
}
-log_to_journal() {
- if [ -S /run/systemd/journal/stdout ]; then
- systemd-cat -t transactional-update "$@"
- fi
-}
-
log_to_file() {
- if [ $# -gt 0 ]; then
- echo -e "$(date "+%Y-%m-%d %T")" "$@" >> ${LOGFILE}
- else # input via pipe
- while read -r line; do
- echo -e "$(date "+%Y-%m-%d %T")" "${line}" >> ${LOGFILE}
- done
- fi
+ echo -e "$(date "+%Y-%m-%d %H:%M")" "$@" >> ${LOGFILE}
}
log_to_stdout() {
- if [ ${VERBOSITY} -ge 2 ] && [ -z "${SYSTEMD_EXEC_PID}" ]; then
+ if [ ${VERBOSITY} -ge 2 ]; then
echo -e "$@"
fi
}
-log_to_stderr() {
- echo -e "$@" 1>&${origstderr}
-}
-
-log_common() {
- local log_to_orig=0
- local loglevel=$1
- shift
-
- if [ "$1" == "-o" ]; then
- log_to_orig=1
- shift
- fi
-
- if [ $# -gt 0 ]; then
- log_to_stdout "$@"
- log_to_file "$@"
- log_to_journal -p "$loglevel" echo "$@"
- else # input via pipe
- if [ "$log_to_orig" == 1 ]; then
- cat | tee -a >(log_to_journal -p "$loglevel") >(log_to_file)
1>&${origstdout}
- else
- cat | tee -a >(log_to_journal -p "$loglevel") >(log_to_file)
- fi
- fi
-}
-
log_info() {
- log_common info "$@"
-}
-
-log_warn() {
- log_common warning "$@"
+ log_to_stdout "$@"
+ log_to_file "$@"
}
log_error() {
+ log_to_file "$@"
echo -e "$@" 1>&2
}
@@ -293,8 +237,6 @@
echo "REBOOT_ASSOCS[${key}]=${REBOOT_ASSOCS[${key}]}" >> ${STATE_FILE}
done
- echo "FORCE_REFRESH=\"${FORCE_REFRESH}\"" >> ${STATE_FILE}
-
if [ "$1" -ne 0 ] && [ ${HAS_SEPARATE_VAR} -eq 0 ]; then
# If /var/lib/misc is not a seperate partition / subvolume, copy the
# state file into the new snapshot as it will contain an outdated
@@ -315,8 +257,8 @@
}
rebuild_kdump_initrd() {
- if tukit ${TUKIT_OPTS} --quiet call "$1" systemctl is-enabled --quiet
kdump.service; then
- tukit ${TUKIT_OPTS} call "$1" /sbin/mkdumprd | log_info -o
+ 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."
@@ -336,13 +278,9 @@
echo -n "${REBOOT_LEVEL_PREV}" > "${NEEDS_RESTARTING_FILE}"
fi
- if [ -n "${SNAPSHOT_ID}" ]; then
- if [ "$KEEP_SNAPSHOT" -eq 1 ]; then
- log_info "WARNING: Keeping snapshot as requested, but not setting
as default."
- else
- log_error "Removing snapshot #${SNAPSHOT_ID}..."
- fi
- tukit ${TUKIT_OPTS} abort "${SNAPSHOT_ID}" | log_info
+ if [ -n "${SNAPSHOT_ID}" ] && [ "$KEEP_SNAPSHOT" -eq 0 ]; then
+ log_error "Removing snapshot #${SNAPSHOT_ID}..."
+ tukit ${TUKIT_OPTS} abort "${SNAPSHOT_ID}" |& tee -a ${LOGFILE}
fi
log_info "transactional-update finished"
exit "$1"
@@ -431,7 +369,7 @@
quit 2
fi
- if [ "$(systemd-sysext | tail -n +2 | grep -c " none ")" -ne 2 ]; then
+ if [ "$(systemd-sysext | tail -n +2 | grep " none " | wc -l)" -ne 2 ];
then
REFRESH_SYSEXTS=1
fi
@@ -637,6 +575,15 @@
shell)
RUN_SHELL=1
shift
+ if [ "$1" = "-c" ]; then
+ if [ -z "$2" ]; then
+ SHELL_CMD="-"
+ else
+ SHELL_CMD="$2"
+ shift
+ fi
+ shift
+ fi
;;
initrd)
REWRITE_INITRD=1
@@ -810,7 +757,7 @@
exec {origstderr}>&2
# Log stderr to log file in case anything goes wrong within
transactional-update
-exec 2> >(exec tee -i -a "${LOGFILE}" >(log_to_journal -p err) >&2)
+exec 2> >(exec tee -i -a "${LOGFILE}" >&2)
if [ "${VERBOSITY}" -eq 1 ]; then
exec 1>/dev/null
if [ -n "${ZYPPER_ARG}" ]; then
@@ -942,14 +889,6 @@
if [ -f ${STATE_FILE} ]; then
. ${STATE_FILE}
fi
-# If we need to refresh the repositories, save this var into the state
-# as t-u might not create/save a snapshot in this call
-# Save it only if not already present
-if [ "$ZYPPER_FORCE_REFRESH" -gt "$FORCE_REFRESH" ]; then
- FORCE_REFRESH=1
- save_state_file 0
-fi
-unset ZYPPER_FORCE_REFRESH
log_info "transactional-update ${VERSION} started"
log_info "Options: ${ORIG_ARGS[*]}"
@@ -1014,7 +953,7 @@
log_info "Rollback to snapshot ${ROLLBACK_SNAPSHOT}..."
- if ! tukit ${TUKIT_OPTS} rollback "${ROLLBACK_SNAPSHOT}"; then
+ if ! tukit rollback "${ROLLBACK_SNAPSHOT}"; then
log_error "ERROR: Rollback to snapshot $ROLLBACK_SNAPSHOT failed!"
quit 1
fi
@@ -1041,7 +980,7 @@
if [ ${DO_APPLY} -eq 1 ]; then
do_apply
else
- log_warn "Please reboot to finish rollback!"
+ log_error "Please reboot to finish rollback!"
fi
fi
log_info "transactional-update finished"
@@ -1059,7 +998,7 @@
for snap in ${LAST_WORKING_SNAPSHOTS}; do
if [ "${CURRENT_SNAPSHOT_ID}" -ne "${snap}" ] && [
"${BOOTED_SNAPSHOT_ID}" -ne "${snap}" ]; then
log_info "Adding cleanup algorithm to snapshot #${snap}"
- snapper modify -c number "${snap}" | log_info
+ snapper modify -c number "${snap}" |& tee -a ${LOGFILE}
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
log_error "ERROR: cannot set cleanup algorithm for
snapshot #${snap}"
fi
@@ -1067,7 +1006,7 @@
# earlier. If not, mark is as important, so that it will not
get deleted too fast.
if [ "${RO_ROOT}" == "true" ]; then
log_info "Adding \"important=yes\" to snapshot #${snap}"
- snapper modify -u "important=yes" "${snap}" | log_info
+ snapper modify -u "important=yes" "${snap}" |& tee -a
${LOGFILE}
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
log_error "ERROR: cannot set \"important=yes for
snapshot\" #${snap}"
fi
@@ -1099,7 +1038,7 @@
[ "${snap}" -ne "${BOOTED_SNAPSHOT_ID}" ] && \
[ "${snap}" -ne "${DEFAULT_SNAPSHOT_ID}" ]; then
log_info "Mark unused snapshot #${snap} for deletion"
- snapper modify -c number "${snap}" | log_info
+ snapper modify -c number "${snap}" |& tee -a ${LOGFILE}
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
log_error "ERROR: cannot set cleanup algorithm for
snapshot #${snap}"
# Is the snapshot still available at all?
@@ -1150,8 +1089,8 @@
fi
fi
- output="$(tukit ${TUKIT_OPTS} -c"${BASE_SNAPSHOT_ID}" open)"
- echo "${output}" | log_info
+ output="$(tukit ${TUKIT_OPTS} -c"${BASE_SNAPSHOT_ID}" open |& tee -a
${LOGFILE})"
+ log_info "$output"
SNAPSHOT_ID=$(echo "${output}" | grep -e "^ID:" | cut -d " " -f 2-)
if [ -z "${SNAPSHOT_ID}" ]; then
quit 1
@@ -1165,7 +1104,7 @@
UNUSED_SNAPSHOTS="${SNAPSHOT_ID} ${UNUSED_SNAPSHOTS}"
if [ ${DO_REGISTRATION} -eq 1 ]; then
- tukit ${TUKIT_OPTS} callext "${SNAPSHOT_ID}" SUSEConnect --root {}
${REGISTRATION_ARGS} | log_info -o
+ tukit ${TUKIT_OPTS} callext "${SNAPSHOT_ID}" SUSEConnect --root {}
${REGISTRATION_ARGS} |& tee -a ${LOGFILE} 1>&${origstdout}
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
EXITCODE=1
fi
@@ -1187,11 +1126,11 @@
for i in ${OCI_RSYNC_EXCLUDES}; do
OCI_RSYNC_EXCLUDES_LIST+=("--exclude $i ")
done
- rsync --delete ${OCI_RSYNC_ARGS} ${OCI_RSYNC_EXCLUDES_LIST[@]}
${OCI_MOUNT}/ ${SNAPSHOT_DIR}/ | log_info -o
+ rsync --delete ${OCI_RSYNC_ARGS} ${OCI_RSYNC_EXCLUDES_LIST[@]}
${OCI_MOUNT}/ ${SNAPSHOT_DIR}/ |& tee -a ${LOGFILE} 1>&${origstdout}
# Merge contents of /etc from container image but preserve existing
configuration
log_info "INFO: Merging /etc from container image into existing
snapshot, preserving existing configuration..."
- tukit ${TUKIT_OPTS} callext "${SNAPSHOT_ID}" rsync --ignore-existing
${OCI_RSYNC_ARGS} "${OCI_MOUNT}/etc/" "${SNAPSHOT_DIR}/etc/" | log_info -o
+ tukit ${TUKIT_OPTS} callext "${SNAPSHOT_ID}" rsync --ignore-existing
${OCI_RSYNC_ARGS} "${OCI_MOUNT}/etc/" "${SNAPSHOT_DIR}/etc/" |& tee -a
${LOGFILE} 1>&${origstdout}
# Unmount the container image
podman image unmount "${OCI_TARGET}"
@@ -1199,19 +1138,7 @@
log_info "Forcing SELinux relabel at next reboot."
touch "${SNAPSHOT_DIR}/.autorelabel"
# Ensure RPM database is using the desired system backend
- tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" rpm --rebuilddb | log_info -o
- fi
-
- # A new key was being imported while t-u was looking for a self-update,
but the system was read-only
- # Force refresh of the repositories to import it
- if [ "$FORCE_REFRESH" -eq 1 ]; then
- if tukit ${TUKIT_OPTS} call ${SNAPSHOT_ID} zypper refresh -f; then
-
- # The refresh succeeded. It's okay to disable it here, because
- # this is included in t-u state, and it is only saved when
- # the transaction is saved
- FORCE_REFRESH=0
- fi
+ tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" rpm --rebuilddb |& tee -a
${LOGFILE} 1>&${origstdout}
fi
if [ -n "${ZYPPER_ARG}" ]; then
@@ -1220,7 +1147,7 @@
if [ ${DO_MIGRATION} -eq 1 ]; then
# transactional-update migration
export DISABLE_RESTART_ON_UPDATE=yes
- tukit ${TUKIT_OPTS} callext "${SNAPSHOT_ID}" zypper ${ZYPPER_ARG}
--root {} ${ZYPPER_NONINTERACTIVE} "${ZYPPER_ARG_EXTRA[@]}" | log_info -o
+ tukit ${TUKIT_OPTS} callext "${SNAPSHOT_ID}" zypper ${ZYPPER_ARG}
--root {} ${ZYPPER_NONINTERACTIVE} "${ZYPPER_ARG_EXTRA[@]}" |& tee -a
${LOGFILE} 1>&${origstdout}
RETVAL=${PIPESTATUS[0]}
else
if [ ${DO_CALLEXT} -eq 1 ]; then
@@ -1247,10 +1174,10 @@
fi
export DISABLE_RESTART_ON_UPDATE=yes
- ${zypper_cmd} ${ZYPPER_ARG} ${ZYPPER_NONINTERACTIVE}
"${ZYPPER_ARG_EXTRA[@]}" | log_info -o
+ ${zypper_cmd} ${ZYPPER_ARG} ${ZYPPER_NONINTERACTIVE}
"${ZYPPER_ARG_EXTRA[@]}" |& tee -a ${LOGFILE} 1>&${origstdout}
RETVAL=${PIPESTATUS[0]}
if { [ "${RETVAL}" -eq 0 ] || [ "${RETVAL}" -eq 102 ] || [
"${RETVAL}" -eq 103 ]; } && [ -n "${INCLUDES_KERNEL_PACKAGES}" ]; then
- ${zypper_cmd} -n purge-kernels | log_info
+ ${zypper_cmd} -n purge-kernels |& tee -a ${LOGFILE}
fi
fi
# in case of migration, we need to do a little bit more:
@@ -1310,7 +1237,7 @@
REWRITE_GRUB_CFG=1
fi
if [ -x "${SNAPSHOT_DIR}/usr/bin/update-crypto-policies" ]; then
- tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" update-crypto-policies
--set FIPS | log_info -o
+ tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" update-crypto-policies
--set FIPS |& tee -a ${LOGFILE} 1>&${origstdout}
fi
fi
if [ ${SETUP_SELINUX} -eq 1 ]; then
@@ -1360,10 +1287,10 @@
if [ ${REWRITE_INITRD} -eq 1 ]; then
log_info "Creating new initrd"
- if is_bls && ! sdbootutil mkinitrd "${SNAPSHOT_ID}" | log_info -o; then
+ if is_bls && ! sdbootutil mkinitrd "${SNAPSHOT_ID}" |& tee -a
${LOGFILE} 1>&${origstdout}; then
log_error "ERROR: sdbootutil mkinitrd failed!"
EXITCODE=1;
- elif ! is_bls && ! tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" dracut
${DRACUT_OPTS} --force --regenerate-all | log_info -o; then
+ elif ! is_bls && ! tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" dracut
${DRACUT_OPTS} --force --regenerate-all |& tee -a ${LOGFILE} 1>&${origstdout};
then
log_error "ERROR: initrd creation failed!"
EXITCODE=1
else
@@ -1386,7 +1313,7 @@
set_reboot_level "soft-reboot"
fi
- if is_bls && { [ ${REWRITE_GRUB_CFG} = 1 ] || [
${REWRITE_GRUB_CFG_NO_REBOOT} = 1 ]; }; then
+ if is_bls && ([ ${REWRITE_GRUB_CFG} = 1 ] || [
${REWRITE_GRUB_CFG_NO_REBOOT} = 1 ]); then
# The first GRUB configuration file in grub2bls is embedded in
# the EFI file, and the second one that contains the menu
# entries is generated dynamically by the new `blscfg` GRUB2
@@ -1397,7 +1324,7 @@
fi
if [ ${REWRITE_GRUB_CFG} -eq 1 ] || [ ${REWRITE_GRUB_CFG_NO_REBOOT} -eq 1
]; then
log_info "Creating a new grub2 config"
- if ! tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" bash -c
"/usr/sbin/grub2-mkconfig --output=/boot/grub2/grub.cfg" 2>&1 | log_info -o;
then
+ if ! tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" bash -c
"/usr/sbin/grub2-mkconfig > /boot/grub2/grub.cfg" |& tee -a ${LOGFILE}
1>&${origstdout}; then
log_error "ERROR: grub2-mkconfig failed!"
EXITCODE=1;
else
@@ -1415,10 +1342,10 @@
# NOTE: pbl has partial support of BLS. It will replace the
# shim bootloader, so for now we make a call of sdbootutil
# directly (bsc#1228864)
- if is_bls && ! sdbootutil update "${SNAPSHOT_ID}" | log_info -o; then
+ if is_bls && ! sdbootutil update "${SNAPSHOT_ID}" |& tee -a ${LOGFILE}
1>&${origstdout}; then
log_error "ERROR: sdbootutil update failed!"
EXITCODE=1;
- elif ! is_bls && ! tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" /sbin/pbl
--install | log_info -o; then
+ elif ! is_bls && ! tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" /sbin/pbl
--install |& tee -a ${LOGFILE} 1>&${origstdout}; then
log_error "ERROR: /sbin/pbl --install failed!"
EXITCODE=1;
fi
@@ -1426,8 +1353,7 @@
fi
if [ ${DO_RUN} -eq 1 ]; then
- tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" "${RUN_CMD[@]}" | log_info -o
- EXITCODE=${PIPESTATUS[0]}
+ tukit ${TUKIT_OPTS} call "${SNAPSHOT_ID}" "${RUN_CMD[@]}" |& tee -a
${LOGFILE} 1>&${origstdout}
set_reboot_level "reboot"
fi
@@ -1445,7 +1371,7 @@
# Save the old snapshot or else it will get lost.
add_unique_id "${CURRENT_SNAPSHOT_ID}"
save_state_file "${SNAPSHOT_ID}"
- tukit ${TUKIT_OPTS} close "${SNAPSHOT_ID}" | log_info
+ tukit ${TUKIT_OPTS} close "${SNAPSHOT_ID}" |& tee -a ${LOGFILE}
fi
# If --drop-if-no-change is used, then the snapshot may not exist any more;
@@ -1474,7 +1400,7 @@
filelist="$(echo "$filelist" | grep -v "^\(${whitelist::-2}\)")"
if [ -n "$filelist" ]; then
- log_info ""
+ log_info
log_info "Warning: The following files were changed in the
snapshot, but are shadowed by"
log_info "other mounts and will not be visible to the system:"
log_info "${filelist}"
@@ -1488,7 +1414,7 @@
write_needs_restarting
if [ "${REBOOT_AFTERWARDS}" -eq 0 ] && [ "${DO_APPLY}" -eq 0 ]; then
log_info ""
- log_warn "Please reboot your machine to activate the changes and avoid
data loss."
+ log_info "Please reboot your machine to activate the changes and avoid
data loss."
fi
if [ "${DEFAULT_SNAPSHOT_ID}" -ne "${BASE_SNAPSHOT_ID}" ]; then
@@ -1518,30 +1444,30 @@
trap '-' HUP INT QUIT TERM
case "$REBOOT_METHOD" in
auto)
- tukit ${TUKIT_OPTS} reboot auto | log_info
+ tukit reboot auto |& tee -a ${LOGFILE}
;;
kured)
- tukit ${TUKIT_OPTS} reboot kured | log_info
+ tukit reboot kured |& tee -a ${LOGFILE}
;;
rebootmgr)
- tukit ${TUKIT_OPTS} reboot rebootmgr | log_info
+ tukit reboot rebootmgr |& tee -a ${LOGFILE}
;;
notify)
- tukit ${TUKIT_OPTS} reboot notify | log_info
+ tukit reboot notify |& tee -a ${LOGFILE}
;;
systemd)
- tukit ${TUKIT_OPTS} reboot systemd | log_info
+ tukit reboot systemd |& tee -a ${LOGFILE}
;;
kexec)
- tukit ${TUKIT_OPTS} reboot kexec | log_info
+ tukit reboot kexec |& tee -a ${LOGFILE}
;;
none)
- tukit ${TUKIT_OPTS} reboot none | log_info
+ tukit reboot none |& tee -a ${LOGFILE}
;;
*)
log_info "Unsupported reboot method, falling back to 'auto';
please"
log_info "check your configuration in ${CONFFILE}."
- tukit ${TUKIT_OPTS} reboot auto | log_info
+ tukit reboot auto |& tee -a ${LOGFILE}
;;
esac
fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/snapper/50-etc
new/transactional-update-5.1.0/snapper/50-etc
--- old/transactional-update-6.0.3/snapper/50-etc 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/snapper/50-etc 2025-08-18
15:54:13.000000000 +0200
@@ -105,7 +105,7 @@
if [ "$2" != "/" ]; then
exit 0
fi
-if [ -e "/.snapshots/${4}/snapshot/etc/fstab" ] && ! findmnt --mountpoint /etc
--noheadings --output TARGET --tab-file "/.snapshots/${4}/snapshot/etc/fstab"
>/dev/null; then
+if [ -e "/.snapshots/${4}/snapshot/etc/fstab" ] && ! findmnt --mountpoint /etc
--noheadings --output TARGET --tab-file "/.snapshots/${4}/snapshot/etc/fstab";
then
echo "/etc is not a mount point - skipping..."
exit 0
fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-6.0.3/tukit/tukit.cpp
new/transactional-update-5.1.0/tukit/tukit.cpp
--- old/transactional-update-6.0.3/tukit/tukit.cpp 2026-01-09
14:08:38.000000000 +0100
+++ new/transactional-update-5.1.0/tukit/tukit.cpp 2025-08-18
15:54:13.000000000 +0200
@@ -72,16 +72,13 @@
cout << "\n";
cout << "Generic Options:\n";
cout << "--help, -h Display this help and exit\n";
- cout << "--log=<output1>[,<output2>,...], -l<...>\n";
- cout << " Restrict output channels to the
given ones\n";
- cout << " Possible values: \"console\",
\"syslog\"\n";
cout << "--quiet, -q Decrease verbosity\n";
cout << "--verbose, -v Increase verbosity\n";
cout << "--version, -V Display version and exit\n" << endl;
}
int TUKit::parseOptions(int argc, char *argv[]) {
- static const char optstring[] = "+c::dkf:hl:qvV";
+ static const char optstring[] = "+c::df:hqvV";
static const struct option longopts[] = {
{ "continue", optional_argument, nullptr, 'c' },
{ "description", required_argument, nullptr, 0 },
@@ -89,7 +86,6 @@
{ "discard", no_argument, nullptr, 'd' },
{ "fields", required_argument, nullptr, 'f' },
{ "help", no_argument, nullptr, 'h' },
- { "log", required_argument, nullptr, 'l' },
{ "quiet", no_argument, nullptr, 'q' },
{ "verbose", no_argument, nullptr, 'v' },
{ "version", no_argument, nullptr, 'V' },
@@ -122,9 +118,6 @@
case 'h':
displayHelp();
return 0;
- case 'l':
- tulog.setLogOutput(optarg);
- break;
case 'q':
tulog.level = TULogLevel::Error;
break;