summaryrefslogtreecommitdiff
path: root/cloudinit/DataSourceNoCloud.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/DataSourceNoCloud.py')
-rw-r--r--cloudinit/DataSourceNoCloud.py152
1 files changed, 152 insertions, 0 deletions
diff --git a/cloudinit/DataSourceNoCloud.py b/cloudinit/DataSourceNoCloud.py
new file mode 100644
index 00000000..573f3f43
--- /dev/null
+++ b/cloudinit/DataSourceNoCloud.py
@@ -0,0 +1,152 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2009-2010 Canonical Ltd.
+#
+# Author: Scott Moser <scott.moser@canonical.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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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 DataSource
+
+import cloudinit
+import cloudinit.util as util
+import sys
+import os.path
+import os
+import errno
+
+class DataSourceNoCloud(DataSource.DataSource):
+ metadata = None
+ userdata = None
+ userdata_raw = None
+ supported_seed_starts = ( "/" , "file://" )
+ seed = None
+ cmdline_id = "ds=nocloud"
+ seeddir = cloudinit.cachedir + '/nocloud'
+
+ def __init__(self):
+ pass
+
+ def __str__(self):
+ mstr="DataSourceNoCloud"
+ mstr = mstr + " [seed=%s]" % self.seed
+ return(mstr)
+
+ def get_data(self):
+ defaults = {
+ "local-hostname" : "ubuntuhost",
+ "instance-id" : "nocloud"
+ }
+
+ md = { }
+ ud = ""
+
+ try:
+ # parse the kernel command line, getting data passed in
+ md = parse_cmdline_data(self.cmdline_id)
+ except:
+ util.logexc(cloudinit.log,util.WARN)
+ return False
+
+ # check to see if the seeddir has data.
+ try:
+ (seeddir_md,ud) = util.read_seeded(self.seeddir + "/")
+ self.metadata = md
+ md = util.mergedict(md,seeddir_md)
+ cloudinit.log.debug("using seeded cache data in %s" % self.seeddir)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ util.logexc(cloudinit.log,util.WARN)
+ raise
+
+ # there was no indication on kernel cmdline or data
+ # in the seeddir suggesting this handler should be used.
+ if md is None:
+ return False
+
+ # the special argument "seedfrom" indicates we should
+ # attempt to seed the userdata / metadata from its value
+ if "seedfrom" in md:
+ seedfrom = md["seedfrom"]
+ found = False
+ for proto in self.supported_seed_starts:
+ if seedfrom.startswith(proto):
+ found=proto
+ break
+ if not found:
+ cloudinit.log.debug("seed from %s not supported by %s" %
+ (seedfrom, self.__class__))
+ return False
+
+ # this could throw errors, but the user told us to do it
+ # so if errors are raised, let them raise
+ (md_seed,ud) = util.read_seeded(seedfrom)
+ cloudinit.log.debug("using seeded cache data from %s" % seedfrom)
+
+ # values in the command line override those from the seed
+ md = util.mergedict(md,md_seed)
+ self.seed = seedfrom
+
+ md = util.mergedict(md,defaults)
+ self.metadata = md;
+ self.userdata_raw = ud
+ return True
+
+# returns a dictionary of key/val or None if cmdline did not have data
+# example cmdline:
+# root=LABEL=uec-rootfs ro ds=nocloud
+def parse_cmdline_data(ds_id,cmdline=None):
+ if cmdline is None:
+ if 'DEBUG_PROC_CMDLINE' in os.environ:
+ cmdline = os.environ["DEBUG_PROC_CMDLINE"]
+ else:
+ cmdfp = open("/proc/cmdline")
+ cmdline = cmdfp.read().strip()
+ cmdfp.close()
+ cmdline = " %s " % cmdline.lower()
+
+ if not ( " %s " % ds_id in cmdline or " %s;" % ds_id in cmdline ):
+ return None
+
+ argline=""
+ # cmdline can contain:
+ # ds=nocloud[;key=val;key=val]
+ for tok in cmdline.split():
+ if tok.startswith(ds_id): argline=tok.split("=",1)
+
+ # argline array is now 'nocloud' followed optionally by
+ # a ';' and then key=value pairs also terminated with ';'
+ tmp=argline[1].split(";")
+ if len(tmp) > 1:
+ kvpairs=tmp[1:]
+ else:
+ kvpairs=()
+
+ # short2long mapping to save cmdline typing
+ s2l = { "h" : "local-hostname", "i" : "instance-id", "s" : "seedfrom" }
+ cfg = { }
+ for item in kvpairs:
+ try:
+ (k,v) = item.split("=",1)
+ except:
+ k=item
+ v=None
+ if k in s2l: k=s2l[k]
+ cfg[k]=v
+
+ return(cfg)
+
+class DataSourceNoCloudNet(DataSourceNoCloud):
+ cmdline_id = "ds=nocloud-net"
+ supported_seed_starts = ( "http://", "https://", "ftp://" )
+ seeddir = cloudinit.cachedir + '/nocloud-net'