diff options
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r-- | cloudinit/util.py | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py index 4a74ba57..a8ddb390 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -32,6 +32,7 @@ import grp import gzip import hashlib import os +import os.path import platform import pwd import random @@ -161,13 +162,13 @@ class SeLinuxGuard(object): self.recursive = recursive def __enter__(self): - if self.selinux: + if self.selinux and self.selinux.is_selinux_enabled(): return True else: return False def __exit__(self, excp_type, excp_value, excp_traceback): - if self.selinux: + if self.selinux and self.selinux.is_selinux_enabled(): path = os.path.realpath(os.path.expanduser(self.path)) do_restore = False try: @@ -360,11 +361,21 @@ def multi_log(text, console=True, stderr=True, if stderr: sys.stderr.write(text) if console: - # Don't use the write_file since - # this might be 'sensitive' info (not debug worthy?) - with open('/dev/console', 'wb') as wfh: - wfh.write(text) - wfh.flush() + conpath = "/dev/console" + if os.path.exists(conpath): + with open(conpath, 'wb') as wfh: + wfh.write(text) + wfh.flush() + else: + # A container may lack /dev/console (arguably a container bug). If + # it does not exist, then write output to stdout. this will result + # in duplicate stderr and stdout messages if stderr was True. + # + # even though upstart or systemd might have set up output to go to + # /dev/console, the user may have configured elsewhere via + # cloud-config 'output'. If there is /dev/console, messages will + # still get there. + sys.stdout.write(text) if log: if text[-1] == "\n": log.log(log_level, text[:-1]) @@ -955,6 +966,13 @@ def get_hostname(): return hostname +def gethostbyaddr(ip): + try: + return socket.gethostbyaddr(ip)[0] + except socket.herror: + return None + + def is_resolvable_url(url): """determine if this url is resolvable (existing or ip).""" return (is_resolvable(urlparse.urlparse(url).hostname)) @@ -1719,6 +1737,15 @@ def parse_mount_info(path, mountinfo_lines, log=LOG): return None +def parse_mtab(path): + """On older kernels there's no /proc/$$/mountinfo, so use mtab.""" + for line in load_file("/etc/mtab").splitlines(): + devpth, mount_point, fs_type = line.split()[:3] + if mount_point == path: + return devpth, fs_type, mount_point + return None + + def get_mount_info(path, log=LOG): # Use /proc/$$/mountinfo to find the device where path is mounted. # This is done because with a btrfs filesystem using os.stat(path) @@ -1749,8 +1776,11 @@ def get_mount_info(path, log=LOG): # So use /proc/$$/mountinfo to find the device underlying the # input path. mountinfo_path = '/proc/%s/mountinfo' % os.getpid() - lines = load_file(mountinfo_path).splitlines() - return parse_mount_info(path, lines, log) + if os.path.exists(mountinfo_path): + lines = load_file(mountinfo_path).splitlines() + return parse_mount_info(path, lines, log) + else: + return parse_mtab(path) def which(program): @@ -1791,17 +1821,29 @@ def log_time(logfunc, msg, func, args=None, kwargs=None, get_uptime=False): ret = func(*args, **kwargs) finally: delta = time.time() - start + udelta = None if ustart is not None: try: udelta = float(uptime()) - ustart except ValueError: - udelta = "N/A" + pass tmsg = " took %0.3f seconds" % delta if get_uptime: - tmsg += "(%0.2f)" % udelta + if isinstance(udelta, (float)): + tmsg += " (%0.2f)" % udelta + else: + tmsg += " (N/A)" try: logfunc(msg + tmsg) except: pass return ret + + +def expand_dotted_devname(dotted): + toks = dotted.rsplit(".", 1) + if len(toks) > 1: + return toks + else: + return (dotted, None) |