Updated to have preinstall and post install in the main stack install loop.

Also updated keystone and glance config "adjustment" to use python config parsers since they can be used directly in that format.
This commit is contained in:
Joshua Harlow 2012-01-18 13:51:51 -08:00
parent ae73a3618a
commit 701502991f
11 changed files with 270 additions and 242 deletions

@ -66,8 +66,14 @@ class InstallComponent():
def configure(self):
raise NotImplementedError()
def pre_install(self):
raise NotImplementedError()
def install(self):
raise NotImplementedError()
def post_install(self):
raise NotImplementedError()
class UninstallComponent():
@ -118,28 +124,35 @@ class PkgInstallComponent(ComponentBase, InstallComponent):
def _get_param_map(self, fn=None):
return None
def _do_pkg_install(self):
def install(self):
pkgs = get_pkg_list(self.distro, self.component_name)
if(len(pkgs)):
pkgnames = sorted(pkgs.keys())
LOG.debug("Installing packages %s" % (", ".join(pkgnames)))
mp = self._get_param_map()
#run pre, install, then post
self.packager.pre_install(pkgs, mp)
LOG.info("Installing packages %s" % (", ".join(pkgnames)))
self.packager.install_batch(pkgs)
self.packager.post_install(pkgs, mp)
#add trace used to remove the pkgs
for name in pkgnames:
self.tracewriter.package_install(name, pkgs.get(name))
return self.tracedir
def install(self):
self._do_pkg_install()
def pre_install(self):
pkgs = get_pkg_list(self.distro, self.component_name)
if(len(pkgs)):
mp = self._get_param_map()
self.packager.pre_install(pkgs, mp)
return self.tracedir
def post_install(self):
pkgs = get_pkg_list(self.distro, self.component_name)
if(len(pkgs)):
mp = self._get_param_map()
self.packager.post_install(pkgs, mp)
return self.tracedir
def _get_config_files(self):
return list()
def _config_adjust(fn, contents):
def _config_adjust(contents, name):
return contents
def configure(self):
@ -186,9 +199,9 @@ class PythonInstallComponent(PkgInstallComponent):
# Overridden
def install(self):
self._do_pkg_install()
parent_result = PkgInstallComponent.install(self)
self._python_install()
return self.tracedir
return parent_result
class PkgUninstallComponent(ComponentBase, UninstallComponent):
@ -294,7 +307,7 @@ class ProgramRuntime(ComponentBase, RuntimeComponent):
raise NotImplementedError()
def _get_app_options(self, app):
return None
return list()
def _get_param_map(self, app=None):
return {
@ -375,6 +388,12 @@ class PythonRuntime(ProgramRuntime):
def __init__(self, component_name, *args, **kargs):
ProgramRuntime.__init__(self, component_name, *args, **kargs)
def status(self):
return None
def restart(self):
return None
def _was_installed(self):
parent_result = ProgramRuntime._was_installed(self)
if(not parent_result):

@ -27,11 +27,52 @@ import Shell
LOG = Logger.getLogger("install.config")
PW_TMPL = "Enter a password for %s: "
ENV_PAT = re.compile(r"^\s*\$\{([\w\d]+):\-(.*)\}\s*$")
CACHE_MSG = "(value will now be internally cached)"
class IgnoreMissingConfigParser(ConfigParser.RawConfigParser):
DEF_INT = 0
DEF_FLOAT = 0.0
DEF_BOOLEAN = False
def __init__(self):
ConfigParser.RawConfigParser.__init__(self, allow_no_value=True)
def get(self, section, option):
value = None
try:
value = ConfigParser.RawConfigParser.get(self, section, option)
except ConfigParser.NoSectionError, e:
pass
except ConfigParser.NoOptionError, e:
pass
return value
def getboolean(self, section, option):
value = self.get(section, option)
if(value == None):
#not there so don't let the parent blowup
return IgnoreMissingConfigParser.DEF_BOOLEAN
return ConfigParser.RawConfigParser.getboolean(self, section, option)
def getfloat(self, section, option):
value = self.get(section, option)
if(value == None):
#not there so don't let the parent blowup
return IgnoreMissingConfigParser.DEF_FLOAT
return ConfigParser.RawConfigParser.getfloat(self, section, option)
def getint(self, section, option):
value = self.get(section, option)
if(value == None):
#not there so don't let the parent blowup
return IgnoreMissingConfigParser.DEF_INT
return ConfigParser.RawConfigParser.getint(self, section, option)
class EnvConfigParser(ConfigParser.RawConfigParser):
def __init__(self):
ConfigParser.RawConfigParser.__init__(self)
ConfigParser.RawConfigParser.__init__(self, allow_no_value=True)
self.pws = dict()
self.configs_fetched = dict()
self.db_dsns = dict()
@ -47,46 +88,10 @@ class EnvConfigParser(ConfigParser.RawConfigParser):
else:
LOG.debug("Fetching value for param %s" % (key))
v = self._get_special(section, option)
LOG.debug("Fetched \"%s\" for %s (will now be cached)" % (v, key))
LOG.debug("Fetched \"%s\" for %s %s" % (v, key, CACHE_MSG))
self.configs_fetched[key] = v
return v
def __len__(self):
return (len(self.pws) +
len(self.configs_fetched) +
len(self.db_dsns))
def __str__(self):
#this will make the items nice and pretty
def item_format(k, v):
return "\t%s=%s" % (str(k), str(v))
#collect all the lines
password_lines = list()
if(len(self.pws)):
password_lines.append("Passwords:")
keys = sorted(self.pws.keys())
for key in keys:
value = self.pws.get(key)
password_lines.append(item_format(key, value))
cfg_lines = list()
if(len(self.configs_fetched)):
cfg_lines.append("Configs:")
keys = sorted(self.configs_fetched.keys())
for key in keys:
if(key in self.pws):
continue
value = self.configs_fetched.get(key)
cfg_lines.append(item_format(key, value))
dsn_lines = list()
if(len(self.db_dsns)):
dsn_lines.append("Data source names:")
keys = sorted(self.db_dsns.keys())
for key in keys:
value = self.db_dsns.get(key)
dsn_lines.append(item_format(key, value))
#make a nice string
combined_lines = cfg_lines + password_lines + dsn_lines
return os.linesep.join(combined_lines)
def _get_special(self, section, option):
key = self._makekey(section, option)
@ -140,7 +145,7 @@ class EnvConfigParser(ConfigParser.RawConfigParser):
dsn += "/" + dbname
else:
dsn += "/"
LOG.debug("For database %s fetched dsn %s" % (dbname, dsn))
LOG.debug("For database %s fetched dsn %s %s" % (dbname, dsn, CACHE_MSG))
#store for later...
self.db_dsns[dbname] = dsn
return dsn
@ -156,6 +161,6 @@ class EnvConfigParser(ConfigParser.RawConfigParser):
if(len(pw) == 0):
while(len(pw) == 0):
pw = Shell.password(PW_TMPL % (key))
LOG.debug("Password for %s will be %s" % (key, pw))
LOG.debug("Password for %s will be %s %s" % (key, pw, CACHE_MSG))
self.pws[key] = pw
return pw

@ -82,8 +82,8 @@ class DBInstaller(PkgInstallComponent):
out['HOST_IP'] = hostip
return out
def install(self):
pres = PkgInstallComponent.install(self)
def post_install(self):
parent_result = PkgInstallComponent.post_install(self)
#extra actions to ensure we are granted access
dbtype = self.cfg.get("db", "type")
dbactions = DB_ACTIONS.get(dbtype)
@ -106,7 +106,7 @@ class DBInstaller(PkgInstallComponent):
execute(*cmd, run_as_root=True, shell=True)
#restart it to make sure all good
self.runtime.restart()
return pres
return parent_result
class DBRuntime(ComponentBase, RuntimeComponent):

@ -15,7 +15,9 @@
import json
import os.path
import io
import Config
import Logger
import Db
@ -36,6 +38,7 @@ API_CONF = "glance-api.conf"
REG_CONF = "glance-registry.conf"
CONFIGS = [API_CONF, REG_CONF]
DB_NAME = "glance"
CFG_SECTION = 'DEFAULT'
#what to start
APP_OPTIONS = {
@ -78,60 +81,67 @@ class GlanceInstaller(PythonInstallComponent):
#these are the config files we will be adjusting
return list(CONFIGS)
def install(self):
parent_res = PythonInstallComponent.install(self)
#setup the database
def post_install(self):
parent_result = PythonInstallComponent.post_install(self)
self._setup_db()
return parent_res
return parent_result
def _setup_db(self):
Db.drop_db(self.cfg, DB_NAME)
Db.create_db(self.cfg, DB_NAME)
def _config_adjust(self, contents, fn):
lines = contents.splitlines()
for line in lines:
cleaned = line.strip()
if(len(cleaned) == 0 or cleaned[0] == '#' or cleaned[0] == '['):
#not useful to examine these
continue
pieces = cleaned.split("=", 1)
if(len(pieces) != 2):
continue
key = pieces[0].strip()
val = pieces[1].strip()
if(len(key) == 0 or len(val) == 0):
continue
#now we take special actions
if(key == 'filesystem_store_datadir'):
#delete existing images
deldir(val)
#recreate the image directory
dirsmade = mkdirslist(val)
self.tracewriter.dir_made(*dirsmade)
elif(key == 'log_file'):
#ensure that we can write to the log file
dirname = os.path.dirname(val)
if(len(dirname)):
dirsmade = mkdirslist(dirname)
def _config_adjust(self, contents, name):
if(name not in CONFIGS):
return contents
#use config parser and
#then extract known configs that
#will need locations/directories/files made (or touched)...
with io.BytesIO(contents) as stream:
config = Config.IgnoreMissingConfigParser()
config.readfp(stream)
if(config.getboolean('image_cache_enabled', CFG_SECTION)):
cache_dir = config.get("image_cache_datadir", CFG_SECTION)
if(cache_dir):
LOG.info("Ensuring image cache data directory %s exists (and is empty)" % (cache_dir))
#destroy then recreate the image cache directory
deldir(cache_dir)
dirsmade = mkdirslist(cache_dir)
#this trace is used to remove the dirs created
self.tracewriter.dir_made(*dirsmade)
if(config.get('default_store', CFG_SECTION) == 'file'):
file_dir = config.get('filesystem_store_datadir', CFG_SECTION)
if(file_dir):
LOG.info("Ensuring file system store directory %s exists and is empty" % (file_dir))
#delete existing images
deldir(file_dir)
#recreate the image directory
dirsmade = mkdirslist(file_dir)
#this trace is used to remove the dirs created
self.tracewriter.dir_made(*dirsmade)
log_filename = config.get('log_file', CFG_SECTION)
if(log_filename):
LOG.info("Ensuring log file %s exists and is empty" % (log_filename))
log_dir = os.path.dirname(log_filename)
if(log_dir):
LOG.info("Ensuring log directory %s exists" % (log_dir))
dirsmade = mkdirslist(log_dir)
#this trace is used to remove the dirs created
self.tracewriter.dir_made(*dirsmade)
#destroy then recreate it (the log file)
unlink(val)
touch_file(val)
self.tracewriter.file_touched(val)
elif(key == 'image_cache_datadir'):
#destroy then recreate the image cache directory
deldir(val)
dirsmade = mkdirslist(val)
#this trace is used to remove the dirs created
self.tracewriter.dir_made(*dirsmade)
elif(key == 'scrubber_datadir'):
#destroy then recreate the scrubber data directory
deldir(val)
dirsmade = mkdirslist(val)
#this trace is used to remove the dirs created
self.tracewriter.dir_made(*dirsmade)
unlink(log_filename)
touch_file(log_filename)
self.tracewriter.file_touched(log_filename)
if(config.getboolean('delayed_delete', CFG_SECTION)):
data_dir = config.get('scrubber_datadir', CFG_SECTION)
if(data_dir):
LOG.info("Ensuring scrubber data dir %s exists and is empty" % (data_dir))
#destroy then recreate the scrubber data directory
deldir(data_dir)
dirsmade = mkdirslist(data_dir)
#this trace is used to remove the dirs created
self.tracewriter.dir_made(*dirsmade)
#we might need to handle more in the future...
#nothing modified so just return the original
return contents
def _get_param_map(self, fn=None):

@ -15,10 +15,12 @@
import os
import os.path
import io
import Pip
import Logger
import Db
import Config
#TODO fix these
from Util import (KEYSTONE,
@ -38,6 +40,7 @@ ROOT_CONF = "keystone.conf"
CONFIGS = [ROOT_CONF]
BIN_DIR = "bin"
DB_NAME = "keystone"
CFG_SECTION = 'DEFAULT'
#what to start
APP_OPTIONS = {
@ -63,13 +66,11 @@ class KeystoneInstaller(PythonInstallComponent):
def _get_download_location(self):
return (self.gitloc, self.brch)
def install(self):
parent_res = PythonInstallComponent.install(self)
#adjust db
def post_install(self):
parent_result = PythonInstallComponent.post_install(self)
self._setup_db()
#setup any data
self._setup_data()
return parent_res
return parent_result
def _get_config_files(self):
return list(CONFIGS)
@ -83,33 +84,30 @@ class KeystoneInstaller(PythonInstallComponent):
cmds = _keystone_setup_cmds(self.othercomponents)
execute_template(*cmds, params=params, ignore_missing=True)
def _config_adjust(self, contents, fn):
lines = contents.splitlines()
for line in lines:
cleaned = line.strip()
if(len(cleaned) == 0 or
cleaned[0] == '#' or cleaned[0] == '['):
#not useful to examine these
continue
pieces = cleaned.split("=", 1)
if(len(pieces) != 2):
continue
key = pieces[0].strip()
val = pieces[1].strip()
if(len(key) == 0 or len(val) == 0):
continue
#now we take special actions
if(key == 'log_file'):
# Ensure that we can write to the log file
dirname = os.path.dirname(val)
if(len(dirname)):
dirsmade = mkdirslist(dirname)
# This trace is used to remove the dirs created
def _config_adjust(self, contents, name):
if(name not in CONFIGS):
return contents
#use config parser and
#then extract known configs that
#will need locations/directories/files made (or touched)...
with io.BytesIO(contents) as stream:
config = Config.IgnoreMissingConfigParser()
config.readfp(stream)
log_filename = config.get('log_file', CFG_SECTION)
if(log_filename):
LOG.info("Ensuring log file %s exists and is empty" % (log_filename))
log_dir = os.path.dirname(log_filename)
if(log_dir):
LOG.info("Ensuring log directory %s exists" % (log_dir))
dirsmade = mkdirslist(log_dir)
#this trace is used to remove the dirs created
self.tracewriter.dir_made(*dirsmade)
# Destroy then recreate it
unlink(val)
touch_file(val)
self.tracewriter.file_touched(val)
#destroy then recreate it (the log file)
unlink(log_filename)
touch_file(log_filename)
self.tracewriter.file_touched(log_filename)
#we might need to handle more in the future...
#nothing modified so just return the original
return contents
def _get_param_map(self, fn=None):

@ -30,8 +30,8 @@ LOG = Logger.getLogger("install.packager")
class Packager():
def __init__(self):
pass
def __init__(self, distro):
self.distro = distro
def install_batch(self, pkgs):
raise NotImplementedError()

@ -57,14 +57,12 @@ class RabbitInstaller(PkgInstallComponent):
passwd = self.cfg.getpw("passwords", "rabbit")
cmd = PWD_CMD + [passwd]
execute(*cmd, run_as_root=True)
def install(self):
pres = PkgInstallComponent.install(self)
#ensure setup right
def post_install(self):
parent_result = PkgInstallComponent.post_install(self)
self._setup_pw()
#restart it to make sure its ok to go
self.runtime.restart()
return pres
return parent_result
class RabbitRuntime(ComponentBase, RuntimeComponent):

@ -25,7 +25,7 @@ import sys
import Logger
#TODO fix these
from Exceptions import (ProcessExecutionError, FileException)
from Exceptions import (ProcessExecutionError, FileException, BadParamException)
from Environment import (get_environment_bool, get_environment)
ROOT_HELPER = ["sudo"]
@ -128,6 +128,16 @@ def joinpths(*pths):
return os.path.join(*pths)
def _gen_password(genlen):
if(genlen <= 0):
msg = "Generated password length %s can not be less than or equal to zero" % (genlen)
raise BadParamException(msg)
LOG.debug("Generating you a pseudo-random password of byte length: %s" % (genlen))
cmd = MKPW_CMD + [genlen]
(stdout, stderr) = execute(*cmd)
return stdout.strip()
def password(prompt=None, genlen=8):
rd = ""
pass_ask = get_environment_bool("PASS_ASK", True)
@ -137,10 +147,7 @@ def password(prompt=None, genlen=8):
else:
rd = getpass.getpass()
if(len(rd) == 0):
LOG.debug("Generating you a password of length: %s" % (genlen))
cmd = MKPW_CMD + [genlen]
(stdout, stderr) = execute(*cmd)
return stdout.strip()
return _gen_password(genlen)
else:
return rd

@ -22,6 +22,7 @@ import Packager
import Logger
#TODO fix these
from Util import (UBUNTU11, RHEL6)
from Util import param_replace
from Shell import execute
@ -39,22 +40,26 @@ APT_DO_REMOVE = APT_PURGE
#make sure its non-interactive
ENV_ADDITIONS = {'DEBIAN_FRONTEND': 'noninteractive'}
#not 100% right but it will work for us
#ie we aren't handling : for epochs
#http://www.ducea.com/2006/06/17/ubuntu-package-version-naming-explanation/
UB_PKG_VERSION_REGEX = re.compile(r"^(\d*)\.(\d*)(?:\.(\d*))?-(\d*)ubuntu(\d*)$", re.IGNORECASE)
#how versions are expressed by apt
VERSION_TEMPL = "%s=%s"
class AptPackager(Packager.Packager):
def __init__(self):
Packager.Packager.__init__(self)
def __init__(self, distro):
Packager.Packager.__init__(self, distro)
def _form_cmd(self, name, version):
cmd = name
if(version and len(version)):
cmd = cmd + "=" + version
cmd = VERSION_TEMPL % (name, version)
else:
cmd = name
return cmd
def _execute_apt(self, cmd, run_as_root, check_exit=True):
execute(*cmd, run_as_root=run_as_root,
check_exit_code=check_exit,
env_overrides=ENV_ADDITIONS)
def remove_batch(self, pkgs):
pkgnames = sorted(pkgs.keys())
#form the needed commands
@ -64,19 +69,17 @@ class AptPackager(Packager.Packager):
removable = info.get('removable', True)
if(not removable):
continue
if(_pkg_remove_special(name, info)):
#handled by the special remove
if(self._pkg_remove_special(name, info)):
continue
torun = self._form_cmd(name, info.get("version"))
cmds.append(torun)
full_cmd = self._form_cmd(name, info.get("version"))
if(full_cmd):
cmds.append(full_cmd)
if(len(cmds)):
cmd = APT_GET + APT_DO_REMOVE + cmds
execute(*cmd, run_as_root=True,
env_overrides=ENV_ADDITIONS)
self._execute_apt(cmd, True)
#clean them out
cmd = APT_GET + APT_AUTOREMOVE
execute(*cmd, run_as_root=True,
env_overrides=ENV_ADDITIONS)
self._execute_apt(cmd, True)
def install_batch(self, pkgs):
pkgnames = sorted(pkgs.keys())
@ -84,83 +87,43 @@ class AptPackager(Packager.Packager):
cmds = []
for name in pkgnames:
info = pkgs.get(name) or {}
if(_pkg_install_special(name, info)):
#handled by the special install
if(self._pkg_install_special(name, info)):
continue
torun = self._form_cmd(name, info.get("version"))
cmds.append(torun)
full_cmd = self._form_cmd(name, info.get("version"))
if(full_cmd):
cmds.append(full_cmd)
#install them
if(len(cmds)):
cmd = APT_GET + APT_INSTALL + cmds
execute(*cmd, run_as_root=True,
env_overrides=ENV_ADDITIONS)
self._execute_apt(cmd, True)
def _extract_version(version):
version_info = dict()
if(version.lower().find("ubuntu") != -1):
mtch = UB_PKG_VERSION_REGEX.search(version)
if(mtch):
major = mtch.group(1)
major = int(major) if major != None else -1
minor = mtch.group(2)
minor = int(minor) if minor != None else -1
release = mtch.group(3)
release = int(release) if release != None else -1
debian_version = mtch.group(4)
debian_version = int(debian_version) if debian_version != None else -1
ubuntu_version = mtch.group(5)
ubuntu_version = int(ubuntu_version) if ubuntu_version != None else -1
version_info['type'] = 'ubuntu'
version_info['major'] = major
version_info['minor'] = minor
version_info['release'] = release
version_info['debian_version'] = debian_version
version_info['ubuntu_version'] = ubuntu_version
return version_info
def _pkg_remove_special(name, pkginfo):
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
if(name == 'rabbitmq-server'):
version = pkginfo.get('version')
version_info = _extract_version(version)
if(len(version_info)):
if(version_info.get('type') == 'ubuntu' and
version_info.get('major') <= 2 and
version_info.get('minor') < 6):
LOG.info("Handling special remove of %s v%s" % (name, version))
#the first time seems to fail with exit code 100 but the second
#time seems to not fail, pretty weird, most likely the above bugs
cmd = APT_GET + APT_REMOVE + [name + "=" + version]
execute(*cmd, run_as_root=True,
check_exit_code=False, env_overrides=ENV_ADDITIONS)
def _pkg_remove_special(self, name, pkginfo):
if(name == 'rabbitmq-server' and self.distro == UBUNTU11):
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
LOG.info("Handling special remove of %s" % (name))
full_cmd = self._form_cmd(name, pkginfo.get("version"))
if(full_cmd):
cmd = APT_GET + APT_REMOVE + [full_cmd]
self._execute_apt(cmd, True. True)
#probably useful to do this
time.sleep(1)
cmd = APT_GET + APT_PURGE + [name + "=" + version]
execute(*cmd, run_as_root=True,
env_overrides=ENV_ADDITIONS)
#purge
cmd = APT_GET + APT_PURGE + [full_cmd]
self._execute_apt(cmd, True)
return True
return False
return False
def _pkg_install_special(name, pkginfo):
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
if(name == 'rabbitmq-server'):
version = pkginfo.get('version')
version_info = _extract_version(version)
if(len(version_info)):
if(version_info.get('type') == 'ubuntu' and
version_info.get('major') <= 2 and
version_info.get('minor') < 6):
LOG.info("Handling special install of %s v%s" % (name, version))
#this seems to be a temporary fix for that bug
with TemporaryFile() as f:
cmd = APT_GET + APT_INSTALL + [name + "=" + version]
execute(*cmd, run_as_root=True,
stdout_fh=f, stderr_fh=f,
env_overrides=ENV_ADDITIONS)
def _pkg_install_special(self, name, pkginfo):
if(name == 'rabbitmq-server' and self.distro == UBUNTU11):
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597
#https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600
LOG.info("Handling special install of %s" % (name))
#this seems to be a temporary fix for that bug
with TemporaryFile() as f:
full_cmd = self._form_cmd(name, pkginfo.get("version"))
if(full_cmd):
cmd = APT_GET + APT_INSTALL + [full_cmd]
execute(*cmd, run_as_root=True, stdout_fh=f, stderr_fh=f, env_overrides=ENV_ADDITIONS)
return True
return False
return False

@ -28,9 +28,8 @@ YUM_INSTALL = ["install", "-y"]
class YumPackager(Packager.Packager):
def __init__(self):
LOG.info("Init called")
Packager.Packager.__init__(self)
def __init__(self, distro):
Packager.Packager.__init__(self, distro)
def _form_cmd(self, name, version):
cmd = name

45
stack

@ -32,7 +32,6 @@ from Util import (NOVA, GLANCE, QUANTUM, SWIFT, KEYSTONE, HORIZON, DB, RABBIT,
UBUNTU11, RHEL6,
STACK_CFG_LOC)
from Shell import (mkdir, joinpths, unlink)
from Config import (EnvConfigParser)
from Exceptions import (NoTraceException)
import Glance
@ -44,6 +43,7 @@ import Config
import Swift
import Db
import Rabbit
import Config
LOG = Logger.getLogger("install")
@ -108,16 +108,41 @@ def get_package_manager_class(distro):
def get_config(action):
LOG.info("Loading config from %s" % (STACK_CFG_LOC))
cfg = EnvConfigParser()
cfg.read(STACK_CFG_LOC)
fn = STACK_CFG_LOC
LOG.info("Loading config from %s" % (fn))
cfg = Config.EnvConfigParser()
cfg.read(fn)
return cfg
def print_cfgs(cfg, action):
if(len(cfg)):
#this will make the items nice and pretty
def item_format(k, v):
return "\t%s=%s" % (str(k), str(v))
def map_print(mp):
for key in sorted(mp.keys()):
value = mp.get(key)
LOG.info(item_format(key, value))
#now make it pretty
passwords_gotten = cfg.pws
full_cfgs = cfg.configs_fetched
db_dsns = cfg.db_dsns
if(len(passwords_gotten) or len(full_cfgs) or len(db_dsns)):
LOG.info("After %s your config is:" % (action))
LOG.info(str(cfg).strip())
if(len(passwords_gotten)):
LOG.info("Passwords:")
map_print(passwords_gotten)
if(len(full_cfgs)):
filtered_mp = dict()
for key in full_cfgs.keys():
if(key in passwords_gotten):
continue
filtered_mp[key] = full_cfgs.get(key)
LOG.info("Configs:")
map_print(filtered_mp)
if(len(db_dsns)):
LOG.info("Data source names:")
map_print(db_dsns)
def runner(action_name, component_set, distro, root_dir, program_args):
@ -125,7 +150,7 @@ def runner(action_name, component_set, distro, root_dir, program_args):
if(action_name == INSTALL):
mkdir(root_dir)
pkg_manager_cls = get_package_manager_class(distro)
pkg_manager = pkg_manager_cls()
pkg_manager = pkg_manager_cls(distro)
config = get_config(action_name)
LOG.info("Will %s [%s] using root directory %s" % (action_name, ", ".join(component_set), root_dir))
results = list()
@ -139,8 +164,12 @@ def runner(action_name, component_set, distro, root_dir, program_args):
instance.download()
LOG.info("Configuring %s." % (c))
instance.configure()
LOG.info("Pre-installing %s." % (c))
instance.pre_install()
LOG.info("Installing %s." % (c))
trace = instance.install()
instance.install()
LOG.info("Post-installing %s." % (c))
trace = instance.post_install()
if(trace):
LOG.info("Finished install of %s - check %s for traces of what happened." % (c, trace))
results.append(trace)