diff options
Diffstat (limited to 'ec2init/__init__.py')
-rw-r--r-- | ec2init/__init__.py | 313 |
1 files changed, 0 insertions, 313 deletions
diff --git a/ec2init/__init__.py b/ec2init/__init__.py deleted file mode 100644 index 76aa34f0..00000000 --- a/ec2init/__init__.py +++ /dev/null @@ -1,313 +0,0 @@ -# -# Common code for the EC2 initialisation scripts in Ubuntu -# Copyright (C) 2008-2009 Canonical Ltd -# -# Author: Soren Hansen <soren@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 os -from configobj import ConfigObj - -import cPickle -import sys -import os.path -import errno -import pwd -import subprocess -import yaml - -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' -user_scripts_dir = datadir + "/scripts" -cloud_config = datadir + '/cloud-config.txt' -data_source_cache = cachedir + '/obj.pkl' -system_config = '/etc/cloud/cloud.cfg' -cfg_env_name = "CLOUD_CFG" - -import DataSourceEc2 -import UserDataHandler -import util - -class EC2Init: - datasource_map = { - "ec2" : DataSourceEc2.DataSourceEc2, - } - datasource = None - auto_order = [ 'ec2' ] - - cfg = None - part_handlers = { } - old_conffile = '/etc/ec2-init/ec2-config.cfg' - - def __init__(self): - self.part_handlers = { - 'text/x-shellscript' : self.handle_user_script, - 'text/cloud-config' : self.handle_cloud_config, - 'text/upstart-job' : self.handle_upstart_job, - 'text/part-handler' : self.handle_handler - } - self.cfg=self.read_cfg() - - def read_cfg(self): - if self.cfg: - return(self.cfg) - - conf = { } - try: - stream = file(system_config) - conf = yaml.load(stream) - stream.close() - except: - pass - - if conf is None: conf = { } - - # support reading the old ConfigObj format file and merging - # it into the yaml dictionary - try: - from configobj import ConfigObj - oldcfg = ConfigObj(self.old_conffile) - if oldcfg is None: oldcfg = { } - conf = util.mergedict(conf,oldcfg) - except: - pass - - if not conf.has_key("cloud_type"): - conf["cloud_type"]=None - - return(conf) - - def restore_from_cache(self): - try: - f=open(data_source_cache, "rb") - data = cPickle.load(f) - self.datasource = data - return True - except: - return False - - def write_to_cache(self): - try: - f=open(data_source_cache, "wb") - data = cPickle.dump(self.datasource,f) - return True - except: - return False - - def get_cloud_type(self): - pass - - def get_data_source(self): - if self.datasource is not None: return True - - if self.restore_from_cache(): - return True - - dslist=[ ] - cfglist=self.cfg['cloud_type'] - if cfglist == "auto": - dslist = self.auto_order - elif cfglist: - for ds in cfglist.split(','): - dslist.append(strip(ds).tolower()) - - for ds in dslist: - if ds not in self.datasource_map: continue - try: - s = self.datasource_map[ds]() - if s.get_data(): - self.datasource = s - self.datasource_name = ds - return True - except Exception as e: - pass - raise Exception("Could not find data source") - - def get_userdata(self): - return(self.datasource.get_userdata()) - - def update_cache(self): - self.write_to_cache() - self.store_userdata() - - def store_userdata(self): - util.write_file(userdata_raw, self.datasource.get_userdata_raw(), 0600) - util.write_file(userdata, self.datasource.get_userdata(), 0600) - - def initctl_emit(self): - subprocess.Popen(['initctl', 'emit', 'cloud-config', - '%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)) - - def sem_has_run(self,name,freq): - if freq is "always": return False - semfile = self.sem_getpath(name,freq) - if os.path.exists(semfile): - return True - return False - - def sem_acquire(self,name,freq): - from time import time - semfile = self.sem_getpath(name,freq) - - try: - os.makedirs(os.path.dirname(semfile)) - except OSError as e: - if e.errno != errno.EEXIST: - raise e - - if os.path.exists(semfile) and freq is not "always": - return False - - # race condition - try: - f = open(semfile,"w") - f.write("%s\n" % str(time())) - f.close() - except: - return(False) - return(True) - - def sem_clear(self,name,freq): - semfile = self.sem_getpath(name,freq) - try: - os.unlink(semfile) - except OSError as e: - if e.errno != errno.ENOENT: - return False - - return True - - # acquire lock on 'name' for given 'freq' - # if that does not exist, then call 'func' with given 'args' - # if 'clear_on_fail' is True and func throws an exception - # then remove the lock (so it would run again) - def sem_and_run(self,semname,freq,func,args=[],clear_on_fail=False): - if self.sem_has_run(semname,freq): return - try: - if not self.sem_acquire(semname,freq): - raise Exception("Failed to acquire lock on %s\n" % semname) - - func(*args) - except: - if clear_on_fail: - self.sem_clear(semname,freq) - raise - - def consume_userdata(self): - self.get_userdata() - data = self - # give callbacks opportunity to initialize - for ctype, func in self.part_handlers.items(): - func(data, "__begin__",None,None) - UserDataHandler.walk_userdata(self.get_userdata(), - self.part_handlers, data) - - # give callbacks opportunity to finalize - for ctype, func in self.part_handlers.items(): - func(data,"__end__",None,None) - - def handle_handler(self,data,ctype,filename,payload): - if ctype == "__end__": return - if ctype == "__begin__" : - 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 - modname = 'part-handler-%03d' % self.handlercount - modfname = modname + ".py" - util.write_file("%s/%s" % (pluginsdir,modfname), payload, 0600) - - try: - mod = __import__(modname) - lister = getattr(mod, "list_types") - handler = getattr(mod, "handle_part") - except: - import traceback - traceback.print_exc(file=sys.stderr) - return - - # - call it with '__begin__' - handler(data, "__begin__", None, None) - - # - add it self.part_handlers - for mtype in lister(): - self.part_handlers[mtype]=handler - - def handle_user_script(self,data,ctype,filename,payload): - if ctype == "__end__": return - if ctype == "__begin__": - # maybe delete existing things here - return - - filename=filename.replace(os.sep,'_') - util.write_file("%s/%s" % (user_scripts_dir,filename), payload, 0700) - - def handle_upstart_job(self,data,ctype,filename,payload): - if ctype == "__end__" or ctype == "__begin__": return - if not filename.endswith(".conf"): - filename=filename+".conf" - - util.write_file("%s/%s" % ("/etc/init",filename), payload, 0644) - - def handle_cloud_config(self,data,ctype,filename,payload): - if ctype == "__begin__": - self.cloud_config_str="" - return - if ctype == "__end__": - util.write_file(cloud_config, self.cloud_config_str, 0600) - - ## this could merge the cloud config with the system config - ## for now, not doing this as it seems somewhat circular - ## as CloudConfig does that also, merging it with this cfg - ## - # ccfg = yaml.load(self.cloud_config_str) - # if ccfg is None: ccfg = { } - # self.cfg = util.mergedict(ccfg, self.cfg) - - return - - self.cloud_config_str+="\n#%s\n%s" % (filename,payload) - - def get_public_ssh_keys(self): - return(self.datasource.get_public_ssh_keys()) - - def get_locale(self): - return(self.datasource.get_locale()) - - def get_mirror(self): - return(self.datasource.get_local_mirror()) - - def get_hostname(self): - return(self.datasource.get_hostname()) - - def device_name_to_device(self,name): - return(self.datasource.device_name_to_device(name)) |