summaryrefslogtreecommitdiff
path: root/cloudinit/sources/__init__.py
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2012-06-09 12:38:19 -0700
committerJoshua Harlow <harlowja@yahoo-inc.com>2012-06-09 12:38:19 -0700
commitad9122034ff59fb6113adfac2713c44af09bc91b (patch)
tree783f23799b67a782c5390d945fb374fe62f3471b /cloudinit/sources/__init__.py
parentc2b0379b6ab35f2d283ee0882f5ce61f0ca19c6f (diff)
downloadvyos-cloud-init-ad9122034ff59fb6113adfac2713c44af09bc91b.tar.gz
vyos-cloud-init-ad9122034ff59fb6113adfac2713c44af09bc91b.zip
Initial cleanups
Diffstat (limited to 'cloudinit/sources/__init__.py')
-rw-r--r--cloudinit/sources/__init__.py188
1 files changed, 93 insertions, 95 deletions
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index 9a9c1316..05c8bfad 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -1,10 +1,12 @@
# vi: ts=4 expandtab
#
-# Copyright (C) 2009-2010 Canonical Ltd.
+# Copyright (C) 2012 Canonical Ltd.
# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2012 Yahoo! Inc.
#
# Author: Scott Moser <scott.moser@canonical.com>
-# Author: Juerg Hafliger <juerg.haefliger@hp.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3, as
@@ -18,78 +20,78 @@
# 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 user_data as ud
+from cloudinit import importer
+from cloudinit import log as logging
from cloudinit import util
-import socket
-
DEP_FILESYSTEM = "FILESYSTEM"
DEP_NETWORK = "NETWORK"
+DS_PREFIX = 'DataSource'
+LOG = logging.getLogger(__name__)
+
class DataSourceNotFoundException(Exception):
pass
-class DataSource:
- userdata = None
- metadata = None
- userdata_raw = None
- cfgname = ""
- # system config (passed in from cloudinit,
- # cloud-config before input from the DataSource)
- sys_cfg = {}
- # datasource config, the cloud-config['datasource']['__name__']
- ds_cfg = {} # datasource config
-
- def __init__(self, sys_cfg=None):
- if not self.cfgname:
- name = str(self.__class__).split(".")[-1]
- if name.startswith("DataSource"):
- name = name[len("DataSource"):]
- self.cfgname = name
+class DataSource(object):
+ def __init__(self, ud_proc, cfg):
+ name = util.obj_name(self)
+ if name.startswith(DS_PREFIX):
+ name = name[DS_PREFIX:]
+ self.cfgname = name
if sys_cfg:
self.sys_cfg = sys_cfg
-
+ else:
+ self.sys_cfg = {}
+ self.ud_proc = ud_proc
+ self.userdata = None
+ self.metadata = None
+ self.userdata_raw = None
self.ds_cfg = util.get_cfg_by_path(self.sys_cfg,
("datasource", self.cfgname), self.ds_cfg)
def get_userdata(self):
- if self.userdata == None:
- self.userdata = ud.preprocess_userdata(self.userdata_raw)
+ if self.userdata is None:
+ raw_data = self.get_userdata_raw()
+ self.userdata = self.ud_proc.process(raw_data)
return self.userdata
def get_userdata_raw(self):
- return(self.userdata_raw)
+ return self.userdata_raw
# the data sources' config_obj is a cloud-config formated
# object that came to it from ways other than cloud-config
# because cloud-config content would be handled elsewhere
def get_config_obj(self):
- return({})
+ return {}
def get_public_ssh_keys(self):
keys = []
- if 'public-keys' not in self.metadata:
- return([])
- if isinstance(self.metadata['public-keys'], str):
- return(str(self.metadata['public-keys']).splitlines())
+ if not self.metadata or 'public-keys' not in self.metadata:
+ return keys
- if isinstance(self.metadata['public-keys'], list):
- return(self.metadata['public-keys'])
+ if isinstance(self.metadata['public-keys'], (str)):
+ return str(self.metadata['public-keys']).splitlines()
- for _keyname, klist in self.metadata['public-keys'].items():
- # lp:506332 uec metadata service responds with
- # data that makes boto populate a string for 'klist' rather
- # than a list.
- if isinstance(klist, str):
- klist = [klist]
- for pkey in klist:
- # there is an empty string at the end of the keylist, trim it
- if pkey:
- keys.append(pkey)
+ if isinstance(self.metadata['public-keys'], (list, set)):
+ return list(self.metadata['public-keys'])
- return(keys)
+ if isinstance(self.metadata['public-keys'], (dict)):
+ for _keyname, klist in self.metadata['public-keys'].items():
+ # lp:506332 uec metadata service responds with
+ # data that makes boto populate a string for 'klist' rather
+ # than a list.
+ if isinstance(klist, (str)):
+ klist = [klist]
+ if isinstance(klist, (list)):
+ for pkey in klist:
+ # there is an empty string at the end of the keylist, trim it
+ if pkey:
+ keys.append(pkey)
+
+ return keys
def device_name_to_device(self, _name):
# translate a 'name' to a device
@@ -97,48 +99,43 @@ class DataSource:
# to consult metadata service, that has
# ephemeral0: sdb
# and return 'sdb' for input 'ephemeral0'
- return(None)
+ return None
def get_locale(self):
- return('en_US.UTF-8')
+ return 'en_US.UTF-8'
def get_local_mirror(self):
return None
def get_instance_id(self):
- if 'instance-id' not in self.metadata:
+ if not self.metadata or 'instance-id' not in self.metadata:
return "iid-datasource"
- return(self.metadata['instance-id'])
+ return str(self.metadata['instance-id'])
def get_hostname(self, fqdn=False):
defdomain = "localdomain"
defhost = "localhost"
-
domain = defdomain
- if not 'local-hostname' in self.metadata:
+ if not self.metadata or not 'local-hostname' in self.metadata:
# this is somewhat questionable really.
# the cloud datasource was asked for a hostname
# and didn't have one. raising error might be more appropriate
# but instead, basically look up the existing hostname
toks = []
-
- hostname = socket.gethostname()
-
+ hostname = util.get_hostname()
fqdn = util.get_fqdn_from_hosts(hostname)
-
if fqdn and fqdn.find(".") > 0:
toks = str(fqdn).split(".")
elif hostname:
toks = [hostname, defdomain]
else:
toks = [defhost, defdomain]
-
else:
# if there is an ipv4 address in 'local-hostname', then
# make up a hostname (LP: #475354) in format ip-xx.xx.xx.xx
lhost = self.metadata['local-hostname']
- if is_ipv4(lhost):
+ if util.is_ipv4(lhost):
toks = "ip-%s" % lhost.replace(".", "-")
else:
toks = lhost.split(".")
@@ -155,22 +152,22 @@ class DataSource:
return hostname
-def find_source(cfg, ds_deps):
- cfglist = cfg.get('datasource_list') or []
- dslist = list_sources(cfglist, ds_deps)
- dsnames = [f.__name__ for f in dslist]
-
- LOG.debug("Searching for data source in %s", dsnames)
- for cls in dslist:
- ds = cls.__name__
+def find_source(cfg, ds_deps, cfg_list, pkg_list, **kwargs):
+ ds_list = list_sources(cfg_list, ds_deps, pkg_list)
+ ds_names = [util.obj_name(f) for f in ds_list]
+ ds_args = dict(kwargs)
+ ds_args['cfg'] = cfg
+ LOG.info("Searching for data source in: %s", ds_names)
+ for cls in ds_list:
+ ds = util.obj_name(cls)
try:
- s = cls(sys_cfg=cfg)
+ s = cls(**ds_args)
if s.get_data():
return (s, ds)
except Exception as e:
- LOG.exception("Getting data from %s raised %s", ds, e)
+ LOG.exception("Getting data from %s failed", ds)
- msg = "Did not find any data source, searched classes: %s" % dsnames
+ msg = "Did not find any data source, searched classes: %s" % (ds_names)
raise DataSourceNotFoundException(msg)
@@ -178,31 +175,33 @@ def find_source(cfg, ds_deps):
# iterate through cfg_list, loading "DataSourceCollections" modules
# and calling their "get_datasource_list".
# return an ordered list of classes that match
-#
-# - modules must be named "DataSource<item>", where 'item' is an entry
-# in cfg_list
-# - if pkglist is given, it will iterate try loading from that package
-# ie, pkglist=[ "foo", "" ]
-# will first try to load foo.DataSource<item>
-# then DataSource<item>
-def list_sources(cfg_list, depends, pkglist=None):
- if pkglist is None:
- pkglist = []
- retlist = []
+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)
for ds_coll in cfg_list:
- for pkg in pkglist:
+ ds_name = str(ds_coll)
+ if not ds_name.startswith(DS_PREFIX):
+ ds_name = '%s%s' % (DS_PREFIX, ds_name)
+ for pkg in pkg_list:
+ pkg_name = []
+ if pkg:
+ pkg_name.append(str(pkg))
+ pkg_name.append(ds_name)
+ mod_name = ".".join(pkg_name)
+ mod = importer.import_module(mod_name)
if pkg:
- pkg = "%s." % pkg
- try:
- mod = __import__("%sDataSource%s" % (pkg, ds_coll))
- if pkg:
- mod = getattr(mod, "DataSource%s" % ds_coll)
- lister = getattr(mod, "get_datasource_list")
- retlist.extend(lister(depends))
- break
- except:
- raise
- return(retlist)
+ mod = getattr(mod, ds_name, None)
+ if not mod:
+ continue
+ lister = getattr(mod, "get_datasource_list", None)
+ if not lister:
+ continue
+ cls_matches = lister(depends)
+ if not cls_matches:
+ continue
+ src_list.extend(cls_matches)
+ break
+ return src_list
# depends is a list of dependencies (DEP_FILESYSTEM)
@@ -213,10 +212,9 @@ def list_sources(cfg_list, depends, pkglist=None):
# it returns a list of 'class' that matched these deps exactly
# it is a helper function for DataSourceCollections
def list_from_depends(depends, dslist):
- retlist = []
+ ret_list = []
depset = set(depends)
- for elem in dslist:
- (cls, deps) = elem
+ for (cls, deps) in dslist:
if depset == set(deps):
- retlist.append(cls)
- return(retlist)
+ ret_list.append(cls)
+ return ret_list