summaryrefslogtreecommitdiff
path: root/cloudinit/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/__init__.py')
-rw-r--r--cloudinit/__init__.py140
1 files changed, 80 insertions, 60 deletions
diff --git a/cloudinit/__init__.py b/cloudinit/__init__.py
index 3bc6516a..90d6b77d 100644
--- a/cloudinit/__init__.py
+++ b/cloudinit/__init__.py
@@ -26,31 +26,31 @@ seeddir = varlibdir + "/seed"
cfg_env_name = "CLOUD_CFG"
cfg_builtin = """
-log_cfgs: [ ]
-datasource_list: [ "NoCloud", "OVF", "Ec2" ]
+log_cfgs: []
+datasource_list: ["NoCloud", "OVF", "Ec2"]
def_log_file: /var/log/cloud-init.log
syslog_fix_perms: syslog:adm
"""
logger_name = "cloudinit"
pathmap = {
- "handlers" : "/handlers",
- "scripts" : "/scripts",
- "sem" : "/sem",
- "boothooks" : "/boothooks",
- "userdata_raw" : "/user-data.txt",
- "userdata" : "/user-data.txt.i",
- "obj_pkl" : "/obj.pkl",
- "cloud_config" : "/cloud-config.txt",
- "data" : "/data",
- None : "",
+ "handlers": "/handlers",
+ "scripts": "/scripts",
+ "sem": "/sem",
+ "boothooks": "/boothooks",
+ "userdata_raw": "/user-data.txt",
+ "userdata": "/user-data.txt.i",
+ "obj_pkl": "/obj.pkl",
+ "cloud_config": "/cloud-config.txt",
+ "data": "/data",
+ None: "",
}
per_instance = "once-per-instance"
per_always = "always"
per_once = "once"
-parsed_cfgs = { }
+parsed_cfgs = {}
import os
from configobj import ConfigObj
@@ -62,30 +62,35 @@ import errno
import pwd
import subprocess
import yaml
-import util
import logging
import logging.config
import StringIO
import glob
import traceback
+import cloudinit.util as util
+
+
class NullHandler(logging.Handler):
def emit(self, record):
pass
+
log = logging.getLogger(logger_name)
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):
log_cfgs = []
logcfg = util.get_cfg_option_str(cfg, "log_cfg", False)
if logcfg:
# if there is a 'logcfg' entry in the config, respect
# it, it is the old keyname
- log_cfgs = [ logcfg ]
+ log_cfgs = [logcfg]
elif "log_cfgs" in cfg:
for cfg in cfg['log_cfgs']:
if isinstance(cfg, list):
@@ -107,26 +112,27 @@ def logging_set_from_cfg(cfg):
raise Exception("no valid logging found\n")
-import DataSource
-import UserDataHandler
+import cloudinit.DataSource as DataSource
+import cloudinit.UserDataHandler as UserDataHandler
+
class CloudInit:
cfg = None
- part_handlers = { }
+ part_handlers = {}
old_conffile = '/etc/ec2-init/ec2-config.cfg'
- ds_deps = [ DataSource.DEP_FILESYSTEM, DataSource.DEP_NETWORK ]
+ ds_deps = [DataSource.DEP_FILESYSTEM, DataSource.DEP_NETWORK]
datasource = None
cloud_config_str = ''
datasource_name = ''
- builtin_handlers = [ ]
+ builtin_handlers = []
- def __init__(self, ds_deps = None, sysconfig=system_config):
+ def __init__(self, ds_deps=None, sysconfig=system_config):
self.builtin_handlers = [
- [ 'text/x-shellscript', self.handle_user_script, per_always ],
- [ 'text/cloud-config', self.handle_cloud_config, per_always ],
- [ 'text/upstart-job', self.handle_upstart_job, per_instance ],
- [ 'text/cloud-boothook', self.handle_cloud_boothook, per_always ],
+ ['text/x-shellscript', self.handle_user_script, per_always],
+ ['text/cloud-config', self.handle_cloud_config, per_always],
+ ['text/upstart-job', self.handle_upstart_job, per_instance],
+ ['text/cloud-boothook', self.handle_cloud_boothook, per_always],
]
if ds_deps != None:
@@ -149,7 +155,7 @@ class CloudInit:
from configobj import ConfigObj
oldcfg = ConfigObj(self.old_conffile)
if oldcfg is None:
- oldcfg = { }
+ oldcfg = {}
conf = util.mergedict(conf, oldcfg)
except:
pass
@@ -177,7 +183,7 @@ class CloudInit:
except OSError as e:
if e.errno != errno.EEXIST:
return False
-
+
try:
f = open(cache, "wb")
cPickle.dump(self.datasource, f)
@@ -185,7 +191,7 @@ class CloudInit:
os.chmod(cache, 0400)
except:
raise
-
+
def get_data_source(self):
if self.datasource is not None:
return True
@@ -226,12 +232,12 @@ class CloudInit:
os.symlink("./instances/%s" % iid, cur_instance_link)
idir = self.get_ipath()
dlist = []
- for d in [ "handlers", "scripts", "sem" ]:
+ for d in ["handlers", "scripts", "sem"]:
dlist.append("%s/%s" % (idir, d))
-
+
util.ensure_dirs(dlist)
- ds = "%s: %s\n" % ( self.datasource.__class__, str(self.datasource) )
+ ds = "%s: %s\n" % (self.datasource.__class__, str(self.datasource))
dp = self.get_cpath('data')
util.write_file("%s/%s" % (idir, 'datasource'), ds)
util.write_file("%s/%s" % (dp, 'previous-datasource'), ds)
@@ -260,7 +266,7 @@ class CloudInit:
if freq == 'once-per-instance':
return("%s/%s" % (self.get_ipath("sem"), name))
return("%s/%s.%s" % (get_cpath("sem"), name, freq))
-
+
def sem_has_run(self, name, freq):
if freq == per_always:
return False
@@ -268,20 +274,20 @@ class CloudInit:
if os.path.exists(semfile):
return True
return False
-
+
def sem_acquire(self, name, freq):
from time import time
semfile = self.sem_getpath(name, freq)
-
+
try:
os.makedirs(os.path.dirname(semfile))
except OSError as e:
if e.errno != errno.EEXIST:
raise e
-
+
if os.path.exists(semfile) and freq != per_always:
return False
-
+
# race condition
try:
f = open(semfile, "w")
@@ -290,7 +296,7 @@ class CloudInit:
except:
return(False)
return(True)
-
+
def sem_clear(self, name, freq):
semfile = self.sem_getpath(name, freq)
try:
@@ -298,7 +304,7 @@ class CloudInit:
except OSError as e:
if e.errno != errno.ENOENT:
return False
-
+
return True
# acquire lock on 'name' for given 'freq'
@@ -326,7 +332,7 @@ class CloudInit:
# get_ipath : get the instance path for a name in pathmap
# (/var/lib/cloud/instances/<instance>/name)<name>)
def get_ipath(self, name=None):
- return("%s/instances/%s%s"
+ return("%s/instances/%s%s"
% (varlibdir, self.get_instance_id(), pathmap[name]))
def consume_userdata(self, frequency=per_instance):
@@ -341,7 +347,7 @@ class CloudInit:
sys.path.insert(0, cdir)
sys.path.insert(0, idir)
- part_handlers = { }
+ part_handlers = {}
# add handlers in cdir
for fname in glob.glob("%s/*.py" % cdir):
if not os.path.isfile(fname):
@@ -364,13 +370,13 @@ class CloudInit:
part_handlers, data, frequency)
# walk the data
- pdata = { 'handlers': part_handlers, 'handlerdir': idir,
- 'data' : data, 'frequency': frequency }
+ pdata = {'handlers': part_handlers, 'handlerdir': idir,
+ 'data': data, 'frequency': frequency}
UserDataHandler.walk_userdata(self.get_userdata(),
- partwalker_callback, data = pdata)
+ partwalker_callback, data=pdata)
# give callbacks opportunity to finalize
- called = [ ]
+ called = []
for (_mtype, mod) in part_handlers.iteritems():
if mod in called:
continue
@@ -385,7 +391,7 @@ class CloudInit:
filename = filename.replace(os.sep, '_')
scriptsdir = get_ipath_cur('scripts')
- util.write_file("%s/%s" %
+ util.write_file("%s/%s" %
(scriptsdir, filename), util.dos2unix(payload), 0700)
def handle_upstart_job(self, _data, ctype, filename, payload, frequency):
@@ -396,7 +402,7 @@ class CloudInit:
if ctype == "__end__" or ctype == "__begin__":
return
if not filename.endswith(".conf"):
- filename = filename+".conf"
+ filename = filename + ".conf"
util.write_file("%s/%s" % ("/etc/init", filename),
util.dos2unix(payload), 0644)
@@ -414,7 +420,7 @@ class CloudInit:
## as CloudConfig does that also, merging it with this cfg
##
# ccfg = yaml.load(self.cloud_config_str)
- # if ccfg is None: ccfg = { }
+ # if ccfg is None: ccfg = {}
# self.cfg = util.mergedict(ccfg, self.cfg)
return
@@ -434,7 +440,7 @@ class CloudInit:
start = 0
if payload.startswith(prefix):
start = len(prefix) + 1
-
+
boothooks_dir = self.get_ipath("boothooks")
filepath = "%s/%s" % (boothooks_dir, filename)
util.write_file(filepath, payload[start:], 0700)
@@ -473,9 +479,9 @@ class CloudInit:
def initfs():
- subds = [ 'scripts/per-instance', 'scripts/per-once', 'scripts/per-boot',
- 'seed', 'instances', 'handlers', 'sem', 'data' ]
- dlist = [ ]
+ subds = ['scripts/per-instance', 'scripts/per-once', 'scripts/per-boot',
+ 'seed', 'instances', 'handlers', 'sem', 'data']
+ dlist = []
for subd in subds:
dlist.append("%s/%s" % (varlibdir, subd))
util.ensure_dirs(dlist)
@@ -494,8 +500,9 @@ def initfs():
g = None
util.chownbyname(log_file, u, g)
+
def purge_cache(rmcur=True):
- rmlist = [ boot_finished ]
+ rmlist = [boot_finished]
if rmcur:
rmlist.append(cur_instance_link)
for f in rmlist:
@@ -509,28 +516,35 @@ def purge_cache(rmcur=True):
return(False)
return(True)
+
# get_ipath_cur: get the current instance path for an item
def get_ipath_cur(name=None):
return("%s/%s%s" % (varlibdir, "instance", pathmap[name]))
+
# get_cpath : get the "clouddir" (/var/lib/cloud/<name>)
# for a name in dirmap
def get_cpath(name=None):
return("%s%s" % (varlibdir, pathmap[name]))
+
def get_base_cfg(cfg_path=None):
if cfg_path is None:
cfg_path = system_config
return(util.get_base_cfg(cfg_path, cfg_builtin, parsed_cfgs))
+
def get_builtin_cfg():
return(yaml.load(cfg_builtin))
+
class DataSourceNotFoundException(Exception):
pass
+
def list_sources(cfg_list, depends):
- return(DataSource.list_sources(cfg_list, depends, ["cloudinit", "" ]))
+ return(DataSource.list_sources(cfg_list, depends, ["cloudinit", ""]))
+
def handler_register(mod, part_handlers, data, frequency=per_instance):
if not hasattr(mod, "handler_version"):
@@ -542,27 +556,30 @@ def handler_register(mod, part_handlers, data, frequency=per_instance):
handler_call_begin(mod, data, frequency)
return(mod)
+
def handler_call_begin(mod, data, frequency):
handler_handle_part(mod, data, "__begin__", None, None, frequency)
+
def handler_call_end(mod, data, frequency):
handler_handle_part(mod, data, "__end__", None, None, frequency)
+
def handler_handle_part(mod, data, ctype, filename, payload, frequency):
# only add the handler if the module should run
modfreq = getattr(mod, "frequency", per_instance)
- if not ( modfreq == per_always or
- ( frequency == per_instance and modfreq == per_instance)):
+ if not (modfreq == per_always or
+ (frequency == per_instance and modfreq == per_instance)):
return
if mod.handler_version == 1:
mod.handle_part(data, ctype, filename, payload)
else:
mod.handle_part(data, ctype, filename, payload, frequency)
-def partwalker_handle_handler(pdata, _ctype, _filename, payload):
+def partwalker_handle_handler(pdata, _ctype, _filename, payload):
curcount = pdata['handlercount']
- modname = 'part-handler-%03d' % curcount
+ modname = 'part-handler-%03d' % curcount
frequency = pdata['frequency']
modfname = modname + ".py"
@@ -578,6 +595,7 @@ def partwalker_handle_handler(pdata, _ctype, _filename, payload):
traceback.print_exc(file=sys.stderr)
return
+
def partwalker_callback(pdata, ctype, filename, payload):
# data here is the part_handlers array and then the data to pass through
if ctype == "text/part-handler":
@@ -590,18 +608,20 @@ def partwalker_callback(pdata, ctype, filename, payload):
handler_handle_part(pdata['handlers'][ctype], pdata['data'],
ctype, filename, payload, pdata['frequency'])
+
class InternalPartHandler:
freq = per_instance
- mtypes = [ ]
+ mtypes = []
handler_version = 1
handler = None
- def __init__(self, handler, mtypes, frequency, version = 2):
+
+ def __init__(self, handler, mtypes, frequency, version=2):
self.handler = handler
self.mtypes = mtypes
self.frequency = frequency
self.handler_version = version
- def __repr__():
+ def __repr__(self):
return("InternalPartHandler: [%s]" % self.mtypes)
def list_types(self):