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-01-24 19:42:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/transactional-update (Old)
and /work/SRC/openSUSE:Factory/.transactional-update.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "transactional-update"
Tue Jan 24 19:42:21 2023 rev:95 rq:1060452 version:4.1.2
Changes:
--------
---
/work/SRC/openSUSE:Factory/transactional-update/transactional-update.changes
2023-01-23 04:38:08.576888702 +0100
+++
/work/SRC/openSUSE:Factory/.transactional-update.new.32243/transactional-update.changes
2023-01-24 20:36:05.561550354 +0100
@@ -0,0 +1,23 @@
+-------------------------------------------------------------------
+Mon Jan 23 13:54:11 UTC 2023 - Ignaz Forster <[email protected]>
+
+- Version 4.1.2
+ - Don't try to mount user mounts if they don't exist [boo#1207366]
+
+-------------------------------------------------------------------
+Wed Jan 18 16:56:16 UTC 2023 - Ignaz Forster <[email protected]>
+
+- Version 4.1.1
+ - Mount user specific binddirs last: Prevously the internal mounts would
+ potentially overwrite user bind mounts [boo#1205011]
+ - selinux: Relabel shadowed /var files during update to make sure they
+ don't interfere with the update [boo#1205937]
+ - Clean up /var/lib/overlay more aggressively [boo#1206947]
+ - tukit: Merge /etc overlay into parent if --discard is used together
+ with --continue - previously the files were incorrectly always merged
+ with the currently running system
+ - status: do not execute the status command if experimental
+ - Don't delete created mount point dirs any more
+ - Small code optimizations
+
+-------------------------------------------------------------------
Old:
----
transactional-update-4.1.0.tar.gz
New:
----
transactional-update-4.1.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ transactional-update.spec ++++++
--- /var/tmp/diff_new_pack.bCmhYg/_old 2023-01-24 20:36:06.061552944 +0100
+++ /var/tmp/diff_new_pack.bCmhYg/_new 2023-01-24 20:36:06.077553027 +0100
@@ -1,7 +1,7 @@
#
# spec file for package transactional-update
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
# Copyright (c) 2021 Neal Gompa
#
# All modifications and additions to the file contributed by third parties
@@ -26,7 +26,7 @@
%{!?_distconfdir: %global _distconfdir %{_prefix}%{_sysconfdir}}
Name: transactional-update
-Version: 4.1.0
+Version: 4.1.2
Release: 0
Summary: Transactional Updates with btrfs and snapshots
License: GPL-2.0-or-later AND LGPL-2.1-or-later
++++++ transactional-update-4.1.0.tar.gz -> transactional-update-4.1.2.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-4.1.0/NEWS
new/transactional-update-4.1.2/NEWS
--- old/transactional-update-4.1.0/NEWS 2022-10-26 16:50:43.000000000 +0200
+++ new/transactional-update-4.1.2/NEWS 2023-01-23 14:31:20.000000000 +0100
@@ -2,6 +2,22 @@
Copyright (C) 2016-2022 Thorsten Kukuk, Ignaz Forster et al.
+Version 4.1.2
+* Don't try to mount user mounts if they don't exist [boo#1207366]
+
+Version 4.1.1
+* Mount user specific binddirs last: Prevously the internal mounts would
+ potentially overwrite user bind mounts [boo#1205011]
+* selinux: Relabel shadowed /var files during update to make sure they
+ don't interfere with the update [boo#1205937]
+* Clean up /var/lib/overlay more aggressively [boo#1206947]
+* tukit: Merge /etc overlay into parent if --discard is used together
+ with --continue - previously the files were incorrectly always merged
+ with the currently running system
+* status: do not execute the status command if experimental
+* Don't delete created mount point dirs any more
+* Small code optimizations
+
Version 4.1.0
* t-u: Add a "setup-kdump" command; implements [jsc#PED-1441]
* Add support for ULP (Userspace Live Patching) [jsc#PED-1078]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-4.1.0/README.md
new/transactional-update-4.1.2/README.md
--- old/transactional-update-4.1.0/README.md 2022-10-26 16:50:43.000000000
+0200
+++ new/transactional-update-4.1.2/README.md 2023-01-23 14:31:20.000000000
+0100
@@ -29,7 +29,7 @@
## Known users
* **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 transactionals systems via the
[cockpit-tukit](https://github.com/openSUSE/cockpit-tukit) plugin (tukitd).
+* **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).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-4.1.0/configure.ac
new/transactional-update-4.1.2/configure.ac
--- old/transactional-update-4.1.0/configure.ac 2022-10-26 16:50:43.000000000
+0200
+++ new/transactional-update-4.1.2/configure.ac 2023-01-23 14:31:20.000000000
+0100
@@ -1,11 +1,11 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(transactional-update, 4.1.0)
+AC_INIT(transactional-update, 4.1.2)
# Increase on any interface change and reset revision
LIBTOOL_CURRENT=4
# On interface change increase if backwards compatible, reset otherwise
LIBTOOL_AGE=0
# Increase on *any* C/C++ library code change, reset at interface change
-LIBTOOL_REVISION=1
+LIBTOOL_REVISION=2
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.1.0/lib/Mount.cpp
new/transactional-update-4.1.2/lib/Mount.cpp
--- old/transactional-update-4.1.0/lib/Mount.cpp 2022-10-26
16:50:43.000000000 +0200
+++ new/transactional-update-4.1.2/lib/Mount.cpp 2023-01-23
14:31:20.000000000 +0100
@@ -13,9 +13,9 @@
namespace TransactionalUpdate {
-Mount::Mount(std::string mountpoint, unsigned long flags)
+Mount::Mount(std::string mountpoint, unsigned long flags, bool umount)
: mnt_table{mnt_new_table()}, mountpoint{std::move(mountpoint)},
- flags{std::move(flags)}
+ flags{std::move(flags)}, umount{std::move(umount)}
{
}
@@ -29,7 +29,7 @@
}
Mount::~Mount() {
- if (mnt_fs) {
+ if (mnt_fs && umount) {
struct libmnt_table* umount_table = mnt_new_table();
if ((mnt_table_parse_mtab(umount_table, nullptr)) != 0)
tulog.error("Error reading mtab for umount");
@@ -39,14 +39,6 @@
mnt_free_table(umount_table);
}
- if (!directoryCreated.empty()) {
- try {
-
std::filesystem::remove_all(std::filesystem::path{directoryCreated});
- } catch (const std::exception &e) {
- tulog.error("ERROR: ", e.what());
- }
- }
-
mnt_free_context(mnt_cxt);
mnt_unref_fs(mnt_fs);
mnt_free_table(mnt_table);
@@ -192,10 +184,6 @@
throw std::runtime_error{"Setting mount flags for '" + mountpoint + "'
failed: " + std::to_string(rc)};
}
- if (! std::filesystem::is_directory(mounttarget)) {
- tulog.debug("Mount target ", mounttarget, " does not exist -
creating...");
- directoryCreated = mounttarget;
- }
std::filesystem::create_directories(mounttarget);
rc = mnt_context_mount(mnt_cxt);
@@ -269,8 +257,8 @@
mnt_free_context(umount_cxt);
}
-BindMount::BindMount(std::string mountpoint, unsigned long flags)
- : Mount(mountpoint, flags | MS_BIND)
+BindMount::BindMount(std::string mountpoint, unsigned long flags, bool umount)
+ : Mount(mountpoint, flags | MS_BIND, umount)
{
}
@@ -281,8 +269,8 @@
Mount::mount(prefix);
}
-PropagatedBindMount::PropagatedBindMount(std::string mountpoint, unsigned long
flags)
- : BindMount(mountpoint, flags | MS_REC | MS_SLAVE)
+PropagatedBindMount::PropagatedBindMount(std::string mountpoint, unsigned long
flags, bool umount)
+ : BindMount(mountpoint, flags | MS_REC | MS_SLAVE, umount)
{
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-4.1.0/lib/Mount.hpp
new/transactional-update-4.1.2/lib/Mount.hpp
--- old/transactional-update-4.1.0/lib/Mount.hpp 2022-10-26
16:50:43.000000000 +0200
+++ new/transactional-update-4.1.2/lib/Mount.hpp 2023-01-23
14:31:20.000000000 +0100
@@ -18,7 +18,7 @@
class Mount
{
public:
- Mount(std::string mountpoint, unsigned long flags = 0);
+ Mount(std::string mountpoint, unsigned long flags = 0, bool umount =
false);
Mount(Mount&& other) noexcept;
virtual ~Mount();
std::string getFilesystem();
@@ -38,7 +38,7 @@
std::string tabsource;
std::string mountpoint;
unsigned long flags;
- std::string directoryCreated;
+ bool umount;
struct libmnt_fs* findFS();
struct libmnt_fs* getTabEntry();
struct libmnt_fs* newFS();
@@ -48,14 +48,14 @@
class BindMount : public Mount
{
public:
- BindMount(std::string mountpoint, unsigned long flags = 0);
+ BindMount(std::string mountpoint, unsigned long flags = 0, bool umount =
false);
void mount(std::string prefix = "/") override;
};
class PropagatedBindMount : public BindMount
{
public:
- PropagatedBindMount(std::string mountpoint, unsigned long flags = 0);
+ PropagatedBindMount(std::string mountpoint, unsigned long flags = 0, bool
umount = false);
};
class MountList
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-4.1.0/lib/Overlay.cpp
new/transactional-update-4.1.2/lib/Overlay.cpp
--- old/transactional-update-4.1.0/lib/Overlay.cpp 2022-10-26
16:50:43.000000000 +0200
+++ new/transactional-update-4.1.2/lib/Overlay.cpp 2023-01-23
14:31:20.000000000 +0100
@@ -115,7 +115,6 @@
previousEtc->removeOption("workdir");
string syncSource = string(previousOvl.upperdir.parent_path() / "sync" /
"etc") + "/";
- string rsyncExtraArgs;
previousEtc->mount(previousOvl.upperdir.parent_path() / "sync");
tulog.info("Syncing /etc of previous snapshot ", previousSnapId, " as base
into new snapshot ", snapRoot);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-4.1.0/lib/Snapshot/Snapper.cpp
new/transactional-update-4.1.2/lib/Snapshot/Snapper.cpp
--- old/transactional-update-4.1.0/lib/Snapshot/Snapper.cpp 2022-10-26
16:50:43.000000000 +0200
+++ new/transactional-update-4.1.2/lib/Snapshot/Snapper.cpp 2023-01-23
14:31:20.000000000 +0100
@@ -7,7 +7,6 @@
#include "Snapper.hpp"
#include "Exceptions.hpp"
-#include "Log.hpp"
#include "Util.hpp"
#include <regex>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transactional-update-4.1.0/lib/Transaction.cpp
new/transactional-update-4.1.2/lib/Transaction.cpp
--- old/transactional-update-4.1.0/lib/Transaction.cpp 2022-10-26
16:50:43.000000000 +0200
+++ new/transactional-update-4.1.2/lib/Transaction.cpp 2023-01-23
14:31:20.000000000 +0100
@@ -25,6 +25,8 @@
#include <limits.h>
#include <poll.h>
#include <sched.h>
+#include <selinux/restorecon.h>
+#include <selinux/selinux.h>
#include <signal.h>
#include <sys/inotify.h>
#include <sys/mount.h>
@@ -106,18 +108,13 @@
// mount the snapshot directory on a temporary mount point
char bindTemplate[] = "/tmp/transactional-update-XXXXXX";
bindDir = mkdtemp(bindTemplate);
- std::unique_ptr<BindMount> mntBind{new BindMount{bindDir, MS_PRIVATE}};
+ std::unique_ptr<BindMount> mntBind{new BindMount{bindDir, MS_PRIVATE,
true}};
mntBind->setSource(snapshot->getRoot());
mntBind->mount();
dirsToMount.push_back(std::make_unique<PropagatedBindMount>("/dev"));
dirsToMount.push_back(std::make_unique<BindMount>("/var/log"));
- std::vector<std::string> customDirs = config.getArray("BINDDIRS");
- for (auto it = customDirs.begin(); it != customDirs.end(); ++it) {
- dirsToMount.push_back(std::make_unique<BindMount>(*it));
- }
-
Mount mntVar{"/var"};
if (mntVar.isMount()) {
if (fs::is_directory("/var/lib/zypp"))
@@ -127,7 +124,41 @@
dirsToMount.push_back(std::make_unique<BindMount>("/var/lib/alternatives"));
if (fs::is_directory("/var/lib/selinux"))
dirsToMount.push_back(std::make_unique<BindMount>("/var/lib/selinux"));
+ if (is_selinux_enabled()) {
+ // If packages installed files into /var (which is not allowed,
but still happens), they will end
+ // 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...
+ BindMount selinuxVar("/var/lib/selinux", 0, true);
+ selinuxVar.mount(bindDir);
+ BindMount selinuxEtc("/etc/selinux", 0, true);
+ selinuxEtc.mount(bindDir);
+
+ // restorecon keeps open file handles, so execute it in a child
process - umount will fail otherwise
+ pid_t childPid = fork();
+ if (childPid < 0) {
+ throw std::runtime_error{"Forking for SELinux relabelling
failed: " + std::string(strerror(errno))};
+ } else if (childPid == 0) {
+ if (chroot(bindDir.c_str()) < 0) {
+ tulog.error("Chrooting to " + bindDir + " for SELinux
relabelling failed: " + std::string(strerror(errno)));
+ _exit(errno);
+ }
+ if (selinux_restorecon("/var", SELINUX_RESTORECON_RECURSE |
SELINUX_RESTORECON_VERBOSE | SELINUX_RESTORECON_IGNORE_DIGEST) < 0) {
+ tulog.error("Relabelling of snapshot /var failed: " +
std::string(strerror(errno)));
+ _exit(errno);
+ }
+ _exit(0);
+ }
+ else {
+ int status;
+ waitpid(childPid, &status, 0);
+ if ((WIFEXITED(status) && WEXITSTATUS(status) != 0) ||
WIFSIGNALED(status)) {
+ throw std::runtime_error{"SELinux relabelling failed."};
+ }
+ }
+ }
}
+
std::unique_ptr<Mount> mntEtc{new Mount{"/etc"}};
if (mntEtc->isMount() && mntEtc->getFilesystem() == "overlay") {
Overlay overlay = Overlay{snapshot->getUid()};
@@ -171,6 +202,14 @@
if (BindMount{"/boot/writable"}.isMount())
dirsToMount.push_back(std::make_unique<BindMount>("/boot/writable"));
+ std::vector<std::string> customDirs = config.getArray("BINDDIRS");
+ for (auto it = customDirs.begin(); it != customDirs.end(); ++it) {
+ if (fs::is_directory(*it))
+ dirsToMount.push_back(std::make_unique<BindMount>(*it));
+ else
+ tulog.info("Not bind mounting directory '" + *it + "' as it
doesn't exist.");
+ }
+
dirsToMount.push_back(std::make_unique<BindMount>("/.snapshots"));
for (auto it = dirsToMount.begin(); it != dirsToMount.end(); ++it) {
@@ -276,7 +315,7 @@
struct pollfd pfd = {inotifyFd, POLLIN, 0};
ret = (poll(&pfd, 1, 500));
if (ret == -1) {
- throw std::runtime_error{"Polling inotify file descriptior failed: " +
std::string(strerror(errno))};
+ throw std::runtime_error{"Polling inotify file descriptor failed: " +
std::string(strerror(errno))};
} else if (ret > 0) {
numRead = read(inotifyFd, buf, bufLen);
if (numRead == 0)
@@ -432,12 +471,33 @@
(inotifyFd == 0 && fs::exists(getRoot() / "discardIfNoChange")))) {
tulog.info("No changes to the root file system - discarding
snapshot.");
- // Even if the snapshot itself did not contain any changes, /etc may
do so. Changes
- // in /etc may be applied immediately, so merge them back into the
running system.
+ // Even if the snapshot itself does not contain any changes, /etc may
do so. If the new snapshot is a
+ // direct descendant of the currently running system, then merge the
changes back into the currently
+ // running system directly and delete the snapshot. Otherwise merge it
back into the previous overlay
+ // (using rsync instead of a plain copy to preserve xattrs).
std::unique_ptr<Mount> mntEtc{new Mount{"/etc"}};
if (mntEtc->isMount() && mntEtc->getFilesystem() == "overlay") {
- Util::exec("rsync --archive --inplace --xattrs --acls --exclude
'fstab' --delete --quiet '" + this->pImpl->bindDir + "/etc/' /etc");
+ std::filesystem::path targetRoot;
+ std::unique_ptr<Mount> previousEtc{new Mount("/etc", 0, true)};
+ if (pImpl->snapshotMgr->getCurrent() ==
Overlay{pImpl->snapshot->getUid()}.getPreviousSnapshotOvlId()) {
+ tulog.info("Merging changes in /etc into the running system.");
+ targetRoot = "/";
+ } else {
+ tulog.info("Merging changes in /etc into the previous
snapshot.");
+
+ auto previousSnapId =
Overlay{pImpl->snapshot->getUid()}.getPreviousSnapshotOvlId();
+ std::unique_ptr<Snapshot> previousSnapshot =
pImpl->snapshotMgr->open(previousSnapId);
+ previousEtc->setTabSource(previousSnapshot->getRoot() / "etc"
/ "fstab");
+
+ Overlay previousOvl{previousSnapId};
+ previousOvl.lowerdirs.back() = previousSnapshot->getRoot();
+ previousOvl.setMountOptionsForMount(previousEtc);
+ targetRoot = previousOvl.upperdir.parent_path() / "sync";
+ previousEtc->mount(targetRoot);
+ }
+ Util::exec("rsync --archive --inplace --xattrs --acls --exclude
'fstab' --delete --quiet '" + this->pImpl->bindDir + "/etc/' " +
targetRoot.native() + "/etc");
}
+
return;
}
if (fs::exists(getRoot() / "discardIfNoChange")) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/transactional-update-4.1.0/sbin/transactional-update.in
new/transactional-update-4.1.2/sbin/transactional-update.in
--- old/transactional-update-4.1.0/sbin/transactional-update.in 2022-10-26
16:50:43.000000000 +0200
+++ new/transactional-update-4.1.2/sbin/transactional-update.in 2023-01-23
14:31:20.000000000 +0100
@@ -1209,10 +1209,14 @@
fi
if [ "${DO_STATUS}" -eq 1 ]; then
- for snapshot in $(ls -d /.snapshots/*/ | cut -d '/' -f 3 | sort --reverse
--numeric-sort); do
- show_snapshot_status "/.snapshots/$snapshot/"
- [ "${DO_STATUS_LAST}" -eq 1 ] && break
- done
+ if [ "${EXPERIMENTAL_STATUS}" -eq 1 ]; then
+ for snapshot in $(ls -d /.snapshots/*/ | cut -d '/' -f 3 | sort
--reverse --numeric-sort); do
+ show_snapshot_status "/.snapshots/$snapshot/"
+ [ "${DO_STATUS_LAST}" -eq 1 ] && break
+ done
+ else
+ echo "The status command is disabled by default as it is marked as
experimental"
+ fi
exit 0
fi
@@ -1290,11 +1294,10 @@
# Clean up old unused overlays
if [ ${RO_ROOT} == "true" ]; then
shopt -s nullglob
- for overlay in /var/lib/overlay/[0-9]*/etc /var/lib/overlay/etc; do
+ for overlay in /var/lib/overlay/*; do
if [ -e ${overlay} ] && ! grep -qs "${overlay}"
/.snapshots/*/snapshot/etc/fstab{,.sys}; then
log_info "Deleting unused overlay ${overlay}"
- rm -rf "${overlay}"
- rmdir --ignore-fail-on-non-empty "$(dirname "${overlay}")"
+ rm -r "${overlay}"
fi
done
shopt -u nullglob