summaryrefslogtreecommitdiff
path: root/cloudinit/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r--cloudinit/util.py66
1 files changed, 48 insertions, 18 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 02ba654a..0d21e11b 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -76,7 +76,11 @@ FALSE_STRINGS = ('off', '0', 'no', 'false')
# Helper utils to see if running in a container
-CONTAINER_TESTS = ('running-in-container', 'lxc-is-container')
+CONTAINER_TESTS = (['systemd-detect-virt', '--quiet', '--container'],
+ ['running-in-container'],
+ ['lxc-is-container'])
+
+PROC_CMDLINE = None
def decode_binary(blob, encoding='utf-8'):
@@ -610,7 +614,7 @@ def redirect_output(outfmt, errfmt, o_out=None, o_err=None):
def make_url(scheme, host, port=None,
- path='', params='', query='', fragment=''):
+ path='', params='', query='', fragment=''):
pieces = []
pieces.append(scheme or '')
@@ -782,7 +786,8 @@ def read_file_or_url(url, timeout=5, retries=10,
code = e.errno
if e.errno == errno.ENOENT:
code = url_helper.NOT_FOUND
- raise url_helper.UrlError(cause=e, code=code, headers=None)
+ raise url_helper.UrlError(cause=e, code=code, headers=None,
+ url=url)
return url_helper.FileResponse(file_path, contents=contents)
else:
return url_helper.readurl(url,
@@ -801,8 +806,8 @@ def load_yaml(blob, default=None, allowed=(dict,)):
blob = decode_binary(blob)
try:
LOG.debug("Attempting to load yaml from string "
- "of length %s with allowed root types %s",
- len(blob), allowed)
+ "of length %s with allowed root types %s",
+ len(blob), allowed)
converted = safeyaml.load(blob)
if not isinstance(converted, allowed):
# Yes this will just be caught, but thats ok for now...
@@ -875,7 +880,7 @@ def read_conf_with_confd(cfgfile):
if not isinstance(confd, six.string_types):
raise TypeError(("Config file %s contains 'conf_d' "
"with non-string type %s") %
- (cfgfile, type_utils.obj_name(confd)))
+ (cfgfile, type_utils.obj_name(confd)))
else:
confd = str(confd).strip()
elif os.path.isdir("%s.d" % cfgfile):
@@ -1038,7 +1043,8 @@ def is_resolvable(name):
for iname in badnames:
try:
result = socket.getaddrinfo(iname, None, 0, 0,
- socket.SOCK_STREAM, socket.AI_CANONNAME)
+ socket.SOCK_STREAM,
+ socket.AI_CANONNAME)
badresults[iname] = []
for (_fam, _stype, _proto, cname, sockaddr) in result:
badresults[iname].append("%s: %s" % (cname, sockaddr[0]))
@@ -1106,7 +1112,7 @@ def close_stdin():
def find_devs_with(criteria=None, oformat='device',
- tag=None, no_cache=False, path=None):
+ tag=None, no_cache=False, path=None):
"""
find devices matching given criteria (via blkid)
criteria can be *one* of:
@@ -1187,12 +1193,27 @@ def load_file(fname, read_cb=None, quiet=False, decode=True):
def get_cmdline():
if 'DEBUG_PROC_CMDLINE' in os.environ:
- cmdline = os.environ["DEBUG_PROC_CMDLINE"]
+ return os.environ["DEBUG_PROC_CMDLINE"]
+
+ global PROC_CMDLINE
+ if PROC_CMDLINE is not None:
+ return PROC_CMDLINE
+
+ if is_container():
+ try:
+ contents = load_file("/proc/1/cmdline")
+ # replace nulls with space and drop trailing null
+ cmdline = contents.replace("\x00", " ")[:-1]
+ except Exception as e:
+ LOG.warn("failed reading /proc/1/cmdline: %s", e)
+ cmdline = ""
else:
try:
cmdline = load_file("/proc/cmdline").strip()
except:
cmdline = ""
+
+ PROC_CMDLINE = cmdline
return cmdline
@@ -1479,8 +1500,8 @@ def mount_cb(device, callback, data=None, rw=False, mtype=None, sync=True):
mounted = mounts()
with tempdir() as tmpd:
umount = False
- if device in mounted:
- mountpoint = mounted[device]['mountpoint']
+ if os.path.realpath(device) in mounted:
+ mountpoint = mounted[os.path.realpath(device)]['mountpoint']
else:
failure_reason = None
for mtype in mtypes:
@@ -1565,7 +1586,7 @@ def uptime():
try:
if os.path.exists("/proc/uptime"):
method = '/proc/uptime'
- contents = load_file("/proc/uptime").strip()
+ contents = load_file("/proc/uptime")
if contents:
uptime_str = contents.split()[0]
else:
@@ -1625,7 +1646,7 @@ def write_file(filename, content, mode=0o644, omode="wb"):
content = decode_binary(content)
write_type = 'characters'
LOG.debug("Writing to %s - %s: [%s] %s %s",
- filename, omode, mode, len(content), write_type)
+ filename, omode, mode, len(content), write_type)
with SeLinuxGuard(path=filename):
with open(filename, omode) as fh:
fh.write(content)
@@ -1748,7 +1769,7 @@ def is_container():
try:
# try to run a helper program. if it returns true/zero
# then we're inside a container. otherwise, no
- subp([helper])
+ subp(helper)
return True
except (IOError, OSError):
pass
@@ -2136,15 +2157,21 @@ def _read_dmi_syspath(key):
LOG.debug("did not find %s", dmi_key_path)
return None
- key_data = load_file(dmi_key_path)
+ key_data = load_file(dmi_key_path, decode=False)
if not key_data:
LOG.debug("%s did not return any data", dmi_key_path)
return None
- LOG.debug("dmi data %s returned %s", dmi_key_path, key_data)
- return key_data.strip()
+ # uninitialized dmi values show as all \xff and /sys appends a '\n'.
+ # in that event, return a string of '.' in the same length.
+ if key_data == b'\xff' * (len(key_data) - 1) + b'\n':
+ key_data = b""
- except Exception as e:
+ str_data = key_data.decode('utf8').strip()
+ LOG.debug("dmi data %s returned %s", dmi_key_path, str_data)
+ return str_data
+
+ except Exception:
logexc(LOG, "failed read of %s", dmi_key_path)
return None
@@ -2158,6 +2185,9 @@ def _call_dmidecode(key, dmidecode_path):
cmd = [dmidecode_path, "--string", key]
(result, _err) = subp(cmd)
LOG.debug("dmidecode returned '%s' for '%s'", result, key)
+ result = result.strip()
+ if result.replace(".", "") == "":
+ return ""
return result
except (IOError, OSError) as _err:
LOG.debug('failed dmidecode cmd: %s\n%s', cmd, _err.message)