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 2021-03-10 08:46:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/transactional-update (Old)
 and      /work/SRC/openSUSE:Factory/.transactional-update.new.2378 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "transactional-update"

Wed Mar 10 08:46:20 2021 rev:69 rq:876314 version:3.2.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/transactional-update/transactional-update.changes    
    2021-02-18 20:50:15.175317660 +0100
+++ 
/work/SRC/openSUSE:Factory/.transactional-update.new.2378/transactional-update.changes
      2021-03-10 08:46:22.686215349 +0100
@@ -1,0 +2,15 @@
+Tue Mar  2 23:58:27 UTC 2021 - Ignaz Forster <ifors...@suse.com>
+
+- Version 3.2.0
+  - tukit: Add new command 'callext' to execute an application while the
+    snapshot is mounted. '{}' as a parameter will be replaced with the path
+    of the bind mount.
+  - Fix --drop-if-no-change [boo#1182525]
+  - Check whether self-updated version is executable (e.g. on noexec /tmp)
+    [bsc#1173842]
+  - Fix overlay synchronisation with SELinux (again)
+  - Always overwrite supplemental files (e.g. for network configuration)
+    even if they exist in the snapshot already [boo#1182544]
+  - Improve logging and error messages
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ transactional-update.spec ++++++
--- /var/tmp/diff_new_pack.bd2OdR/_old  2021-03-10 08:46:23.198215877 +0100
+++ /var/tmp/diff_new_pack.bd2OdR/_new  2021-03-10 08:46:23.202215881 +0100
@@ -26,7 +26,7 @@
 %{!?_distconfdir: %global _distconfdir %{_prefix}%{_sysconfdir}}
 
 Name:           transactional-update
-Version:        3.1.4
+Version:        3.2.0
 Release:        0
 Summary:        Transactional Updates with btrfs and snapshots
 License:        GPL-2.0-or-later AND LGPL-2.1-or-later

++++++ transactional-update-3.1.4.tar.gz -> transactional-update-3.2.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-3.1.4/NEWS 
new/transactional-update-3.2.0/NEWS
--- old/transactional-update-3.1.4/NEWS 2021-02-17 09:41:55.000000000 +0100
+++ new/transactional-update-3.2.0/NEWS 2021-03-03 00:56:13.000000000 +0100
@@ -2,6 +2,18 @@
 
 Copyright (C) 2016-2020 Thorsten Kukuk, Ignaz Forster et al.
 
+Version 3.2.0
+* tukit: Add new command 'callext' to execute an application while the
+  snapshot is mounted. '{}' as a parameter will be replaced with the path
+  of the bind mount.
+* Fix --drop-if-no-change [boo#1182525]
+* Check whether self-updated version is executable (e.g. on noexec /tmp)
+  [bsc#1173842]
+* Fix overlay synchronisation with SELinux (again)
+* Always overwrite supplemental files (e.g. for network configuration)
+  even if they exist in the snapshot already [boo#1182544]
+* Improve logging and error messages
+
 Version 3.1.4
 * SELinux: Fix syncing of SELinux attributes when using overlays
 * SELinux: Tag the overlay directory itself (again)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-3.1.4/configure.ac 
new/transactional-update-3.2.0/configure.ac
--- old/transactional-update-3.1.4/configure.ac 2021-02-17 09:41:55.000000000 
+0100
+++ new/transactional-update-3.2.0/configure.ac 2021-03-03 00:56:13.000000000 
+0100
@@ -1,8 +1,11 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT(transactional-update, 3.1.4)
-LIBTOOL_CURRENT=1 # Increase on any interface change and reset revision
-LIBTOOL_REVISION=4 # Increase or reset on any VERSION update
-LIBTOOL_AGE=1 # Increase if interface change is backwards compatible, reset 
otherwise
+AC_INIT(transactional-update, 3.2.0)
+# Increase on any interface change and reset revision
+LIBTOOL_CURRENT=2
+# Increase or reset on any VERSION update
+LIBTOOL_REVISION=0
+# Increase if interface change is backwards compatible, reset otherwise
+LIBTOOL_AGE=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-3.1.4/lib/Overlay.cpp 
new/transactional-update-3.2.0/lib/Overlay.cpp
--- old/transactional-update-3.1.4/lib/Overlay.cpp      2021-02-17 
09:41:55.000000000 +0100
+++ new/transactional-update-3.2.0/lib/Overlay.cpp      2021-03-03 
00:56:13.000000000 +0100
@@ -15,6 +15,7 @@
 #include <filesystem>
 #include <regex>
 #include <selinux/selinux.h>
+#include <selinux/context.h>
 #include <sstream>
 #include <unistd.h>
 
@@ -117,11 +118,15 @@
     previousEtc->mount(previousOvl.upperdir.parent_path() / "sync");
     tulog.info("Syncing /etc of previous snapshot ", previousSnapId, " as base 
into new snapshot ", snapshot);
     if (is_selinux_enabled()) {
+        tulog.info("SELinux is enabled.");
         // Ignore the SELinux attributes when synchronizing pre-SELinux files,
         // rsync will fail otherwise
         char* context;
-        if (getfilecon(syncSource.c_str(), &context) > 0 && strcmp(context, 
"unlabeled_t") == 0) {
-            rsyncExtraArgs = "--filter='-x security.selinux'";
+        if (getfilecon(syncSource.c_str(), &context) > 0) { // &&
+            auto contextt = context_new(context);
+            if (strcmp(context_type_get(contextt), "unlabeled_t") == 0) {
+                rsyncExtraArgs = "--filter='-x security.selinux'";
+            }
         }
     }
     Util::exec("rsync --quiet --archive --inplace --xattrs --exclude='/fstab' 
" + rsyncExtraArgs + " --acls --delete " + syncSource + " " + snapshot + 
"/etc");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-3.1.4/lib/Supplement.cpp 
new/transactional-update-3.2.0/lib/Supplement.cpp
--- old/transactional-update-3.1.4/lib/Supplement.cpp   2021-02-17 
09:41:55.000000000 +0100
+++ new/transactional-update-3.2.0/lib/Supplement.cpp   2021-03-03 
00:56:13.000000000 +0100
@@ -41,11 +41,9 @@
 
 void Supplements::addFile(fs::path file) {
     if (fs::exists(file)) {
-        auto copyOptions = fs::copy_options::none;
+        auto copyOptions = fs::copy_options::overwrite_existing | 
fs::copy_options::recursive;
         createDirs(file.parent_path());
         fs::path target = snapshot / file.relative_path();
-        if (fs::is_regular_file(file))
-            copyOptions = fs::copy_options::overwrite_existing;
         fs::copy(file, target, copyOptions);
         supplementalFiles.push_back(std::move(target));
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-3.1.4/lib/Transaction.cpp 
new/transactional-update-3.2.0/lib/Transaction.cpp
--- old/transactional-update-3.1.4/lib/Transaction.cpp  2021-02-17 
09:41:55.000000000 +0100
+++ new/transactional-update-3.2.0/lib/Transaction.cpp  2021-03-03 
00:56:13.000000000 +0100
@@ -28,6 +28,7 @@
 public:
     void addSupplements();
     void mount();
+    int runCommand(char* argv[], bool inChroot);
     std::unique_ptr<Snapshot> snapshot;
     std::string bindDir;
     std::vector<std::unique_ptr<Mount>> dirsToMount;
@@ -55,8 +56,10 @@
         }
     }
     try {
-        if (isInitialized() && !getSnapshot().empty())
+        if (isInitialized() && !getSnapshot().empty() && 
fs::exists(getRoot())) {
+            tulog.info("Discarding snapshot ", pImpl->snapshot->getUid(), ".");
             pImpl->snapshot->abort();
+        }
     }  catch (const std::exception &e) {
         tulog.error("ERROR: ", e.what());
     }
@@ -183,7 +186,7 @@
     pImpl->addSupplements();
 }
 
-int Transaction::execute(char* argv[]) {
+int Transaction::impl::runCommand(char* argv[], bool inChroot) {
     std::string opts = "Executing `";
     int i = 0;
     while (argv[i]) {
@@ -201,11 +204,13 @@
     if (pid < 0) {
         throw std::runtime_error{"fork() failed: " + 
std::string(strerror(errno))};
     } else if (pid == 0) {
-        if (chdir(pImpl->bindDir.c_str()) < 0) {
-            tulog.info("Warning: Couldn't set working directory: ", 
std::string(strerror(errno)));
-        }
-        if (chroot(pImpl->bindDir.c_str()) < 0) {
-            throw std::runtime_error{"Chrooting to " + pImpl->bindDir + " 
failed: " + std::string(strerror(errno))};
+        if (inChroot) {
+            if (chdir(bindDir.c_str()) < 0) {
+                tulog.info("Warning: Couldn't set working directory: ", 
std::string(strerror(errno)));
+            }
+            if (chroot(bindDir.c_str()) < 0) {
+                throw std::runtime_error{"Chrooting to " + bindDir + " failed: 
" + std::string(strerror(errno))};
+            }
         }
         // Set indicator for RPM pre/post sections to detect whether we run in 
a
         // transactional update
@@ -216,9 +221,9 @@
             throw std::runtime_error{"Calling " + std::string(argv[0]) + " 
failed: " + std::string(strerror(errno))};
         }
     } else {
-        this->pImpl->pid = pid;
+        this->pid = pid;
         ret = waitpid(pid, &status, 0);
-        this->pImpl->pid = 0;
+        this->pid = 0;
         if (tulog.level > TULogLevel::ERROR)
             std::cout << "???" << std::endl;
         if (ret < 0) {
@@ -237,6 +242,20 @@
     return ret;
 }
 
+int Transaction::execute(char* argv[]) {
+    return this->pImpl->runCommand(argv, true);
+}
+
+int Transaction::callExt(char* argv[]) {
+    for (int i=0; argv[i] != nullptr; i++) {
+        if (strcmp(argv[i], "{}") == 0) {
+            char* bindDir = strdup(pImpl->bindDir.c_str());
+            argv[i] = bindDir;
+        }
+    }
+    return this->pImpl->runCommand(argv, false);
+}
+
 void Transaction::sendSignal(int signal) {
     if (pImpl->pid != 0) {
         if (kill(pImpl->pid, signal) < 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-3.1.4/lib/Transaction.hpp 
new/transactional-update-3.2.0/lib/Transaction.hpp
--- old/transactional-update-3.1.4/lib/Transaction.hpp  2021-02-17 
09:41:55.000000000 +0100
+++ new/transactional-update-3.2.0/lib/Transaction.hpp  2021-03-03 
00:56:13.000000000 +0100
@@ -64,8 +64,8 @@
      * @param argv
      * @return application's return code
      *
-     * Execute any given command in the new snapshot. The application's output 
will not be
-     * modified and printed to the corresponding streams.
+     * Execute any given command within the new snapshot. The application's 
output will be
+     * printed to the corresponding streams.
      *
      * Note that @param is following the default C style syntax:
      * @example: char *args[] = {(char*)"ls", (char*)"-l", NULL};
@@ -74,6 +74,23 @@
     int execute(char* argv[]);
 
     /**
+     * @brief Replace '{}' in argv with mount directory and execute command
+     * @param argv
+     * @return application's return code
+     *
+     * Replace any standalone occurrence of '{}' in argv with the snapshot's 
mount directory
+     * and execute the given command *outside* of the snapshot in the running 
system. This may
+     * be useful if the command needs access to the current environment, e.g. 
to copy a file
+     * from a directory not accessible from within the chroot environment.
+     * The application's output will be printed to the corresponding streams.
+     *
+     * Note that @param is following the default C style syntax:
+     * @example: char *args[] = {(char*)"zypper", (char*)"-R", (char*)"{}", 
(char*)"up", NULL};
+                 int status = transaction.execute(args);
+     */
+    int callExt(char* argv[]);
+
+    /**
      * @brief Close a transaction and set it as the new default snapshot
      *
      * Note that it is necessary to call this method if the snapshot is 
supposed to be kept.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/transactional-update-3.1.4/sbin/transactional-update.in 
new/transactional-update-3.2.0/sbin/transactional-update.in
--- old/transactional-update-3.1.4/sbin/transactional-update.in 2021-02-17 
09:41:55.000000000 +0100
+++ new/transactional-update-3.2.0/sbin/transactional-update.in 2021-03-03 
00:56:13.000000000 +0100
@@ -101,7 +101,6 @@
            log_error "ERROR: Couldn't create temporary directory for 
self-update."
            quit 1
        fi
-       export TA_UPDATE_TMPFILE
        pushd "${TA_UPDATE_TMPFILE}" >/dev/null
        zypper --non-interactive --pkg-cache-dir "${TA_UPDATE_TMPFILE}" 
download transactional-update
        find . -name transactional-update*.rpm -exec rpm2cpio {} \; | cpio 
-idmv 2>/dev/null
@@ -111,6 +110,12 @@
        fi
        # Reset CWD before restart
        popd >/dev/null
+       if ! "${TA_UPDATE_TMPFILE}/usr/sbin/transactional-update" --version 
>/dev/null; then
+           log_error "Cannot execute updated transactional-update - skipping"
+           rm -rf "${TA_UPDATE_TMPFILE}"
+           return
+       fi
+       export TA_UPDATE_TMPFILE
        exec "${TA_UPDATE_TMPFILE}/usr/sbin/transactional-update" "$@"
     fi
 }
@@ -252,12 +257,6 @@
 quit() {
     teardown
 
-    # Exit open transaction (used by zypper commands)
-    pkill -f "tu_keep-transaction-alive 1d"
-    while pgrep -f tukit >/dev/null; do
-       sleep 0.5
-    done
-
     if [ -n "${SNAPSHOT_ID}" ] ; then
        log_error "Removing snapshot #${SNAPSHOT_ID}..."
        tukit abort ${SNAPSHOT_ID} |& tee -a ${LOGFILE}
@@ -360,7 +359,7 @@
     # If VARDIR is part of the root file system (usually on rw systems), then
     # create the file in the new snapshot
     if [ "$(findmnt --noheadings --output TARGET --target "${VARDIR}")" = "/" 
]; then
-        VARDIR="${SNAPSHOT_DIR}/${VARDIR}"
+        VARDIR="${SNAPSHOT_DIR}${VARDIR}"
     fi
     test -d "${VARDIR}" || mkdir -p "${VARDIR}"
     touch "${VARDIR}/check-registration"
@@ -878,8 +877,13 @@
        fi
     fi
 
-    SNAPSHOT_ID=`tukit -c"${BASE_SNAPSHOT_ID}" open | grep -e "^ID:" | cut -d 
" " -f 2-`
-    SNAPSHOT_DIR="/.snapshots/${SNAPSHOT_ID}/snapshot/"
+    output="`tukit -c"${BASE_SNAPSHOT_ID}" open |& tee -a ${LOGFILE}`"
+    echo "$output"
+    SNAPSHOT_ID=`echo "${output}" | grep -e "^ID:" | cut -d " " -f 2-`
+    if [ -z ${SNAPSHOT_ID} ]; then
+       quit 1
+    fi
+    SNAPSHOT_DIR="/.snapshots/${SNAPSHOT_ID}/snapshot"
 
     # Remember all snapshots we create for update. If transactional-update is
     # run several times before a reboot, we need to clean up the unused
@@ -910,34 +914,20 @@
        else
            # Check if there are updates at all.
            TMPFILE=`mktemp ${TMPDIR}/transactional-update.XXXXXXXXXX`
-           tukit call "${SNAPSHOT_ID}" bash -c 'exec -a 
tu_keep-transaction-alive sleep 1d' &
-           while ! pgrep -f "tu_keep-transaction-alive 1d" >/dev/null; do
-               sleep 0.5
-           done
-           BINDMNT=$(realpath /proc/$(pgrep -fn 
tu_keep-transaction-alive)/root)
-           echo zypper -R ${BINDMNT} --xmlout ${ZYPPER_ARG} -y 
--auto-agree-with-product-licenses --dry-run "${ZYPPER_ARG_PKGS[@]}" > 
${TMPFILE}
-           zypper -R ${BINDMNT} --xmlout ${ZYPPER_ARG} -y 
--auto-agree-with-product-licenses --dry-run "${ZYPPER_ARG_PKGS[@]}" > 
${TMPFILE}
+           tukit callext "${SNAPSHOT_ID}" zypper -R {} --xmlout ${ZYPPER_ARG} 
-y --auto-agree-with-product-licenses --dry-run "${ZYPPER_ARG_PKGS[@]}" > 
${TMPFILE}
            PACKAGE_UPDATES=`grep "install-summary download-size" ${TMPFILE} | 
sed -e 's|.*install-summary download-size=\"\(.*\)\" space-usage-diff.*|\1|g'`
            SIZE_OF_UPDATES=`grep "install-summary.*space-usage-diff" 
${TMPFILE} | sed -e 
's|.*install-summary.*space-usage-diff=\"\([^"]*\)\".*|\1|g'`
            NUM_OF_UPDATES=`grep "install-summary.*packages-to-change" 
${TMPFILE} | sed -e 
's|.*install-summary.*packages-to-change=\"\([^"]*\)\".*|\1|g'`
            rm -f ${TMPFILE}
            
TELEM_PAYLOAD="${TELEM_PAYLOAD}\npackages=${NUM_OF_UPDATES}\ndownload_size=${PACKAGE_UPDATES}\nspace-usage=${SIZE_OF_UPDATES}"
            if [ "${NUM_OF_UPDATES}" = "0" ] || [ -z "${NUM_OF_UPDATES}" -a 
"${PACKAGE_UPDATES}" = "0" -a "${SIZE_OF_UPDATES}" = "0" ]; then
-               pkill -f "tu_keep-transaction-alive 1d"
-               while pgrep -f tukit >/dev/null; do
-                   sleep 0.5
-               done
                log_info "zypper: nothing to update"
                quit 0
            fi
 
            export DISABLE_RESTART_ON_UPDATE=yes
-           zypper -R ${BINDMNT} ${ZYPPER_ARG} ${ZYPPER_NONINTERACTIVE} 
"${ZYPPER_ARG_PKGS[@]}" |& tee -a ${LOGFILE}
+           tukit callext "${SNAPSHOT_ID}" zypper -R {} ${ZYPPER_ARG} 
${ZYPPER_NONINTERACTIVE} "${ZYPPER_ARG_PKGS[@]}" |& tee -a ${LOGFILE}
            RETVAL=${PIPESTATUS[0]}
-           pkill -f "tu_keep-transaction-alive 1d"
-           while pgrep -f tukit >/dev/null; do
-               sleep 0.5
-           done
        fi
        # in case of migration, we need to do a little bit more:
        if [ ${DO_MIGRATION} -eq 1 ]; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/transactional-update-3.1.4/tukit/tukit.cpp 
new/transactional-update-3.2.0/tukit/tukit.cpp
--- old/transactional-update-3.1.4/tukit/tukit.cpp      2021-02-17 
09:41:55.000000000 +0100
+++ new/transactional-update-3.2.0/tukit/tukit.cpp      2021-03-03 
00:56:13.000000000 +0100
@@ -35,9 +35,14 @@
     cout << "open\n";
     cout << "\tCreates a new transaction and prints its unique ID\n";
     cout << "call <ID> <command>\n";
-    cout << "\tExecutes the given command, resuming the transaction with the 
given ID; returns\n";
-    cout << "\tthe exit status of the given command, but will not delete the 
snapshot in case\n";
-    cout << "\tof errors\n";
+    cout << "\tExecutes the given command from within the transaction's chroot 
environment,\n";
+    cout << "\tresuming the transaction with the given ID; returns the exit 
status of the\n";
+    cout << "\tgiven command, but will not delete the snapshot in case of 
errors\n";
+    cout << "callext <ID> <command>\n";
+    cout << "\tExecutes the given command. The command is not executed in a 
chroot\n";
+    cout << "\tenvironment, but instead runs in the current system, replacing 
'{}' with the\n";
+    cout << "\tmount directory of the given snapshot; returns the exit status 
of the given\n";
+    cout << "\tcommand, but will not delete the snapshot in case of errors\n";
     cout << "close <ID>\n";
     cout << "\tCloses the given transaction and sets the snapshot as the new 
default snapshot\n";
     cout << "abort <ID>\n";
@@ -96,6 +101,9 @@
 int TUKit::processCommand(char *argv[]) {
     TransactionalUpdate::Transaction transaction{};
 
+    if (argv[0] == nullptr) {
+        throw invalid_argument{"Missing command. See --help for usage 
information."};
+    }
     string arg = argv[0];
     if (arg == "execute") {
         transaction.init(baseSnapshot);
@@ -123,6 +131,16 @@
         transaction.keep();
         return status;
     }
+    else if (arg == "callext") {
+        if (argv[1] == nullptr) {
+            displayHelp();
+            throw invalid_argument{"Missing argument for 'callext'"};
+        }
+        transaction.resume(argv[1]);
+        int status = transaction.callExt(&argv[2]); // All remaining arguments
+        transaction.keep();
+        return status;
+    }
     else if (arg == "close") {
         transaction.resume(argv[1]);
         transaction.finalize();

Reply via email to