summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorScott Moser <smoser@ubuntu.com>2011-01-24 21:28:36 -0500
committerScott Moser <smoser@ubuntu.com>2011-01-24 21:28:36 -0500
commit2b94f4428f669defbebf0be720d83452c553e8d6 (patch)
tree4e79feafb2db1b1ad3d57d5c55015104428a27f2 /cloudinit
parent0ef850f81aa3f652ecf1e869ad0de622695782d8 (diff)
parent10d4048677a90ab66ab4a314f311163b6e6d9cf1 (diff)
downloadvyos-cloud-init-2b94f4428f669defbebf0be720d83452c553e8d6.tar.gz
vyos-cloud-init-2b94f4428f669defbebf0be720d83452c553e8d6.zip
add support for redirecting output of cloud-init, cloud-config and cloud-final
minor change to timestamps to all use gmtime()
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/CloudConfig/__init__.py109
-rw-r--r--cloudinit/CloudConfig/cc_final_message.py4
-rw-r--r--cloudinit/DataSourceEc2.py2
-rw-r--r--cloudinit/__init__.py5
4 files changed, 116 insertions, 4 deletions
diff --git a/cloudinit/CloudConfig/__init__.py b/cloudinit/CloudConfig/__init__.py
index 6932acbe..22ad63a6 100644
--- a/cloudinit/CloudConfig/__init__.py
+++ b/cloudinit/CloudConfig/__init__.py
@@ -21,6 +21,8 @@ import cloudinit
import cloudinit.util as util
import sys
import traceback
+import os
+import subprocess
per_instance="once-per-instance"
per_always="always"
@@ -103,3 +105,110 @@ def run_cc_modules(cc,module_list,log):
failures.append(name)
return(failures)
+
+# always returns well formated values
+# cfg is expected to have an entry 'output' in it, which is a dictionary
+# that includes entries for 'init', 'config', 'final' or 'all'
+# init: /var/log/cloud.out
+# config: [ ">> /var/log/cloud-config.out", /var/log/cloud-config.err ]
+# final:
+# output: "| logger -p"
+# error: "> /dev/null"
+# this returns the specific 'mode' entry, cleanly formatted, with value
+# None if if none is given
+def get_output_cfg(cfg, mode="init"):
+ ret = [ None, None ]
+ if not 'output' in cfg: return ret
+
+ outcfg = cfg['output']
+ if mode in outcfg:
+ modecfg = outcfg[mode]
+ else:
+ if 'all' not in outcfg: return ret
+ # if there is a 'all' item in the output list
+ # then it applies to all users of this (init, config, final)
+ modecfg = outcfg['all']
+
+ # if value is a string, it specifies stdout
+ if isinstance(modecfg,str):
+ ret = [ modecfg, None ]
+
+ # if its a list, then we expect (stdout, stderr)
+ if isinstance(modecfg,list):
+ if len(modecfg) > 0: ret[0] = modecfg[0]
+ if len(modecfg) > 1:
+ ret[1] = modecfg[1]
+
+ # if it is a dictionary, expect 'out' and 'error'
+ # items, which indicate out and error
+ if isinstance(modecfg, dict):
+ if 'output' in modecfg:
+ ret[0] = modecfg['output']
+ if 'error' in modecfg:
+ ret[1] = modecfg['error']
+
+ # if err's entry == "&1", then make it same as stdout
+ # as in shell syntax of "echo foo >/dev/null 2>&1"
+ if ret[1] == "&1": ret[1] = ret[0]
+
+ swlist = [ ">>", ">", "|" ]
+ for i in range(len(ret)):
+ if not ret[i]: continue
+ val = ret[i].lstrip()
+ found = False
+ for s in swlist:
+ if val.startswith(s):
+ val = "%s %s" % (s,val[len(s):].strip())
+ found = True
+ break
+ if not found:
+ # default behavior is append
+ val = "%s %s" % ( ">>", val.strip())
+ ret[i] = val
+
+ return(ret)
+
+
+# redirect_output(outfmt, errfmt, orig_out, orig_err)
+# replace orig_out and orig_err with filehandles specified in outfmt or errfmt
+# fmt can be:
+# > FILEPATH
+# >> FILEPATH
+# | program [ arg1 [ arg2 [ ... ] ] ]
+#
+# with a '|', arguments are passed to shell, so one level of
+# shell escape is required.
+def redirect_output(outfmt,errfmt, o_out=sys.stdout, o_err=sys.stderr):
+ if outfmt:
+ (mode, arg) = outfmt.split(" ",1)
+ if mode == ">" or mode == ">>":
+ owith = "ab"
+ if mode == ">": owith = "wb"
+ new_fp = open(arg, owith)
+ elif mode == "|":
+ proc = subprocess.Popen(arg, shell=True, stdin=subprocess.PIPE)
+ new_fp = proc.stdin
+ else:
+ raise TypeError("invalid type for outfmt: %s" % outfmt)
+
+ if o_out:
+ os.dup2(new_fp.fileno(), o_out.fileno())
+ if errfmt == outfmt:
+ os.dup2(new_fp.fileno(), o_err.fileno())
+ return
+
+ if errfmt:
+ (mode, arg) = errfmt.split(" ",1)
+ if mode == ">" or mode == ">>":
+ owith = "ab"
+ if mode == ">": owith = "wb"
+ new_fp = open(arg, owith)
+ elif mode == "|":
+ proc = subprocess.Popen(arg, shell=True, stdin=subprocess.PIPE)
+ new_fp = proc.stdin
+ else:
+ raise TypeError("invalid type for outfmt: %s" % outfmt)
+
+ if o_err:
+ os.dup2(new_fp.fileno(), o_err.fileno())
+ return
diff --git a/cloudinit/CloudConfig/cc_final_message.py b/cloudinit/CloudConfig/cc_final_message.py
index febfd017..8f9dc786 100644
--- a/cloudinit/CloudConfig/cc_final_message.py
+++ b/cloudinit/CloudConfig/cc_final_message.py
@@ -18,6 +18,7 @@
from cloudinit.CloudConfig import per_instance
import sys
from cloudinit import util, boot_finished
+import time
frequency = per_instance
@@ -39,8 +40,7 @@ def handle(name,cfg,cloud,log,args):
try:
- from datetime import datetime
- ts = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S +0000')
+ ts = time.strftime("%a, %d %b %Y %H:%M:%S %z",time.gmtime())
except:
ts = "na"
diff --git a/cloudinit/DataSourceEc2.py b/cloudinit/DataSourceEc2.py
index fc8fac5a..1c0edc59 100644
--- a/cloudinit/DataSourceEc2.py
+++ b/cloudinit/DataSourceEc2.py
@@ -108,7 +108,7 @@ class DataSourceEc2(DataSource.DataSource):
cloudinit.log.warning("waiting for metadata service at %s\n" % url)
cloudinit.log.warning(" %s [%02s/%s]: %s\n" %
- (time.strftime("%H:%M:%S"), x+1, sleeps, reason))
+ (time.strftime("%H:%M:%S",time.gmtime()), x+1, sleeps, reason))
time.sleep(sleeptime)
cloudinit.log.critical("giving up on md after %i seconds\n" %
diff --git a/cloudinit/__init__.py b/cloudinit/__init__.py
index 1786cc2f..9c02ff8a 100644
--- a/cloudinit/__init__.py
+++ b/cloudinit/__init__.py
@@ -73,7 +73,7 @@ log.addHandler(NullHandler())
def logging_set_from_cfg_file(cfg_file=system_config):
logging_set_from_cfg(util.get_base_cfg(cfg_file,cfg_builtin,parsed_cfgs))
-def logging_set_from_cfg(cfg, logfile=None):
+def logging_set_from_cfg(cfg):
log_cfgs = []
logcfg=util.get_cfg_option_str(cfg, "log_cfg", False)
if logcfg:
@@ -530,5 +530,8 @@ def get_ipath_cur(name=None):
def get_cpath(name=None):
return("%s%s" % (varlibdir, pathmap[name]))
+def get_base_cfg():
+ return(util.get_base_cfg(system_config,cfg_builtin,parsed_cfgs))
+
class DataSourceNotFoundException(Exception):
pass