diff options
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r-- | cloudinit/util.py | 151 |
1 files changed, 84 insertions, 67 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py index 5bf8e8b2..7df773ce 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -39,7 +39,7 @@ except ImportError: def read_conf(fname): try: - stream = open(fname,"r") + stream = open(fname, "r") conf = yaml.load(stream) stream.close() return conf @@ -48,7 +48,7 @@ def read_conf(fname): return { } raise -def get_base_cfg(cfgfile,cfg_builtin="", parsed_cfgs=None): +def get_base_cfg(cfgfile, cfg_builtin="", parsed_cfgs=None): kerncfg = { } syscfg = { } if parsed_cfgs and cfgfile in parsed_cfgs: @@ -65,7 +65,7 @@ def get_base_cfg(cfgfile,cfg_builtin="", parsed_cfgs=None): if cfg_builtin: builtin = yaml.load(cfg_builtin) - fin = mergedict(combined,builtin) + fin = mergedict(combined, builtin) else: fin = combined @@ -74,53 +74,60 @@ def get_base_cfg(cfgfile,cfg_builtin="", parsed_cfgs=None): return(fin) def get_cfg_option_bool(yobj, key, default=False): - if not yobj.has_key(key): return default + if not yobj.has_key(key): + return default val = yobj[key] - if val is True: return True + if val is True: + return True if str(val).lower() in [ 'true', '1', 'on', 'yes']: return True return False def get_cfg_option_str(yobj, key, default=None): - if not yobj.has_key(key): return default + if not yobj.has_key(key): + return default return yobj[key] def get_cfg_option_list_or_str(yobj, key, default=None): - if not yobj.has_key(key): return default - if yobj[key] is None: return [] - if isinstance(yobj[key],list): return yobj[key] + if not yobj.has_key(key): + return default + if yobj[key] is None: + return [] + if isinstance(yobj[key], list): + return yobj[key] return([yobj[key]]) # get a cfg entry by its path array # for f['a']['b']: get_cfg_by_path(mycfg,('a','b')) -def get_cfg_by_path(yobj,keyp,default=None): +def get_cfg_by_path(yobj, keyp, default=None): cur = yobj for tok in keyp: - if tok not in cur: return(default) + if tok not in cur: + return(default) cur = cur[tok] return(cur) # merge values from cand into source # if src has a key, cand will not override -def mergedict(src,cand): - if isinstance(src,dict) and isinstance(cand,dict): - for k,v in cand.iteritems(): +def mergedict(src, cand): + if isinstance(src, dict) and isinstance(cand, dict): + for k, v in cand.iteritems(): if k not in src: src[k] = v else: - src[k] = mergedict(src[k],v) + src[k] = mergedict(src[k], v) return src -def write_file(filename,content,mode=0644,omode="wb"): +def write_file(filename, content, mode=0644, omode="wb"): try: os.makedirs(os.path.dirname(filename)) except OSError as e: if e.errno != errno.EEXIST: raise e - f=open(filename,omode) + f = open(filename, omode) if mode != None: - os.chmod(filename,mode) + os.chmod(filename, mode) f.write(content) f.close() restorecon_if_possible(filename) @@ -130,8 +137,8 @@ def restorecon_if_possible(path, recursive=False): selinux.restorecon(path, recursive=recursive) # get keyid from keyserver -def getkeybyid(keyid,keyserver): - shcmd=""" +def getkeybyid(keyid, keyserver): + shcmd = """ k=${1} ks=${2}; exec 2>/dev/null [ -n "$k" ] || exit 1; @@ -143,32 +150,35 @@ def getkeybyid(keyid,keyserver): fi [ -n "${armour}" ] && echo "${armour}" """ - args=['sh', '-c', shcmd, "export-gpg-keyid", keyid, keyserver] + args = ['sh', '-c', shcmd, "export-gpg-keyid", keyid, keyserver] return(subp(args)[0]) def runparts(dirp, skip_no_exist=True): - if skip_no_exist and not os.path.isdir(dirp): return + if skip_no_exist and not os.path.isdir(dirp): + return # per bug 857926, Fedora's run-parts will exit failure on empty dir - if os.path.isdir(dirp) and os.listdir(dirp) == []: return + if os.path.isdir(dirp) and os.listdir(dirp) == []: + return cmd = [ 'run-parts', '--regex', '.*', dirp ] sp = subprocess.Popen(cmd) sp.communicate() if sp.returncode is not 0: - raise subprocess.CalledProcessError(sp.returncode,cmd) + raise subprocess.CalledProcessError(sp.returncode, cmd) return def subp(args, input_=None): sp = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - out,err = sp.communicate(input_) + out, err = sp.communicate(input_) if sp.returncode is not 0: - raise subprocess.CalledProcessError(sp.returncode,args, (out,err)) - return(out,err) + raise subprocess.CalledProcessError(sp.returncode, args, (out, err)) + return(out, err) def render_to_file(template, outfile, searchList): - t = Template(file='/etc/cloud/templates/%s.tmpl' % template, searchList=[searchList]) + t = Template(file='/etc/cloud/templates/%s.tmpl' % template, + searchList=[searchList]) f = open(outfile, 'w') f.write(t.respond()) f.close() @@ -181,11 +191,11 @@ def render_string(template, searchList): # returns boolean indicating success or failure (presense of files) # if files are present, populates 'fill' dictionary with 'user-data' and # 'meta-data' entries -def read_optional_seed(fill,base="",ext="", timeout=5): +def read_optional_seed(fill, base="", ext="", timeout=5): try: - (md,ud) = read_seeded(base,ext,timeout) - fill['user-data']= ud - fill['meta-data']= md + (md, ud) = read_seeded(base, ext, timeout) + fill['user-data'] = ud + fill['meta-data'] = md return True except OSError, e: if e.errno == errno.ENOENT: @@ -196,7 +206,7 @@ def read_optional_seed(fill,base="",ext="", timeout=5): # raise OSError with enoent if not found def read_seeded(base="", ext="", timeout=5, retries=10, file_retries=0): if base.startswith("/"): - base="file://%s" % base + base = "file://%s" % base # default retries for file is 0. for network is 10 if base.startswith("file://"): @@ -210,18 +220,18 @@ def read_seeded(base="", ext="", timeout=5, retries=10, file_retries=0): md_url = "%s%s%s" % (base, "meta-data", ext) raise_err = None - for attempt in range(0,retries+1): + for attempt in range(0, retries+1): try: md_str = readurl(md_url, timeout=timeout) ud = readurl(ud_url, timeout=timeout) md = yaml.load(md_str) - return(md,ud) + return(md, ud) except urllib2.HTTPError as e: raise_err = e except urllib2.URLError as e: raise_err = e - if isinstance(e.reason,OSError) and e.reason.errno == errno.ENOENT: + if isinstance(e.reason, OSError) and e.reason.errno == errno.ENOENT: raise_err = e.reason if attempt == retries: @@ -232,8 +242,8 @@ def read_seeded(base="", ext="", timeout=5, retries=10, file_retries=0): raise(raise_err) -def logexc(log,lvl=logging.DEBUG): - log.log(lvl,traceback.format_exc()) +def logexc(log, lvl=logging.DEBUG): + log.log(lvl, traceback.format_exc()) class RecursiveInclude(Exception): pass @@ -253,7 +263,7 @@ def read_file_with_includes(fname, rel = ".", stack=None, patt = None): (fname, len(stack)))) if patt == None: - patt = re.compile("^#(opt_include|include)[ \t].*$",re.MULTILINE) + patt = re.compile("^#(opt_include|include)[ \t].*$", re.MULTILINE) try: fp = open(fname) @@ -268,11 +278,12 @@ def read_file_with_includes(fname, rel = ".", stack=None, patt = None): cur = 0 while True: match = patt.search(contents[cur:]) - if not match: break + if not match: + break loc = match.start() + cur endl = match.end() + cur - (key, cur_fname) = contents[loc:endl].split(None,2) + (key, cur_fname) = contents[loc:endl].split(None, 2) cur_fname = cur_fname.strip() try: @@ -289,17 +300,17 @@ def read_file_with_includes(fname, rel = ".", stack=None, patt = None): def read_conf_d(confd): # get reverse sorted list (later trumps newer) - confs = sorted(os.listdir(confd),reverse=True) + confs = sorted(os.listdir(confd), reverse=True) # remove anything not ending in '.cfg' confs = [f for f in confs if f.endswith(".cfg")] # remove anything not a file - confs = [f for f in confs if os.path.isfile("%s/%s" % (confd,f))] + confs = [f for f in confs if os.path.isfile("%s/%s" % (confd, f))] cfg = { } for conf in confs: - cfg = mergedict(cfg,read_conf("%s/%s" % (confd,conf))) + cfg = mergedict(cfg, read_conf("%s/%s" % (confd, conf))) return(cfg) @@ -309,16 +320,18 @@ def read_conf_with_confd(cfgfile): if "conf_d" in cfg: if cfg['conf_d'] is not None: confd = cfg['conf_d'] - if not isinstance(confd,str): - raise Exception("cfgfile %s contains 'conf_d' with non-string" % cfgfile) + if not isinstance(confd, str): + raise Exception("cfgfile %s contains 'conf_d' " + "with non-string" % cfgfile) elif os.path.isdir("%s.d" % cfgfile): confd = "%s.d" % cfgfile - if not confd: return(cfg) + if not confd: + return(cfg) confd_cfg = read_conf_d(confd) - return(mergedict(confd_cfg,cfg)) + return(mergedict(confd_cfg, cfg)) def get_cmdline(): @@ -345,8 +358,8 @@ def read_cc_from_cmdline(cmdline=None): if cmdline is None: cmdline = get_cmdline() - tag_begin="cc:" - tag_end="end_cc" + tag_begin = "cc:" + tag_end = "end_cc" begin_l = len(tag_begin) end_l = len(tag_end) clen = len(cmdline) @@ -356,7 +369,7 @@ def read_cc_from_cmdline(cmdline=None): end = cmdline.find(tag_end, begin + begin_l) if end < 0: end = clen - tokens.append(cmdline[begin+begin_l:end].lstrip().replace("\\n","\n")) + tokens.append(cmdline[begin+begin_l:end].lstrip().replace("\\n", "\n")) begin = cmdline.find(tag_begin, end + end_l) @@ -371,16 +384,19 @@ def ensure_dirs(dirlist, mode=0755): else: os.makedirs(d, mode) except OSError as e: - if e.errno != errno.EEXIST: raise - if mode != None: fixmodes.append(d) + if e.errno != errno.EEXIST: + raise + if mode != None: + fixmodes.append(d) for d in fixmodes: os.chmod(d, mode) -def chownbyname(fname,user=None,group=None): +def chownbyname(fname, user=None, group=None): uid = -1 gid = -1 - if user == None and group == None: return + if user == None and group == None: + return if user: import pwd uid = pwd.getpwnam(user).pw_uid @@ -388,7 +404,7 @@ def chownbyname(fname,user=None,group=None): import grp gid = grp.getgrnam(group).gr_gid - os.chown(fname,uid,gid) + os.chown(fname, uid, gid) def readurl(url, data=None, timeout=None): openargs = { } @@ -409,25 +425,26 @@ def readurl(url, data=None, timeout=None): # if it is an array, shell protect it (with single ticks) # if it is a string, do nothing def shellify(cmdlist): - content="#!/bin/sh\n" - escaped="%s%s%s%s" % ( "'", '\\', "'", "'" ) + content = "#!/bin/sh\n" + escaped = "%s%s%s%s" % ( "'", '\\', "'", "'" ) for args in cmdlist: # if the item is a list, wrap all items in single tick # if its not, then just write it directly - if isinstance(args,list): + if isinstance(args, list): fixed = [ ] for f in args: - fixed.append("'%s'" % str(f).replace("'",escaped)) - content="%s%s\n" % ( content, ' '.join(fixed) ) + fixed.append("'%s'" % str(f).replace("'", escaped)) + content = "%s%s\n" % ( content, ' '.join(fixed) ) else: - content="%s%s\n" % ( content, str(args) ) + content = "%s%s\n" % ( content, str(args) ) return content def dos2unix(string): # find first end of line pos = string.find('\n') - if pos <= 0 or string[pos-1] != '\r': return(string) - return(string.replace('\r\n','\n')) + if pos <= 0 or string[pos-1] != '\r': + return(string) + return(string.replace('\r\n', '\n')) def islxc(): # is this host running lxc? @@ -440,8 +457,8 @@ def islxc(): raise try: - # try to run a program named 'lxc-is-container'. if it returns true, then - # we're inside a container. otherwise, no + # try to run a program named 'lxc-is-container'. if it returns true, + # then we're inside a container. otherwise, no sp = subprocess.Popen(['lxc-is-container'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) sp.communicate(None) @@ -458,7 +475,7 @@ def get_hostname_fqdn(cfg, cloud): if "fqdn" in cfg: # user specified a fqdn. Default hostname then is based off that fqdn = cfg['fqdn'] - hostname = get_cfg_option_str(cfg,"hostname",fqdn.split('.')[0]) + hostname = get_cfg_option_str(cfg, "hostname", fqdn.split('.')[0]) else: if "hostname" in cfg and cfg['hostname'].find('.') > 0: # user specified hostname, and it had '.' in it |