merge in work form ds-rework
rework of DataSource loading. The DataSources that are loaded are now controlled entirely via configuration file of 'datasource_list', like: datasource_list: [ "NoCloud", "OVF", "Ec2" ] Each item in that list is a "DataSourceCollection". for each item in the list, cloudinit will attempt to load: cloudinit.DataSource<item> and, failing that, DataSource<item> The module is required to have a method named 'get_datasource_list' in it that takes a single list of "dependencies" and returns a list of python classes inside the collection that can run needing only those dependencies. The dependencies are defines in DataSource.py. Currently: DEP_FILESYSTEM = "FILESYSTEM" DEP_NETWORK = "NETWORK" When 'get_datasource_list' is called for the DataSourceOVF module with [DEP_FILESYSTEM], then DataSourceOVF returns a single item list with a reference to the 'DataSourceOVF' class. When 'get_datasource_list' is called for the DataSourceOVF module with [DEP_FILESYSTEM, DEP_NETWORK], it will return a single item list with a reference to 'DataSourceOVFNet'. cloudinit will then instanciate the class and call its 'get_data' method. if the get_data method returns 'True', then it selects this class as the selected Datasource.
This commit is contained in:
commit
319a824e04
@ -31,3 +31,7 @@
|
|||||||
via the config file, or user data config file
|
via the config file, or user data config file
|
||||||
- add support for posting data about the instance to a url (phone_home)
|
- add support for posting data about the instance to a url (phone_home)
|
||||||
- add minimal OVF transport (iso) support
|
- add minimal OVF transport (iso) support
|
||||||
|
- make DataSources that are attempted dynamic and configurable from
|
||||||
|
system config. changen "cloud_type: auto" as configuration for this
|
||||||
|
to 'datasource_list: [ "Ec2" ]'. Each of the items in that list
|
||||||
|
must be modules that can be loaded by "DataSource<item>"
|
||||||
|
@ -23,6 +23,7 @@ import sys
|
|||||||
import cloudinit
|
import cloudinit
|
||||||
import cloudinit.util as util
|
import cloudinit.util as util
|
||||||
import cloudinit.CloudConfig as CC
|
import cloudinit.CloudConfig as CC
|
||||||
|
import cloudinit.DataSource as ds
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
import errno
|
import errno
|
||||||
@ -32,10 +33,19 @@ def warn(wstr):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
cmds = ( "start", "start-local" )
|
cmds = ( "start", "start-local" )
|
||||||
|
deps = { "start" : ( ds.DEP_FILESYSTEM, ds.DEP_NETWORK ),
|
||||||
|
"start-local" : ( ds.DEP_FILESYSTEM, ) }
|
||||||
|
|
||||||
cmd = ""
|
cmd = ""
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
cmd = sys.argv[1]
|
cmd = sys.argv[1]
|
||||||
|
|
||||||
|
cfg_path = None
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
# this is really for debugging only
|
||||||
|
# but you can invoke on development system with ./config/cloud.cfg
|
||||||
|
cfg_path = sys.argv[2]
|
||||||
|
|
||||||
if not cmd in cmds:
|
if not cmd in cmds:
|
||||||
sys.stderr.write("bad command %s. use one of %s\n" % (cmd, cmds))
|
sys.stderr.write("bad command %s. use one of %s\n" % (cmd, cmds))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@ -49,12 +59,17 @@ def main():
|
|||||||
warn("unable to open /proc/uptime\n")
|
warn("unable to open /proc/uptime\n")
|
||||||
uptime = "na"
|
uptime = "na"
|
||||||
|
|
||||||
source_type = "all"
|
try:
|
||||||
if cmd == "start-local":
|
cfg = cloudinit.get_base_cfg(cfg_path)
|
||||||
source_type = "local"
|
except Exception as e:
|
||||||
|
warn("Failed to get base config. falling back to builtin: %s\n" % e)
|
||||||
|
try:
|
||||||
|
cfg = cloudinit.get_builtin_cfg()
|
||||||
|
except Exception as e:
|
||||||
|
warn("Unable to load builtin config\n")
|
||||||
|
raise
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cfg = cloudinit.get_base_cfg()
|
|
||||||
(outfmt, errfmt) = CC.get_output_cfg(cfg,"init")
|
(outfmt, errfmt) = CC.get_output_cfg(cfg,"init")
|
||||||
CC.redirect_output(outfmt, errfmt)
|
CC.redirect_output(outfmt, errfmt)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -80,7 +95,7 @@ def main():
|
|||||||
if cmd == "start-local":
|
if cmd == "start-local":
|
||||||
cloudinit.purge_cache()
|
cloudinit.purge_cache()
|
||||||
|
|
||||||
cloud = cloudinit.CloudInit(source_type=source_type)
|
cloud = cloudinit.CloudInit(ds_deps=deps[cmd])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cloud.get_data_source()
|
cloud.get_data_source()
|
||||||
|
@ -16,16 +16,23 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import cloudinit
|
|
||||||
|
DEP_FILESYSTEM = "FILESYSTEM"
|
||||||
|
DEP_NETWORK = "NETWORK"
|
||||||
|
|
||||||
import UserDataHandler as ud
|
import UserDataHandler as ud
|
||||||
|
|
||||||
class DataSource:
|
class DataSource:
|
||||||
userdata = None
|
userdata = None
|
||||||
metadata = None
|
metadata = None
|
||||||
userdata_raw = None
|
userdata_raw = None
|
||||||
|
log = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, log=None):
|
||||||
pass
|
if not log:
|
||||||
|
import logging
|
||||||
|
log = logging.log
|
||||||
|
self.log = log
|
||||||
|
|
||||||
def get_userdata(self):
|
def get_userdata(self):
|
||||||
if self.userdata == None:
|
if self.userdata == None:
|
||||||
@ -91,3 +98,46 @@ class DataSource:
|
|||||||
return("ip-%s" % '-'.join(r))
|
return("ip-%s" % '-'.join(r))
|
||||||
except: pass
|
except: pass
|
||||||
return toks[0]
|
return toks[0]
|
||||||
|
|
||||||
|
# return a list of classes that have the same depends as 'depends'
|
||||||
|
# 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=[]):
|
||||||
|
retlist = []
|
||||||
|
for ds_coll in cfg_list:
|
||||||
|
for pkg in pkglist:
|
||||||
|
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)
|
||||||
|
|
||||||
|
# depends is a list of dependencies (DEP_FILESYSTEM)
|
||||||
|
# dslist is a list of 2 item lists
|
||||||
|
# dslist = [
|
||||||
|
# ( class, ( depends-that-this-class-needs ) )
|
||||||
|
# }
|
||||||
|
# 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 = [ ]
|
||||||
|
depset = set(depends)
|
||||||
|
for elem in dslist:
|
||||||
|
(cls, deps) = elem
|
||||||
|
if depset == set(deps):
|
||||||
|
retlist.append(cls)
|
||||||
|
return(retlist)
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
import DataSource
|
import DataSource
|
||||||
|
|
||||||
import cloudinit
|
from cloudinit import seeddir
|
||||||
import cloudinit.util as util
|
import cloudinit.util as util
|
||||||
import socket
|
import socket
|
||||||
import urllib2
|
import urllib2
|
||||||
@ -30,10 +30,7 @@ import errno
|
|||||||
|
|
||||||
class DataSourceEc2(DataSource.DataSource):
|
class DataSourceEc2(DataSource.DataSource):
|
||||||
api_ver = '2009-04-04'
|
api_ver = '2009-04-04'
|
||||||
seeddir = cloudinit.seeddir + '/ec2'
|
seeddir = seeddir + '/ec2'
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return("DataSourceEc2")
|
return("DataSourceEc2")
|
||||||
@ -43,7 +40,7 @@ class DataSourceEc2(DataSource.DataSource):
|
|||||||
if util.read_optional_seed(seedret,base=self.seeddir+ "/"):
|
if util.read_optional_seed(seedret,base=self.seeddir+ "/"):
|
||||||
self.userdata_raw = seedret['user-data']
|
self.userdata_raw = seedret['user-data']
|
||||||
self.metadata = seedret['meta-data']
|
self.metadata = seedret['meta-data']
|
||||||
cloudinit.log.debug("using seeded ec2 data in %s" % self.seeddir)
|
self.log.debug("using seeded ec2 data in %s" % self.seeddir)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -105,13 +102,13 @@ class DataSourceEc2(DataSource.DataSource):
|
|||||||
reason = "url error [%s]" % e.reason
|
reason = "url error [%s]" % e.reason
|
||||||
|
|
||||||
if x == 0:
|
if x == 0:
|
||||||
cloudinit.log.warning("waiting for metadata service at %s\n" % url)
|
self.log.warning("waiting for metadata service at %s\n" % url)
|
||||||
|
|
||||||
cloudinit.log.warning(" %s [%02s/%s]: %s\n" %
|
self.log.warning(" %s [%02s/%s]: %s\n" %
|
||||||
(time.strftime("%H:%M:%S",time.gmtime()), x+1, sleeps, reason))
|
(time.strftime("%H:%M:%S",time.gmtime()), x+1, sleeps, reason))
|
||||||
time.sleep(sleeptime)
|
time.sleep(sleeptime)
|
||||||
|
|
||||||
cloudinit.log.critical("giving up on md after %i seconds\n" %
|
self.log.critical("giving up on md after %i seconds\n" %
|
||||||
int(time.time()-starttime))
|
int(time.time()-starttime))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -131,7 +128,7 @@ class DataSourceEc2(DataSource.DataSource):
|
|||||||
if entname == "ephemeral" and name == "ephemeral0":
|
if entname == "ephemeral" and name == "ephemeral0":
|
||||||
found = device
|
found = device
|
||||||
if found == None:
|
if found == None:
|
||||||
cloudinit.log.warn("unable to convert %s to a device" % name)
|
self.log.warn("unable to convert %s to a device" % name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# LP: #611137
|
# LP: #611137
|
||||||
@ -154,7 +151,7 @@ class DataSourceEc2(DataSource.DataSource):
|
|||||||
for nto in tlist:
|
for nto in tlist:
|
||||||
cand = "/dev/%s%s" % (nto, short[len(nfrom):])
|
cand = "/dev/%s%s" % (nto, short[len(nfrom):])
|
||||||
if os.path.exists(cand):
|
if os.path.exists(cand):
|
||||||
cloudinit.log.debug("remapped device name %s => %s" % (found,cand))
|
self.log.debug("remapped device name %s => %s" % (found,cand))
|
||||||
return(cand)
|
return(cand)
|
||||||
return ofound
|
return ofound
|
||||||
|
|
||||||
@ -165,3 +162,11 @@ class DataSourceEc2(DataSource.DataSource):
|
|||||||
(p4 not in self.metadata or self.metadata[p4] == "")):
|
(p4 not in self.metadata or self.metadata[p4] == "")):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
datasources = [
|
||||||
|
( DataSourceEc2, ( DataSource.DEP_FILESYSTEM , DataSource.DEP_NETWORK ) ),
|
||||||
|
]
|
||||||
|
|
||||||
|
# return a list of data sources that match this set of dependencies
|
||||||
|
def get_datasource_list(depends):
|
||||||
|
return(DataSource.list_from_depends(depends, datasources))
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
import DataSource
|
import DataSource
|
||||||
|
|
||||||
import cloudinit
|
from cloudinit import seeddir
|
||||||
import cloudinit.util as util
|
import cloudinit.util as util
|
||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
@ -32,10 +32,7 @@ class DataSourceNoCloud(DataSource.DataSource):
|
|||||||
supported_seed_starts = ( "/" , "file://" )
|
supported_seed_starts = ( "/" , "file://" )
|
||||||
seed = None
|
seed = None
|
||||||
cmdline_id = "ds=nocloud"
|
cmdline_id = "ds=nocloud"
|
||||||
seeddir = cloudinit.seeddir + '/nocloud'
|
seeddir = seeddir + '/nocloud'
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
mstr="DataSourceNoCloud"
|
mstr="DataSourceNoCloud"
|
||||||
@ -57,7 +54,7 @@ class DataSourceNoCloud(DataSource.DataSource):
|
|||||||
if parse_cmdline_data(self.cmdline_id, md):
|
if parse_cmdline_data(self.cmdline_id, md):
|
||||||
found.append("cmdline")
|
found.append("cmdline")
|
||||||
except:
|
except:
|
||||||
util.logexc(cloudinit.log,util.WARN)
|
util.logexc(self.log,util.WARN)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# check to see if the seeddir has data.
|
# check to see if the seeddir has data.
|
||||||
@ -66,7 +63,7 @@ class DataSourceNoCloud(DataSource.DataSource):
|
|||||||
md = util.mergedict(md,seedret['meta-data'])
|
md = util.mergedict(md,seedret['meta-data'])
|
||||||
ud = seedret['user-data']
|
ud = seedret['user-data']
|
||||||
found.append(self.seeddir)
|
found.append(self.seeddir)
|
||||||
cloudinit.log.debug("using seeded cache data in %s" % self.seeddir)
|
self.log.debug("using seeded cache data in %s" % self.seeddir)
|
||||||
|
|
||||||
# there was no indication on kernel cmdline or data
|
# there was no indication on kernel cmdline or data
|
||||||
# in the seeddir suggesting this handler should be used.
|
# in the seeddir suggesting this handler should be used.
|
||||||
@ -83,14 +80,14 @@ class DataSourceNoCloud(DataSource.DataSource):
|
|||||||
seedfound=proto
|
seedfound=proto
|
||||||
break
|
break
|
||||||
if not seedfound:
|
if not seedfound:
|
||||||
cloudinit.log.debug("seed from %s not supported by %s" %
|
self.log.debug("seed from %s not supported by %s" %
|
||||||
(seedfrom, self.__class__))
|
(seedfrom, self.__class__))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# this could throw errors, but the user told us to do it
|
# this could throw errors, but the user told us to do it
|
||||||
# so if errors are raised, let them raise
|
# so if errors are raised, let them raise
|
||||||
(md_seed,ud) = util.read_seeded(seedfrom)
|
(md_seed,ud) = util.read_seeded(seedfrom)
|
||||||
cloudinit.log.debug("using seeded cache data from %s" % seedfrom)
|
self.log.debug("using seeded cache data from %s" % seedfrom)
|
||||||
|
|
||||||
# values in the command line override those from the seed
|
# values in the command line override those from the seed
|
||||||
md = util.mergedict(md,md_seed)
|
md = util.mergedict(md,md_seed)
|
||||||
@ -143,4 +140,14 @@ def parse_cmdline_data(ds_id,fill,cmdline=None):
|
|||||||
class DataSourceNoCloudNet(DataSourceNoCloud):
|
class DataSourceNoCloudNet(DataSourceNoCloud):
|
||||||
cmdline_id = "ds=nocloud-net"
|
cmdline_id = "ds=nocloud-net"
|
||||||
supported_seed_starts = ( "http://", "https://", "ftp://" )
|
supported_seed_starts = ( "http://", "https://", "ftp://" )
|
||||||
seeddir = cloudinit.seeddir + '/nocloud-net'
|
seeddir = seeddir + '/nocloud-net'
|
||||||
|
|
||||||
|
datasources = (
|
||||||
|
( DataSourceNoCloud, ( DataSource.DEP_FILESYSTEM, ) ),
|
||||||
|
( DataSourceNoCloudNet,
|
||||||
|
( DataSource.DEP_FILESYSTEM, DataSource.DEP_NETWORK ) ),
|
||||||
|
)
|
||||||
|
|
||||||
|
# return a list of data sources that match this set of dependencies
|
||||||
|
def get_datasource_list(depends):
|
||||||
|
return(DataSource.list_from_depends(depends, datasources))
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
import DataSource
|
import DataSource
|
||||||
|
|
||||||
import cloudinit
|
from cloudinit import seeddir
|
||||||
import cloudinit.util as util
|
import cloudinit.util as util
|
||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
@ -27,19 +27,19 @@ import errno
|
|||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from xml.dom import Node
|
from xml.dom import Node
|
||||||
import base64
|
import base64
|
||||||
|
import re
|
||||||
|
import tempfile
|
||||||
|
import subprocess
|
||||||
|
|
||||||
class DataSourceOVF(DataSource.DataSource):
|
class DataSourceOVF(DataSource.DataSource):
|
||||||
seed = None
|
seed = None
|
||||||
seeddir = cloudinit.seeddir + '/ovf'
|
seeddir = seeddir + '/ovf'
|
||||||
environment = None
|
environment = None
|
||||||
cfg = { }
|
cfg = { }
|
||||||
userdata_raw = None
|
userdata_raw = None
|
||||||
metadata = None
|
metadata = None
|
||||||
supported_seed_starts = ( "/" , "file://" )
|
supported_seed_starts = ( "/" , "file://" )
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
mstr="DataSourceOVF"
|
mstr="DataSourceOVF"
|
||||||
mstr = mstr + " [seed=%s]" % self.seed
|
mstr = mstr + " [seed=%s]" % self.seed
|
||||||
@ -87,12 +87,12 @@ class DataSourceOVF(DataSource.DataSource):
|
|||||||
seedfound = proto
|
seedfound = proto
|
||||||
break
|
break
|
||||||
if not seedfound:
|
if not seedfound:
|
||||||
cloudinit.log.debug("seed from %s not supported by %s" %
|
self.log.debug("seed from %s not supported by %s" %
|
||||||
(seedfrom, self.__class__))
|
(seedfrom, self.__class__))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
(md_seed,ud) = util.read_seeded(seedfrom)
|
(md_seed,ud) = util.read_seeded(seedfrom)
|
||||||
cloudinit.log.debug("using seeded cache data from %s" % seedfrom)
|
self.log.debug("using seeded cache data from %s" % seedfrom)
|
||||||
|
|
||||||
md = util.mergedict(md,md_seed)
|
md = util.mergedict(md,md_seed)
|
||||||
found.append(seedfrom)
|
found.append(seedfrom)
|
||||||
@ -119,7 +119,7 @@ class DataSourceOVF(DataSource.DataSource):
|
|||||||
return(self.cfg)
|
return(self.cfg)
|
||||||
|
|
||||||
class DataSourceOVFNet(DataSourceOVF):
|
class DataSourceOVFNet(DataSourceOVF):
|
||||||
seeddir = cloudinit.seeddir + '/ovf-net'
|
seeddir = seeddir + '/ovf-net'
|
||||||
supported_seed_starts = ( "http://", "https://", "ftp://" )
|
supported_seed_starts = ( "http://", "https://", "ftp://" )
|
||||||
|
|
||||||
# this will return a dict with some content
|
# this will return a dict with some content
|
||||||
@ -280,6 +280,16 @@ def getProperties(environString):
|
|||||||
|
|
||||||
return(props)
|
return(props)
|
||||||
|
|
||||||
|
datasources = (
|
||||||
|
( DataSourceOVF, ( DataSource.DEP_FILESYSTEM, ) ),
|
||||||
|
( DataSourceOVFNet,
|
||||||
|
( DataSource.DEP_FILESYSTEM, DataSource.DEP_NETWORK ) ),
|
||||||
|
)
|
||||||
|
|
||||||
|
# return a list of data sources that match this set of dependencies
|
||||||
|
def get_datasource_list(depends):
|
||||||
|
return(DataSource.list_from_depends(depends, datasources))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
envStr = open(sys.argv[1]).read()
|
envStr = open(sys.argv[1]).read()
|
||||||
|
@ -27,7 +27,7 @@ cfg_env_name = "CLOUD_CFG"
|
|||||||
|
|
||||||
cfg_builtin = """
|
cfg_builtin = """
|
||||||
log_cfgs: [ ]
|
log_cfgs: [ ]
|
||||||
cloud_type: auto
|
datasource_list: [ "NoCloud", "OVF", "Ec2" ]
|
||||||
def_log_file: /var/log/cloud-init.log
|
def_log_file: /var/log/cloud-init.log
|
||||||
syslog_fix_perms: syslog:adm
|
syslog_fix_perms: syslog:adm
|
||||||
"""
|
"""
|
||||||
@ -101,29 +101,17 @@ def logging_set_from_cfg(cfg):
|
|||||||
raise Exception("no valid logging found\n")
|
raise Exception("no valid logging found\n")
|
||||||
|
|
||||||
|
|
||||||
import DataSourceEc2
|
import DataSource
|
||||||
import DataSourceNoCloud
|
|
||||||
import DataSourceOVF
|
|
||||||
import UserDataHandler
|
import UserDataHandler
|
||||||
|
|
||||||
class CloudInit:
|
class CloudInit:
|
||||||
datasource_map = {
|
|
||||||
"ec2" : DataSourceEc2.DataSourceEc2,
|
|
||||||
"nocloud" : DataSourceNoCloud.DataSourceNoCloud,
|
|
||||||
"nocloud-net" : DataSourceNoCloud.DataSourceNoCloudNet,
|
|
||||||
"ovf" : DataSourceOVF.DataSourceOVF,
|
|
||||||
}
|
|
||||||
datasource = None
|
|
||||||
auto_orders = {
|
|
||||||
"all": ( "nocloud-net", "ec2" ),
|
|
||||||
"local" : ( "nocloud", "ovf" ),
|
|
||||||
}
|
|
||||||
cfg = None
|
cfg = None
|
||||||
part_handlers = { }
|
part_handlers = { }
|
||||||
old_conffile = '/etc/ec2-init/ec2-config.cfg'
|
old_conffile = '/etc/ec2-init/ec2-config.cfg'
|
||||||
source_type = "all"
|
ds_deps = [ DataSource.DEP_FILESYSTEM, DataSource.DEP_NETWORK ]
|
||||||
|
datasource = None
|
||||||
|
|
||||||
def __init__(self, source_type = "all", sysconfig=system_config):
|
def __init__(self, ds_deps = None, sysconfig=system_config):
|
||||||
self.part_handlers = {
|
self.part_handlers = {
|
||||||
'text/x-shellscript' : self.handle_user_script,
|
'text/x-shellscript' : self.handle_user_script,
|
||||||
'text/cloud-config' : self.handle_cloud_config,
|
'text/cloud-config' : self.handle_cloud_config,
|
||||||
@ -131,15 +119,19 @@ class CloudInit:
|
|||||||
'text/part-handler' : self.handle_handler,
|
'text/part-handler' : self.handle_handler,
|
||||||
'text/cloud-boothook' : self.handle_cloud_boothook
|
'text/cloud-boothook' : self.handle_cloud_boothook
|
||||||
}
|
}
|
||||||
|
if ds_deps != None:
|
||||||
|
self.ds_deps = ds_deps
|
||||||
self.sysconfig=sysconfig
|
self.sysconfig=sysconfig
|
||||||
self.cfg=self.read_cfg()
|
self.cfg=self.read_cfg()
|
||||||
self.source_type = source_type
|
|
||||||
|
|
||||||
def read_cfg(self):
|
def read_cfg(self):
|
||||||
if self.cfg:
|
if self.cfg:
|
||||||
return(self.cfg)
|
return(self.cfg)
|
||||||
|
|
||||||
conf = util.get_base_cfg(self.sysconfig,cfg_builtin, parsed_cfgs)
|
try:
|
||||||
|
conf = util.get_base_cfg(self.sysconfig,cfg_builtin, parsed_cfgs)
|
||||||
|
except Exception as e:
|
||||||
|
conf = get_builtin_cfg()
|
||||||
|
|
||||||
# support reading the old ConfigObj format file and merging
|
# support reading the old ConfigObj format file and merging
|
||||||
# it into the yaml dictionary
|
# it into the yaml dictionary
|
||||||
@ -182,9 +174,6 @@ class CloudInit:
|
|||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_cloud_type(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_data_source(self):
|
def get_data_source(self):
|
||||||
if self.datasource is not None: return True
|
if self.datasource is not None: return True
|
||||||
|
|
||||||
@ -192,21 +181,14 @@ class CloudInit:
|
|||||||
log.debug("restored from cache type %s" % self.datasource)
|
log.debug("restored from cache type %s" % self.datasource)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
dslist=[ ]
|
cfglist=self.cfg['datasource_list']
|
||||||
cfglist=self.cfg['cloud_type']
|
dslist = list_sources(cfglist, self.ds_deps)
|
||||||
if cfglist == "auto":
|
dsnames = map(lambda f: f.__name__, dslist)
|
||||||
dslist = self.auto_orders[self.source_type]
|
log.debug("searching for data source in %s" % dsnames)
|
||||||
elif cfglist:
|
for cls in dslist:
|
||||||
for ds in cfglist.split(','):
|
ds = cls.__name__
|
||||||
dslist.append(strip(ds).tolower())
|
|
||||||
|
|
||||||
log.debug("searching for data source in [%s]" % str(dslist))
|
|
||||||
for ds in dslist:
|
|
||||||
if ds not in self.datasource_map:
|
|
||||||
log.warn("data source %s not found in map" % ds)
|
|
||||||
continue
|
|
||||||
try:
|
try:
|
||||||
s = self.datasource_map[ds]()
|
s = cls(log)
|
||||||
if s.get_data():
|
if s.get_data():
|
||||||
self.datasource = s
|
self.datasource = s
|
||||||
self.datasource_name = ds
|
self.datasource_name = ds
|
||||||
@ -216,8 +198,9 @@ class CloudInit:
|
|||||||
log.warn("get_data of %s raised %s" % (ds,e))
|
log.warn("get_data of %s raised %s" % (ds,e))
|
||||||
util.logexc(log)
|
util.logexc(log)
|
||||||
pass
|
pass
|
||||||
log.debug("did not find data source from %s" % dslist)
|
msg = "Did not find data source. searched classes: %s" % dsnames
|
||||||
raise DataSourceNotFoundException("Could not find data source")
|
log.debug(msg)
|
||||||
|
raise DataSourceNotFoundException(msg)
|
||||||
|
|
||||||
def set_cur_instance(self):
|
def set_cur_instance(self):
|
||||||
try:
|
try:
|
||||||
@ -532,8 +515,15 @@ def get_ipath_cur(name=None):
|
|||||||
def get_cpath(name=None):
|
def get_cpath(name=None):
|
||||||
return("%s%s" % (varlibdir, pathmap[name]))
|
return("%s%s" % (varlibdir, pathmap[name]))
|
||||||
|
|
||||||
def get_base_cfg():
|
def get_base_cfg(cfg_path=None):
|
||||||
return(util.get_base_cfg(system_config,cfg_builtin,parsed_cfgs))
|
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):
|
class DataSourceNotFoundException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def list_sources(cfg_list, depends):
|
||||||
|
return(DataSource.list_sources(cfg_list,depends, ["cloudinit", "" ]))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
cloud: auto
|
|
||||||
user: ubuntu
|
user: ubuntu
|
||||||
disable_root: 1
|
disable_root: 1
|
||||||
preserve_hostname: False
|
preserve_hostname: False
|
||||||
|
# datasource_list: [ "NoCloud", "OVF", "Ec2" ]
|
||||||
|
|
||||||
cloud_init_modules:
|
cloud_init_modules:
|
||||||
- resizefs
|
- resizefs
|
||||||
|
Loading…
x
Reference in New Issue
Block a user