summaryrefslogtreecommitdiff
path: root/cloudinit/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r--cloudinit/util.py64
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)