summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Moser <smoser@ubuntu.com>2011-01-19 18:35:07 +0000
committerScott Moser <smoser@ubuntu.com>2011-01-19 18:35:07 +0000
commitee03480e670c10d48a4825a458fac18aaf4fbec0 (patch)
treeeebc82706725efaa70eb9267791bb03f30c47678
parent32eab86a04f4f6056b200e1cfac99ec0495cd5c0 (diff)
downloadvyos-cloud-init-ee03480e670c10d48a4825a458fac18aaf4fbec0.tar.gz
vyos-cloud-init-ee03480e670c10d48a4825a458fac18aaf4fbec0.zip
initial /var/lib rework still lots to do. includes a fix for LP: #704509
LP: #704509
-rwxr-xr-xcloud-init.py17
-rw-r--r--cloudinit/__init__.py93
-rw-r--r--cloudinit/util.py28
-rw-r--r--doc/var-lib-cloud.txt7
4 files changed, 125 insertions, 20 deletions
diff --git a/cloud-init.py b/cloud-init.py
index 28828648..1278d2eb 100755
--- a/cloud-init.py
+++ b/cloud-init.py
@@ -56,6 +56,13 @@ def main():
if cmd == "start-local":
source_type = "local"
+ if cmd == "start-local":
+ try:
+ cloudinit.initfs()
+ except:
+ warn("failed to initfs, likely bad things to come")
+
+
cloudinit.logging_set_from_cfg_file()
log = logging.getLogger()
log.info(msg)
@@ -74,6 +81,9 @@ def main():
sys.stderr.write("no instance data found in %s\n" % cmd)
sys.exit(1)
+ # set this as the current instance
+ cloud.set_cur_instance()
+
# store the metadata
cloud.update_cache()
@@ -103,13 +113,6 @@ def main():
#print "user data is:" + cloud.get_user_data()
- # set the defaults (like what ec2-set-defaults.py did)
- try:
- cloud.sem_and_run("set_defaults", "once-per-instance",
- set_defaults,[ cloud ],False)
- except:
- warn("failed to set defaults\n")
-
# finish, send the cloud-config event
cloud.initctl_emit()
diff --git a/cloudinit/__init__.py b/cloudinit/__init__.py
index be366d4c..1de32f2e 100644
--- a/cloudinit/__init__.py
+++ b/cloudinit/__init__.py
@@ -18,9 +18,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+varlibdir = '/var/lib/cloud'
datadir = '/var/lib/cloud/data'
semdir = '/var/lib/cloud/sem'
-pluginsdir = datadir + '/plugins'
cachedir = datadir + '/cache'
userdata_raw = datadir + '/user-data.txt'
userdata = datadir + '/user-data.txt.i'
@@ -32,6 +32,9 @@ system_config = '/etc/cloud/cloud.cfg'
cfg_env_name = "CLOUD_CFG"
def_log_file = '/var/log/cloud-init.log'
+def_log_user = "syslog"
+def_log_group = "adm"
+
cfg_builtin = """
log_cfgs: [ ]
cloud_type: auto
@@ -52,9 +55,10 @@ import util
import logging
import logging.config
import StringIO
+import glob
class NullHandler(logging.Handler):
- def emit(self,record): pass
+ def emit(self,record): pass
log = logging.getLogger(logger_name)
log.addHandler(NullHandler())
@@ -104,6 +108,12 @@ class CloudInit:
"all": ( "nocloud-net", "ec2" ),
"local" : ( "nocloud", ),
}
+ dirmap = {
+ "handlers" : "/handlers",
+ "scripts" : "/scripts",
+ "sem" : "/sem",
+ None : "",
+ }
cfg = None
part_handlers = { }
@@ -200,6 +210,21 @@ class CloudInit:
log.debug("did not find data source from %s" % dslist)
raise DataSourceNotFoundException("Could not find data source")
+ def set_cur_instance(self):
+ lname = "%s/instance" % varlibdir
+ try:
+ os.unlink(lname)
+ except OSError, e:
+ if e.errno != errno.ENOENT: raise
+
+ os.symlink("./instances/%s" % self.get_instance_id(), lname)
+ idir = self.get_idir()
+ dlist = []
+ for d in [ "handlers", "scripts", "sem" ]:
+ dlist.append("%s/%s" % (idir, d))
+
+ util.ensure_dirs(dlist)
+
def get_userdata(self):
return(self.datasource.get_userdata())
@@ -222,11 +247,9 @@ class CloudInit:
'%s=%s' % (cfg_env_name,cloud_config)]).communicate()
def sem_getpath(self,name,freq):
- freqtok = freq
if freq == 'once-per-instance':
- freqtok = self.datasource.get_instance_id()
-
- return("%s/%s.%s" % (semdir,name,freqtok))
+ return("%s/%s" % (self.get_idir("sem"),name))
+ return("%s/%s.%s" % (self.get_cdir("sem"), name, freq))
def sem_has_run(self,name,freq):
if freq == "always": return False
@@ -285,9 +308,45 @@ class CloudInit:
self.sem_clear(semname,freq)
raise
+ # get_cdir : get the "clouddir" (/var/lib/cloud/<name>)
+ # for a name in dirmap
+ def get_idir(self, name=None):
+ return("%s/instances/%s%s"
+ % (varlibdir,self.get_instance_id(), self.dirmap[name]))
+
+ # get_cdir : get the "clouddir" (/var/lib/cloud/<name>)
+ # for a name in dirmap
+ def get_cdir(self, name=None):
+ return("%s%s" % (varlibdir, self.dirmap[name]))
+
def consume_userdata(self):
self.get_userdata()
data = self
+
+ cdir = self.get_cdir("handlers")
+ idir = self.get_idir("handlers")
+
+ # add the path to the plugins dir to the top of our list for import
+ # instance dir should be read before cloud-dir
+ sys.path.insert(0,cdir)
+ sys.path.insert(0,idir)
+
+ # add handlers in cdir
+ for fname in glob.glob("%s/*.py" % cdir):
+ if not os.path.isfile(fname): continue
+ modname = os.path.basename(fname)[0:-3]
+ try:
+ mod = __import__(modname)
+ lister = getattr(mod, "list_types")
+ handler = getattr(mod, "handle_part")
+ mtypes = lister()
+ for mtype in mtypes:
+ self.part_handlers[mtype]=handler
+ log.debug("added handler for [%s] from %s" % (mtypes,fname))
+ except:
+ log.warn("failed to initialize handler in %s" % fname)
+ util.logexc(log)
+
# give callbacks opportunity to initialize
for ctype, func in self.part_handlers.items():
func(data, "__begin__",None,None)
@@ -304,16 +363,13 @@ class CloudInit:
self.handlercount = 0
return
- # add the path to the plugins dir to the top of our list for import
- if self.handlercount == 0:
- sys.path.insert(0,pluginsdir)
-
self.handlercount=self.handlercount+1
- # write content to pluginsdir
+ # write content to instance's handlerdir
+ handlerdir = self.get_idir("handler")
modname = 'part-handler-%03d' % self.handlercount
modfname = modname + ".py"
- util.write_file("%s/%s" % (pluginsdir,modfname), payload, 0600)
+ util.write_file("%s/%s" % (handlerdir,modfname), payload, 0600)
try:
mod = __import__(modname)
@@ -418,6 +474,19 @@ class CloudInit:
return(self.datasource.device_name_to_device(name))
+def initfs():
+ subds = [ 'scripts', 'seed', 'instances', 'handlers', 'sem' ]
+ dlist = [ ]
+ for subd in subds:
+ dlist.append("%s/%s" % (varlibdir, subd))
+ util.ensure_dirs(dlist)
+
+ fp = open(def_log_file,"ab")
+ fp.close()
+ util.chownbyname(def_log_file,def_log_user, def_log_group)
+
+
+
def purge_cache():
try:
os.unlink(data_source_cache)
diff --git a/cloudinit/util.py b/cloudinit/util.py
index d5ae2bec..a2291164 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -278,3 +278,31 @@ def read_cc_from_cmdline(cmdline=None):
begin = cmdline.find(tag_begin, end + end_l)
return('\n'.join(tokens))
+
+def ensure_dirs(dirlist, mode=0755):
+ fixmodes = []
+ for d in dirlist:
+ try:
+ if mode != None:
+ os.makedirs(d)
+ else:
+ os.makedirs(d, mode)
+ except OSError as e:
+ if e.errno != errno.EEXIST: raise
+ if mode != None: fixmodes.append(d)
+
+ for d in fixmodes:
+ os.chmod(d, mode)
+
+def chownbyname(fname,user=None,group=None):
+ uid = -1
+ gid = -1
+ if user == None and group == None: return
+ if user:
+ import pwd
+ uid = pwd.getpwnam(user).pw_uid
+ if group:
+ import grp
+ gid = grp.getgrnam(group).gr_gid
+
+ os.chown(fname,uid,gid)
diff --git a/doc/var-lib-cloud.txt b/doc/var-lib-cloud.txt
index 328edd01..5cdcddbb 100644
--- a/doc/var-lib-cloud.txt
+++ b/doc/var-lib-cloud.txt
@@ -33,12 +33,17 @@
user-data.txt
user-data.txt.i
obj.pkl
+ handlers/
- sem/
scripts.once
These are the cloud-specific semaphores. The only thing that
would go here are files to mark that a "per-once" script
has run.
-
+
+ - handlers/
+ "persistent" handlers (not per-instance). Same as handlers
+ from user-data, just will be cross-instance id
+
to clear out the current instance's data as if to force a "new run" on reboot
do: