From 53f1938a1c33b4d9e333101d1d614803373a6bc5 Mon Sep 17 00:00:00 2001 From: Harm Weites Date: Fri, 6 Dec 2013 21:25:04 +0000 Subject: new: FreeBSD module to support cloud-init on the FBSD10 platform. In its current form its still missing some modules though. Supported: -SSH-keys -growpart -growfs -adduser -powerstate --- cloudinit/config/cc_growpart.py | 40 +++++++++++++++++++++++++++++-- cloudinit/config/cc_power_state_change.py | 32 +++++++++++++++++++------ cloudinit/config/cc_resizefs.py | 7 +++++- 3 files changed, 69 insertions(+), 10 deletions(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py index 0dd92a46..81de4c37 100644 --- a/cloudinit/config/cc_growpart.py +++ b/cloudinit/config/cc_growpart.py @@ -22,6 +22,7 @@ import os import os.path import re import stat +import sys from cloudinit import log as logging from cloudinit.settings import PER_ALWAYS @@ -137,6 +138,35 @@ class ResizeGrowPart(object): return (before, get_size(partdev)) +class ResizeGpart(object): + def available(self): + if not os.path.exists('/usr/local/sbin/gpart'): + return False + return True + + def resize(self, diskdev, partnum, partdev): + """ + GPT disks store metadata at the beginning (primary) and at the + end (secondary) of the disk. When launching an image with a + larger disk compared to the original image, the secondary copy + is lost. Thus, the metadata will be marked CORRUPT, and need to + be recovered. + """ + try: + util.subp(["gpart", "recover", diskdev]) + except util.ProcessExecutionError as e: + if e.exit_code != 0: + util.logexc(LOG, "Failed: gpart recover %s", diskdev) + raise ResizeFailedException(e) + + before = get_size(partdev) + try: + util.subp(["gpart", "resize", "-i", partnum, diskdev]) + except util.ProcessExecutionError as e: + util.logexc(LOG, "Failed: gpart resize -i %s %s", partnum, diskdev) + raise ResizeFailedException(e) + + return (before, get_size(partdev)) def get_size(filename): fd = os.open(filename, os.O_RDONLY) @@ -156,6 +186,12 @@ def device_part_info(devpath): bname = os.path.basename(rpath) syspath = "/sys/class/block/%s" % bname + # FreeBSD doesn't know of sysfs so just get everything we need from + # the device, like /dev/vtbd0p2. + if sys.platform.startswith('freebsd'): + m = re.search('^(/dev/.+)p([0-9])$', devpath) + return (m.group(1), m.group(2)) + if not os.path.exists(syspath): raise ValueError("%s had no syspath (%s)" % (devpath, syspath)) @@ -206,7 +242,7 @@ def resize_devices(resizer, devices): "stat of '%s' failed: %s" % (blockdev, e),)) continue - if not stat.S_ISBLK(statret.st_mode): + if not stat.S_ISBLK(statret.st_mode) and not stat.S_ISCHR(statret.st_mode): info.append((devent, RESIZE.SKIPPED, "device '%s' not a block device" % blockdev,)) continue @@ -281,4 +317,4 @@ def handle(_name, cfg, _cloud, log, _args): # LP: 1212444 FIXME re-order and favor ResizeParted #RESIZERS = (('growpart', ResizeGrowPart),) -RESIZERS = (('growpart', ResizeGrowPart), ('parted', ResizeParted)) +RESIZERS = (('growpart', ResizeGrowPart), ('parted', ResizeParted), ('gpart', ResizeGpart)) diff --git a/cloudinit/config/cc_power_state_change.py b/cloudinit/config/cc_power_state_change.py index e3150808..46ce5ba5 100644 --- a/cloudinit/config/cc_power_state_change.py +++ b/cloudinit/config/cc_power_state_change.py @@ -23,12 +23,34 @@ import errno import os import re import subprocess +import sys import time frequency = PER_INSTANCE EXIT_FAIL = 254 +# +# Returns the cmdline for the given process id. +# + +def givecmdline(pid): + # Check if this pid still exists by sending it the harmless 0 signal. + try: + os.kill(pid, 0) + except OSError: + return None + else: + # Example output from procstat -c 16357 + # PID COMM ARGS + # 1 init /bin/init -- + if sys.platform.startswith('freebsd'): + (output, _err) = util.subp(['procstat', '-c', str(pid)]) + line = output.splitlines()[1] + m = re.search('\d+ (\w|\.|-)+\s+(/\w.+)', line) + return m.group(2) + else: + return util.load_file("/proc/%s/cmdline" % pid) def handle(_name, cfg, _cloud, log, _args): @@ -42,8 +64,8 @@ def handle(_name, cfg, _cloud, log, _args): return mypid = os.getpid() - cmdline = util.load_file("/proc/%s/cmdline" % mypid) + cmdline = givecmdline(mypid) if not cmdline: log.warn("power_state: failed to get cmdline of current process") return @@ -119,8 +141,6 @@ def run_after_pid_gone(pid, pidcmdline, timeout, log, func, args): msg = None end_time = time.time() + timeout - cmdline_f = "/proc/%s/cmdline" % pid - def fatal(msg): if log: log.warn(msg) @@ -134,16 +154,14 @@ def run_after_pid_gone(pid, pidcmdline, timeout, log, func, args): break try: - cmdline = "" - with open(cmdline_f) as fp: - cmdline = fp.read() + cmdline = givecmdline(pid) if cmdline != pidcmdline: msg = "cmdline changed for %s [now: %s]" % (pid, cmdline) break except IOError as ioerr: if ioerr.errno in known_errnos: - msg = "pidfile '%s' gone [%d]" % (cmdline_f, ioerr.errno) + msg = "pidfile gone [%d]" % ioerr.errno else: fatal("IOError during wait: %s" % ioerr) break diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py index 56040fdd..95bc7a4e 100644 --- a/cloudinit/config/cc_resizefs.py +++ b/cloudinit/config/cc_resizefs.py @@ -39,6 +39,10 @@ def _resize_ext(mount_point, devpth): # pylint: disable=W0613 def _resize_xfs(mount_point, devpth): # pylint: disable=W0613 return ('xfs_growfs', devpth) + +def _resize_ufs(mount_point, devpth): # pylint: disable=W0613 + return ('growfs', devpth) + # Do not use a dictionary as these commands should be able to be used # for multiple filesystem types if possible, e.g. one command for # ext2, ext3 and ext4. @@ -46,6 +50,7 @@ RESIZE_FS_PREFIXES_CMDS = [ ('btrfs', _resize_btrfs), ('ext', _resize_ext), ('xfs', _resize_xfs), + ('ufs', _resize_ufs), ] NOBLOCK = "noblock" @@ -91,7 +96,7 @@ def handle(name, cfg, _cloud, log, args): raise exc return - if not stat.S_ISBLK(statret.st_mode): + if not stat.S_ISBLK(statret.st_mode) and not stat.S_ISCHR(statret.st_mode): if util.is_container(): log.debug("device '%s' not a block device in container." " cannot resize: %s" % (devpth, info)) -- cgit v1.2.3 From 43b88392a14f6ab9395313353e28e60acc85ab75 Mon Sep 17 00:00:00 2001 From: Harm Weites Date: Sat, 14 Dec 2013 19:11:47 +0000 Subject: change: Use util.system_info(). --- cloudinit/config/cc_growpart.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py index 81de4c37..07556f03 100644 --- a/cloudinit/config/cc_growpart.py +++ b/cloudinit/config/cc_growpart.py @@ -22,7 +22,6 @@ import os import os.path import re import stat -import sys from cloudinit import log as logging from cloudinit.settings import PER_ALWAYS @@ -188,7 +187,7 @@ def device_part_info(devpath): # FreeBSD doesn't know of sysfs so just get everything we need from # the device, like /dev/vtbd0p2. - if sys.platform.startswith('freebsd'): + if util.system_info()["platform"].startswith('FreeBSD'): m = re.search('^(/dev/.+)p([0-9])$', devpath) return (m.group(1), m.group(2)) -- cgit v1.2.3 From bd96af406f268e3fe41537125be4cf2dfc9ea5bc Mon Sep 17 00:00:00 2001 From: Harm Weites Date: Sat, 14 Dec 2013 19:14:18 +0000 Subject: new: Touch a reboot-required file to make clear we want a reboot after resizing the partition. --- cloudinit/config/cc_growpart.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py index 07556f03..29d8b49b 100644 --- a/cloudinit/config/cc_growpart.py +++ b/cloudinit/config/cc_growpart.py @@ -165,6 +165,10 @@ class ResizeGpart(object): util.logexc(LOG, "Failed: gpart resize -i %s %s", partnum, diskdev) raise ResizeFailedException(e) + # Since growing the FS requires a reboot, make sure we reboot + # first when this module has finished. + open('/var/run/reboot-required', 'a').close() + return (before, get_size(partdev)) def get_size(filename): -- cgit v1.2.3 From 8a2b80adfb66f9036dc617ff65b7f6ab4464ca5d Mon Sep 17 00:00:00 2001 From: Harm Weites Date: Sat, 14 Dec 2013 19:16:05 +0000 Subject: change: Use util.system_info(). --- cloudinit/config/cc_power_state_change.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_power_state_change.py b/cloudinit/config/cc_power_state_change.py index 46ce5ba5..8efef24b 100644 --- a/cloudinit/config/cc_power_state_change.py +++ b/cloudinit/config/cc_power_state_change.py @@ -23,7 +23,6 @@ import errno import os import re import subprocess -import sys import time frequency = PER_INSTANCE @@ -44,7 +43,7 @@ def givecmdline(pid): # Example output from procstat -c 16357 # PID COMM ARGS # 1 init /bin/init -- - if sys.platform.startswith('freebsd'): + if util.system_info()["platform"].startswith('FreeBSD'): (output, _err) = util.subp(['procstat', '-c', str(pid)]) line = output.splitlines()[1] m = re.search('\d+ (\w|\.|-)+\s+(/\w.+)', line) -- cgit v1.2.3 From 76756d5985cac6d0d8eafbbc336dc140cb3ecb1d Mon Sep 17 00:00:00 2001 From: Harm Weites Date: Sat, 14 Dec 2013 22:30:29 +0000 Subject: change: Use a proper signal instead of 'just' 0. --- cloudinit/config/cc_power_state_change.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_power_state_change.py b/cloudinit/config/cc_power_state_change.py index 8efef24b..2797b3d9 100644 --- a/cloudinit/config/cc_power_state_change.py +++ b/cloudinit/config/cc_power_state_change.py @@ -22,6 +22,7 @@ from cloudinit import util import errno import os import re +import signal import subprocess import time @@ -36,7 +37,7 @@ EXIT_FAIL = 254 def givecmdline(pid): # Check if this pid still exists by sending it the harmless 0 signal. try: - os.kill(pid, 0) + os.kill(pid, signal.SIG_DFL) except OSError: return None else: -- cgit v1.2.3 From d6dcee2a818b97ccae8cd662cf108e954fc89e5c Mon Sep 17 00:00:00 2001 From: Harm Weites Date: Sat, 14 Dec 2013 22:31:32 +0000 Subject: fix: Proper comment. --- cloudinit/config/cc_power_state_change.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_power_state_change.py b/cloudinit/config/cc_power_state_change.py index 2797b3d9..50897b5f 100644 --- a/cloudinit/config/cc_power_state_change.py +++ b/cloudinit/config/cc_power_state_change.py @@ -41,7 +41,7 @@ def givecmdline(pid): except OSError: return None else: - # Example output from procstat -c 16357 + # Example output from procstat -c 1 # PID COMM ARGS # 1 init /bin/init -- if util.system_info()["platform"].startswith('FreeBSD'): -- cgit v1.2.3 From d5613a54c27f3b494c7012dbdd68635a112e1e57 Mon Sep 17 00:00:00 2001 From: Harm Weites Date: Sat, 14 Dec 2013 22:49:32 +0000 Subject: change: Just run the required command and let the exception do the rest if the process died. Checking first if the process is still alive proofed to be quite error prone, atleast on a rather slow compute node. --- cloudinit/config/cc_power_state_change.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_power_state_change.py b/cloudinit/config/cc_power_state_change.py index 50897b5f..6bd14b7e 100644 --- a/cloudinit/config/cc_power_state_change.py +++ b/cloudinit/config/cc_power_state_change.py @@ -31,16 +31,12 @@ frequency = PER_INSTANCE EXIT_FAIL = 254 # -# Returns the cmdline for the given process id. +# Returns the cmdline for the given process id. In Linux we can use procfs for +# this but on BSD there is /usr/bin/procstat. # def givecmdline(pid): - # Check if this pid still exists by sending it the harmless 0 signal. try: - os.kill(pid, signal.SIG_DFL) - except OSError: - return None - else: # Example output from procstat -c 1 # PID COMM ARGS # 1 init /bin/init -- @@ -51,6 +47,8 @@ def givecmdline(pid): return m.group(2) else: return util.load_file("/proc/%s/cmdline" % pid) + except IOError: + return None def handle(_name, cfg, _cloud, log, _args): -- cgit v1.2.3 From 84514cdff8ff025df052fe6301d2a7ed751d7d61 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 22 Jan 2014 16:54:07 -0500 Subject: cc_resizefs: figure out what /dev/root means via kernel cmdline If mount_info says that the root filesystem is on /dev/root and /dev/root does not exist, then we'll try to glean that information from the linux kernel cmdline. This situation occurs at least when you boot without an initramfs for the current ppc64el cloud images: qemu-system-ppc64 ... -kernel my.kernel -append 'root=/dev/sda' When doing that, /proc/1/mountinfo will say '/dev/root' for '/'. --- ChangeLog | 2 ++ cloudinit/config/cc_resizefs.py | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'cloudinit/config') diff --git a/ChangeLog b/ChangeLog index cb9586f0..32f2a8d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,8 @@ - drop dependency on boto for crawling ec2 metadata service. - add 'Requires' on sudo (for OpenNebula datasource) in rpm specs, and 'Recommends' in the debian/control.in [Vlastimil Holer] + - if mount_info reports /dev/root is a device path for /, then convert + that to a device via help of kernel cmdline. 0.7.4: - fix issue mounting 'ephemeral0' if ephemeral0 was an alias for a partitioned block device with target filesystem on ephemeral0.1. diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py index 56040fdd..388ca66f 100644 --- a/cloudinit/config/cc_resizefs.py +++ b/cloudinit/config/cc_resizefs.py @@ -51,6 +51,25 @@ RESIZE_FS_PREFIXES_CMDS = [ NOBLOCK = "noblock" +def rootdev_from_cmdline(cmdline): + found = None + for tok in cmdline.split(): + if tok.startswith("root="): + found = tok[5:] + break + if found is None: + return None + + if found.startswith("/dev/"): + return found + if found.startswith("LABEL="): + return "/dev/disk/by-label/" + found[len("LABEL="):] + if found.startswith("UUID="): + return "/dev/disk/by-uuid/" + found[len("UUID="):] + + return "/dev/" + found + + def handle(name, cfg, _cloud, log, args): if len(args) != 0: resize_root = args[0] @@ -78,10 +97,20 @@ def handle(name, cfg, _cloud, log, args): info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) log.debug("resize_info: %s" % info) + container = util.is_container() + + if (devpth == "/dev/root" and not os.path.exists(devpth) and + not container): + devpth = rootdev_from_cmdline(util.get_cmdline()) + if devpth is None: + log.warn("Unable to find device '/dev/root'") + return + log.debug("Converted /dev/root to '%s' per kernel cmdline", devpth) + try: statret = os.stat(devpth) except OSError as exc: - if util.is_container() and exc.errno == errno.ENOENT: + if container and exc.errno == errno.ENOENT: log.debug("Device '%s' did not exist in container. " "cannot resize: %s" % (devpth, info)) elif exc.errno == errno.ENOENT: @@ -92,7 +121,7 @@ def handle(name, cfg, _cloud, log, args): return if not stat.S_ISBLK(statret.st_mode): - if util.is_container(): + if container: log.debug("device '%s' not a block device in container." " cannot resize: %s" % (devpth, info)) else: -- cgit v1.2.3 From c833a84f08019ba4413937f2f1b1f12a4ffe5632 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Thu, 23 Jan 2014 14:28:59 -0500 Subject: pep8 --- cloudinit/config/cc_debug.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_debug.py b/cloudinit/config/cc_debug.py index cfd31fa1..7219b0f8 100644 --- a/cloudinit/config/cc_debug.py +++ b/cloudinit/config/cc_debug.py @@ -14,10 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from StringIO import StringIO -from cloudinit import util from cloudinit import type_utils +from cloudinit import util import copy +from StringIO import StringIO def _make_header(text): -- cgit v1.2.3 From 5323320a7251b124c231ba6be25b8583535f1b62 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Thu, 23 Jan 2014 16:13:09 -0500 Subject: pep8, use which rather than hard coded path --- cloudinit/config/cc_growpart.py | 6 ++++-- cloudinit/config/cc_power_state_change.py | 7 +++---- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py index 1d3a4412..b81951ad 100644 --- a/cloudinit/config/cc_growpart.py +++ b/cloudinit/config/cc_growpart.py @@ -113,9 +113,10 @@ class ResizeGrowPart(object): return (before, get_size(partdev)) + class ResizeGpart(object): def available(self): - if not os.path.exists('/usr/local/sbin/gpart'): + if not util.which('gpart'): return False return True @@ -138,7 +139,7 @@ class ResizeGpart(object): try: util.subp(["gpart", "resize", "-i", partnum, diskdev]) except util.ProcessExecutionError as e: - util.logexc(LOG, "Failed: gpart resize -i %s %s", partnum, diskdev) + util.logexc(LOG, "Failed: gpart resize -i %s %s", partnum, diskdev) raise ResizeFailedException(e) # Since growing the FS requires a reboot, make sure we reboot @@ -147,6 +148,7 @@ class ResizeGpart(object): return (before, get_size(partdev)) + def get_size(filename): fd = os.open(filename, os.O_RDONLY) try: diff --git a/cloudinit/config/cc_power_state_change.py b/cloudinit/config/cc_power_state_change.py index 6bd14b7e..561c5abd 100644 --- a/cloudinit/config/cc_power_state_change.py +++ b/cloudinit/config/cc_power_state_change.py @@ -30,12 +30,10 @@ frequency = PER_INSTANCE EXIT_FAIL = 254 -# -# Returns the cmdline for the given process id. In Linux we can use procfs for -# this but on BSD there is /usr/bin/procstat. -# def givecmdline(pid): + # Returns the cmdline for the given process id. In Linux we can use procfs + # for this but on BSD there is /usr/bin/procstat. try: # Example output from procstat -c 1 # PID COMM ARGS @@ -50,6 +48,7 @@ def givecmdline(pid): except IOError: return None + def handle(_name, cfg, _cloud, log, _args): try: -- cgit v1.2.3 From 4919cd124e57e82ecfcdaa9bfcbc051c719708e6 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 24 Jan 2014 15:29:09 -0500 Subject: pylint and long line fixes. This fixes up many long lines to be < 80 chars and some other pylint issues. pylint 1.1 (in trusty) is now complaining about the lazy logging, so I'll clean that up when I touch things. --- cloudinit/config/cc_growpart.py | 3 +- cloudinit/distros/freebsd.py | 47 +++++++++++----------- cloudinit/netinfo.py | 30 ++++++-------- cloudinit/user_data.py | 3 +- cloudinit/util.py | 12 +++--- .../unittests/test_datasource/test_configdrive.py | 2 +- 6 files changed, 49 insertions(+), 48 deletions(-) (limited to 'cloudinit/config') diff --git a/cloudinit/config/cc_growpart.py b/cloudinit/config/cc_growpart.py index b81951ad..f52c41f0 100644 --- a/cloudinit/config/cc_growpart.py +++ b/cloudinit/config/cc_growpart.py @@ -223,7 +223,8 @@ def resize_devices(resizer, devices): "stat of '%s' failed: %s" % (blockdev, e),)) continue - if not stat.S_ISBLK(statret.st_mode) and not stat.S_ISCHR(statret.st_mode): + if (not stat.S_ISBLK(statret.st_mode) and + not stat.S_ISCHR(statret.st_mode)): info.append((devent, RESIZE.SKIPPED, "device '%s' not a block device" % blockdev,)) continue diff --git a/cloudinit/distros/freebsd.py b/cloudinit/distros/freebsd.py index d28860eb..4c0c6d29 100644 --- a/cloudinit/distros/freebsd.py +++ b/cloudinit/distros/freebsd.py @@ -16,15 +16,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import re + from cloudinit import distros from cloudinit import helpers from cloudinit import log as logging -from cloudinit import netinfo from cloudinit import ssh_util from cloudinit import util -from cloudinit.settings import PER_INSTANCE - LOG = logging.getLogger(__name__) @@ -39,26 +38,27 @@ class Distro(distros.Distro): # Updates a key in /etc/rc.conf. def updatercconf(self, key, value): - LOG.debug("updatercconf: %s => %s" % (key, value)) + LOG.debug("updatercconf: %s => %s", key, value) conf = self.loadrcconf() configchanged = False for item in conf: if item == key and conf[item] != value: conf[item] = value - LOG.debug("[rc.conf]: Value %s for key %s needs to be changed" % (value, key)) + LOG.debug("[rc.conf]: Value %s for key %s needs to be changed", + value, key) configchanged = True if configchanged: LOG.debug("Writing new /etc/rc.conf file") - with open('/etc/rc.conf', 'w') as file: + with open('/etc/rc.conf', 'w') as fp: for keyval in conf.items(): - file.write("%s=%s\n" % keyval) + fp.write("%s=%s\n" % keyval) # Load the contents of /etc/rc.conf and store all keys in a dict. def loadrcconf(self): conf = {} - with open("/etc/rc.conf") as file: - for line in file: + with open("/etc/rc.conf") as fp: + for line in fp: tok = line.split('=') conf[tok[0]] = tok[1].rstrip() return conf @@ -75,7 +75,7 @@ class Distro(distros.Distro): sys_hostname = self._read_hostname() return ('rc.conf', sys_hostname) - def _read_hostname(self, default=None): + def _read_hostname(self, filename, default=None): hostname = None try: hostname = self.readrcconf('hostname') @@ -90,17 +90,17 @@ class Distro(distros.Distro): return fqdn return hostname - def _write_hostname(self, your_hostname, out_fn): - self.updatercconf('hostname', your_hostname) + def _write_hostname(self, hostname, filename): + self.updatercconf('hostname', hostname) def create_group(self, name, members): group_add_cmd = ['pw', '-n', name] if util.is_group(name): - LOG.warn("Skipping creation of existing group '%s'" % name) + LOG.warn("Skipping creation of existing group '%s'", name) else: try: util.subp(group_add_cmd) - LOG.info("Created new group %s" % name) + LOG.info("Created new group %s", name) except Exception: util.logexc("Failed to create group %s", name) @@ -111,11 +111,11 @@ class Distro(distros.Distro): "; user does not exist.", member, name) continue util.subp(['pw', 'usermod', '-n', name, '-G', member]) - LOG.info("Added user '%s' to group '%s'" % (member, name)) + LOG.info("Added user '%s' to group '%s'", member, name) def add_user(self, name, **kwargs): if util.is_user(name): - LOG.info("User %s already exists, skipping." % name) + LOG.info("User %s already exists, skipping.", name) return False adduser_cmd = ['pw', 'useradd', '-n', name] @@ -170,7 +170,7 @@ class Distro(distros.Distro): raise e # TODO: - def set_passwd(self, name, **kwargs): + def set_passwd(self, user, passwd, hashed=False): return False def lock_passwd(self, name): @@ -182,7 +182,7 @@ class Distro(distros.Distro): # TODO: def write_sudo_rules(self, name, rules, sudo_file=None): - LOG.debug("[write_sudo_rules] Name: %s" % name) + LOG.debug("[write_sudo_rules] Name: %s", name) def create_user(self, name, **kwargs): self.add_user(name, **kwargs) @@ -217,7 +217,8 @@ class Distro(distros.Distro): origconf = open(loginconf, 'r') for line in origconf: - newconf.write(re.sub('^default:', r'default:lang=%s:' % locale, line)) + newconf.write(re.sub(r'^default:', + r'default:lang=%s:' % locale, line)) newconf.close() origconf.close() # Make a backup of login.conf. @@ -233,14 +234,14 @@ class Distro(distros.Distro): util.logexc("Failed to apply locale %s", locale) copyfile(backupconf, loginconf) - def install_packages(): + def install_packages(self, pkglist): return - def package_command(): + def package_command(self, cmd, args=None, pkgs=None): return - def set_timezone(): + def set_timezone(self, tz): return - def update_package_sources(): + def update_package_sources(self): return diff --git a/cloudinit/netinfo.py b/cloudinit/netinfo.py index 63f720e4..ac3c011f 100644 --- a/cloudinit/netinfo.py +++ b/cloudinit/netinfo.py @@ -44,7 +44,7 @@ def netdev_info(empty=""): # If the output of ifconfig doesn't contain the required info in the # obvious place, use a regex filter to be sure. elif len(toks) > 1: - if re.search("flags=\d+ %r" % (link, source)) + LOG.debug("Creating symbolic link from %r => %r", link, source) os.symlink(source, link) @@ -1444,7 +1445,8 @@ def uptime(): size = ctypes.c_size_t() buf = ctypes.c_int() size.value = ctypes.sizeof(buf) - libc.sysctlbyname("kern.boottime", ctypes.byref(buf), ctypes.byref(size), None, 0) + libc.sysctlbyname("kern.boottime", ctypes.byref(buf), + ctypes.byref(size), None, 0) now = time.time() bootup = buf.value uptime_str = now - bootup @@ -1793,7 +1795,7 @@ def parse_mount(path): (mountoutput, _err) = subp("mount") mount_locs = mountoutput.splitlines() for line in mount_locs: - m = re.search('^(/dev/[\S]+) on (/.*) \((.+), .+, (.+)\)$', line) + m = re.search(r'^(/dev/[\S]+) on (/.*) \((.+), .+, (.+)\)$', line) devpth = m.group(1) mount_point = m.group(2) fs_type = m.group(3) diff --git a/tests/unittests/test_datasource/test_configdrive.py b/tests/unittests/test_datasource/test_configdrive.py index 3c1e8add..1f4a0a0b 100644 --- a/tests/unittests/test_datasource/test_configdrive.py +++ b/tests/unittests/test_datasource/test_configdrive.py @@ -285,7 +285,7 @@ class TestConfigDriveDataSource(MockerTestCase): self.assertEqual(["/dev/vdb", "/dev/zdd"], ds.find_candidate_devs()) - # verify that partitions are considered, but only if they have a label. + # verify that partitions are considered, that have correct label. devs_with_answers = {"TYPE=vfat": ["/dev/sda1"], "TYPE=iso9660": [], "LABEL=config-2": ["/dev/vdb3"]} self.assertEqual(["/dev/vdb3"], -- cgit v1.2.3