Fixups to ensure that pylint does not find anything major wrong.

This commit is contained in:
Joshua Harlow 2012-06-15 21:33:55 -07:00
parent 830131b1fd
commit 29e0ccd4ed
52 changed files with 388 additions and 300 deletions

View File

@ -23,8 +23,6 @@
import copy
import os
from cloudinit import distros
from cloudinit import helpers
from cloudinit import log as logging
LOG = logging.getLogger(__name__)

View File

@ -20,29 +20,32 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from StringIO import StringIO
import abc
import copy
from cloudinit import importer
from cloudinit import log as logging
from cloudinit import util
from StringIO import StringIO
# TODO: Make this via config??
IFACE_ACTIONS = {
'up': ['ifup', '--all'],
'down': ['ifdown', '--all'],
}
LOG = logging.getLogger(__name__)
class Distro(object):
__metaclass__ = abc.ABCMeta
def __init__(self, cfg, runner):
def __init__(self, name, cfg, runner):
self._runner = runner
self._cfg = util.get_cfg_by_path(cfg, ('system_info', ), {})
self.name = self._cfg.pop("distro", 'generic')
self._cfg = cfg
self.name = name
@abc.abstractmethod
def install_packages(self, pkglist):
@ -135,10 +138,9 @@ class Distro(object):
action, cmd)
(_out, err) = util.subp(cmd)
if len(err):
LOG.warn("Running %s resulted in stderr output: %s",
IF_UP_CMD, err)
LOG.warn("Running %s resulted in stderr output: %s", cmd, err)
return True
except util.ProcessExecutionError as exc:
except util.ProcessExecutionError:
util.logexc(LOG, "Running %s failed", cmd)
return False
@ -152,7 +154,8 @@ def fetch(distro_name, mods=(__name__, )):
except RuntimeError:
pass
if not mod:
raise RuntimeError("No distribution found for distro %s" % (distro_name))
raise RuntimeError("No distribution found for distro %s"
% (distro_name))
distro_cls = getattr(mod, 'Distro')
return distro_cls

View File

@ -20,17 +20,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from StringIO import StringIO
import os
import socket
from cloudinit import distros
from cloudinit import log as logging
from cloudinit import templater
from cloudinit import util
from cloudinit.settings import (PER_INSTANCE)
from cloudinit.settings import PER_INSTANCE
LOG = logging.getLogger(__name__)
@ -65,9 +61,11 @@ class Distro(distros.Distro):
try:
util.write_file(fn, "%s\n" % hostname, 0644)
except:
util.logexc(LOG, "Failed to write hostname %s to %s", hostname, fn)
if hostname_in_etc and hostname_prev and hostname_in_etc != hostname_prev:
LOG.debug(("%s differs from /etc/hostname."
util.logexc(LOG, "Failed to write hostname %s to %s",
hostname, fn)
if (hostname_in_etc and hostname_prev and
hostname_in_etc != hostname_prev):
LOG.debug(("%s differs from /etc/hostname."
" Assuming user maintained hostname."), prev_file)
if "/etc/hostname" in update_files:
LOG.debug("Setting hostname to %s", hostname)
@ -91,7 +89,8 @@ class Distro(distros.Distro):
def set_timezone(self, tz):
tz_file = os.path.join("/usr/share/zoneinfo", tz)
if not os.path.isfile(tz_file):
raise Exception("Invalid timezone %s, no file found at %s" % (tz, tz_file))
raise Exception(("Invalid timezone %s,"
" no file found at %s") % (tz, tz_file))
tz_contents = "%s\n" % tz
util.write_file("/etc/timezone", tz_contents)
# TODO, this should be in a rhel distro subclass??
@ -101,9 +100,6 @@ class Distro(distros.Distro):
# This ensures that the correct tz will be used for the system
util.copy(tz_file, "/etc/localtime")
def name(self):
return "ubuntu"
# apt_get top level command (install, update...), and args to pass it
def _apt_get(self, tlc, args=None):
e = os.environ.copy()
@ -116,4 +112,5 @@ class Distro(distros.Distro):
util.subp(cmd, env=e, capture=False)
def _update_package_sources(self):
self.runner.run("update-sources", self._apt_get, ["update"], freq=PER_INSTANCE)
self._runner.run("update-sources", self._apt_get,
["update"], freq=PER_INSTANCE)

View File

@ -32,9 +32,9 @@ LOG = logging.getLogger(__name__)
class BootHookPartHandler(ud.PartHandler):
def __init__(self, boothook_dir, instance_id):
def __init__(self, paths, instance_id, **_kwargs):
ud.PartHandler.__init__(self, PER_ALWAYS)
self.boothook_dir = boothook_dir
self.boothook_dir = paths.get_ipath("boothooks")
self.instance_id = instance_id
def list_types(self):
@ -54,13 +54,15 @@ class BootHookPartHandler(ud.PartHandler):
start = len(prefix) + 1
filepath = os.path.join(self.boothook_dir, filename)
util.write_file(filepath, payload[start:], 0700)
contents = payload[start:]
util.write_file(filepath, contents, 0700)
try:
env = os.environ.copy()
env['INSTANCE_ID'] = str(self.instance_id)
if self.instance_id:
env['INSTANCE_ID'] = str(self.instance_id)
util.subp([filepath], env=env)
except util.ProcessExecutionError as e:
except util.ProcessExecutionError:
util.logexc(LOG, "Boothooks script %s execution error", filepath)
except Exception as e:
except Exception:
util.logexc(LOG, ("Boothooks unknown "
"error when running %s"), filepath)

View File

@ -30,10 +30,10 @@ LOG = logging.getLogger(__name__)
class CloudConfigPartHandler(ud.PartHandler):
def __init__(self, cloud_fn):
def __init__(self, paths, **_kwargs):
ud.PartHandler.__init__(self, PER_ALWAYS)
self.cloud_buf = []
self.cloud_fn = cloud_fn
self.cloud_fn = paths.get_ipath("cloud_config")
def list_types(self):
return [

View File

@ -32,10 +32,9 @@ LOG = logging.getLogger(__name__)
class ShellScriptPartHandler(ud.PartHandler):
def __init__(self, script_dir):
def __init__(self, paths, **_kwargs):
ud.PartHandler.__init__(self, PER_ALWAYS)
self.script_dir = script_dir
self.script_dir = paths.get_ipath_cur('scripts')
def list_types(self):
return [

View File

@ -33,9 +33,9 @@ LOG = logging.getLogger(__name__)
class UpstartJobPartHandler(ud.PartHandler):
def __init__(self, upstart_dir):
def __init__(self, paths, **_kwargs):
ud.PartHandler.__init__(self, PER_INSTANCE)
self.upstart_dir = upstart_dir
self.upstart_dir = paths.upstart_conf_d
def list_types(self):
return [
@ -46,6 +46,9 @@ class UpstartJobPartHandler(ud.PartHandler):
if ctype in ud.CONTENT_SIGNALS:
return
if not self.upstart_dir:
return
filename = util.clean_filename(filename)
(_name, ext) = os.path.splitext(filename)
if not ext:

View File

@ -30,11 +30,6 @@ from cloudinit.settings import (PER_INSTANCE, PER_ALWAYS, PER_ONCE)
from cloudinit import log as logging
from cloudinit import util
from cloudinit.user_data import boot_hook as bh_part
from cloudinit.user_data import cloud_config as cc_part
from cloudinit.user_data import shell_script as ss_part
from cloudinit.user_data import upstart_job as up_part
LOG = logging.getLogger(__name__)
@ -77,7 +72,7 @@ class FileSemaphores(object):
sem_file = self._get_path(name, freq)
try:
util.del_file(sem_file)
except (IOError, OSError) as e:
except (IOError, OSError):
util.logexc(LOG, "Failed deleting semaphore %s", sem_file)
return False
return True
@ -99,7 +94,7 @@ class FileSemaphores(object):
contents = "%s: %s\n" % (os.getpid(), time())
try:
util.write_file(sem_file, contents)
except (IOError, OSError) as e:
except (IOError, OSError):
util.logexc(LOG, "Failed writing semaphore file %s", sem_file)
return None
return sem_file
@ -162,9 +157,10 @@ class Runners(object):
class ContentHandlers(object):
def __init__(self, paths):
def __init__(self, paths, iid=None):
self.paths = paths
self.registered = {}
self.iid = iid
def __contains__(self, item):
return self.is_registered(item)
@ -191,34 +187,9 @@ class ContentHandlers(object):
def iteritems(self):
return self.registered.iteritems()
def _get_default_handlers(self):
def_handlers = []
cc_path = self.paths.get_ipath("cloud_config")
if cc_path:
cc_h = cc_part.CloudConfigPartHandler(cc_path)
def_handlers.append(cc_h)
sc_path = self.paths.get_ipath_cur('scripts')
if sc_path:
ss_h = ss_part.ShellScriptPartHandler(sc_path)
def_handlers.append(ss_h)
bh_path = self.paths.get_ipath("boothooks")
if bh_path:
bh_h = bh_part.BootHookPartHandler(bh_path)
def_handlers.append(bh_h)
upstart_pth = self.paths.upstart_conf_d
if upstart_pth:
up_h = up_part.UpstartJobPartHandler(upstart_pth)
def_handlers.append(up_h)
return def_handlers
def register_defaults(self):
def register_defaults(self, defs):
registered = set()
for mod in self._get_default_handlers():
for mod in defs:
for t in mod.list_types():
if not self.is_registered(t):
self.registered[t] = mod

View File

@ -56,7 +56,7 @@ def setupBasicLogging():
cfile = logging.FileHandler('/var/log/cloud-init.log')
cfile.setFormatter(logging.Formatter(DEF_CON_FORMAT))
cfile.setLevel(DEBUG)
root.addHandle(cfile)
root.addHandler(cfile)
except (IOError, OSError):
# Likely that u can't write to that file...
# Make console now have DEBUG??

View File

@ -79,7 +79,7 @@ class DataSourceCloudStack(sources.DataSource):
tot_time = (time.time() - start)
LOG.debug("Crawl of metadata service took %s", int(tot_time))
return True
except Exception as e:
except Exception:
util.logexc(LOG, ('Failed fetching from metadata '
'service %s'), self.metadata_address)
return False

View File

@ -51,8 +51,8 @@ class DataSourceConfigDrive(sources.DataSource):
self.seed_dir = os.path.join(paths.seed_dir, 'config_drive')
def __str__(self):
mstr = "%s[%s]" % (util.obj_name(self), self.dsmode)
mstr += " [seed=%s]" % (self.seed)
mstr = "%s [%s]" % (util.obj_name(self), self.dsmode)
mstr += "[seed=%s]" % (self.seed)
return mstr
def get_data(self):

View File

@ -18,9 +18,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import errno
import oauth.oauth as oauth
import os
import time
import urllib2
@ -48,7 +48,7 @@ class DataSourceMAAS(sources.DataSource):
self.seed_dir = os.path.join(paths.seed_dir, 'maas')
def __str__(self):
return "%s[%s]" % (util.obj_name(self), self.base_url)
return "%s [%s]" % (util.obj_name(self), self.base_url)
def get_data(self):
mcfg = self.ds_cfg
@ -122,9 +122,10 @@ class DataSourceMAAS(sources.DataSource):
starttime = time.time()
check_url = "%s/%s/meta-data/instance-id" % (url, MD_VERSION)
url = util.wait_for_url(urls=[check_url], max_wait=max_wait,
timeout=timeout, status_cb=LOG.warn,
headers_cb=self.md_headers)
urls = [check_url]
url = uhelp.wait_for_url(urls=urls, max_wait=max_wait,
timeout=timeout, status_cb=LOG.warn,
headers_cb=self.md_headers)
if url:
LOG.info("Using metadata source: '%s'", url)
@ -185,7 +186,8 @@ def read_maas_seed_url(seed_url, header_cb=None, timeout=None,
headers = {}
try:
(resp, sc) = uhelp.readurl(url, headers=headers, timeout=timeout)
md[name] = resp
if uhelp.ok_http_code(sc):
md[name] = resp
except urllib2.HTTPError as e:
if e.code != 404:
raise

View File

@ -106,7 +106,8 @@ class DataSourceNoCloud(sources.DataSource):
if e.errno != errno.ENOENT:
raise
except util.MountFailedError:
util.logexc(LOG, "Failed to mount %s when looking for seed", dev)
util.logexc(LOG, ("Failed to mount %s"
" when looking for data"), dev)
# There was no indication on kernel cmdline or data
# in the seeddir suggesting this handler should be used.

View File

@ -21,10 +21,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from xml.dom import minidom
import base64
import os
import re
import tempfile
from cloudinit import log as logging
from cloudinit import sources
@ -51,7 +51,7 @@ class DataSourceOVF(sources.DataSource):
ud = ""
defaults = {
"instance-id": "iid-dsovf"
"instance-id": "iid-dsovf",
}
(seedfile, contents) = get_ovf_env(self.paths.seed_dir)
@ -198,7 +198,7 @@ def transport_iso9660(require_iso=True):
for dev in devs:
fullp = os.path.join("/dev/", dev)
if (fullp in mounted or
if (fullp in mounts or
not cdmatch.match(dev) or os.path.isdir(fullp)):
continue
@ -210,7 +210,8 @@ def transport_iso9660(require_iso=True):
continue
try:
(fname, contents) = utils.mount_cb(fullp, get_ovf_env, mtype="iso9660")
(fname, contents) = util.mount_cb(fullp,
get_ovf_env, mtype="iso9660")
except util.MountFailedError:
util.logexc(LOG, "Failed mounting %s", fullp)
continue
@ -265,7 +266,8 @@ def get_properties(contents):
raise XmlError("No 'PropertySection's")
props = {}
propElems = find_child(propSections[0], lambda n: n.localName == "Property")
propElems = find_child(propSections[0],
(lambda n: n.localName == "Property"))
for elem in propElems:
key = elem.attributes.getNamedItemNS(envNsURI, "key").value

View File

@ -22,10 +22,9 @@
from cloudinit import importer
from cloudinit import log as logging
from cloudinit import user_data as ud
from cloudinit import util
from cloudinit.user_data import processor as ud_proc
DEP_FILESYSTEM = "FILESYSTEM"
DEP_NETWORK = "NETWORK"
DS_PREFIX = 'DataSource'
@ -42,7 +41,6 @@ class DataSource(object):
self.sys_cfg = sys_cfg
self.distro = distro
self.paths = paths
self.userdata_proc = ud_proc.UserDataProcessor(paths)
self.userdata = None
self.metadata = None
self.userdata_raw = None
@ -55,7 +53,7 @@ class DataSource(object):
def get_userdata(self):
if self.userdata is None:
raw_data = self.get_userdata_raw()
self.userdata = self.userdata_proc.process(raw_data)
self.userdata = ud.UserDataProcessor(self.paths).process(raw_data)
return self.userdata
def get_userdata_raw(self):
@ -73,7 +71,7 @@ class DataSource(object):
if not self.metadata or 'public-keys' not in self.metadata:
return keys
if isinstance(self.metadata['public-keys'], (str)):
if isinstance(self.metadata['public-keys'], (basestring, str)):
return str(self.metadata['public-keys']).splitlines()
if isinstance(self.metadata['public-keys'], (list, set)):
@ -84,11 +82,12 @@ class DataSource(object):
# lp:506332 uec metadata service responds with
# data that makes boto populate a string for 'klist' rather
# than a list.
if isinstance(klist, (str)):
if isinstance(klist, (str, basestring)):
klist = [klist]
if isinstance(klist, (list, set)):
for pkey in klist:
# there is an empty string at the end of the keylist, trim it
# There is an empty string at
# the end of the keylist, trim it
if pkey:
keys.append(pkey)
@ -159,13 +158,14 @@ def find_source(sys_cfg, distro, paths, ds_deps, cfg_list, pkg_list):
ds_list = list_sources(cfg_list, ds_deps, pkg_list)
ds_names = [util.obj_name(f) for f in ds_list]
LOG.info("Searching for data source in: %s", ds_names)
for cls in ds_list:
ds = util.obj_name(cls)
try:
s = cls(distro, sys_cfg, paths)
if s.get_data():
return (s, ds)
except Exception as e:
except Exception:
util.logexc(LOG, "Getting data from %s failed", ds)
msg = "Did not find any data source, searched classes: %s" % (ds_names)
@ -178,7 +178,8 @@ def find_source(sys_cfg, distro, paths, ds_deps, cfg_list, pkg_list):
# return an ordered list of classes that match
def list_sources(cfg_list, depends, pkg_list):
src_list = []
LOG.info("Looking for for data source in: %s, %s that match %s", cfg_list, pkg_list, depends)
LOG.info(("Looking for for data source in: %s,"
" %s that matches %s"), cfg_list, pkg_list, depends)
for ds_coll in cfg_list:
ds_name = str(ds_coll)
if not ds_name.startswith(DS_PREFIX):
@ -201,8 +202,8 @@ def list_sources(cfg_list, depends, pkg_list):
if not cls_matches:
continue
src_list.extend(cls_matches)
LOG.debug("Found a match for data source %s in %s with matches %s",
ds_name, mod, cls_matches)
LOG.debug(("Found a match for data source %s"
" in %s with matches %s"), ds_name, mod, cls_matches)
break
return src_list

View File

@ -31,19 +31,23 @@ try:
except ImportError:
ConfigObj = None
from cloudinit.settings import (PER_INSTANCE, FREQUENCIES)
from cloudinit.settings import (OLD_CLOUD_CONFIG)
from cloudinit.settings import (PER_INSTANCE, FREQUENCIES)
from cloudinit.handlers import boot_hook as bh_part
from cloudinit.handlers import cloud_config as cc_part
from cloudinit.handlers import shell_script as ss_part
from cloudinit.handlers import upstart_job as up_part
from cloudinit import cloud
from cloudinit import distros
from cloudinit import modules
from cloudinit import helpers
from cloudinit import importer
from cloudinit import log as logging
from cloudinit import sources
from cloudinit import util
from cloudinit import transforms
from cloudinit import user_data as ud
from cloudinit import util
LOG = logging.getLogger(__name__)
@ -73,12 +77,19 @@ class Init(object):
def distro(self):
if not self._distro:
d_cfg = util.get_cfg_by_path(self.cfg, ('system_info'), {})
# Ensure its a dictionary
if not isinstance(d_cfg, (dict)):
d_cfg = {}
# Ensure not modified indirectly
d_cfg = copy.deepcopy(d_cfg)
# Remove this since its path config, not distro config
d_cfg.pop('paths', None)
distro_cls = distros.fetch(sys_cfg.pop('distro', 'ubuntu'))
# Try to find the right class to use
distro_name = d_cfg.pop('distro', 'ubuntu')
distro_cls = distros.fetch(distro_name)
LOG.debug("Using distro class %s", distro_cls)
distro = distro_cls(d_cfg, helpers.Runners(self.paths))
distro = distro_cls(distro_name, d_cfg,
helpers.Runners(self.paths))
self._distro = distro
return self._distro
@ -93,7 +104,8 @@ class Init(object):
@property
def paths(self):
if not self._paths:
path_info = util.get_cfg_by_path(self.cfg, ('system_info', 'paths'), {})
path_info = util.get_cfg_by_path(self.cfg,
('system_info', 'paths'), {})
# Ensure not modified indirectly
path_info = copy.deepcopy(path_info)
self._paths = helpers.Paths(path_info, self.datasource)
@ -156,7 +168,7 @@ class Init(object):
# by using the instance link, if purge_cache was called
# the file wont exist
return pickle.loads(util.load_file(pickled_fn))
except Exception as e:
except Exception:
util.logexc(LOG, "Failed loading pickled datasource from %s",
pickled_fn)
return None
@ -166,7 +178,7 @@ class Init(object):
try:
contents = pickle.dumps(self.datasource)
util.write_file(pickled_fn, contents, mode=0400)
except Exception as e:
except Exception:
util.logexc(LOG, "Failed pickling datasource to %s", pickled_fn)
return False
@ -192,7 +204,8 @@ class Init(object):
# (which will affect user-data handlers down the line...)
sys_cfg = copy.deepcopy(self.cfg)
ds_deps = copy.deepcopy(self.ds_deps)
(ds, dsname) = sources.find_source(sys_cfg, self.distro, self.paths,
(ds, dsname) = sources.find_source(sys_cfg, self.distro,
self.paths,
ds_deps, cfg_list, pkg_list)
LOG.debug("Loaded datasource %s - %s", dsname, ds)
self.datasource = ds
@ -270,6 +283,20 @@ class Init(object):
processed_ud = "%s" % (self.datasource.get_userdata())
util.write_file(self.paths.get_ipath('userdata'), processed_ud, 0600)
def _default_userdata_handlers(self):
opts = {
'paths': self.paths,
'instance_id': self.datasource.get_instance_id(),
}
# TODO Hmmm, should we dynamically import these??
def_handlers = [
cc_part.CloudConfigPartHandler(**opts),
ss_part.ShellScriptPartHandler(**opts),
bh_part.BootHookPartHandler(**opts),
up_part.UpstartJobPartHandler(**opts),
]
return def_handlers
def consume(self, frequency=PER_INSTANCE):
cdir = self.paths.get_cpath("handlers")
idir = self.paths.get_ipath("handlers")
@ -279,8 +306,11 @@ class Init(object):
sys.path.insert(0, cdir)
sys.path.insert(0, idir)
# Ensure datasource fetched before activation (just incase)
ud_obj = self.datasource.get_userdata()
# This keeps track of all the active handlers
c_handlers = helpers.ContentHandlers(self.paths)
c_handlers = helpers.ContentHandlers(paths=self.paths)
# Add handlers in cdir
potential_handlers = util.find_modules(cdir)
@ -292,13 +322,10 @@ class Init(object):
except:
util.logexc(LOG, "Failed to register handler from %s", fname)
def_handlers = c_handlers.register_defaults()
if def_handlers:
LOG.debug("Registered default handlers for %s", def_handlers)
# Ensure userdata fetched before activation (just incase)
ud_obj = self.datasource.get_userdata()
def_handlers = self._default_userdata_handlers()
applied_def_handlers = c_handlers.register_defaults(def_handlers)
if applied_def_handlers:
LOG.debug("Registered default handlers: %s", applied_def_handlers)
# Form our cloud interface
data = self.cloudify()
@ -334,11 +361,11 @@ class Init(object):
class Transforms(object):
def __init__(self, cloudobj, cfgfile=None):
self.datasource = cloudobj.datasource
def __init__(self, init, cfgfile=None):
self.datasource = init.fetch()
self.cfgfile = cfgfile
self.basecfg = copy.deepcopy(cloudobj.cfg)
self.cloudobj = cloudobj
self.basecfg = copy.deepcopy(init.cfg)
self.init = init
# Created on first use
self._cachedcfg = None
@ -409,25 +436,28 @@ class Transforms(object):
(item, util.obj_name(item)))
return module_list
def _transforms_modules(self, raw_mods):
def _fixup_transforms(self, raw_mods):
mostly_mods = []
for raw_mod in raw_mods:
raw_name = raw_mod['mod']
freq = raw_mod.get('freq')
run_args = raw_mod.get('args') or []
mod_name = modules.form_module_name(raw_name)
mod_name = transforms.form_module_name(raw_name)
if not mod_name:
continue
if freq and freq not in FREQUENCIES:
LOG.warn("Config specified module %s has an unknown frequency %s", raw_name, freq)
LOG.warn(("Config specified transform %s"
" has an unknown frequency %s"), raw_name, freq)
# Reset it so when ran it will get set to a known value
freq = None
mod = modules.fixup_module(importer.import_module(mod_name))
mod = transforms.fixup_module(importer.import_module(mod_name))
mostly_mods.append([mod, raw_name, freq, run_args])
return mostly_mods
def _run_transforms(self, mostly_mods):
failures = []
d_name = self.init.distro.name
c_cloud = self.init.cloudify()
for (mod, name, freq, args) in mostly_mods:
try:
# Try the modules frequency, otherwise fallback to a known one
@ -436,17 +466,17 @@ class Transforms(object):
if not freq in FREQUENCIES:
freq = PER_INSTANCE
worked_distros = mod.distros
if worked_distros and self.cloud.distro.name() not in worked_distros:
LOG.warn(("Module %s is verified on %s distros"
if (worked_distros and d_name not in worked_distros):
LOG.warn(("Transform %s is verified on %s distros"
" but not on %s distro. It may or may not work"
" correctly."), name, worked_distros,
self.cloud.distro.name())
" correctly."), name, worked_distros, d_name)
# Deep copy the config so that modules can't alter it
# Use the transforms logger and not our own
func_args = [name, copy.deepcopy(self.cfg),
self.cloudobj, LOG, args]
# This name will affect the semphapore name created
c_cloud, transforms.LOG, args]
# This name will affect the semaphore name created
run_name = "config-%s" % (name)
self.cloudobj.run(run_name, mod.handle, func_args, freq=freq)
c_cloud.run(run_name, mod.handle, func_args, freq=freq)
except Exception as e:
util.logexc(LOG, "Running %s failed", mod)
failures.append((name, e))
@ -454,5 +484,5 @@ class Transforms(object):
def run(self, name):
raw_mods = self._read_transforms(name)
mostly_mods = self._transforms_modules(raw_mods)
mostly_mods = self._fixup_transforms(raw_mods)
return self._run_transforms(mostly_mods)

View File

@ -44,7 +44,7 @@ def fixup_module(mod, def_freq=PER_INSTANCE):
else:
freq = mod.frequency
if freq and freq not in FREQUENCIES:
LOG.warn("Module %s has an unknown frequency %s", mod, freq)
LOG.warn("Transform %s has an unknown frequency %s", mod, freq)
if not hasattr(mod, 'handle'):
def empty_handle(_name, _cfg, _cloud, _log, _args):
pass

View File

@ -71,7 +71,7 @@ def handle(_name, cfg, cloud, log, _args):
except:
util.logexc(log, "Failed to run debconf-set-selections")
pkglist = util.get_cfg_option_list_or_str(cfg, 'packages', [])
pkglist = util.get_cfg_option_list(cfg, 'packages', [])
errors = []
if update or len(pkglist) or upgrade:
@ -96,7 +96,9 @@ def handle(_name, cfg, cloud, log, _args):
errors.append(e)
if len(errors):
raise errors[0]
log.warn("%s failed with exceptions, re-raising the last one",
len(errors))
raise errors[-1]
def mirror2lists_fileprefix(mirror):
@ -186,7 +188,8 @@ def add_sources(srclist, template_params=None):
try:
util.write_file(ent['filename'], source + "\n", omode="ab")
except:
errorlist.append([source, "failed write to file %s" % ent['filename']])
errorlist.append([source,
"failed write to file %s" % ent['filename']])
return errorlist
@ -219,9 +222,10 @@ def find_apt_mirror(cloud, cfg):
doms.extend((".localdomain", "",))
mirror_list = []
distro = cloud.distro.name
mirrorfmt = "http://%s-mirror%s/%s" % (distro, "%s", distro)
for post in doms:
mirror_list.append(mirrorfmt % post)
mirror_list.append(mirrorfmt % (post))
mirror = util.search_for_mirror(mirror_list)

View File

@ -30,7 +30,8 @@ frequency = PER_ALWAYS
def handle(name, cfg, cloud, log, _args):
if "bootcmd" not in cfg:
log.debug("Skipping module named %s, no 'bootcomd' key in configuration", name)
log.debug(("Skipping transform named %s,"
" no 'bootcomd' key in configuration"), name)
return
with tempfile.NamedTemporaryFile(suffix=".sh") as tmpf:
@ -39,7 +40,7 @@ def handle(name, cfg, cloud, log, _args):
tmpf.write(content)
tmpf.flush()
except:
log.warn("Failed to shellify bootcmd")
util.logexc(log, "Failed to shellify bootcmd")
raise
try:
@ -48,5 +49,6 @@ def handle(name, cfg, cloud, log, _args):
cmd = ['/bin/sh', tmpf.name]
util.subp(cmd, env=env, capture=False)
except:
log.warn("Failed to run commands from bootcmd")
util.logexc(log,
("Failed to run bootcmd transform %s"), name)
raise

View File

@ -30,7 +30,7 @@ def handle(name, cfg, _cloud, log, args):
value = util.get_cfg_option_str(cfg, "byobu_by_default", "")
if not value:
log.debug("Skipping module named %s, no 'byobu' values found", name)
log.debug("Skipping transform named %s, no 'byobu' values found", name)
return
if value == "user" or value == "system":

View File

@ -23,6 +23,8 @@ CA_CERT_FILENAME = "cloud-init-ca-certs.crt"
CA_CERT_CONFIG = "/etc/ca-certificates.conf"
CA_CERT_SYSTEM_PATH = "/etc/ssl/certs/"
distros = ['ubuntu']
def update_ca_certs():
"""
@ -70,22 +72,25 @@ def handle(name, cfg, _cloud, log, _args):
"""
# If there isn't a ca-certs section in the configuration don't do anything
if "ca-certs" not in cfg:
log.debug("Skipping module named %s, no 'ca-certs' key in configuration", name)
log.debug(("Skipping transform named %s,"
" no 'ca-certs' key in configuration"), name)
return
ca_cert_cfg = cfg['ca-certs']
# If there is a remove-defaults option set to true, remove the system
# default trusted CA certs first.
if ca_cert_cfg.get("remove-defaults", False):
log.debug("removing default certificates")
log.debug("Removing default certificates")
remove_default_ca_certs()
# If we are given any new trusted CA certs to add, add them.
if "trusted" in ca_cert_cfg:
trusted_certs = util.get_cfg_option_list_or_str(ca_cert_cfg, "trusted")
trusted_certs = util.get_cfg_option_list(ca_cert_cfg, "trusted")
if trusted_certs:
log.debug("adding %d certificates" % len(trusted_certs))
log.debug("Adding %d certificates" % len(trusted_certs))
add_ca_certs(trusted_certs)
# Update the system with the new cert configuration.
log.debug("Updating certificates")
update_ca_certs()

View File

@ -31,7 +31,8 @@ def handle(name, cfg, cloud, log, _args):
# If there isn't a chef key in the configuration don't do anything
if 'chef' not in cfg:
log.debug("Skipping module named %s, no 'chef' key in configuration", name)
log.debug(("Skipping transform named %s,"
" no 'chef' key in configuration"), name)
return
chef_cfg = cfg['chef']

View File

@ -28,5 +28,6 @@ reject_cmd = ['route', 'add', '-host', '169.254.169.254', 'reject']
def handle(_name, cfg, _cloud, _log, _args):
if util.get_cfg_option_bool(cfg, "disable_ec2_metadata", False):
disabled = util.get_cfg_option_bool(cfg, "disable_ec2_metadata", False)
if disabled:
util.subp(reject_cmd)

View File

@ -32,7 +32,7 @@ final_message_def = ("Cloud-init v. {{version}} finished at {{timestamp}}."
" Up {{uptime}} seconds.")
def handle(name, cfg, cloud, log, args):
def handle(_name, cfg, cloud, log, args):
msg_in = None
if len(args) != 0:
@ -60,7 +60,7 @@ def handle(name, cfg, cloud, log, args):
# Use stdout, stderr or the logger??
content = templater.render_string(msg_in, subs)
sys.stderr.write("%s\n" % (content))
except Exception as e:
except Exception:
util.logexc(log, "Failed to render final message template")
boot_fin_fn = cloud.paths.boot_finished

View File

@ -45,8 +45,8 @@ from cloudinit.settings import PER_INSTANCE
# informational purposes. If non existent all distros are assumed and
# no warning occurs.
frequency = settings.PER_INSTANCE
frequency = PER_INSTANCE
def handle(name, _cfg, _cloud, _log, _args):
print("Hi from %s" % (name))
def handle(name, _cfg, _cloud, log, _args):
log.debug("Hi from transform %s", name)

View File

@ -54,9 +54,9 @@ def handle(_name, cfg, _cloud, log, _args):
# now idevs and idevs_empty are set to determined values
# or, those set by user
dconf_sel = ("grub-pc grub-pc/install_devices string %s\n"
dconf_sel = (("grub-pc grub-pc/install_devices string %s\n"
"grub-pc grub-pc/install_devices_empty boolean %s\n") %
(idevs, idevs_empty)
(idevs, idevs_empty))
log.debug("Setting grub debconf-set-selections with '%s','%s'" %
(idevs, idevs_empty))

View File

@ -18,23 +18,34 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from cloudinit.settings import PER_INSTANCE
from cloudinit import util
frequency = PER_INSTANCE
# This is a tool that cloud init provides
helper_tool = '/usr/lib/cloud-init/write-ssh-key-fingerprints'
def handle(_name, cfg, _cloud, log, _args):
cmd = ['/usr/lib/cloud-init/write-ssh-key-fingerprints']
fp_blacklist = util.get_cfg_option_list_or_str(cfg,
def handle(name, cfg, _cloud, log, _args):
if not os.path.exists(helper_tool):
log.warn(("Unable to activate transform %s,"
" helper tool not found at %s"), name, helper_tool)
return
fp_blacklist = util.get_cfg_option_list(cfg,
"ssh_fp_console_blacklist", [])
key_blacklist = util.get_cfg_option_list_or_str(cfg,
key_blacklist = util.get_cfg_option_list(cfg,
"ssh_key_console_blacklist", ["ssh-dss"])
try:
cmd = [helper_tool]
cmd.append(','.join(fp_blacklist))
cmd.append(','.join(key_blacklist))
(stdout, stderr) = util.subp(cmd)
(stdout, _stderr) = util.subp(cmd)
util.write_file('/dev/console', stdout)
except:
log.warn("Writing keys to console failed!")
log.warn("Writing keys to /dev/console failed!")
raise

View File

@ -55,7 +55,8 @@ def handle(name, cfg, _cloud, log, _args):
/etc/landscape/client.conf
"""
if not ConfigObj:
log.warn("'ConfigObj' support not enabled, running %s disabled", name)
log.warn(("'ConfigObj' support not available,"
" running transform %s disabled"), name)
return
ls_cloudcfg = cfg.get("landscape", {})

View File

@ -49,7 +49,7 @@ def handle(name, cfg, cloud, log, args):
"/etc/default/locale")
if not locale:
log.debug(("Skipping module named %s, "
log.debug(("Skipping transform named %s, "
"no 'locale' configuration found"), name)
return

View File

@ -19,13 +19,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ConfigParser import ConfigParser
from StringIO import StringIO
import os
from cloudinit import cfg as config
from cloudinit import util
from cloudinit import cfg
pubcert_file = "/etc/mcollective/ssl/server-public.pem"
pricert_file = "/etc/mcollective/ssl/server-private.pem"
@ -35,7 +32,7 @@ def handle(name, cfg, cloud, log, _args):
# If there isn't a mcollective key in the configuration don't do anything
if 'mcollective' not in cfg:
log.debug(("Skipping module named %s, "
log.debug(("Skipping transform named %s, "
"no 'mcollective' key in configuration"), name)
return
@ -47,7 +44,7 @@ def handle(name, cfg, cloud, log, _args):
# ... and then update the mcollective configuration
if 'conf' in mcollective_cfg:
# Create object for reading server.cfg values
mcollective_config = cfg.DefaultingConfigParser()
mcollective_config = config.DefaultingConfigParser()
# Read server.cfg values from original file in order to be able to mix
# the rest up
old_contents = util.load_file('/etc/mcollective/server.cfg')

View File

@ -20,7 +20,6 @@
from string import whitespace # pylint: disable=W0402
import os
import re
from cloudinit import util
@ -28,7 +27,7 @@ from cloudinit import util
# shortname matches 'sda', 'sda1', 'xvda', 'hda', 'sdb', xvdb, vda, vdd1
shortname_filter = r"^[x]{0,1}[shv]d[a-z][0-9]*$"
shortname = re.compile(shortname_filter)
ws = re.compile("[%s]+" % whitespace)
ws = re.compile("[%s]+" % (whitespace))
def is_mdname(name):
@ -65,13 +64,14 @@ def handle(_name, cfg, cloud, log, _args):
continue
startname = str(cfgmnt[i][0])
LOG.debug("Attempting to determine the real name of %s", startname)
log.debug("Attempting to determine the real name of %s", startname)
# workaround, allow user to specify 'ephemeral'
# rather than more ec2 correct 'ephemeral0'
if startname == "ephemeral":
cfgmnt[i][0] = "ephemeral0"
log.debug("Adjusted mount option %s name from ephemeral to ephemeral0", (i + 1))
log.debug(("Adjusted mount option %s "
"name from ephemeral to ephemeral0"), (i + 1))
if is_mdname(startname):
newname = cloud.device_name_to_device(startname)
@ -136,7 +136,8 @@ def handle(_name, cfg, cloud, log, _args):
break
if cfgmnt_has:
log.debug("Not including %s, already previously included", startname)
log.debug(("Not including %s, already"
" previously included"), startname)
continue
cfgmnt.append(defmnt)
@ -159,7 +160,7 @@ def handle(_name, cfg, cloud, log, _args):
dirs = []
for line in actlist:
# write 'comment' in the fs_mntops, entry, claiming this
line[3] = "%s,comment=cloudconfig" % line[3]
line[3] = "%s,%s" % (line[3], comment)
if line[2] == "swap":
needswap = True
if line[1].startswith("/"):
@ -168,7 +169,7 @@ def handle(_name, cfg, cloud, log, _args):
fstab_lines = []
fstab = util.load_file("/etc/fstab")
for line in fstab.read().splitlines():
for line in fstab.splitlines():
try:
toks = ws.split(line)
if toks[3].find(comment) != -1:

View File

@ -24,9 +24,8 @@ from cloudinit import util
from cloudinit.settings import PER_INSTANCE
from time import sleep
frequency = PER_INSTANCE
post_list_all = ['pub_key_dsa', 'pub_key_rsa', 'pub_key_ecdsa',
'instance_id', 'hostname']
@ -49,7 +48,7 @@ def handle(name, cfg, cloud, log, args):
ph_cfg = cfg['phone_home']
if 'url' not in ph_cfg:
log.warn(("Skipping module named %s, "
log.warn(("Skipping transform named %s, "
"no 'url' found in 'phone_home' configuration"), name)
return
@ -60,7 +59,8 @@ def handle(name, cfg, cloud, log, args):
tries = int(tries)
except:
tries = 10
util.logexc(log, "Configuration entry 'tries' is not an integer, using %s", tries)
util.logexc(log, ("Configuration entry 'tries'"
" is not an integer, using %s instead"), tries)
if post_list == "all":
post_list = post_list_all
@ -75,23 +75,37 @@ def handle(name, cfg, cloud, log, args):
'pub_key_ecdsa': '/etc/ssh/ssh_host_ecdsa_key.pub',
}
for n, path in pubkeys.iteritems():
for (n, path) in pubkeys.iteritems():
try:
all_keys[n] = util.load_file(path)
except:
util.logexc(log, "%s: failed to open, can not phone home that data", path)
util.logexc(log, ("%s: failed to open, can not"
" phone home that data"), path)
submit_keys = {}
for k in post_list:
if k in all_keys:
submit_keys[k] = all_keys[k]
else:
submit_keys[k] = "N/A"
log.warn("Requested key %s from 'post' configuration list not available", k)
submit_keys[k] = None
log.warn(("Requested key %s from 'post'"
" configuration list not available"), k)
url = templater.render_string(url, {'INSTANCE_ID': all_keys['instance_id']})
# Get them read to be posted
real_submit_keys = {}
for (k, v) in submit_keys.iteritems():
if v is None:
real_submit_keys[k] = 'N/A'
else:
real_submit_keys[k] = str(v)
# Incase the url is parameterized
url_params = {
'INSTANCE_ID': all_keys['instance_id'],
}
url = templater.render_string(url, url_params)
try:
uhelp.readurl(url, data=submit_keys, retries=tries, sec_between=3)
uhelp.readurl(url, data=real_submit_keys, retries=tries, sec_between=3)
except:
util.logexc(log, "Failed to post phone home data to %s in %s tries", url, tries)
util.logexc(log, ("Failed to post phone home data to"
" %s in %s tries"), url, tries)

View File

@ -24,31 +24,32 @@ import os
import pwd
import socket
from cloudinit import cfg as config
from cloudinit import util
from cloudinit import cfg
def handle(name, cfg, cloud, log, _args):
# If there isn't a puppet key in the configuration don't do anything
if 'puppet' not in cfg:
log.debug(("Skipping module named %s,"
log.debug(("Skipping transform named %s,"
" no 'puppet' configuration found"), name)
return
puppet_cfg = cfg['puppet']
# Start by installing the puppet package ...
cloud.distro.install_packages(("puppet",))
cloud.distro.install_packages(["puppet"])
# ... and then update the puppet configuration
if 'conf' in puppet_cfg:
# Add all sections from the conf object to puppet.conf
contents = util.load_file('/etc/puppet/puppet.conf')
# Create object for reading puppet.conf values
puppet_config = cfg.DefaultingConfigParser()
puppet_config = config.DefaultingConfigParser()
# Read puppet.conf values from original file in order to be able to
# mix the rest up. First clean them up (TODO is this really needed??)
cleaned_contents = '\n'.join([i.lstrip() for i in contents.splitlines()])
cleaned_lines = [i.lstrip() for i in contents.splitlines()]
cleaned_contents = '\n'.join(cleaned_lines)
puppet_config.readfp(StringIO(cleaned_contents),
filename='/etc/puppet/puppet.conf')
for (cfg_name, cfg) in puppet_cfg['conf'].iteritems():
@ -81,7 +82,8 @@ def handle(name, cfg, cloud, log, _args):
puppet_config.set(cfg_name, o, v)
# We got all our config as wanted we'll rename
# the previous puppet.conf and create our new one
util.rename('/etc/puppet/puppet.conf', '/etc/puppet/puppet.conf.old')
util.rename('/etc/puppet/puppet.conf',
'/etc/puppet/puppet.conf.old')
contents = puppet_config.stringify()
util.write_file('/etc/puppet/puppet.conf', contents)
@ -91,7 +93,8 @@ def handle(name, cfg, cloud, log, _args):
'-e', 's/^START=.*/START=yes/',
'/etc/default/puppet'], capture=False)
elif os.path.exists('/bin/systemctl'):
util.subp(['/bin/systemctl', 'enable', 'puppet.service'], capture=False)
util.subp(['/bin/systemctl', 'enable', 'puppet.service'],
capture=False)
elif os.path.exists('/sbin/chkconfig'):
util.subp(['/sbin/chkconfig', 'puppet', 'on'], capture=False)
else:

View File

@ -18,11 +18,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import errno
import os
import stat
import sys
import tempfile
import time
from cloudinit import util
@ -46,15 +43,18 @@ def nodeify_path(devpth, where, log):
if util.is_container():
log.debug("Inside container, ignoring mknod failure in resizefs")
return
log.warn("Failed to make device node to resize %s at %s", where, devpth)
log.warn("Failed to make device node to resize %s at %s",
where, devpth)
raise
def get_fs_type(st_dev, path, log):
try:
fs_type = util.find_devs_with(tag='TYPE', oformat='value',
dev_entries = util.find_devs_with(tag='TYPE', oformat='value',
no_cache=True, path=path)
return fs_type
if not dev_entries:
return None
return dev_entries[0].strip()
except util.ProcessExecutionError:
util.logexc(log, ("Failed to get filesystem type"
" of maj=%s, min=%s for path %s"),
@ -69,12 +69,16 @@ def handle(name, cfg, _cloud, log, args):
resize_root = util.get_cfg_option_str(cfg, "resize_rootfs", True)
if not util.translate_bool(resize_root):
log.debug("Skipping module named %s, resizing disabled", name)
log.debug("Skipping transform named %s, resizing disabled", name)
return
# TODO is the directory ok to be used??
resize_root_d = util.get_cfg_option_str(cfg, "resize_rootfs_tmp", "/run")
util.ensure_dir(resize_root_d)
# TODO: allow what is to be resized to
# be configurable??
resize_what = "/"
with util.SilentTemporaryFile(prefix="cloudinit.resizefs.",
dir=resize_root_d, delete=True) as tfh:
devpth = tfh.name
@ -86,23 +90,25 @@ def handle(name, cfg, _cloud, log, args):
# auto deletion
tfh.unlink_now()
# TODO: allow what is to be resized to
# be configurable??
st_dev = nodeify_path(devpth, "/", log)
fs_type = get_fs_type(st_dev, devpath, log)
st_dev = nodeify_path(devpth, resize_what, log)
fs_type = get_fs_type(st_dev, devpth, log)
if not fs_type:
log.warn("Could not determine filesystem type of %s", resize_what)
return
resizer = None
fstype_lc = fstype.lower()
fstype_lc = fs_type.lower()
for (pfix, root_cmd) in resize_fs_prefixes_cmds:
if fstype_lc.startswith(pfix):
resizer = root_cmd
break
if not resizer:
log.warn("Not resizing unknown filesystem type %s", fs_type)
log.warn("Not resizing unknown filesystem type %s for %s",
fs_type, resize_what)
return
log.debug("Resizing using %s", resizer)
log.debug("Resizing %s (%s) using %s", resize_what, fs_type, resizer)
resize_cmd = [resizer, devpth]
if resize_root == "noblock":
@ -125,8 +131,8 @@ def do_resize(resize_cmd, log):
start = time.time()
try:
util.subp(resize_cmd)
except util.ProcessExecutionError as e:
util.logexc(log, "Failed to resize filesystem (using %s)", resize_cmd)
except util.ProcessExecutionError:
util.logexc(log, "Failed to resize filesystem (cmd=%s)", resize_cmd)
raise
tot_time = int(time.time() - start)
log.debug("Resizing took %s seconds", tot_time)

View File

@ -53,16 +53,19 @@ def handle(name, _cfg, cloud, log, _args):
try:
ud = cloud.get_userdata_raw()
except:
log.warn("Failed to get raw userdata in module %s", name)
log.warn("Failed to get raw userdata in transform %s", name)
return
try:
mdict = parse_qs(ud)
if not mdict or not my_hookname in mdict:
log.debug("Skipping module %s, did not find %s in parsed raw userdata", name, my_hookname)
log.debug(("Skipping transform %s, "
"did not find %s in parsed"
" raw userdata"), name, my_hookname)
return
except:
log.warn("Failed to parse query string %s into a dictionary", ud)
util.logexc(log, ("Failed to parse query string %s"
" into a dictionary"), ud)
raise
wrote_fns = []
@ -83,7 +86,8 @@ def handle(name, _cfg, cloud, log, _args):
wrote_fns.append(fname)
except Exception as e:
captured_excps.append(e)
util.logexc(log, "%s failed to read %s and write %s", my_name, url, fname)
util.logexc(log, "%s failed to read %s and write %s",
my_name, url, fname)
if wrote_fns:
log.debug("Wrote out rightscale userdata to %s files", len(wrote_fns))
@ -93,6 +97,6 @@ def handle(name, _cfg, cloud, log, _args):
log.debug("%s urls were skipped or failed", skipped)
if captured_excps:
log.warn("%s failed with exceptions, re-raising the last one", len(captured_excps))
log.warn("%s failed with exceptions, re-raising the last one",
len(captured_excps))
raise captured_excps[-1]

View File

@ -36,7 +36,8 @@ def handle(name, cfg, cloud, log, _args):
# process 'rsyslog'
if not 'rsyslog' in cfg:
log.debug("Skipping module named %s, no 'rsyslog' key in configuration", name)
log.debug(("Skipping transform named %s,"
" no 'rsyslog' key in configuration"), name)
return
def_dir = cfg.get('rsyslog_dir', DEF_DIR)
@ -62,15 +63,16 @@ def handle(name, cfg, cloud, log, _args):
if not filename.startswith("/"):
filename = os.path.join(def_dir, filename)
# Truncate filename first time you see it
omode = "ab"
# truncate filename first time you see it
if filename not in files:
omode = "wb"
files.append(filename)
try:
util.write_file(filename, content + "\n", omode=omode)
except Exception as e:
contents = "%s\n" % (content)
util.write_file(filename, contents, omode=omode)
except Exception:
util.logexc(log, "Failed to write to %s", filename)
# Attempt to restart syslogd
@ -87,8 +89,8 @@ def handle(name, cfg, cloud, log, _args):
log.debug("Restarting rsyslog")
util.subp(['service', 'rsyslog', 'restart'])
restarted = True
except Exception as e:
util.logexc("Failed restarting rsyslog")
except Exception:
util.logexc(log, "Failed restarting rsyslog")
if restarted:
# This only needs to run if we *actually* restarted

View File

@ -25,13 +25,14 @@ from cloudinit import util
def handle(name, cfg, cloud, log, _args):
if "runcmd" not in cfg:
log.debug("Skipping module named %s, no 'runcmd' key in configuration", name)
log.debug(("Skipping transform named %s,"
" no 'runcmd' key in configuration"), name)
return
outfile = os.path.join(cloud.get_ipath('scripts'), "runcmd")
out_fn = os.path.join(cloud.get_ipath('scripts'), "runcmd")
cmd = cfg["runcmd"]
try:
content = util.shellify(cmd)
util.write_file(outfile, content, 0700)
util.write_file(out_fn, content, 0700)
except:
util.logexc(log, "Failed to shellify %s into file %s", cmd, outfile)
util.logexc(log, "Failed to shellify %s into file %s", cmd, out_fn)

View File

@ -21,16 +21,17 @@ from cloudinit import util
# Note: see http://saltstack.org/topics/installation/
def handle(name, cfg, cloud, _log, _args):
def handle(name, cfg, cloud, log, _args):
# If there isn't a salt key in the configuration don't do anything
if 'salt_minion' not in cfg:
log.debug("Skipping module named %s, no 'salt_minion' key in configuration", name)
log.debug(("Skipping transform named %s,"
" no 'salt_minion' key in configuration"), name)
return
salt_cfg = cfg['salt_minion']
# Start by installing the salt package ...
cloud.distro.install_packages(("salt",))
cloud.distro.install_packages(["salt"])
# Ensure we can configure files at the right dir
config_dir = salt_cfg.get("config_dir", '/etc/salt')

View File

@ -29,12 +29,13 @@ frequency = PER_ALWAYS
script_subdir = 'per-boot'
def handle(_name, _cfg, cloud, log, _args):
def handle(name, _cfg, cloud, log, _args):
# Comes from the following:
# https://forums.aws.amazon.com/thread.jspa?threadID=96918
runparts_path = os.path.join(cloud.get_cpath(), 'scripts', script_subdir)
try:
util.runparts(runparts_path)
except:
log.warn("Failed to run-parts(%s) in %s", script_subdir, runparts_path)
log.warn("Failed to run transform %s (%s in %s)",
name, script_subdir, runparts_path)
raise

View File

@ -29,12 +29,13 @@ frequency = PER_INSTANCE
script_subdir = 'per-instance'
def handle(_name, _cfg, cloud, log, _args):
def handle(name, _cfg, cloud, log, _args):
# Comes from the following:
# https://forums.aws.amazon.com/thread.jspa?threadID=96918
runparts_path = os.path.join(cloud.get_cpath(), 'scripts', script_subdir)
try:
util.runparts(runparts_path)
except:
log.warn("Failed to run-parts(%s) in %s", script_subdir, runparts_path)
log.warn("Failed to run transform %s (%s in %s)",
name, script_subdir, runparts_path)
raise

View File

@ -29,12 +29,13 @@ frequency = PER_ONCE
script_subdir = 'per-once'
def handle(_name, _cfg, cloud, log, _args):
def handle(name, _cfg, cloud, log, _args):
# Comes from the following:
# https://forums.aws.amazon.com/thread.jspa?threadID=96918
runparts_path = os.path.join(cloud.get_cpath(), 'scripts', script_subdir)
try:
util.runparts(runparts_path)
except:
log.warn("Failed to run-parts(%s) in %s", script_subdir, runparts_path)
log.warn("Failed to run transform %s (%s in %s)",
name, script_subdir, runparts_path)
raise

View File

@ -26,14 +26,17 @@ from cloudinit.settings import PER_INSTANCE
frequency = PER_INSTANCE
script_subdir = 'scripts'
def handle(_name, _cfg, cloud, log, _args):
def handle(name, _cfg, cloud, log, _args):
# This is written to by the user data handlers
# Ie, any custom shell scripts that come down
# go here...
runparts_path = os.path.join(cloud.get_ipath_cur(), "scripts")
runparts_path = os.path.join(cloud.get_ipath_cur(), script_subdir)
try:
util.runparts(runparts_path)
except:
log.warn("Failed to run-parts(%s) in %s", "user-data", runparts_path)
log.warn("Failed to run transform %s (%s in %s)",
name, script_subdir, runparts_path)
raise

View File

@ -24,7 +24,7 @@ from cloudinit import util
def handle(name, cfg, cloud, log, _args):
if util.get_cfg_option_bool(cfg, "preserve_hostname", False):
log.debug(("Configuration option 'preserve_hostname' is set,"
" not setting the hostname in %s"), name)
" not setting the hostname in transform %s"), name)
return
(hostname, _fqdn) = util.get_hostname_fqdn(cfg, cloud)

View File

@ -22,7 +22,7 @@ import sys
from cloudinit import util
from string import letters, digits
from string import letters, digits # pylint: disable=W0402
# We are removing certain 'painful' letters/numbers
pw_set = (letters.translate(None, 'loLOI') +
@ -71,11 +71,13 @@ def handle(_name, cfg, cloud, log, args):
util.subp(['chpasswd'], ch_in)
except Exception as e:
errors.append(e)
util.logexc(log, "Failed to set passwords with chpasswd for %s", users)
util.logexc(log,
"Failed to set passwords with chpasswd for %s", users)
if len(randlist):
sys.stderr.write("%s\n%s\n" % ("Set the following 'random' passwords\n",
'\n'.join(randlist)))
blurb = ("Set the following 'random' passwords\n",
'\n'.join(randlist))
sys.stderr.write("%s\n%s\n" % blurb)
if expire:
expired_users = []

View File

@ -66,7 +66,6 @@ def handle(_name, cfg, cloud, log, _args):
tgt_perms = key2file[key][1]
util.write_file(tgt_fn, val, tgt_perms)
cmd = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"'
for priv, pub in priv2pub.iteritems():
if pub in cfg['ssh_keys'] or not priv in cfg['ssh_keys']:
continue
@ -78,11 +77,15 @@ def handle(_name, cfg, cloud, log, _args):
util.subp(cmd, capture=False)
log.debug("Generated a key for %s from %s", pair[0], pair[1])
except:
util.logexc(log, "Failed generated a key for %s from %s", pair[0], pair[1])
util.logexc(log, ("Failed generated a key"
" for %s from %s"), pair[0], pair[1])
else:
# if not, generate them
for keytype in util.get_cfg_option_list_or_str(cfg, 'ssh_genkeytypes', generate_keys):
keyfile = '/etc/ssh/ssh_host_%s_key' % keytype
genkeys = util.get_cfg_option_list(cfg,
'ssh_genkeytypes',
generate_keys)
for keytype in genkeys:
keyfile = '/etc/ssh/ssh_host_%s_key' % (keytype)
if not os.path.exists(keyfile):
cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile]
try:
@ -90,26 +93,27 @@ def handle(_name, cfg, cloud, log, _args):
with util.SeLinuxGuard("/etc/ssh", recursive=True):
util.subp(cmd, capture=False)
except:
util.logexc(log, "Failed generating key type %s to file %s", keytype, keyfile)
util.logexc(log, ("Failed generating key type"
" %s to file %s"), keytype, keyfile)
try:
user = util.get_cfg_option_str(cfg, 'user')
disable_root = util.get_cfg_option_bool(cfg, "disable_root", True)
disable_root_opts = util.get_cfg_option_str(cfg, "disable_root_opts",
DISABLE_ROOT_OPTS)
DISABLE_ROOT_OPTS)
keys = cloud.get_public_ssh_keys() or []
if "ssh_authorized_keys" in cfg:
cfgkeys = cfg["ssh_authorized_keys"]
keys.extend(cfgkeys)
apply_credentials(keys, user, disable_root, disable_root_opts, log)
apply_credentials(keys, user, disable_root, disable_root_opts)
except:
util.logexc(log, "Applying ssh credentials failed!")
def apply_credentials(keys, user, disable_root,
disable_root_opts=DISABLE_ROOT_OPTS, log=None):
disable_root_opts=DISABLE_ROOT_OPTS):
keys = set(keys)
if user:

View File

@ -33,10 +33,14 @@ def handle(name, cfg, _cloud, log, args):
ids = args[1:]
else:
user = util.get_cfg_option_str(cfg, "user", "ubuntu")
ids = util.get_cfg_option_list_or_str(cfg, "ssh_import_id", [])
ids = util.get_cfg_option_list(cfg, "ssh_import_id", [])
if len(ids) == 0:
log.debug("Skipping module named %s, no ids found to import", name)
log.debug("Skipping transform named %s, no ids found to import", name)
return
if not user:
log.debug("Skipping transform named %s, no user found to import", name)
return
cmd = ["sudo", "-Hu", user, "ssh-import-id"] + ids

View File

@ -18,19 +18,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from cloudinit import util
from cloudinit.settings import PER_INSTANCE
frequency = PER_INSTANCE
def handle(_name, cfg, cloud, log, args):
def handle(name, cfg, cloud, log, args):
if len(args) != 0:
timezone = args[0]
else:
timezone = util.get_cfg_option_str(cfg, "timezone", False)
if not timezone:
log.debug("Skipping module named %s, no 'timezone' specified", name)
log.debug("Skipping transform named %s, no 'timezone' specified", name)
return
# Let the distro handle settings its timezone

View File

@ -30,22 +30,30 @@ def handle(name, cfg, cloud, log, _args):
manage_hosts = util.get_cfg_option_str(cfg, "manage_etc_hosts", False)
if util.translate_bool(manage_hosts, addons=['template']):
(hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
# Render from template file
if not hostname:
log.warn("Option 'manage_etc_hosts' was set, but no hostname was found")
log.warn(("Option 'manage_etc_hosts' was set,"
" but no hostname was found"))
return
tpl_fn_name = cloud.get_template_filename("hosts.%s" % (cloud.distro.name()))
# Render from a template file
distro_n = cloud.distro.name
tpl_fn_name = cloud.get_template_filename("hosts.%s" % (distro_n))
if not tpl_fn_name:
raise Exception("No hosts template could be found for distro %s" % (cloud.distro.name()))
raise Exception(("No hosts template could be"
" found for distro %s") % (distro_n))
templater.render_to_file(tpl_fn_name, '/etc/hosts',
{'hostname': hostname, 'fqdn': fqdn})
elif manage_hosts == "localhost":
log.debug("Managing localhost in /etc/hosts")
(hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
if not hostname:
log.warn("Option 'manage_etc_hosts' was set, but no hostname was found")
log.warn(("Option 'manage_etc_hosts' was set,"
" but no hostname was found"))
return
log.debug("Managing localhost in /etc/hosts")
cloud.distro.update_etc_hosts(hostname, fqdn)
else:
log.debug(("Configuration option 'manage_etc_hosts' is not set,"
" not managing /etc/hosts in %s"), name)
" not managing /etc/hosts in transform %s"), name)

View File

@ -18,6 +18,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from cloudinit import util
from cloudinit.settings import PER_ALWAYS
@ -27,7 +29,7 @@ frequency = PER_ALWAYS
def handle(name, cfg, cloud, log, _args):
if util.get_cfg_option_bool(cfg, "preserve_hostname", False):
log.debug(("Configuration option 'preserve_hostname' is set,"
" not updating the hostname in %s"), name)
" not updating the hostname in transform %s"), name)
return
(hostname, _fqdn) = util.get_hostname_fqdn(cfg, cloud)

View File

@ -35,9 +35,9 @@ welcome_message_def = ("Cloud-init v. {{version}} starting stage {{stage}} at "
frequency = PER_ALWAYS
def handle(name, cfg, cloud, log, args):
def handle(_name, cfg, cloud, log, args):
welcome_msg = util.get_cfg_option_str(cfg, "welcome_msg"):
welcome_msg = util.get_cfg_option_str(cfg, "welcome_msg")
if not welcome_msg:
tpl_fn = cloud.get_template_filename("welcome_msg")
if tpl_fn:
@ -54,7 +54,7 @@ def handle(name, cfg, cloud, log, args):
'stage': stage,
'version': version.version_string(),
'uptime': util.uptime(),
'timestamp', util.time_rfc2822(),
'timestamp': util.time_rfc2822(),
}
try:
contents = templater.render_string(welcome_msg, tpl_params)

View File

@ -22,14 +22,15 @@
import os
import glob
import email
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from cloudinit import importer
from cloudinit import log as logging
from cloudinit import url_helper
from cloudinit import util
from cloudinit.settings import (PER_ALWAYS, PER_INSTANCE, FREQUENCIES)
@ -86,7 +87,7 @@ class UserDataProcessor(object):
self.paths = paths
def process(self, blob):
base_msg = ud.convert_string(blob)
base_msg = convert_string(blob)
process_msg = MIMEMultipart()
self._process_msg(base_msg, process_msg)
return process_msg
@ -105,7 +106,7 @@ class UserDataProcessor(object):
ctype_orig = UNDEF_TYPE
if ctype_orig in TYPE_NEEDED:
ctype = ud.type_from_starts_with(payload)
ctype = type_from_starts_with(payload)
if ctype is None:
ctype = ctype_orig
@ -158,7 +159,7 @@ class UserDataProcessor(object):
if not url_helper.ok_http_code(st):
content = ''
new_msg = ud.convert_string(content)
new_msg = convert_string(content)
self._process_msg(new_msg, append_msg)
def _explode_archive(self, archive, append_msg):
@ -179,7 +180,7 @@ class UserDataProcessor(object):
content = ent.get('content', '')
mtype = ent.get('type')
if not mtype:
mtype = ud.type_from_starts_with(content, ARCHIVE_UNDEF_TYPE)
mtype = type_from_starts_with(content, ARCHIVE_UNDEF_TYPE)
maintype, subtype = mtype.split('/', 1)
if maintype == "text":

View File

@ -22,8 +22,8 @@
from StringIO import StringIO
import copy as obj_copy
import contextlib
import copy
import errno
import glob
import grp
@ -35,12 +35,11 @@ import pwd
import random
import shutil
import socket
import string
import string # pylint: disable=W0402
import subprocess
import sys
import tempfile
import time
import traceback
import types
import urlparse
@ -171,7 +170,8 @@ def fork_cb(child_cb, *args):
child_cb(*args)
os._exit(0) # pylint: disable=W0212
except:
logexc(LOG, "Failed forking and calling callback %s", obj_name(child_cb))
logexc(LOG, ("Failed forking and"
" calling callback %s"), obj_name(child_cb))
os._exit(1) # pylint: disable=W0212
else:
LOG.debug("Forked child %s who will run callback %s",
@ -549,10 +549,11 @@ def load_yaml(blob, default=None, allowed=(dict,)):
converted = yaml.load(blob)
if not isinstance(converted, allowed):
# Yes this will just be caught, but thats ok for now...
raise TypeError("Yaml load allows %s root types, but got %s instead" %
raise TypeError(("Yaml load allows %s root types,"
" but got %s instead") %
(allowed, obj_name(converted)))
loaded = converted
except (yaml.YAMLError, TypeError, ValueError) as exc:
except (yaml.YAMLError, TypeError, ValueError):
logexc(LOG, "Failed loading yaml blob")
return loaded
@ -833,15 +834,12 @@ def find_devs_with(criteria=None, oformat='device',
options.append(path)
cmd = blk_id_cmd + options
(out, _err) = subp(cmd)
if path:
return out.strip()
else:
entries = []
for line in out.splitlines():
line = line.strip()
if line:
entries.append(line)
return entries
entries = []
for line in out.splitlines():
line = line.strip()
if line:
entries.append(line)
return entries
def load_file(fname, read_cb=None, quiet=False):
@ -1109,7 +1107,7 @@ def mount_cb(device, callback, data=None, rw=False, mtype=None):
def get_builtin_cfg():
# Deep copy so that others can't modify
return copy.deepcopy(CFG_BUILTIN)
return obj_copy.deepcopy(CFG_BUILTIN)
def sym_link(source, link):
@ -1140,16 +1138,14 @@ def time_rfc2822():
def uptime():
uptime_str = '??'
try:
uptimef = load_file("/proc/uptime").strip()
if not uptimef:
uptime = 'na'
else:
uptime = uptimef.split()[0]
contents = load_file("/proc/uptime").strip()
if contents:
uptime_str = contents.split()[0]
except:
logexc(LOG, "Unable to read uptime from /proc/uptime")
uptime = '??'
return uptime
return uptime_str
def ensure_file(path):
@ -1261,7 +1257,8 @@ def shellify(cmdlist, add_header=True):
content = "%s%s\n" % (content, args)
else:
raise RuntimeError(("Unable to shellify type %s"
" which is not a list or string") % (obj_name(args)))
" which is not a list or string")
% (obj_name(args)))
LOG.debug("Shellified %s to %s", cmdlist, content)
return content
@ -1275,8 +1272,7 @@ def is_container():
try:
# try to run a helper program. if it returns true/zero
# then we're inside a container. otherwise, no
cmd = [helper]
subp(cmd, allowed_rc=[0])
subp([helper])
return True
except (IOError, OSError):
pass