--- cloudinit/distros/opensuse.py.orig +++ cloudinit/distros/opensuse.py @@ -9,6 +9,7 @@ # This file is part of cloud-init. See LICENSE file for license information. import logging +import os from cloudinit import distros, helpers, subp, util from cloudinit.distros import rhel_util as rhutil @@ -49,6 +50,7 @@ class Distro(distros.Distro): distros.Distro.__init__(self, name, cfg, paths) self._runner = helpers.Runners(paths) self.osfamily = "suse" + self.update_method = None cfg["ssh_svcname"] = "sshd" if self.uses_systemd(): self.init_cmd = ["systemctl"] @@ -74,12 +76,45 @@ class Distro(distros.Distro): if pkgs is None: pkgs = [] + if self.update_method == None: + result = util.get_mount_info("/") + fs_type = "" + if result: + (devpth, fs_type, mount_point) = result + if ( + fs_type.lower() == 'btrfs' and + os.path.exists("/usr/sbin/transactional-update") + ): + self.update_method = 'transactional' + else: + self.update_method = 'zypper' + else: + LOG.info( + "Could not determine filesystem type of '/' using zypper" + ) + self.update_method = 'zypper' + # No user interaction possible, enable non-interactive mode - cmd = ["zypper", "--non-interactive"] + if self.update_method == 'zypper': + cmd = ["zypper", "--non-interactive"] + else: + cmd = [ + "transactional-update", + "--non-interactive", + "--drop-if-no-change", + "pkg" + ] # Command is the operation, such as install if command == "upgrade": command = "update" + if self.update_method == 'transactional' and not pkgs: + command = "up" + cmd = [ + "transactional-update", + "--non-interactive", + "--drop-if-no-change" + ] cmd.append(command) # args are the arguments to the command, not global options