def start(self, name, program, *args, **kargs): tracedir = kargs.get("trace_dir") appdir = kargs.get("app_dir") pidfile = joinpths(tracedir, name + ".pid") stderr = joinpths(tracedir, name + ".stderr") stdout = joinpths(tracedir, name + ".stdout") tracefn = Trace.trace_fn(tracedir, name) tracefn = Trace.touch_trace(tracedir, name) runtrace = Trace.Trace(tracefn) runtrace.trace(RUN, RUN_TYPE) runtrace.trace(PID_FN, pidfile) runtrace.trace(STDERR_FN, stderr) runtrace.trace(STDOUT_FN, stdout) #fork to get daemon out pid = os.fork() if(pid == 0): os.setsid() pid = os.fork() #fork to get daemon out - this time under init control #and now fully detached (no shell possible) if(pid == 0): #move to where application should be os.chdir(appdir) #close other fds limits = resource.getrlimit(resource.RLIMIT_NOFILE) mkfd = limits[1] if(mkfd == resource.RLIM_INFINITY): mkfd = MAXFD for fd in range(0, mkfd): try: os.close(fd) except OSError: #not open, thats ok pass #now adjust stderr and stdout stdoh = open(stdout, "w") stdeh = open(stderr, "w") os.dup2(stdoh.fileno(), sys.stdout.fileno()) os.dup2(stdeh.fileno(), sys.stderr.fileno()) #now exec... #the arguments to the child process should #start with the name of the command being run actualargs = [program] + list(args) os.execlp(program, *actualargs) else: #write out the child pid contents = str(pid) + "\n" write_file(pidfile, contents) #not exit or sys.exit, this is recommended #since it will do the right cleanups that we want #not calling any atexit functions, which would #be bad right now os._exit(0) else: return tracefn
def component_pths(root, compnent_type): component_root = joinpths(root, compnent_type) tracedir = joinpths(component_root, TRACE_DIR) appdir = joinpths(component_root, APP_DIR) cfgdir = joinpths(component_root, CONFIG_DIR) out = dict() out['root_dir'] = component_root out['trace_dir'] = tracedir out['app_dir'] = appdir out['config_dir'] = cfgdir return out
def configure(self): dirsmade = mkdirslist(self.cfgdir) self.tracewriter.dir_made(*dirsmade) configs = self._get_config_files() if(configs and len(configs)): for fn in configs: parameters = self._get_param_map(fn) sourcefn = joinpths(STACK_CONFIG_DIR, self.component_name, fn) tgtfn = joinpths(self.cfgdir, fn) LOG.info("Configuring template file %s" % (sourcefn)) contents = load_file(sourcefn) LOG.info("Replacing parameters in file %s" % (sourcefn)) LOG.debug("Replacements = %s" % (parameters)) contents = param_replace(contents, parameters) LOG.debug("Applying side-effects of param replacement for template %s" % (sourcefn)) contents = self._config_adjust(contents, fn) LOG.info("Writing configuration file %s" % (tgtfn)) write_file(tgtfn, contents) #this trace is used to remove the files configured self.tracewriter.cfg_write(tgtfn) return self.tracedir
def _get_param_map(self, fn=None): #these be used to fill in the configuration/cmds + #params with actual values mp = dict() mp['DEST'] = self.appdir mp['SQL_CONN'] = self.cfg.get_dbdsn(DB_NAME) mp['ADMIN_PASSWORD'] = self.cfg.getpw('passwords', 'horizon_keystone_admin') mp['HOST_IP'] = get_host_ip(self.cfg) mp['SERVICE_TOKEN'] = self.cfg.getpw("passwords", "service_token") mp['BIN_DIR'] = self.bindir mp['CONFIG_FILE'] = joinpths(self.cfgdir, ROOT_CONF) return mp
def configure(self): dirsmade = mkdirslist(self.cfgdir) self.tracewriter.dir_made(*dirsmade) configs = self._get_config_files() if (configs and len(configs)): for fn in configs: parameters = self._get_param_map(fn) sourcefn = joinpths(STACK_CONFIG_DIR, self.component_name, fn) tgtfn = joinpths(self.cfgdir, fn) LOG.info("Configuring template file %s" % (sourcefn)) contents = load_file(sourcefn) LOG.info("Replacing parameters in file %s" % (sourcefn)) LOG.debug("Replacements = %s" % (parameters)) contents = param_replace(contents, parameters) LOG.debug( "Applying side-effects of param replacement for template %s" % (sourcefn)) contents = self._config_adjust(contents, fn) LOG.info("Writing configuration file %s" % (tgtfn)) write_file(tgtfn, contents) #this trace is used to remove the files configured self.tracewriter.cfg_write(tgtfn) return self.tracedir
def stop(self, name, *args, **kargs): rootdir = kargs.get("trace_dir") pidfile = joinpths(rootdir, name + ".pid") stderr = joinpths(rootdir, name + ".stderr") stdout = joinpths(rootdir, name + ".stdout") tfname = Trace.trace_fn(rootdir, name) if(isfile(pidfile) and isfile(tfname)): pid = int(load_file(pidfile).strip()) killed = False lastmsg = "" attempts = 1 for attempt in range(0, MAX_KILL_TRY): try: os.kill(pid, signal.SIGKILL) attempts += 1 except OSError as (ec, msg): if(ec == errno.ESRCH): killed = True break else: lastmsg = msg time.sleep(SLEEP_TIME) #trash the files if(killed): LOG.info("Killed pid %s in %s attempts" % (str(pid), str(attempts))) LOG.info("Removing pid file %s" % (pidfile)) unlink(pidfile) LOG.info("Removing stderr file %s" % (stderr)) unlink(stderr) LOG.info("Removing stdout file %s" % (stdout)) unlink(stdout) LOG.info("Removing %s trace file %s" % (name, tfname)) unlink(tfname) else: msg = "Could not stop program named %s after %s attempts - [%s]" % (name, MAX_KILL_TRY, lastmsg) raise StopException(msg)
PythonRuntime) from Shell import (mkdirslist, unlink, touch_file, joinpths) LOG = Logger.getLogger("install.keystone") TYPE = KEYSTONE ROOT_CONF = "keystone.conf" CONFIGS = [ROOT_CONF] BIN_DIR = "bin" DB_NAME = "keystone" #what to start APP_OPTIONS = { 'keystone': ['--config-file', joinpths('%ROOT%', "config", ROOT_CONF), "--verbose"], } class KeystoneUninstaller(PythonUninstallComponent): def __init__(self, *args, **kargs): PythonUninstallComponent.__init__(self, TYPE, *args, **kargs) self.cfgdir = joinpths(self.appdir, CONFIG_DIR) self.bindir = joinpths(self.appdir, BIN_DIR) class KeystoneInstaller(PythonInstallComponent): def __init__(self, *args, **kargs): PythonInstallComponent.__init__(self, TYPE, *args, **kargs) self.gitloc = self.cfg.get("git", "keystone_repo") self.brch = self.cfg.get("git", "keystone_branch")
def __init__(self, *args, **kargs): PythonInstallComponent.__init__(self, TYPE, *args, **kargs) self.gitloc = self.cfg.get("git", "keystone_repo") self.brch = self.cfg.get("git", "keystone_branch") self.cfgdir = joinpths(self.appdir, CONFIG_DIR) self.bindir = joinpths(self.appdir, BIN_DIR)
def __init__(self, *args, **kargs): PythonUninstallComponent.__init__(self, TYPE, *args, **kargs) self.cfgdir = joinpths(self.appdir, CONFIG_DIR) self.bindir = joinpths(self.appdir, BIN_DIR)
def __init__(self, *args, **kargs): PythonRuntime.__init__(self, TYPE, *args, **kargs) self.cfgdir = joinpths(self.appdir, CONFIG_DIR) self.bindir = joinpths(self.appdir, BIN_DIR)
import Logger import Db from Component import (PythonUninstallComponent, PythonInstallComponent, PythonRuntime) from Shell import (mkdirslist, unlink, touch_file, joinpths) LOG = Logger.getLogger("install.keystone") TYPE = KEYSTONE ROOT_CONF = "keystone.conf" CONFIGS = [ROOT_CONF] BIN_DIR = "bin" DB_NAME = "keystone" #what to start APP_OPTIONS = { 'keystone': ['--config-file', joinpths('%ROOT%', "config", ROOT_CONF), "--verbose"], } class KeystoneUninstaller(PythonUninstallComponent): def __init__(self, *args, **kargs): PythonUninstallComponent.__init__(self, TYPE, *args, **kargs) self.cfgdir = joinpths(self.appdir, CONFIG_DIR) self.bindir = joinpths(self.appdir, BIN_DIR) class KeystoneInstaller(PythonInstallComponent): def __init__(self, *args, **kargs): PythonInstallComponent.__init__(self, TYPE, *args, **kargs) self.gitloc = self.cfg.get("git", "keystone_repo") self.brch = self.cfg.get("git", "keystone_branch")
START = "start" STOP = "stop" ACTIONS = [INSTALL, UNINSTALL, START, STOP] #this is used to map an action to a useful string for #the welcome display... WELCOME_MAP = { INSTALL: "Installer", UNINSTALL: "Uninstaller", START: "Runner", STOP: "Stopper", } #where we should get the config file... STACK_CONFIG_DIR = "conf" STACK_CFG_LOC = joinpths(STACK_CONFIG_DIR, "stack.ini") #this regex is how we match python platform output to #a known constant KNOWN_OS = { UBUNTU11: '/Ubuntu(.*)oneiric/i', RHEL6: '/redhat-6\.(\d+)/i', } #the pip files that each component #needs PIP_MAP = { NOVA: [], GLANCE: [],
from Component import PythonUninstallComponent, PythonInstallComponent, PythonRuntime from Util import GLANCE, get_host_ip, param_replace from Shell import deldir, mkdirslist, unlink, joinpths, touch_file LOG = Logger.getLogger("install.glance") # naming + config files TYPE = GLANCE API_CONF = "glance-api.conf" REG_CONF = "glance-registry.conf" CONFIGS = [API_CONF, REG_CONF] DB_NAME = "glance" # what to start APP_OPTIONS = { "glance-api": ["--config-file", joinpths("%ROOT%", "etc", API_CONF)], "glance-registry": ["--config-file", joinpths("%ROOT%", "etc", REG_CONF)], } CONFIG_ACTUAL_DIR = "etc" class GlanceUninstaller(PythonUninstallComponent): def __init__(self, *args, **kargs): PythonUninstallComponent.__init__(self, TYPE, *args, **kargs) self.cfgdir = joinpths(self.appdir, CONFIG_ACTUAL_DIR) class GlanceRuntime(PythonRuntime): def __init__(self, *args, **kargs): PythonRuntime.__init__(self, TYPE, *args, **kargs) self.cfgdir = joinpths(self.appdir, CONFIG_ACTUAL_DIR)
START = "start" STOP = "stop" ACTIONS = [INSTALL, UNINSTALL, START, STOP] #this is used to map an action to a useful string for #the welcome display... WELCOME_MAP = { INSTALL: "Installer", UNINSTALL: "Uninstaller", START: "Runner", STOP: "Stopper", } #where we should get the config file... STACK_CONFIG_DIR = "conf" STACK_CFG_LOC = joinpths(STACK_CONFIG_DIR, "stack.ini") #this regex is how we match python platform output to #a known constant KNOWN_OS = { UBUNTU11: '/Ubuntu(.*)oneiric/i', RHEL6: '/redhat-6\.(\d+)/i', } #the pip files that each component #needs PIP_MAP = { NOVA: [], GLANCE: [], KEYSTONE: [ joinpths(STACK_CONFIG_DIR, "pips", 'keystone.json'),
from Util import (GLANCE, get_host_ip, param_replace) from Shell import (deldir, mkdirslist, unlink, joinpths, touch_file) LOG = Logger.getLogger("install.glance") #naming + config files TYPE = GLANCE API_CONF = "glance-api.conf" REG_CONF = "glance-registry.conf" CONFIGS = [API_CONF, REG_CONF] DB_NAME = "glance" #what to start APP_OPTIONS = { 'glance-api': ['--config-file', joinpths('%ROOT%', "etc", API_CONF)], 'glance-registry': ['--config-file', joinpths('%ROOT%', "etc", REG_CONF)] } CONFIG_ACTUAL_DIR = 'etc' class GlanceUninstaller(PythonUninstallComponent): def __init__(self, *args, **kargs): PythonUninstallComponent.__init__(self, TYPE, *args, **kargs) self.cfgdir = joinpths(self.appdir, CONFIG_ACTUAL_DIR) class GlanceRuntime(PythonRuntime): def __init__(self, *args, **kargs): PythonRuntime.__init__(self, TYPE, *args, **kargs)
def trace_fn(rootdir, name): fullname = name + TRACE_EXT return joinpths(rootdir, fullname)