Initial attempt/work for personas

This commit is contained in:
Joshua Harlow 2012-03-15 14:22:14 -07:00
parent 7e9dc5f7fc
commit a20a06edac
31 changed files with 470 additions and 795 deletions

View File

@ -18,6 +18,8 @@ commands:
status: ["service", "apache2", "status"] status: ["service", "apache2", "status"]
settings: settings:
conf-link-target: /etc/apache2/sites-enabled/000-default conf-link-target: /etc/apache2/sites-enabled/000-default
libvirt-daemon: 'libvirt-bin'
mysql: mysql:
start: ["service", "mysql", 'start'] start: ["service", "mysql", 'start']
@ -31,7 +33,12 @@ commands:
drop_db: ['mysql', '--user=%USER%', '--password=%PASSWORD%', '-e', 'DROP DATABASE IF EXISTS %DB%;'] drop_db: ['mysql', '--user=%USER%', '--password=%PASSWORD%', '-e', 'DROP DATABASE IF EXISTS %DB%;']
grant_all: ["mysql", "--user=%USER%", "--password=%PASSWORD%", '-e', grant_all: ["mysql", "--user=%USER%", "--password=%PASSWORD%", '-e',
"\"GRANT ALL PRIVILEGES ON *.* TO '%USER%'@'%' IDENTIFIED BY '%PASSWORD%'; FLUSH PRIVILEGES;\""] "\"GRANT ALL PRIVILEGES ON *.* TO '%USER%'@'%' IDENTIFIED BY '%PASSWORD%'; FLUSH PRIVILEGES;\""]
iscsi:
start: ['service', 'tgt', 'start']
stop: ['service', 'tgt', 'stop']
restart: ['service', 'tgt', 'restart']
status: ['service', 'tgt', 'status']
components: components:
db: db:
@ -435,7 +442,7 @@ components:
removable: True removable: True
version: 0.14.* version: 0.14.*
n-vnc: no-vnc:
install: devstack.components.novnc:NoVNCInstaller install: devstack.components.novnc:NoVNCInstaller
uninstall: devstack.components.novnc:NoVNCUninstaller uninstall: devstack.components.novnc:NoVNCUninstaller
start: devstack.components.novnc:NoVNCRuntime start: devstack.components.novnc:NoVNCRuntime
@ -664,7 +671,7 @@ components:
removable: True removable: True
version: 1.12* version: 1.12*
rabbit: rabbit-mq:
install: devstack.components.rabbit:RabbitInstaller install: devstack.components.rabbit:RabbitInstaller
uninstall: devstack.components.rabbit:RabbitUninstaller uninstall: devstack.components.rabbit:RabbitUninstaller
start: devstack.components.rabbit:RabbitRuntime start: devstack.components.rabbit:RabbitRuntime

View File

@ -0,0 +1,31 @@
---
created_on: Wed, 14 Mar 2012 17:28:24 -0700
description: Devstack.sh matching component installation (as of the above date).
supports:
- rhel-6
- ubuntu-oneiric
- fedora-16
components:
- db
- rabbit-mq
- keystone-client
- keystone
- glance
- nova
- no-vnc
- quantum-client
- nova-client
- horizon
subsystems:
glance:
- api
- reg
nova:
- api
- cauth
- cert
- cpu
- net
- sched
- vol
- xvnc

View File

@ -22,6 +22,7 @@ from devstack import date
from devstack import env from devstack import env
from devstack import exceptions as excp from devstack import exceptions as excp
from devstack import log as logging from devstack import log as logging
from devstack import settings
from devstack import shell as sh from devstack import shell as sh
from devstack import utils from devstack import utils
@ -31,6 +32,16 @@ SUB_MATCH = re.compile(r"(?:\$\(([\w\d]+):([\w\d]+))\)")
CACHE_MSG = "(value will now be internally cached)" CACHE_MSG = "(value will now be internally cached)"
def get_config(cfg_fn=None, cfg_cls=None):
if not cfg_fn:
cfg_fn = sh.canon_path(settings.STACK_CONFIG_LOCATION)
if not cfg_cls:
cfg_cls = StackConfigParser
config_instance = cfg_cls()
config_instance.read(cfg_fn)
return config_instance
class IgnoreMissingConfigParser(ConfigParser.RawConfigParser): class IgnoreMissingConfigParser(ConfigParser.RawConfigParser):
DEF_INT = 0 DEF_INT = 0
DEF_FLOAT = 0.0 DEF_FLOAT = 0.0

View File

@ -32,12 +32,10 @@ def make_id(section, option):
def fetch_run_type(config): def fetch_run_type(config):
run_type = config.getdefaulted("default", "run_type", settings.RUN_TYPE_DEF) run_type = config.getdefaulted("default", "run_type", settings.RUN_TYPE_DEF)
run_type = run_type.upper() return run_type.upper()
return run_type
def fetch_dbdsn(config, pw_gen, dbname=''): def fetch_dbdsn(config, pw_gen, dbname=''):
#check the dsn cache
user = config.get("db", "sql_user") user = config.get("db", "sql_user")
host = config.get("db", "sql_host") host = config.get("db", "sql_host")
port = config.get("db", "port") port = config.get("db", "port")
@ -65,5 +63,5 @@ def fetch_dbdsn(config, pw_gen, dbname=''):
dsn += "/" + dbname dsn += "/" + dbname
else: else:
dsn += "/" dsn += "/"
LOG.debug("For database [%s] fetched dsn [%s]" % (dbname, dsn)) LOG.audit("For database [%s] fetched dsn [%s]" % (dbname, dsn))
return dsn return dsn

View File

@ -53,37 +53,40 @@ BASE_LINK_DIR = "/etc"
class ComponentBase(object): class ComponentBase(object):
def __init__(self, component_name, runner, def __init__(self,
root_dir, component_options, subsystems,
instances=None, runner,
**kwds): component_dir,
self.component_name = component_name all_instances,
name,
*args,
**kargs):
# Required vars
self.subsystems = subsystems
self.instances = all_instances
# The runner has a reference to us, so use a weakref here to # The runner has a reference to us, so use a weakref here to
# avoid breaking garbage collection. # avoid breaking garbage collection.
self.runner = weakref.proxy(runner) self.runner = weakref.proxy(runner)
self.root = root_dir
self.component_opts = component_options or {}
self.instances = instances or {}
# Parts of the global runner context that we use # Parts of the global runner context that we use
self.cfg = runner.cfg self.cfg = runner.cfg
self.pw_gen = runner.pw_gen self.pw_gen = runner.pw_gen
self.packager = runner.pkg_manager self.packager = runner.pkg_manager
self.distro = runner.distro self.distro = runner.distro
self.component_root = sh.joinpths(self.root, component_name) # What this component is called
self.tracedir = sh.joinpths(self.component_root, self.component_name = name
# Required component directories
self.component_dir = component_dir
self.trace_dir = sh.joinpths(self.component_dir,
settings.COMPONENT_TRACE_DIR) settings.COMPONENT_TRACE_DIR)
self.appdir = sh.joinpths(self.component_root, self.app_dir = sh.joinpths(self.component_dir,
settings.COMPONENT_APP_DIR) settings.COMPONENT_APP_DIR)
self.cfgdir = sh.joinpths(self.component_root, self.cfg_dir = sh.joinpths(self.component_dir,
settings.COMPONENT_CONFIG_DIR) settings.COMPONENT_CONFIG_DIR)
self.kargs = kwds
def get_dependencies(self):
return self.runner.distro.components[self.component_name].get('dependencies', [])[:]
def verify(self): def verify(self):
pass pass
@ -92,26 +95,25 @@ class ComponentBase(object):
pass pass
def is_started(self): def is_started(self):
reader = tr.TraceReader(tr.trace_fn(self.tracedir, tr.START_TRACE)) reader = tr.TraceReader(tr.trace_fn(self.trace_dir, tr.START_TRACE))
return reader.exists() return reader.exists()
def is_installed(self): def is_installed(self):
return tr.TraceReader(tr.trace_fn(self.tracedir, tr.IN_TRACE)).exists() return tr.TraceReader(tr.trace_fn(self.trace_dir, tr.IN_TRACE)).exists()
class PkgInstallComponent(ComponentBase): class PkgInstallComponent(ComponentBase):
def __init__(self, component_name, **kargs): def __init__(self, *args, **kargs):
ComponentBase.__init__(self, component_name, **kargs) ComponentBase.__init__(self, *args, **kargs)
self.tracewriter = tr.TraceWriter(tr.trace_fn(self.tracedir, self.tracewriter = tr.TraceWriter(tr.trace_fn(self.trace_dir,
tr.IN_TRACE) tr.IN_TRACE))
)
def _get_download_locations(self): def _get_download_locations(self):
return list() return list()
def download(self): def download(self):
locations = self._get_download_locations() locations = self._get_download_locations()
base_dir = self.appdir base_dir = self.app_dir
for location_info in locations: for location_info in locations:
uri_tuple = location_info["uri"] uri_tuple = location_info["uri"]
branch_tuple = location_info.get("branch") branch_tuple = location_info.get("branch")
@ -164,7 +166,7 @@ class PkgInstallComponent(ComponentBase):
else: else:
LOG.info('No packages to install for %s', LOG.info('No packages to install for %s',
self.component_name) self.component_name)
return self.tracedir return self.trace_dir
def pre_install(self): def pre_install(self):
pkgs = self.component_opts.get('packages', []) pkgs = self.component_opts.get('packages', [])
@ -185,7 +187,7 @@ class PkgInstallComponent(ComponentBase):
return contents return contents
def _get_target_config_name(self, config_fn): def _get_target_config_name(self, config_fn):
return sh.joinpths(self.cfgdir, config_fn) return sh.joinpths(self.cfg_dir, config_fn)
def _get_source_config(self, config_fn): def _get_source_config(self, config_fn):
return utils.load_template(self.component_name, config_fn) return utils.load_template(self.component_name, config_fn)
@ -246,12 +248,12 @@ class PkgInstallComponent(ComponentBase):
class PythonInstallComponent(PkgInstallComponent): class PythonInstallComponent(PkgInstallComponent):
def __init__(self, component_name, *args, **kargs): def __init__(self, *args, **kargs):
PkgInstallComponent.__init__(self, component_name, *args, **kargs) PkgInstallComponent.__init__(self, *args, **kargs)
def _get_python_directories(self): def _get_python_directories(self):
py_dirs = dict() py_dirs = dict()
py_dirs[self.component_name] = self.appdir py_dirs[self.component_name] = self.app_dir
return py_dirs return py_dirs
def _install_pips(self): def _install_pips(self):
@ -273,7 +275,7 @@ class PythonInstallComponent(PkgInstallComponent):
LOG.info("Setting up %s python directories (%s)", LOG.info("Setting up %s python directories (%s)",
len(pydirs), pydirs) len(pydirs), pydirs)
for (name, wkdir) in pydirs.items(): for (name, wkdir) in pydirs.items():
working_dir = wkdir or self.appdir working_dir = wkdir or self.app_dir
#ensure working dir is there #ensure working dir is there
self.tracewriter.dirs_made(*sh.mkdirslist(working_dir)) self.tracewriter.dirs_made(*sh.mkdirslist(working_dir))
#do this before write just incase it craps out half way through #do this before write just incase it craps out half way through
@ -283,7 +285,7 @@ class PythonInstallComponent(PkgInstallComponent):
cwd=working_dir, cwd=working_dir,
run_as_root=True) run_as_root=True)
py_trace_name = "%s-%s" % (tr.PY_TRACE, name) py_trace_name = "%s-%s" % (tr.PY_TRACE, name)
py_writer = tr.TraceWriter(tr.trace_fn(self.tracedir, py_writer = tr.TraceWriter(tr.trace_fn(self.trace_dir,
py_trace_name)) py_trace_name))
py_writer.trace("CMD", " ".join(PY_INSTALL)) py_writer.trace("CMD", " ".join(PY_INSTALL))
py_writer.trace("STDOUT", stdout) py_writer.trace("STDOUT", stdout)
@ -301,11 +303,11 @@ class PythonInstallComponent(PkgInstallComponent):
class PkgUninstallComponent(ComponentBase): class PkgUninstallComponent(ComponentBase):
def __init__(self, component_name, keep_old=None, **kargs): def __init__(self, *args, **kargs):
ComponentBase.__init__(self, component_name, **kargs) ComponentBase.__init__(self, *args, **kargs)
self.tracereader = tr.TraceReader(tr.trace_fn(self.tracedir, self.tracereader = tr.TraceReader(tr.trace_fn(self.trace_dir,
tr.IN_TRACE)) tr.IN_TRACE))
self.keep_old = keep_old self.keep_old = kargs.get('keep_old')
def unconfigure(self): def unconfigure(self):
if not self.keep_old: if not self.keep_old:
@ -321,7 +323,7 @@ class PkgUninstallComponent(ComponentBase):
if RUNNER_CLS_MAPPING: if RUNNER_CLS_MAPPING:
LOG.info("Unconfiguring %s runners.", len(RUNNER_CLS_MAPPING)) LOG.info("Unconfiguring %s runners.", len(RUNNER_CLS_MAPPING))
for (_, cls) in RUNNER_CLS_MAPPING.items(): for (_, cls) in RUNNER_CLS_MAPPING.items():
instance = cls(self.cfg, self.component_name, self.tracedir) instance = cls(self.cfg, self.component_name, self.trace_dir)
instance.unconfigure() instance.unconfigure()
def _unconfigure_links(self): def _unconfigure_links(self):
@ -386,8 +388,8 @@ class PkgUninstallComponent(ComponentBase):
class PythonUninstallComponent(PkgUninstallComponent): class PythonUninstallComponent(PkgUninstallComponent):
def __init__(self, component_name, *args, **kargs): def __init__(self, *args, **kargs):
PkgUninstallComponent.__init__(self, component_name, *args, **kargs) PkgUninstallComponent.__init__(self, *args, **kargs)
def uninstall(self): def uninstall(self):
self._uninstall_python() self._uninstall_python()
@ -409,10 +411,10 @@ class PythonUninstallComponent(PkgUninstallComponent):
class ProgramRuntime(ComponentBase): class ProgramRuntime(ComponentBase):
def __init__(self, component_name, **kargs): def __init__(self, *args, **kargs):
ComponentBase.__init__(self, component_name, **kargs) ComponentBase.__init__(self, *args, **kargs)
self.tracewriter = tr.TraceWriter(tr.trace_fn(self.tracedir, tr.START_TRACE)) self.tracewriter = tr.TraceWriter(tr.trace_fn(self.trace_dir, tr.START_TRACE))
self.tracereader = tr.TraceReader(tr.trace_fn(self.tracedir, tr.START_TRACE)) self.tracereader = tr.TraceReader(tr.trace_fn(self.trace_dir, tr.START_TRACE))
def _get_apps_to_start(self): def _get_apps_to_start(self):
return list() return list()
@ -422,7 +424,7 @@ class ProgramRuntime(ComponentBase):
def _get_param_map(self, app_name): def _get_param_map(self, app_name):
return { return {
'ROOT': self.appdir, 'ROOT': self.app_dir,
} }
def pre_start(self): def pre_start(self):
@ -435,12 +437,12 @@ class ProgramRuntime(ComponentBase):
# First make a pass and make sure all runtime (e.g. upstart) # First make a pass and make sure all runtime (e.g. upstart)
# config files are in place.... # config files are in place....
cls = RUNNER_CLS_MAPPING[cfg_helpers.fetch_run_type(self.cfg)] cls = RUNNER_CLS_MAPPING[cfg_helpers.fetch_run_type(self.cfg)]
instance = cls(self.cfg, self.component_name, self.tracedir) instance = cls(self.cfg, self.component_name, self.trace_dir)
tot_am = 0 tot_am = 0
for app_info in self._get_apps_to_start(): for app_info in self._get_apps_to_start():
app_name = app_info["name"] app_name = app_info["name"]
app_pth = app_info.get("path", app_name) app_pth = app_info.get("path", app_name)
app_dir = app_info.get("app_dir", self.appdir) app_dir = app_info.get("app_dir", self.app_dir)
# Adjust the program options now that we have real locations # Adjust the program options now that we have real locations
program_opts = utils.param_replace_list( program_opts = utils.param_replace_list(
self._get_app_options(app_name), self._get_app_options(app_name),
@ -458,12 +460,12 @@ class ProgramRuntime(ComponentBase):
def start(self): def start(self):
# Select how we are going to start it # Select how we are going to start it
cls = RUNNER_CLS_MAPPING[cfg_helpers.fetch_run_type(self.cfg)] cls = RUNNER_CLS_MAPPING[cfg_helpers.fetch_run_type(self.cfg)]
instance = cls(self.cfg, self.component_name, self.tracedir) instance = cls(self.cfg, self.component_name, self.trace_dir)
am_started = 0 am_started = 0
for app_info in self._get_apps_to_start(): for app_info in self._get_apps_to_start():
app_name = app_info["name"] app_name = app_info["name"]
app_pth = app_info.get("path", app_name) app_pth = app_info.get("path", app_name)
app_dir = app_info.get("app_dir", self.appdir) app_dir = app_info.get("app_dir", self.app_dir)
# Adjust the program options now that we have real locations # Adjust the program options now that we have real locations
program_opts = utils.param_replace_list( program_opts = utils.param_replace_list(
self._get_app_options(app_name), self._get_app_options(app_name),
@ -500,7 +502,7 @@ class ProgramRuntime(ComponentBase):
else: else:
killer = killcls(self.cfg, killer = killcls(self.cfg,
self.component_name, self.component_name,
self.tracedir, self.trace_dir,
) )
killer_instances[killcls] = killer killer_instances[killcls] = killer
to_kill.append((app_name, killer)) to_kill.append((app_name, killer))
@ -526,14 +528,14 @@ class ProgramRuntime(ComponentBase):
class PythonRuntime(ProgramRuntime): class PythonRuntime(ProgramRuntime):
def __init__(self, component_name, *args, **kargs): def __init__(self, *args, **kargs):
ProgramRuntime.__init__(self, component_name, *args, **kargs) ProgramRuntime.__init__(self, *args, **kargs)
class EmptyRuntime(ComponentBase): class EmptyRuntime(ComponentBase):
def __init__(self, component_name, **kargs): def __init__(self, *args, **kargs):
ComponentBase.__init__(self, component_name, **kargs) ComponentBase.__init__(self, *args, **kargs)
self.tracereader = tr.TraceReader(tr.trace_fn(self.tracedir, tr.IN_TRACE)) self.tracereader = tr.TraceReader(tr.trace_fn(self.trace_dir, tr.IN_TRACE))
def configure(self): def configure(self):
return 0 return 0

View File

@ -21,8 +21,6 @@ from devstack import settings
from devstack import shell as sh from devstack import shell as sh
from devstack import utils from devstack import utils
#id
TYPE = settings.DB
LOG = logging.getLogger("devstack.components.db") LOG = logging.getLogger("devstack.components.db")
#used for special setups #used for special setups
@ -239,7 +237,7 @@ class DBRuntime(comp.EmptyRuntime):
def drop_db(cfg, pw_gen, distro, dbname): def drop_db(cfg, pw_gen, distro, dbname):
dbtype = cfg.get("db", "type") dbtype = cfg.get("db", "type")
dbactions = distro.commands[dbtype] dbactions = distro.get_command(dbtype)
if dbactions and dbactions.get('drop_db'): if dbactions and dbactions.get('drop_db'):
dropcmd = dbactions.get('drop_db') dropcmd = dbactions.get('drop_db')
params = dict() params = dict()
@ -259,7 +257,7 @@ def drop_db(cfg, pw_gen, distro, dbname):
def create_db(cfg, pw_gen, distro, dbname): def create_db(cfg, pw_gen, distro, dbname):
dbtype = cfg.get("db", "type") dbtype = cfg.get("db", "type")
dbactions = distro.commands[dbtype] dbactions = distro.get_command(dbtype)
if dbactions and dbactions.get('create_db'): if dbactions and dbactions.get('create_db'):
createcmd = dbactions.get('create_db') createcmd = dbactions.get('create_db')
params = dict() params = dict()

View File

@ -28,8 +28,6 @@ from devstack.components import keystone
from devstack.image import creator from devstack.image import creator
#id
TYPE = settings.GLANCE
LOG = logging.getLogger("devstack.components.glance") LOG = logging.getLogger("devstack.components.glance")
#config files/sections #config files/sections
@ -82,13 +80,13 @@ BIN_DIR = 'bin'
class GlanceUninstaller(comp.PythonUninstallComponent): class GlanceUninstaller(comp.PythonUninstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonUninstallComponent.__init__(self, *args, **kargs) comp.PythonUninstallComponent.__init__(self, *args, **kargs)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
class GlanceInstaller(comp.PythonInstallComponent): class GlanceInstaller(comp.PythonInstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonInstallComponent.__init__(self, *args, **kargs) comp.PythonInstallComponent.__init__(self, *args, **kargs)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
def _get_download_locations(self): def _get_download_locations(self):
places = list() places = list()
@ -112,11 +110,11 @@ class GlanceInstaller(comp.PythonInstallComponent):
def _get_source_config(self, config_fn): def _get_source_config(self, config_fn):
if config_fn == POLICY_JSON: if config_fn == POLICY_JSON:
fn = sh.joinpths(self.cfgdir, POLICY_JSON) fn = sh.joinpths(self.cfg_dir, POLICY_JSON)
contents = sh.load_file(fn) contents = sh.load_file(fn)
return (fn, contents) return (fn, contents)
elif config_fn == LOGGING_CONF: elif config_fn == LOGGING_CONF:
fn = sh.joinpths(self.cfgdir, LOGGING_SOURCE_FN) fn = sh.joinpths(self.cfg_dir, LOGGING_SOURCE_FN)
contents = sh.load_file(fn) contents = sh.load_file(fn)
return (fn, contents) return (fn, contents)
return comp.PythonInstallComponent._get_source_config(self, config_fn) return comp.PythonInstallComponent._get_source_config(self, config_fn)
@ -171,7 +169,7 @@ class GlanceInstaller(comp.PythonInstallComponent):
#this dict will be used to fill in the configuration #this dict will be used to fill in the configuration
#params with actual values #params with actual values
mp = dict() mp = dict()
mp['DEST'] = self.appdir mp['DEST'] = self.app_dir
mp['SYSLOG'] = self.cfg.getboolean("default", "syslog") mp['SYSLOG'] = self.cfg.getboolean("default", "syslog")
mp['SQL_CONN'] = cfg_helpers.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME) mp['SQL_CONN'] = cfg_helpers.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME)
mp['SERVICE_HOST'] = self.cfg.get('host', 'ip') mp['SERVICE_HOST'] = self.cfg.get('host', 'ip')
@ -183,11 +181,11 @@ class GlanceInstaller(comp.PythonInstallComponent):
class GlanceRuntime(comp.PythonRuntime): class GlanceRuntime(comp.PythonRuntime):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonRuntime.__init__(self, *args, **kargs) comp.PythonRuntime.__init__(self, *args, **kargs)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
def _get_apps_to_start(self): def _get_apps_to_start(self):
apps = [{'name': app_name, apps = [{'name': app_name,
'path': sh.joinpths(self.appdir, BIN_DIR, app_name), 'path': sh.joinpths(self.app_dir, BIN_DIR, app_name),
} }
for app_name in APP_OPTIONS.keys() for app_name in APP_OPTIONS.keys()
] ]

View File

@ -21,8 +21,6 @@ from devstack import settings
from devstack import shell as sh from devstack import shell as sh
from devstack import utils from devstack import utils
#id
TYPE = settings.HORIZON
LOG = logging.getLogger("devstack.components.horizon") LOG = logging.getLogger("devstack.components.horizon")
#actual dir names #actual dir names
@ -52,11 +50,12 @@ APACHE_ACCESS_LOG_FN = "access.log"
APACHE_DEF_PORT = 80 APACHE_DEF_PORT = 80
#TODO: maybe this should be a subclass that handles these differences #TODO: maybe this should be a subclass that handles these differences
APACHE_FIXUPS = { # APACHE_FIXUPS = {
'SOCKET_CONF': "/etc/httpd/conf.d/wsgi-socket-prefix.conf", # 'SOCKET_CONF': "/etc/httpd/conf.d/wsgi-socket-prefix.conf",
'HTTPD_CONF': '/etc/httpd/conf/httpd.conf', # 'HTTPD_CONF': '/etc/httpd/conf/httpd.conf',
} # }
APACHE_FIXUPS_DISTROS = [settings.RHEL6, settings.FEDORA16] # APACHE_FIXUPS_DISTROS = [settings.RHEL6, settings.FEDORA16]
APACHE_FIXUPS_DISTROS = []
#for when quantum client is not need we need some fake files so python doesn't croak #for when quantum client is not need we need some fake files so python doesn't croak
FAKE_QUANTUM_FILES = ['__init__.py', 'client.py'] FAKE_QUANTUM_FILES = ['__init__.py', 'client.py']
@ -76,9 +75,9 @@ class HorizonUninstaller(comp.PythonUninstallComponent):
class HorizonInstaller(comp.PythonInstallComponent): class HorizonInstaller(comp.PythonInstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonInstallComponent.__init__(self, *args, **kargs) comp.PythonInstallComponent.__init__(self, *args, **kargs)
self.horizon_dir = sh.joinpths(self.appdir, ROOT_HORIZON) self.horizon_dir = sh.joinpths(self.app_dir, ROOT_HORIZON)
self.dash_dir = sh.joinpths(self.appdir, ROOT_DASH) self.dash_dir = sh.joinpths(self.app_dir, ROOT_DASH)
self.log_dir = sh.joinpths(self.component_root, LOGS_DIR) self.log_dir = sh.joinpths(self.component_dir, LOGS_DIR)
def _get_download_locations(self): def _get_download_locations(self):
places = list() places = list()
@ -98,7 +97,7 @@ class HorizonInstaller(comp.PythonInstallComponent):
if utils.service_enabled(settings.QUANTUM_CLIENT, self.instances, False): if utils.service_enabled(settings.QUANTUM_CLIENT, self.instances, False):
#TODO remove this junk, blah, puke that we have to do this #TODO remove this junk, blah, puke that we have to do this
qc = self.instances[settings.QUANTUM_CLIENT] qc = self.instances[settings.QUANTUM_CLIENT]
src_pth = sh.joinpths(qc.appdir, 'quantum') src_pth = sh.joinpths(qc.app_dir, 'quantum')
tgt_dir = sh.joinpths(self.dash_dir, 'quantum') tgt_dir = sh.joinpths(self.dash_dir, 'quantum')
links[src_pth] = tgt_dir links[src_pth] = tgt_dir
return links return links
@ -126,13 +125,13 @@ class HorizonInstaller(comp.PythonInstallComponent):
def _setup_blackhole(self): def _setup_blackhole(self):
#create an empty directory that apache uses as docroot #create an empty directory that apache uses as docroot
self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.appdir, BLACKHOLE_DIR))) self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.app_dir, BLACKHOLE_DIR)))
def _sync_db(self): def _sync_db(self):
#Initialize the horizon database (it stores sessions and notices shown to users). #Initialize the horizon database (it stores sessions and notices shown to users).
#The user system is external (keystone). #The user system is external (keystone).
LOG.info("Initializing the horizon database.") LOG.info("Initializing the horizon database.")
sh.execute(*DB_SYNC_CMD, cwd=self.appdir) sh.execute(*DB_SYNC_CMD, cwd=self.app_dir)
def _ensure_db_access(self): def _ensure_db_access(self):
# ../openstack-dashboard/local needs to be writeable by the runtime user # ../openstack-dashboard/local needs to be writeable by the runtime user
@ -208,10 +207,10 @@ class HorizonInstaller(comp.PythonInstallComponent):
mp['ACCESS_LOG'] = sh.joinpths(self.log_dir, APACHE_ACCESS_LOG_FN) mp['ACCESS_LOG'] = sh.joinpths(self.log_dir, APACHE_ACCESS_LOG_FN)
mp['ERROR_LOG'] = sh.joinpths(self.log_dir, APACHE_ERROR_LOG_FN) mp['ERROR_LOG'] = sh.joinpths(self.log_dir, APACHE_ERROR_LOG_FN)
mp['GROUP'] = group mp['GROUP'] = group
mp['HORIZON_DIR'] = self.appdir mp['HORIZON_DIR'] = self.app_dir
mp['HORIZON_PORT'] = self.cfg.getdefaulted('horizon', 'port', APACHE_DEF_PORT) mp['HORIZON_PORT'] = self.cfg.getdefaulted('horizon', 'port', APACHE_DEF_PORT)
mp['USER'] = user mp['USER'] = user
mp['VPN_DIR'] = sh.joinpths(self.appdir, "vpn") mp['VPN_DIR'] = sh.joinpths(self.app_dir, "vpn")
else: else:
mp['OPENSTACK_HOST'] = self.cfg.get('host', 'ip') mp['OPENSTACK_HOST'] = self.cfg.get('host', 'ip')
return mp return mp

View File

@ -28,8 +28,6 @@ from devstack import utils
from devstack.components import db from devstack.components import db
#id
TYPE = settings.KEYSTONE
LOG = logging.getLogger("devstack.components.keystone") LOG = logging.getLogger("devstack.components.keystone")
#this db will be dropped then created #this db will be dropped then created
@ -86,15 +84,15 @@ QUANTUM_TEMPL_ADDS = ['catalog.RegionOne.network.publicURL = http://%SERVICE_HOS
class KeystoneUninstaller(comp.PythonUninstallComponent): class KeystoneUninstaller(comp.PythonUninstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonUninstallComponent.__init__(self, *args, **kargs) comp.PythonUninstallComponent.__init__(self, *args, **kargs)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
class KeystoneInstaller(comp.PythonInstallComponent): class KeystoneInstaller(comp.PythonInstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonInstallComponent.__init__(self, *args, **kargs) comp.PythonInstallComponent.__init__(self, *args, **kargs)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
def _get_download_locations(self): def _get_download_locations(self):
places = list() places = list()
@ -113,9 +111,9 @@ class KeystoneInstaller(comp.PythonInstallComponent):
def _sync_db(self): def _sync_db(self):
LOG.info("Syncing keystone to database named %s.", DB_NAME) LOG.info("Syncing keystone to database named %s.", DB_NAME)
params = dict() params = dict()
params['BINDIR'] = self.bindir params['BINDIR'] = self.bin_dir
cmds = [{'cmd': SYNC_DB_CMD}] cmds = [{'cmd': SYNC_DB_CMD}]
utils.execute_template(*cmds, cwd=self.bindir, params=params) utils.execute_template(*cmds, cwd=self.bin_dir, params=params)
def _get_config_files(self): def _get_config_files(self):
return list(CONFIGS) return list(CONFIGS)
@ -130,7 +128,7 @@ class KeystoneInstaller(comp.PythonInstallComponent):
(_, contents) = utils.load_template(self.component_name, MANAGE_DATA_CONF) (_, contents) = utils.load_template(self.component_name, MANAGE_DATA_CONF)
params = self._get_param_map(MANAGE_DATA_CONF) params = self._get_param_map(MANAGE_DATA_CONF)
contents = utils.param_replace(contents, params, True) contents = utils.param_replace(contents, params, True)
tgt_fn = sh.joinpths(self.bindir, MANAGE_DATA_CONF) tgt_fn = sh.joinpths(self.bin_dir, MANAGE_DATA_CONF)
sh.write_file(tgt_fn, contents) sh.write_file(tgt_fn, contents)
sh.chmod(tgt_fn, 0755) sh.chmod(tgt_fn, 0755)
self.tracewriter.file_touched(tgt_fn) self.tracewriter.file_touched(tgt_fn)
@ -175,7 +173,7 @@ class KeystoneInstaller(comp.PythonInstallComponent):
def _get_source_config(self, config_fn): def _get_source_config(self, config_fn):
if config_fn == LOGGING_CONF: if config_fn == LOGGING_CONF:
fn = sh.joinpths(self.cfgdir, LOGGING_SOURCE_FN) fn = sh.joinpths(self.cfg_dir, LOGGING_SOURCE_FN)
contents = sh.load_file(fn) contents = sh.load_file(fn)
return (fn, contents) return (fn, contents)
return comp.PythonInstallComponent._get_source_config(self, config_fn) return comp.PythonInstallComponent._get_source_config(self, config_fn)
@ -188,12 +186,12 @@ class KeystoneInstaller(comp.PythonInstallComponent):
#params with actual values #params with actual values
mp = dict() mp = dict()
mp['SERVICE_HOST'] = self.cfg.get('host', 'ip') mp['SERVICE_HOST'] = self.cfg.get('host', 'ip')
mp['DEST'] = self.appdir mp['DEST'] = self.app_dir
mp['BIN_DIR'] = self.bindir mp['BIN_DIR'] = self.bin_dir
mp['CONFIG_FILE'] = sh.joinpths(self.cfgdir, ROOT_CONF) mp['CONFIG_FILE'] = sh.joinpths(self.cfg_dir, ROOT_CONF)
if config_fn == ROOT_CONF: if config_fn == ROOT_CONF:
mp['SQL_CONN'] = cfg_helpers.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME) mp['SQL_CONN'] = cfg_helpers.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME)
mp['KEYSTONE_DIR'] = self.appdir mp['KEYSTONE_DIR'] = self.app_dir
mp.update(get_shared_params(self.cfg, self.pw_gen)) mp.update(get_shared_params(self.cfg, self.pw_gen))
elif config_fn == MANAGE_DATA_CONF: elif config_fn == MANAGE_DATA_CONF:
mp.update(get_shared_params(self.cfg, self.pw_gen)) mp.update(get_shared_params(self.cfg, self.pw_gen))
@ -203,11 +201,11 @@ class KeystoneInstaller(comp.PythonInstallComponent):
class KeystoneRuntime(comp.PythonRuntime): class KeystoneRuntime(comp.PythonRuntime):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonRuntime.__init__(self, *args, **kargs) comp.PythonRuntime.__init__(self, *args, **kargs)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
def post_start(self): def post_start(self):
tgt_fn = sh.joinpths(self.bindir, MANAGE_DATA_CONF) tgt_fn = sh.joinpths(self.bin_dir, MANAGE_DATA_CONF)
if sh.isfile(tgt_fn): if sh.isfile(tgt_fn):
#still there, run it #still there, run it
#these environment additions are important #these environment additions are important
@ -216,7 +214,7 @@ class KeystoneRuntime(comp.PythonRuntime):
sh.sleep(WAIT_ONLINE_TO) sh.sleep(WAIT_ONLINE_TO)
env = dict() env = dict()
env['ENABLED_SERVICES'] = ",".join(self.instances.keys()) env['ENABLED_SERVICES'] = ",".join(self.instances.keys())
env['BIN_DIR'] = self.bindir env['BIN_DIR'] = self.bin_dir
setup_cmd = MANAGE_CMD_ROOT + [tgt_fn] setup_cmd = MANAGE_CMD_ROOT + [tgt_fn]
LOG.info("Running (%s) command to initialize keystone." % (" ".join(setup_cmd))) LOG.info("Running (%s) command to initialize keystone." % (" ".join(setup_cmd)))
sh.execute(*setup_cmd, env_overrides=env, run_as_root=False) sh.execute(*setup_cmd, env_overrides=env, run_as_root=False)
@ -228,7 +226,7 @@ class KeystoneRuntime(comp.PythonRuntime):
for app_name in APP_OPTIONS.keys(): for app_name in APP_OPTIONS.keys():
apps.append({ apps.append({
'name': app_name, 'name': app_name,
'path': sh.joinpths(self.bindir, app_name), 'path': sh.joinpths(self.bin_dir, app_name),
}) })
return apps return apps

View File

@ -18,8 +18,6 @@ from devstack import component as comp
from devstack import log as logging from devstack import log as logging
from devstack import settings from devstack import settings
#id
TYPE = settings.KEYSTONE_CLIENT
LOG = logging.getLogger("devstack.components.keystone_client") LOG = logging.getLogger("devstack.components.keystone_client")

View File

@ -26,8 +26,6 @@ from devstack import utils
from devstack.components import db from devstack.components import db
#id
TYPE = settings.MELANGE
LOG = logging.getLogger("devstack.components.melange") LOG = logging.getLogger("devstack.components.melange")
#this db will be dropped then created #this db will be dropped then created
@ -47,7 +45,7 @@ DEF_CIDR_RANGE = 'FE-EE-DD-00-00-00/24'
#how we sync melange with the db #how we sync melange with the db
DB_SYNC_CMD = [ DB_SYNC_CMD = [
{'cmd': ['%BINDIR%/melange-manage', '--config-file=%CFG_FILE%', 'db_sync']}, {'cmd': ['%BIN_DIR%/melange-manage', '--config-file=%CFG_FILE%', 'db_sync']},
] ]
#??? #???
@ -73,8 +71,8 @@ class MelangeUninstaller(comp.PythonUninstallComponent):
class MelangeInstaller(comp.PythonInstallComponent): class MelangeInstaller(comp.PythonInstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonInstallComponent.__init__(self, *args, **kargs) comp.PythonInstallComponent.__init__(self, *args, **kargs)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.cfgdir = sh.joinpths(self.appdir, *CFG_LOC) self.cfg_dir = sh.joinpths(self.app_dir, *CFG_LOC)
def _get_download_locations(self): def _get_download_locations(self):
places = list() places = list()
@ -97,8 +95,8 @@ class MelangeInstaller(comp.PythonInstallComponent):
def _sync_db(self): def _sync_db(self):
LOG.info("Syncing the database with melange.") LOG.info("Syncing the database with melange.")
mp = dict() mp = dict()
mp['BINDIR'] = self.bindir mp['BIN_DIR'] = self.bin_dir
mp['CFG_FILE'] = sh.joinpths(self.cfgdir, ROOT_CONF_REAL_NAME) mp['CFG_FILE'] = sh.joinpths(self.cfg_dir, ROOT_CONF_REAL_NAME)
utils.execute_template(*DB_SYNC_CMD, params=mp) utils.execute_template(*DB_SYNC_CMD, params=mp)
def _get_config_files(self): def _get_config_files(self):
@ -123,7 +121,7 @@ class MelangeInstaller(comp.PythonInstallComponent):
def _get_source_config(self, config_fn): def _get_source_config(self, config_fn):
if config_fn == ROOT_CONF: if config_fn == ROOT_CONF:
srcfn = sh.joinpths(self.cfgdir, config_fn) srcfn = sh.joinpths(self.cfg_dir, config_fn)
contents = sh.load_file(srcfn) contents = sh.load_file(srcfn)
return (srcfn, contents) return (srcfn, contents)
else: else:
@ -131,7 +129,7 @@ class MelangeInstaller(comp.PythonInstallComponent):
def _get_target_config_name(self, config_fn): def _get_target_config_name(self, config_fn):
if config_fn == ROOT_CONF: if config_fn == ROOT_CONF:
return sh.joinpths(self.cfgdir, ROOT_CONF_REAL_NAME) return sh.joinpths(self.cfg_dir, ROOT_CONF_REAL_NAME)
else: else:
return comp.PythonInstallComponent._get_target_config_name(self, config_fn) return comp.PythonInstallComponent._get_target_config_name(self, config_fn)
@ -139,15 +137,15 @@ class MelangeInstaller(comp.PythonInstallComponent):
class MelangeRuntime(comp.PythonRuntime): class MelangeRuntime(comp.PythonRuntime):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonRuntime.__init__(self, *args, **kargs) comp.PythonRuntime.__init__(self, *args, **kargs)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.cfgdir = sh.joinpths(self.appdir, *CFG_LOC) self.cfg_dir = sh.joinpths(self.app_dir, *CFG_LOC)
def _get_apps_to_start(self): def _get_apps_to_start(self):
apps = list() apps = list()
for app_name in APP_OPTIONS.keys(): for app_name in APP_OPTIONS.keys():
apps.append({ apps.append({
'name': app_name, 'name': app_name,
'path': sh.joinpths(self.bindir, app_name), 'path': sh.joinpths(self.bin_dir, app_name),
}) })
return apps return apps
@ -156,7 +154,7 @@ class MelangeRuntime(comp.PythonRuntime):
def _get_param_map(self, app_name): def _get_param_map(self, app_name):
pmap = comp.PythonRuntime._get_param_map(self, app_name) pmap = comp.PythonRuntime._get_param_map(self, app_name)
pmap['CFG_FILE'] = sh.joinpths(self.cfgdir, ROOT_CONF_REAL_NAME) pmap['CFG_FILE'] = sh.joinpths(self.cfg_dir, ROOT_CONF_REAL_NAME)
return pmap return pmap
def post_start(self): def post_start(self):

View File

@ -18,8 +18,6 @@ from devstack import component as comp
from devstack import log as logging from devstack import log as logging
from devstack import settings from devstack import settings
#id
TYPE = settings.MELANGE_CLIENT
LOG = logging.getLogger("devstack.components.melange_client") LOG = logging.getLogger("devstack.components.melange_client")

View File

@ -29,17 +29,15 @@ from devstack import utils
from devstack.components import db from devstack.components import db
from devstack.components import keystone from devstack.components import keystone
#id
TYPE = settings.NOVA
LOG = logging.getLogger('devstack.components.nova') LOG = logging.getLogger('devstack.components.nova')
#special generated conf # Special generated conf
API_CONF = 'nova.conf' API_CONF = 'nova.conf'
#how we reference some config files (in applications) # How we reference some config files (in applications)
CFG_FILE_OPT = '--config-file' CFG_FILE_OPT = '--config-file'
#normal conf # Normal conf
PASTE_CONF = 'nova-api-paste.ini' PASTE_CONF = 'nova-api-paste.ini'
PASTE_SOURCE_FN = 'api-paste.ini' PASTE_SOURCE_FN = 'api-paste.ini'
POLICY_CONF = 'policy.json' POLICY_CONF = 'policy.json'
@ -48,19 +46,19 @@ LOGGING_CONF = "logging.conf"
CONFIGS = [PASTE_CONF, POLICY_CONF, LOGGING_CONF] CONFIGS = [PASTE_CONF, POLICY_CONF, LOGGING_CONF]
ADJUST_CONFIGS = [PASTE_CONF] ADJUST_CONFIGS = [PASTE_CONF]
#this is a special conf # This is a special conf
NET_INIT_CONF = 'nova-network-init.sh' NET_INIT_CONF = 'nova-network-init.sh'
NET_INIT_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')] NET_INIT_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
#this db will be dropped then created # This db will be dropped then created
DB_NAME = 'nova' DB_NAME = 'nova'
#this makes the database be in sync with nova # This makes the database be in sync with nova
DB_SYNC_CMD = [ DB_SYNC_CMD = [
{'cmd': ['%BINDIR%/nova-manage', CFG_FILE_OPT, '%CFGFILE%', 'db', 'sync']}, {'cmd': ['%BIN_DIR%/nova-manage', CFG_FILE_OPT, '%CFGFILE%', 'db', 'sync']},
] ]
#these are used for nova volumens # These are used for nova volumes
VG_CHECK_CMD = [ VG_CHECK_CMD = [
{'cmd': ['vgs', '%VOLUME_GROUP%'], {'cmd': ['vgs', '%VOLUME_GROUP%'],
'run_as_root': True} 'run_as_root': True}
@ -82,21 +80,6 @@ VG_LVREMOVE_CMD = [
'run_as_root': True} 'run_as_root': True}
] ]
# iscsi restart commands
RESTART_TGT_CMD = {
settings.UBUNTU11: [
{'cmd': ['stop', 'tgt'], 'run_as_root': True},
{'cmd': ['start', 'tgt'], 'run_as_root': True}
],
settings.RHEL6: [
{'cmd': ['service', 'tgtd', 'stop'], 'run_as_root': True},
{'cmd': ['service', 'tgtd', 'start'], 'run_as_root': True}
],
settings.FEDORA16: [
{'cmd': ['service', 'tgtd', 'stop'], 'run_as_root': True},
{'cmd': ['service', 'tgtd', 'start'], 'run_as_root': True}
],
}
# NCPU, NVOL, NAPI ... are here as possible subcomponents of nova # NCPU, NVOL, NAPI ... are here as possible subcomponents of nova
NCPU = "cpu" NCPU = "cpu"
@ -187,16 +170,15 @@ CLEANER_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
#rhel6/fedora libvirt policy #rhel6/fedora libvirt policy
#http://wiki.libvirt.org/page/SSHPolicyKitSetup #http://wiki.libvirt.org/page/SSHPolicyKitSetup
LIBVIRT_POLICY_FN = "/etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla" #LIBVIRT_POLICY_FN = "/etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla"
LIBVIRT_POLICY_CONTENTS = """ #LIBVIRT_POLICY_CONTENTS = """
[libvirt Management Access] #[libvirt Management Access]
Identity=unix-group:libvirtd #Identity=unix-group:libvirtd
Action=org.libvirt.unix.manage #Action=org.libvirt.unix.manage
ResultAny=yes #ResultAny=yes
ResultInactive=yes #ResultInactive=yes
ResultActive=yes #ResultActive=yes
""" #"""
POLICY_DISTROS = [settings.RHEL6, settings.FEDORA16]
#xenserver specific defaults #xenserver specific defaults
XS_DEF_INTERFACE = 'eth1' XS_DEF_INTERFACE = 'eth1'
@ -245,8 +227,8 @@ def _canon_libvirt_type(virt_type):
class NovaUninstaller(comp.PythonUninstallComponent): class NovaUninstaller(comp.PythonUninstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonUninstallComponent.__init__(self, *args, **kargs) comp.PythonUninstallComponent.__init__(self, *args, **kargs)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
def pre_uninstall(self): def pre_uninstall(self):
self._clear_libvirt_domains() self._clear_libvirt_domains()
@ -256,10 +238,10 @@ class NovaUninstaller(comp.PythonUninstallComponent):
#these environment additions are important #these environment additions are important
#in that they eventually affect how this script runs #in that they eventually affect how this script runs
env = dict() env = dict()
env['ENABLED_SERVICES'] = ",".join(SUBCOMPONENTS) env['ENABLED_SERVICES'] = ",".join(self.subsystems)
env['BIN_DIR'] = self.bindir env['BIN_DIR'] = self.bin_dir
env['VOLUME_NAME_PREFIX'] = self.cfg.getdefaulted('nova', 'volume_name_prefix', DEF_VOL_PREFIX) env['VOLUME_NAME_PREFIX'] = self.cfg.getdefaulted('nova', 'volume_name_prefix', DEF_VOL_PREFIX)
cleaner_fn = sh.joinpths(self.bindir, CLEANER_DATA_CONF) cleaner_fn = sh.joinpths(self.bin_dir, CLEANER_DATA_CONF)
if sh.isfile(cleaner_fn): if sh.isfile(cleaner_fn):
LOG.info("Cleaning up your system by running nova cleaner script [%s]." % (cleaner_fn)) LOG.info("Cleaning up your system by running nova cleaner script [%s]." % (cleaner_fn))
cmd = CLEANER_CMD_ROOT + [cleaner_fn] cmd = CLEANER_CMD_ROOT + [cleaner_fn]
@ -270,28 +252,25 @@ class NovaUninstaller(comp.PythonUninstallComponent):
if virt_driver == 'libvirt': if virt_driver == 'libvirt':
inst_prefix = self.cfg.getdefaulted('nova', 'instance_name_prefix', DEF_INSTANCE_PREFIX) inst_prefix = self.cfg.getdefaulted('nova', 'instance_name_prefix', DEF_INSTANCE_PREFIX)
libvirt_type = _canon_libvirt_type(self.cfg.get('nova', 'libvirt_type')) libvirt_type = _canon_libvirt_type(self.cfg.get('nova', 'libvirt_type'))
virsh.clear_libvirt_domains(self.distro.name, libvirt_type, inst_prefix) virsh.clear_libvirt_domains(self.distro, libvirt_type, inst_prefix)
class NovaInstaller(comp.PythonInstallComponent): class NovaInstaller(comp.PythonInstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonInstallComponent.__init__(self, *args, **kargs) comp.PythonInstallComponent.__init__(self, *args, **kargs)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
self.paste_conf_fn = self._get_target_config_name(PASTE_CONF) self.paste_conf_fn = self._get_target_config_name(PASTE_CONF)
self.volumes_enabled = False self.volumes_enabled = False
package_names = [p['name'] if NVOL in self.subsystems:
for p in self.component_opts.get('packages', [])
]
if NVOL in package_names:
self.volumes_enabled = True self.volumes_enabled = True
self.xvnc_enabled = False self.xvnc_enabled = False
if NXVNC in package_names: if NXVNC in self.subsystems:
self.xvnc_enabled = True self.xvnc_enabled = True
def _get_symlinks(self): def _get_symlinks(self):
links = comp.PythonInstallComponent._get_symlinks(self) links = comp.PythonInstallComponent._get_symlinks(self)
source_fn = sh.joinpths(self.cfgdir, API_CONF) source_fn = sh.joinpths(self.cfg_dir, API_CONF)
links[source_fn] = sh.joinpths(self._get_link_dir(), API_CONF) links[source_fn] = sh.joinpths(self._get_link_dir(), API_CONF)
return links return links
@ -318,7 +297,7 @@ class NovaInstaller(comp.PythonInstallComponent):
(_, contents) = utils.load_template(self.component_name, NET_INIT_CONF) (_, contents) = utils.load_template(self.component_name, NET_INIT_CONF)
params = self._get_param_map(NET_INIT_CONF) params = self._get_param_map(NET_INIT_CONF)
contents = utils.param_replace(contents, params, True) contents = utils.param_replace(contents, params, True)
tgt_fn = sh.joinpths(self.bindir, NET_INIT_CONF) tgt_fn = sh.joinpths(self.bin_dir, NET_INIT_CONF)
sh.write_file(tgt_fn, contents) sh.write_file(tgt_fn, contents)
sh.chmod(tgt_fn, 0755) sh.chmod(tgt_fn, 0755)
self.tracewriter.file_touched(tgt_fn) self.tracewriter.file_touched(tgt_fn)
@ -326,8 +305,8 @@ class NovaInstaller(comp.PythonInstallComponent):
def _sync_db(self): def _sync_db(self):
LOG.info("Syncing the database with nova.") LOG.info("Syncing the database with nova.")
mp = dict() mp = dict()
mp['BINDIR'] = self.bindir mp['BIN_DIR'] = self.bin_dir
mp['CFGFILE'] = sh.joinpths(self.cfgdir, API_CONF) mp['CFGFILE'] = sh.joinpths(self.cfg_dir, API_CONF)
utils.execute_template(*DB_SYNC_CMD, params=mp) utils.execute_template(*DB_SYNC_CMD, params=mp)
def post_install(self): def post_install(self):
@ -345,7 +324,7 @@ class NovaInstaller(comp.PythonInstallComponent):
def _setup_cleaner(self): def _setup_cleaner(self):
LOG.info("Configuring cleaner template %s.", CLEANER_DATA_CONF) LOG.info("Configuring cleaner template %s.", CLEANER_DATA_CONF)
(_, contents) = utils.load_template(self.component_name, CLEANER_DATA_CONF) (_, contents) = utils.load_template(self.component_name, CLEANER_DATA_CONF)
tgt_fn = sh.joinpths(self.bindir, CLEANER_DATA_CONF) tgt_fn = sh.joinpths(self.bin_dir, CLEANER_DATA_CONF)
sh.write_file(tgt_fn, contents) sh.write_file(tgt_fn, contents)
sh.chmod(tgt_fn, 0755) sh.chmod(tgt_fn, 0755)
self.tracewriter.file_touched(tgt_fn) self.tracewriter.file_touched(tgt_fn)
@ -372,15 +351,15 @@ class NovaInstaller(comp.PythonInstallComponent):
return comp.PythonInstallComponent._get_source_config(self, PASTE_SOURCE_FN) return comp.PythonInstallComponent._get_source_config(self, PASTE_SOURCE_FN)
elif config_fn == LOGGING_CONF: elif config_fn == LOGGING_CONF:
name = LOGGING_SOURCE_FN name = LOGGING_SOURCE_FN
srcfn = sh.joinpths(self.cfgdir, "nova", name) srcfn = sh.joinpths(self.cfg_dir, "nova", name)
contents = sh.load_file(srcfn) contents = sh.load_file(srcfn)
return (srcfn, contents) return (srcfn, contents)
def _get_param_map(self, config_fn): def _get_param_map(self, config_fn):
mp = dict() mp = dict()
if config_fn == NET_INIT_CONF: if config_fn == NET_INIT_CONF:
mp['NOVA_DIR'] = self.appdir mp['NOVA_DIR'] = self.app_dir
mp['CFG_FILE'] = sh.joinpths(self.cfgdir, API_CONF) mp['CFG_FILE'] = sh.joinpths(self.cfg_dir, API_CONF)
mp['FLOATING_RANGE'] = self.cfg.getdefaulted('nova', 'floating_range', '172.24.4.224/28') mp['FLOATING_RANGE'] = self.cfg.getdefaulted('nova', 'floating_range', '172.24.4.224/28')
mp['TEST_FLOATING_RANGE'] = self.cfg.getdefaulted('nova', 'test_floating_range', '192.168.253.0/29') mp['TEST_FLOATING_RANGE'] = self.cfg.getdefaulted('nova', 'test_floating_range', '192.168.253.0/29')
mp['TEST_FLOATING_POOL'] = self.cfg.getdefaulted('nova', 'test_floating_pool', 'test') mp['TEST_FLOATING_POOL'] = self.cfg.getdefaulted('nova', 'test_floating_pool', 'test')
@ -394,15 +373,16 @@ class NovaInstaller(comp.PythonInstallComponent):
configs_made = comp.PythonInstallComponent.configure(self) configs_made = comp.PythonInstallComponent.configure(self)
self._generate_nova_conf() self._generate_nova_conf()
configs_made += 1 configs_made += 1
# TODO: maybe this should be a subclass that handles these differences
driver_canon = _canon_virt_driver(self.cfg.get('nova', 'virt_driver')) driver_canon = _canon_virt_driver(self.cfg.get('nova', 'virt_driver'))
if (self.distro.name in POLICY_DISTROS) and driver_canon == 'libvirt': # TODO maybe move this??
if driver_canon == 'libvirt' and self.distro.get_command('virt-policy', quiet=True):
(fn, contents) = self.distro.get_command('virt-policy')
dirs_made = list() dirs_made = list()
with sh.Rooted(True): with sh.Rooted(True):
dirs_made = sh.mkdirslist(sh.dirname(LIBVIRT_POLICY_FN)) dirs_made = sh.mkdirslist(sh.dirname(fn))
sh.write_file(LIBVIRT_POLICY_FN, LIBVIRT_POLICY_CONTENTS) sh.write_file(fn, contents)
self.tracewriter.dirs_made(*dirs_made) self.tracewriter.dirs_made(*dirs_made)
self.tracewriter.cfg_file_written(LIBVIRT_POLICY_FN) self.tracewriter.cfg_file_written(fn)
configs_made += 1 configs_made += 1
return configs_made return configs_made
@ -410,11 +390,11 @@ class NovaInstaller(comp.PythonInstallComponent):
class NovaRuntime(comp.PythonRuntime): class NovaRuntime(comp.PythonRuntime):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonRuntime.__init__(self, *args, **kargs) comp.PythonRuntime.__init__(self, *args, **kargs)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
def _setup_network_init(self): def _setup_network_init(self):
tgt_fn = sh.joinpths(self.bindir, NET_INIT_CONF) tgt_fn = sh.joinpths(self.bin_dir, NET_INIT_CONF)
if sh.isfile(tgt_fn): if sh.isfile(tgt_fn):
LOG.info("Creating your nova network to be used with instances.") LOG.info("Creating your nova network to be used with instances.")
#still there, run it #still there, run it
@ -434,16 +414,9 @@ class NovaRuntime(comp.PythonRuntime):
def post_start(self): def post_start(self):
self._setup_network_init() self._setup_network_init()
def get_dependencies(self):
deps = comp.PythonRuntime.get_dependencies(self)
# FIXME: This should come from a persona.
if utils.service_enabled(settings.QUANTUM, self.instances, False):
deps.append(settings.QUANTUM)
return deps
def _get_apps_to_start(self): def _get_apps_to_start(self):
result = [{'name': app_name, result = [{'name': app_name,
'path': sh.joinpths(self.bindir, app_name), 'path': sh.joinpths(self.bin_dir, app_name),
} }
for app_name in sorted(APP_OPTIONS.keys()) for app_name in sorted(APP_OPTIONS.keys())
] ]
@ -456,15 +429,15 @@ class NovaRuntime(comp.PythonRuntime):
if virt_driver == 'libvirt': if virt_driver == 'libvirt':
virt_type = _canon_libvirt_type(self.cfg.get('nova', 'libvirt_type')) virt_type = _canon_libvirt_type(self.cfg.get('nova', 'libvirt_type'))
LOG.info("Checking that your selected libvirt virtualization type [%s] is working and running." % (virt_type)) LOG.info("Checking that your selected libvirt virtualization type [%s] is working and running." % (virt_type))
if not virsh.virt_ok(virt_type, self.distro.name): if not virsh.virt_ok(virt_type, self.distro):
msg = ("Libvirt type %s for distro %s does not seem to be active or configured correctly, " msg = ("Libvirt type %s does not seem to be active or configured correctly, "
"perhaps you should be using %s instead." % (virt_type, self.distro.name, DEF_VIRT_TYPE)) "perhaps you should be using %s instead." % (virt_type, DEF_VIRT_TYPE))
raise exceptions.StartException(msg) raise exceptions.StartException(msg)
virsh.restart(self.distro.name) virsh.restart(self.distro)
def _get_param_map(self, app_name): def _get_param_map(self, app_name):
params = comp.PythonRuntime._get_param_map(self, app_name) params = comp.PythonRuntime._get_param_map(self, app_name)
params['CFGFILE'] = sh.joinpths(self.cfgdir, API_CONF) params['CFGFILE'] = sh.joinpths(self.cfg_dir, API_CONF)
return params return params
def _get_app_options(self, app): def _get_app_options(self, app):
@ -476,7 +449,7 @@ class NovaRuntime(comp.PythonRuntime):
class NovaVolumeConfigurator(object): class NovaVolumeConfigurator(object):
def __init__(self, ni): def __init__(self, ni):
self.cfg = ni.cfg self.cfg = ni.cfg
self.appdir = ni.appdir self.app_dir = ni.app_dir
self.distro = ni.distro self.distro = ni.distro
def setup_volumes(self): def setup_volumes(self):
@ -485,7 +458,7 @@ class NovaVolumeConfigurator(object):
def _setup_vol_groups(self): def _setup_vol_groups(self):
LOG.info("Attempting to setup volume groups for nova volume management.") LOG.info("Attempting to setup volume groups for nova volume management.")
mp = dict() mp = dict()
backing_file = self.cfg.getdefaulted('nova', 'volume_backing_file', sh.joinpths(self.appdir, 'nova-volumes-backing-file')) backing_file = self.cfg.getdefaulted('nova', 'volume_backing_file', sh.joinpths(self.app_dir, 'nova-volumes-backing-file'))
vol_group = self.cfg.getdefaulted('nova', 'volume_group', 'nova-volumes') vol_group = self.cfg.getdefaulted('nova', 'volume_group', 'nova-volumes')
backing_file_size = utils.to_bytes(self.cfg.getdefaulted('nova', 'volume_backing_file_size', '2052M')) backing_file_size = utils.to_bytes(self.cfg.getdefaulted('nova', 'volume_backing_file_size', '2052M'))
mp['VOLUME_GROUP'] = vol_group mp['VOLUME_GROUP'] = vol_group
@ -512,7 +485,10 @@ class NovaVolumeConfigurator(object):
# logical volumes # logical volumes
self._process_lvs(mp) self._process_lvs(mp)
# Finish off by restarting tgt, and ignore any errors # Finish off by restarting tgt, and ignore any errors
utils.execute_template(*RESTART_TGT_CMD[self.distro.name], check_exit_code=False) iscsi_cmds = self.distro.get_command('iscsi', quiet=True)
if iscsi_cmds:
restart_cmd = iscsi_cmds['restart']
utils.execute_template(*restart_cmd, run_as_root=True, check_exit_code=False)
def _process_lvs(self, mp): def _process_lvs(self, mp):
LOG.info("Attempting to setup logical volumes for nova volume management.") LOG.info("Attempting to setup logical volumes for nova volume management.")
@ -548,12 +524,12 @@ class NovaConfConfigurator(object):
self.cfg = ni.cfg self.cfg = ni.cfg
self.pw_gen = ni.pw_gen self.pw_gen = ni.pw_gen
self.instances = ni.instances self.instances = ni.instances
self.component_root = ni.component_root self.component_dir = ni.component_dir
self.appdir = ni.appdir self.app_dir = ni.app_dir
self.tracewriter = ni.tracewriter self.tracewriter = ni.tracewriter
self.paste_conf_fn = ni.paste_conf_fn self.paste_conf_fn = ni.paste_conf_fn
self.distro = ni.distro self.distro = ni.distro
self.cfgdir = ni.cfgdir self.cfg_dir = ni.cfg_dir
self.xvnc_enabled = ni.xvnc_enabled self.xvnc_enabled = ni.xvnc_enabled
self.volumes_enabled = ni.volumes_enabled self.volumes_enabled = ni.volumes_enabled
self.novnc_enabled = utils.service_enabled(settings.NOVNC, self.instances) self.novnc_enabled = utils.service_enabled(settings.NOVNC, self.instances)
@ -649,7 +625,7 @@ class NovaConfConfigurator(object):
nova_conf.add('rabbit_password', self.cfg.get("passwords", "rabbit")) nova_conf.add('rabbit_password', self.cfg.get("passwords", "rabbit"))
#where instances will be stored #where instances will be stored
instances_path = self._getstr('instances_path', sh.joinpths(self.component_root, 'instances')) instances_path = self._getstr('instances_path', sh.joinpths(self.component_dir, 'instances'))
self._configure_instances_path(instances_path, nova_conf) self._configure_instances_path(instances_path, nova_conf)
#is this a multihost setup? #is this a multihost setup?
@ -766,7 +742,7 @@ class NovaConfConfigurator(object):
nova_conf.add('network_manager', NET_MANAGER_TEMPLATE % (self._getstr('network_manager', DEF_NET_MANAGER))) nova_conf.add('network_manager', NET_MANAGER_TEMPLATE % (self._getstr('network_manager', DEF_NET_MANAGER)))
#dhcp bridge stuff??? #dhcp bridge stuff???
nova_conf.add('dhcpbridge_flagfile', sh.joinpths(self.cfgdir, API_CONF)) nova_conf.add('dhcpbridge_flagfile', sh.joinpths(self.cfg_dir, API_CONF))
#Network prefix for the IP network that all the projects for future VM guests reside on. Example: 192.168.0.0/12 #Network prefix for the IP network that all the projects for future VM guests reside on. Example: 192.168.0.0/12
nova_conf.add('fixed_range', self._getstr('fixed_range')) nova_conf.add('fixed_range', self._getstr('fixed_range'))

View File

@ -18,8 +18,6 @@ from devstack import component as comp
from devstack import log as logging from devstack import log as logging
from devstack import settings from devstack import settings
#id
TYPE = settings.NOVA_CLIENT
LOG = logging.getLogger("devstack.components.nova_client") LOG = logging.getLogger("devstack.components.nova_client")

View File

@ -22,8 +22,6 @@ from devstack import utils
from devstack.components import nova from devstack.components import nova
#id
TYPE = settings.NOVNC
LOG = logging.getLogger("devstack.components.novnc") LOG = logging.getLogger("devstack.components.novnc")
#where the application is really #where the application is really
@ -67,7 +65,7 @@ class NoVNCRuntime(comp.ProgramRuntime):
for app_name in APP_OPTIONS.keys(): for app_name in APP_OPTIONS.keys():
apps.append({ apps.append({
'name': app_name, 'name': app_name,
'path': sh.joinpths(self.appdir, UTIL_DIR, app_name), 'path': sh.joinpths(self.app_dir, UTIL_DIR, app_name),
}) })
return apps return apps
@ -76,7 +74,7 @@ class NoVNCRuntime(comp.ProgramRuntime):
if app_name == VNC_PROXY_APP and utils.service_enabled(settings.NOVA, self.instances, False): if app_name == VNC_PROXY_APP and utils.service_enabled(settings.NOVA, self.instances, False):
#have to reach into the nova conf (puke) #have to reach into the nova conf (puke)
nova_runtime = self.instances[settings.NOVA] nova_runtime = self.instances[settings.NOVA]
root_params['NOVA_CONF'] = sh.joinpths(nova_runtime.cfgdir, nova.API_CONF) root_params['NOVA_CONF'] = sh.joinpths(nova_runtime.cfg_dir, nova.API_CONF)
return root_params return root_params
def _get_app_options(self, app): def _get_app_options(self, app):

View File

@ -26,8 +26,6 @@ from devstack import utils
from devstack.components import db from devstack.components import db
#id
TYPE = settings.QUANTUM
LOG = logging.getLogger("devstack.components.quantum") LOG = logging.getLogger("devstack.components.quantum")
#vswitch pkgs #vswitch pkgs
@ -117,10 +115,10 @@ class QuantumInstaller(comp.PkgInstallComponent):
def _get_target_config_name(self, config_fn): def _get_target_config_name(self, config_fn):
if config_fn == PLUGIN_CONF: if config_fn == PLUGIN_CONF:
tgt_loc = [self.appdir] + PLUGIN_LOC + [config_fn] tgt_loc = [self.app_dir] + PLUGIN_LOC + [config_fn]
return sh.joinpths(*tgt_loc) return sh.joinpths(*tgt_loc)
elif config_fn == AGENT_CONF: elif config_fn == AGENT_CONF:
tgt_loc = [self.appdir] + AGENT_LOC + [config_fn] tgt_loc = [self.app_dir] + AGENT_LOC + [config_fn]
return sh.joinpths(*tgt_loc) return sh.joinpths(*tgt_loc)
else: else:
return comp.PkgInstallComponent._get_target_config_name(self, config_fn) return comp.PkgInstallComponent._get_target_config_name(self, config_fn)
@ -190,12 +188,12 @@ class QuantumInstaller(comp.PkgInstallComponent):
def _get_source_config(self, config_fn): def _get_source_config(self, config_fn):
if config_fn == PLUGIN_CONF: if config_fn == PLUGIN_CONF:
srcloc = [self.appdir] + PLUGIN_LOC + [config_fn] srcloc = [self.app_dir] + PLUGIN_LOC + [config_fn]
srcfn = sh.joinpths(*srcloc) srcfn = sh.joinpths(*srcloc)
contents = sh.load_file(srcfn) contents = sh.load_file(srcfn)
return (srcfn, contents) return (srcfn, contents)
elif config_fn == AGENT_CONF: elif config_fn == AGENT_CONF:
srcloc = [self.appdir] + AGENT_LOC + [config_fn] srcloc = [self.app_dir] + AGENT_LOC + [config_fn]
srcfn = sh.joinpths(*srcloc) srcfn = sh.joinpths(*srcloc)
contents = sh.load_file(srcfn) contents = sh.load_file(srcfn)
return (srcfn, contents) return (srcfn, contents)
@ -225,10 +223,10 @@ class QuantumRuntime(comp.ProgramRuntime):
if self.q_vswitch_service: if self.q_vswitch_service:
app_list.append({ app_list.append({
'name': APP_Q_SERVER, 'name': APP_Q_SERVER,
'path': sh.joinpths(self.appdir, BIN_DIR, APP_Q_SERVER), 'path': sh.joinpths(self.app_dir, BIN_DIR, APP_Q_SERVER),
}) })
if self.q_vswitch_agent: if self.q_vswitch_agent:
full_pth = [self.appdir] + AGENT_BIN_LOC + [APP_Q_AGENT] full_pth = [self.app_dir] + AGENT_BIN_LOC + [APP_Q_AGENT]
app_list.append({ app_list.append({
'name': APP_Q_AGENT, 'name': APP_Q_AGENT,
'path': sh.joinpths(*full_pth) 'path': sh.joinpths(*full_pth)
@ -241,8 +239,8 @@ class QuantumRuntime(comp.ProgramRuntime):
def _get_param_map(self, app_name): def _get_param_map(self, app_name):
param_dict = comp.ProgramRuntime._get_param_map(self, app_name) param_dict = comp.ProgramRuntime._get_param_map(self, app_name)
if app_name == APP_Q_AGENT: if app_name == APP_Q_AGENT:
tgt_loc = [self.appdir] + AGENT_LOC + [AGENT_CONF] tgt_loc = [self.app_dir] + AGENT_LOC + [AGENT_CONF]
param_dict['OVS_CONFIG_FILE'] = sh.joinpths(*tgt_loc) param_dict['OVS_CONFIG_FILE'] = sh.joinpths(*tgt_loc)
elif app_name == APP_Q_SERVER: elif app_name == APP_Q_SERVER:
param_dict['QUANTUM_CONFIG_FILE'] = sh.joinpths(self.appdir, CONFIG_DIR, QUANTUM_CONF) param_dict['QUANTUM_CONFIG_FILE'] = sh.joinpths(self.app_dir, CONFIG_DIR, QUANTUM_CONF)
return param_dict return param_dict

View File

@ -18,8 +18,6 @@ from devstack import component as comp
from devstack import log as logging from devstack import log as logging
from devstack import settings from devstack import settings
#id
TYPE = settings.QUANTUM_CLIENT
LOG = logging.getLogger("devstack.components.quantum_client") LOG = logging.getLogger("devstack.components.quantum_client")

View File

@ -21,8 +21,6 @@ from devstack import log as logging
from devstack import settings from devstack import settings
from devstack import shell as sh from devstack import shell as sh
#id
TYPE = settings.RABBIT
LOG = logging.getLogger("devstack.components.rabbit") LOG = logging.getLogger("devstack.components.rabbit")
#hopefully these are distro independent.. #hopefully these are distro independent..

View File

@ -22,8 +22,6 @@ from devstack import settings
from devstack import shell as sh from devstack import shell as sh
from devstack import utils from devstack import utils
#id
TYPE = settings.SWIFT
LOG = logging.getLogger("devstack.components.swift") LOG = logging.getLogger("devstack.components.swift")
#swift has alot of config files! #swift has alot of config files!
@ -71,9 +69,9 @@ WARMUP_PWS = ['service_token', 'swift_hash']
class SwiftUninstaller(comp.PythonUninstallComponent): class SwiftUninstaller(comp.PythonUninstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonUninstallComponent.__init__(self, *args, **kargs) comp.PythonUninstallComponent.__init__(self, *args, **kargs)
self.datadir = sh.joinpths(self.appdir, self.cfg.getdefaulted('swift', 'data_location', 'data')) self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.logdir = sh.joinpths(self.datadir, LOG_DIR) self.logdir = sh.joinpths(self.datadir, LOG_DIR)
def pre_uninstall(self): def pre_uninstall(self):
@ -88,12 +86,12 @@ class SwiftUninstaller(comp.PythonUninstallComponent):
class SwiftInstaller(comp.PythonInstallComponent): class SwiftInstaller(comp.PythonInstallComponent):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonInstallComponent.__init__(self, *args, **kargs) comp.PythonInstallComponent.__init__(self, *args, **kargs)
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.datadir = sh.joinpths(self.appdir, self.cfg.getdefaulted('swift', 'data_location', 'data')) self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
self.logdir = sh.joinpths(self.datadir, LOG_DIR) self.logdir = sh.joinpths(self.datadir, LOG_DIR)
self.startmain_file = sh.joinpths(self.bindir, SWIFT_STARTMAIN) self.startmain_file = sh.joinpths(self.bin_dir, SWIFT_STARTMAIN)
self.makerings_file = sh.joinpths(self.bindir, SWIFT_MAKERINGS) self.makerings_file = sh.joinpths(self.bin_dir, SWIFT_MAKERINGS)
self.fs_dev = sh.joinpths(self.datadir, DEVICE_PATH) self.fs_dev = sh.joinpths(self.datadir, DEVICE_PATH)
self.fs_image = sh.joinpths(self.datadir, SWIFT_IMG) self.fs_image = sh.joinpths(self.datadir, SWIFT_IMG)
self.auth_server = AUTH_SERVICE self.auth_server = AUTH_SERVICE
@ -118,7 +116,7 @@ class SwiftInstaller(comp.PythonInstallComponent):
'USER': self.cfg.getdefaulted('swift', 'swift_user', sh.getuser()), 'USER': self.cfg.getdefaulted('swift', 'swift_user', sh.getuser()),
'GROUP': self.cfg.getdefaulted('swift', 'swift_group', sh.getgroupname()), 'GROUP': self.cfg.getdefaulted('swift', 'swift_group', sh.getgroupname()),
'SWIFT_DATA_LOCATION': self.datadir, 'SWIFT_DATA_LOCATION': self.datadir,
'SWIFT_CONFIG_LOCATION': self.cfgdir, 'SWIFT_CONFIG_LOCATION': self.cfg_dir,
'SERVICE_TOKEN': self.cfg.get('passwords', 'service_token'), 'SERVICE_TOKEN': self.cfg.get('passwords', 'service_token'),
'AUTH_SERVER': self.auth_server, 'AUTH_SERVER': self.auth_server,
'SWIFT_HASH': self.cfg.get('passwords', 'swift_hash'), 'SWIFT_HASH': self.cfg.get('passwords', 'swift_hash'),
@ -145,8 +143,8 @@ class SwiftInstaller(comp.PythonInstallComponent):
def _create_node_config(self, node_number, port): def _create_node_config(self, node_number, port):
for t in ['object', 'container', 'account']: for t in ['object', 'container', 'account']:
src_fn = sh.joinpths(self.cfgdir, '%s-server.conf' % t) src_fn = sh.joinpths(self.cfg_dir, '%s-server.conf' % t)
tgt_fn = sh.joinpths(self.cfgdir, '%s-server/%d.conf' % (t, node_number)) tgt_fn = sh.joinpths(self.cfg_dir, '%s-server/%d.conf' % (t, node_number))
adjustments = { adjustments = {
'%NODE_PATH%': sh.joinpths(self.datadir, str(node_number)), '%NODE_PATH%': sh.joinpths(self.datadir, str(node_number)),
'%BIND_PORT%': str(port), '%BIND_PORT%': str(port),
@ -157,7 +155,7 @@ class SwiftInstaller(comp.PythonInstallComponent):
def _delete_templates(self): def _delete_templates(self):
for t in ['object', 'container', 'account']: for t in ['object', 'container', 'account']:
sh.unlink(sh.joinpths(self.cfgdir, '%s-server.conf' % t)) sh.unlink(sh.joinpths(self.cfg_dir, '%s-server.conf' % t))
def _create_nodes(self): def _create_nodes(self):
for i in range(1, 5): for i in range(1, 5):
@ -170,20 +168,20 @@ class SwiftInstaller(comp.PythonInstallComponent):
self._delete_templates() self._delete_templates()
def _turn_on_rsync(self): def _turn_on_rsync(self):
sh.symlink(sh.joinpths(self.cfgdir, RSYNC_CONF), RSYNCD_CONF_LOC) sh.symlink(sh.joinpths(self.cfg_dir, RSYNC_CONF), RSYNCD_CONF_LOC)
self.tracewriter.symlink_made(RSYNCD_CONF_LOC) self.tracewriter.symlink_made(RSYNCD_CONF_LOC)
sh.replace_in(RSYNC_CONF_LOC, RSYNC_ON_OFF_RE, 'RSYNC_ENABLE=true', True) sh.replace_in(RSYNC_CONF_LOC, RSYNC_ON_OFF_RE, 'RSYNC_ENABLE=true', True)
def _create_log_dirs(self): def _create_log_dirs(self):
self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.logdir, 'hourly'))) self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.logdir, 'hourly')))
sh.symlink(sh.joinpths(self.cfgdir, SYSLOG_CONF), SWIFT_RSYNC_LOC) sh.symlink(sh.joinpths(self.cfg_dir, SYSLOG_CONF), SWIFT_RSYNC_LOC)
self.tracewriter.symlink_made(SWIFT_RSYNC_LOC) self.tracewriter.symlink_made(SWIFT_RSYNC_LOC)
def _setup_binaries(self): def _setup_binaries(self):
sh.move(sh.joinpths(self.cfgdir, SWIFT_MAKERINGS), self.makerings_file) sh.move(sh.joinpths(self.cfg_dir, SWIFT_MAKERINGS), self.makerings_file)
sh.chmod(self.makerings_file, 0777) sh.chmod(self.makerings_file, 0777)
self.tracewriter.file_touched(self.makerings_file) self.tracewriter.file_touched(self.makerings_file)
sh.move(sh.joinpths(self.cfgdir, SWIFT_STARTMAIN), self.startmain_file) sh.move(sh.joinpths(self.cfg_dir, SWIFT_STARTMAIN), self.startmain_file)
sh.chmod(self.startmain_file, 0777) sh.chmod(self.startmain_file, 0777)
self.tracewriter.file_touched(self.startmain_file) self.tracewriter.file_touched(self.startmain_file)
@ -202,21 +200,21 @@ class SwiftInstaller(comp.PythonInstallComponent):
class SwiftRuntime(comp.PythonRuntime): class SwiftRuntime(comp.PythonRuntime):
def __init__(self, *args, **kargs): def __init__(self, *args, **kargs):
comp.PythonRuntime.__init__(self, *args, **kargs) comp.PythonRuntime.__init__(self, *args, **kargs)
self.datadir = sh.joinpths(self.appdir, self.cfg.getdefaulted('swift', 'data_location', 'data')) self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR)
self.bindir = sh.joinpths(self.appdir, BIN_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.logdir = sh.joinpths(self.datadir, LOG_DIR) self.logdir = sh.joinpths(self.datadir, LOG_DIR)
def start(self): def start(self):
sh.execute(*RSYSLOG_SERVICE_RESTART, run_as_root=True) sh.execute(*RSYSLOG_SERVICE_RESTART, run_as_root=True)
sh.execute(*RSYNC_SERVICE_RESTART, run_as_root=True) sh.execute(*RSYNC_SERVICE_RESTART, run_as_root=True)
swift_start_cmd = [sh.joinpths(self.bindir, SWIFT_INIT)] + ['all', 'start'] swift_start_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'start']
sh.execute(*swift_start_cmd, run_as_root=True) sh.execute(*swift_start_cmd, run_as_root=True)
def stop(self): def stop(self):
swift_stop_cmd = [sh.joinpths(self.bindir, SWIFT_INIT)] + ['all', 'stop'] swift_stop_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'stop']
sh.execute(*swift_stop_cmd, run_as_root=True) sh.execute(*swift_stop_cmd, run_as_root=True)
def restart(self): def restart(self):
swift_restart_cmd = [sh.joinpths(self.bindir, SWIFT_INIT)] + ['all', 'restart'] swift_restart_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'restart']
sh.execute(*swift_restart_cmd, run_as_root=True) sh.execute(*swift_restart_cmd, run_as_root=True)

View File

@ -64,7 +64,7 @@ class Distro(object):
LOG.debug('Looking for distro data for %s (%s)', plt, distname) LOG.debug('Looking for distro data for %s (%s)', plt, distname)
for p in cls.load_all(): for p in cls.load_all():
if p.supports_distro(plt): if p.supports_distro(plt):
LOG.info('Using distro "%s" for "%s"', p.name, plt) LOG.info('Using distro "%s" for platform "%s"', p.name, plt)
return p return p
else: else:
raise RuntimeError( raise RuntimeError(
@ -78,6 +78,15 @@ class Distro(object):
self.commands = commands self.commands = commands
self.components = components self.components = components
def __repr__(self):
return "\"%s\" using packager \"%s\"" % (self.name, self.packager_name)
def get_command(self, cmd_key, quiet=False):
if not quiet:
return self.commands[cmd_key]
else:
return self.commands.get(cmd_key)
def supports_distro(self, distro_name): def supports_distro(self, distro_name):
"""Does this distro support the named Linux distro? """Does this distro support the named Linux distro?
@ -97,27 +106,3 @@ class Distro(object):
raise RuntimeError('No class configured to %s %s on %s' % raise RuntimeError('No class configured to %s %s on %s' %
(action, name, self.name)) (action, name, self.name))
return importer.import_entry_point(entry_point) return importer.import_entry_point(entry_point)
def resolve_component_dependencies(self, components):
"""Returns list of all components needed for the named components."""
all_components = {}
active_names = [(c, None) for c in components]
while active_names:
component, parent = active_names.pop()
try:
component_details = self.components[component]
except KeyError:
if parent:
raise RuntimeError(
'Could not find details about component %r, a dependency of %s, for %s' %
(component, parent, self.name))
else:
raise RuntimeError(
'Could not find details about component %r for %s' %
(component, self.name))
deps = set(component_details.get('dependencies', []))
all_components[component] = deps
for d in deps:
if d not in all_components and d not in active_names:
active_names.append((d, component))
return all_components

View File

@ -10,7 +10,7 @@ LOG = logging.getLogger(__name__)
class OneiricDBInstaller(db.DBInstaller): class OneiricDBInstaller(db.DBInstaller):
def _configure_db_confs(self): def _configure_db_confs(self):
LOG.info("Fixing up %s mysql configs.", self.distro.name) LOG.info("Fixing up %s mysql configs.", self.distro.name)
fc = sh.load_file('/etc/mysql/my.cnf') fc = sh.load_file('/etc/mysql/my.cnf')

View File

@ -43,5 +43,5 @@ def get_key(key, default_value=None):
LOG.debug("Could not find anything in environment variable [%s]" % (key)) LOG.debug("Could not find anything in environment variable [%s]" % (key))
value = default_value value = default_value
else: else:
LOG.debug("Found [%s] in environment variable [%s]" % (value, key)) LOG.audit("Found [%s] in environment variable [%s]" % (value, key))
return value return value

View File

@ -246,11 +246,25 @@ class RcReader(object):
def __init__(self): def __init__(self):
pass pass
def _is_comment(self, line):
if line.lstrip().startswith("#"):
return True
return False
def extract(self, fn): def extract(self, fn):
extracted_vars = dict() extracted_vars = dict()
contents = sh.load_file(fn) contents = ''
#not using shell here since
#we don't want this to be "nulled" in a dry-run
LOG.audit("Loading rc file [%s]" % (fn))
try:
with open(fn, 'r') as fh:
contents = fh.read()
except IOError as e:
LOG.warn("Failed extracting rc file [%s] due to [%s]" % (fn, e.message))
return extracted_vars
for line in contents.splitlines(): for line in contents.splitlines():
if line.lstrip().startswith("#"): if self._is_comment(line):
continue continue
m = EXP_PAT.search(line) m = EXP_PAT.search(line)
if m: if m:

View File

@ -1,13 +1,36 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
# Copyright (C) 2012 Dreamhost Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
def import_entry_point(fullname): def partition(fullname):
"""Given a name import the class and return it. """
The name should be in dotted.path:ClassName syntax. The name should be in dotted.path:ClassName syntax.
""" """
if ':' not in fullname: if ':' not in fullname:
raise ValueError('Invalid entry point specifier %r' % fullname) raise ValueError('Invalid entry point specifier %r' % fullname)
module_name, ignore, classname = fullname.partition(':') module_name, ignore, classname = fullname.partition(':')
return (module_name, ignore, classname)
def import_entry_point(fullname):
"""
Given a name import the class and return it.
"""
module_name, ignore, classname = partition(fullname)
try: try:
module = __import__(module_name) module = __import__(module_name)
for submodule in module_name.split('.')[1:]: for submodule in module_name.split('.')[1:]:

View File

@ -32,13 +32,6 @@ LIBVIRT_PROTOCOL_MAP = {
} }
VIRT_LIB = 'libvirt' VIRT_LIB = 'libvirt'
#distros name the libvirt service differently :-(
SV_NAME_MAP = {
settings.RHEL6: 'libvirtd',
settings.FEDORA16: 'libvirtd',
settings.UBUNTU11: 'libvirt-bin',
}
#how libvirt is restarted #how libvirt is restarted
LIBVIRT_RESTART_CMD = ['service', '%SERVICE%', 'restart'] LIBVIRT_RESTART_CMD = ['service', '%SERVICE%', 'restart']
@ -71,7 +64,7 @@ def _status(distro):
'run_as_root': True, 'run_as_root': True,
}) })
mp = dict() mp = dict()
mp['SERVICE'] = SV_NAME_MAP[distro] mp['SERVICE'] = distro.get_command('libvirt-daemon')
result = utils.execute_template(*cmds, result = utils.execute_template(*cmds,
check_exit_code=False, check_exit_code=False,
params=mp) params=mp)
@ -104,7 +97,7 @@ def restart(distro):
'run_as_root': True, 'run_as_root': True,
}) })
mp = dict() mp = dict()
mp['SERVICE'] = SV_NAME_MAP[distro] mp['SERVICE'] = distro.get_command('libvirt-daemon')
utils.execute_template(*cmds, params=mp) utils.execute_template(*cmds, params=mp)
LOG.info("Restarting the libvirt service, please wait %s seconds until its started." % (WAIT_ALIVE_TIME)) LOG.info("Restarting the libvirt service, please wait %s seconds until its started." % (WAIT_ALIVE_TIME))
sh.sleep(WAIT_ALIVE_TIME) sh.sleep(WAIT_ALIVE_TIME)
@ -117,7 +110,7 @@ def virt_ok(virt_type, distro):
try: try:
restart(distro) restart(distro)
except excp.ProcessExecutionError, e: except excp.ProcessExecutionError, e:
LOG.warn("Could not restart libvirt on distro [%s] due to [%s]" % (distro, e.message)) LOG.warn("Could not restart libvirt due to [%s]" % (e))
return False return False
try: try:
cmds = list() cmds = list()
@ -148,7 +141,7 @@ def clear_libvirt_domains(distro, virt_type, inst_prefix):
try: try:
restart(distro) restart(distro)
except excp.ProcessExecutionError, e: except excp.ProcessExecutionError, e:
LOG.warn("Could not restart libvirt on distro [%s] due to [%s]" % (distro, e.message)) LOG.warn("Could not restart libvirt due to [%s]" % (e))
return return
try: try:
conn = libvirt.open(virt_protocol) conn = libvirt.open(virt_protocol)

View File

@ -35,10 +35,8 @@ def parse():
version_str = "%prog v" + version.version_string() version_str = "%prog v" + version.version_string()
help_formatter = IndentedHelpFormatter(width=HELP_WIDTH) help_formatter = IndentedHelpFormatter(width=HELP_WIDTH)
parser = OptionParser(version=version_str, formatter=help_formatter) parser = OptionParser(version=version_str, formatter=help_formatter)
parser.add_option("-c", "--component",
action="append", #root options
dest="component",
help="openstack component: %s" % (_format_list(settings.COMPONENT_NAMES)))
parser.add_option("-v", "--verbose", parser.add_option("-v", "--verbose",
action="append_const", action="append_const",
const=1, const=1,
@ -52,7 +50,14 @@ def parse():
help=("perform ACTION but do not actually run any of the commands" help=("perform ACTION but do not actually run any of the commands"
" that would normally complete ACTION: (default: %default)")) " that would normally complete ACTION: (default: %default)"))
#install/start/stop/uninstall specific options
base_group = OptionGroup(parser, "Install & uninstall & start & stop specific options") base_group = OptionGroup(parser, "Install & uninstall & start & stop specific options")
base_group.add_option("-p", "--persona",
action="store",
type="string",
dest="persona_fn",
metavar="FILE",
help="required persona yaml file to apply")
base_group.add_option("-a", "--action", base_group.add_option("-a", "--action",
action="store", action="store",
type="string", type="string",
@ -66,28 +71,15 @@ def parse():
metavar="DIR", metavar="DIR",
help=("empty root DIR for install or " help=("empty root DIR for install or "
"DIR with existing components for start/stop/uninstall")) "DIR with existing components for start/stop/uninstall"))
base_group.add_option("-i", "--ignore-deps",
action="store_false",
dest="ensure_deps",
help="ignore dependencies when performing ACTION")
base_group.add_option("--no-prompt-passwords", base_group.add_option("--no-prompt-passwords",
action="store_false", action="store_false",
dest="prompt_for_passwords", dest="prompt_for_passwords",
default=True, default=True,
help="do not prompt the user for passwords", help="do not prompt the user for passwords",
) )
base_group.add_option("-e", "--ensure-deps",
action="store_true",
dest="ensure_deps",
help="ensure dependencies when performing ACTION (default: %default)",
default=True)
base_group.add_option("-r", "--ref-component",
action="append",
dest="ref_components",
metavar="COMPONENT",
help="component which will not have ACTION applied but will be referenced as if it was (ACTION dependent)")
parser.add_option_group(base_group) parser.add_option_group(base_group)
#uninstall and stop options
stop_un_group = OptionGroup(parser, "Uninstall & stop specific options") stop_un_group = OptionGroup(parser, "Uninstall & stop specific options")
stop_un_group.add_option("-n", "--no-force", stop_un_group.add_option("-n", "--no-force",
action="store_true", action="store_true",
@ -107,15 +99,13 @@ def parse():
#extract only what we care about #extract only what we care about
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
output = dict() output = dict()
output['components'] = options.component or list()
output['dir'] = options.dir or "" output['dir'] = options.dir or ""
output['dryrun'] = options.dryrun or False output['dryrun'] = options.dryrun or False
output['ref_components'] = options.ref_components or list()
output['action'] = options.action or "" output['action'] = options.action or ""
output['force'] = not options.force output['force'] = not options.force
output['ignore_deps'] = not options.ensure_deps
output['keep_old'] = options.keep_old output['keep_old'] = options.keep_old
output['extras'] = args output['extras'] = args
output['persona_fn'] = options.persona_fn
output['verbosity'] = len(options.verbosity) output['verbosity'] = len(options.verbosity)
output['prompt_for_passwords'] = options.prompt_for_passwords output['prompt_for_passwords'] = options.prompt_for_passwords

View File

@ -14,22 +14,23 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License.. # under the License..
import yaml
from devstack import env_rc from devstack import env_rc
from devstack import exceptions as excp from devstack import exceptions as excp
from devstack import log as logging from devstack import log as logging
from devstack import settings from devstack import settings
from devstack import shell as sh from devstack import shell as sh
from devstack import utils from devstack import utils
from devstack import passwords
from devstack.progs import common
LOG = logging.getLogger("devstack.progs.actions") LOG = logging.getLogger("devstack.progs.actions")
# For actions in this list we will reverse the component order # For actions in this list we will reverse the component order
_REVERSE_ACTIONS = [settings.UNINSTALL, settings.STOP] REVERSE_ACTIONS = [settings.UNINSTALL, settings.STOP]
# For these actions we will attempt to make an rc file if it does not exist # For these actions we will attempt to make an rc file if it does not exist
_RC_FILE_MAKE_ACTIONS = [settings.INSTALL] RC_FILE_MAKE_ACTIONS = [settings.INSTALL]
# The order of which uninstalls happen + message of what is happening # The order of which uninstalls happen + message of what is happening
# (before and after) # (before and after)
@ -138,125 +139,93 @@ PREQ_ACTIONS = {
class ActionRunner(object): class ActionRunner(object):
def __init__(self, distro, action, directory, config, def __init__(self, distro, action, cfg, **kargs):
pw_gen, pkg_manager,
**kargs):
self.distro = distro self.distro = distro
self.action = action self.action = action
self.directory = directory self.cfg = cfg
self.cfg = config self.pw_gen = passwords.PasswordGenerator(self.cfg, kargs.get('prompt_for_passwords', True))
self.pw_gen = pw_gen pkg_cls = distro.get_packager_factory()
self.pkg_manager = pkg_manager self.pkg_manager = pkg_cls(self.distro.name, kargs.get('keep_old', False))
self.kargs = kargs
self.components = dict()
def_components = common.get_default_components()
unclean_components = kargs.pop("components")
if not unclean_components:
self.components = def_components
else:
for (c, opts) in unclean_components.items():
if opts is None and c in def_components:
self.components[c] = def_components[c]
elif opts is None:
self.components[c] = list()
else:
self.components[c] = opts
self.force = kargs.get('force', False) self.force = kargs.get('force', False)
self.ignore_deps = kargs.get('ignore_deps', False) self.kargs = kargs
self.ref_components = kargs.get("ref_components")
self.gen_rc = action in _RC_FILE_MAKE_ACTIONS
def _get_components(self): def _apply_reverse(self, action, component_order):
return dict(self.components) if not component_order:
component_order = list()
else:
component_order = list(component_order)
adjusted_order = list(component_order)
if action in REVERSE_ACTIONS:
adjusted_order.reverse()
return adjusted_order
def _order_components(self, components): def _load_persona(self, persona_fn):
adjusted_components = dict(components) persona_fn = sh.abspth(persona_fn)
if self.ignore_deps: LOG.audit("Loading persona from file [%s]", persona_fn)
return (adjusted_components, list(components.keys())) contents = ''
all_components = self.distro.resolve_component_dependencies( with open(persona_fn, "r") as fh:
list(components.keys()) contents = fh.read()
) return self._verify_persona(yaml.load(contents), persona_fn)
component_diff = set(all_components.keys()).difference(components.keys())
if component_diff:
LOG.info("Activating dependencies: [%s]",
", ".join(sorted(component_diff))
)
for new_component in component_diff:
adjusted_components[new_component] = []
return (adjusted_components, utils.get_components_order(all_components))
def _inject_references(self, components): def _verify_persona(self, persona, fn):
ref_components = utils.parse_components(self.ref_components) # Some sanity checks
adjusted_components = dict(components) try:
for c in ref_components.keys(): if self.distro.name not in persona['supports']:
if c not in components: raise RuntimeError("Persona does not support distro %s"
adjusted_components[c] = ref_components.get(c) % (self.distro.name))
return adjusted_components for c in persona['components']:
if c not in self.distro.components:
def _instantiate_components(self, components): raise RuntimeError("Distro %s does not support component %s" %
all_instances = dict() (self.distro.name, c))
for component in components.keys(): except (KeyError, RuntimeError) as e:
cls = self.distro.get_component_action_class(component, msg = ("Could not validate persona defined in [%s] due to: %s"
self.action) % (fn, e))
LOG.debug('instantiating %s to handle %s for %s', raise excp.ConfigException(msg)
cls, self.action, component) return persona
instance = cls(component_name=component,
instances=all_instances, def _construct_instances(self, persona, action, root_dir):
runner=self, components = persona['components'] # Required
root_dir=self.directory, subsystems = persona.get('subsystems') or dict() # Not required
component_options=self.distro.components[component], instances = dict()
keep_old=self.kargs.get("keep_old") for c in components:
) cls = self.distro.get_component_action_class(c, action)
all_instances[component] = instance LOG.debug("Constructing class %s" % (cls))
return all_instances cls_kvs = dict()
cls_kvs['runner'] = self
def _run_preqs(self, components, component_order): cls_kvs['component_dir'] = sh.joinpths(root_dir, c)
if not (self.action in PREQ_ACTIONS): cls_kvs['subsystems'] = set(subsystems.get(c, list()))
return cls_kvs['all_instances'] = instances
(check_functor, preq_action) = PREQ_ACTIONS[self.action] cls_kvs['name'] = c
instances = self._instantiate_components(components) # FIXME:
preq_components = dict() cls_kvs['keep_old'] = False
LOG.debug("Using k/v map %s", cls_kvs)
instances[c] = cls(*list(), **cls_kvs)
return instances
def _verify_components(self, component_order, instances):
LOG.info("Verifying that the components are ready to rock-n-roll.")
for c in component_order: for c in component_order:
instance = instances[c] instance = instances[c]
if check_functor(instance): instance.verify()
preq_components[c] = components[c]
if preq_components: def _warm_components(self, component_order, instances):
LOG.info("Having to activate prerequisite action [%s] for %s components." % (preq_action, len(preq_components)))
preq_runner = ActionRunner(distro=self.distro,
action=preq_action,
directory=self.directory,
config=self.cfg,
pw_gen=self.pw_gen,
pkg_manager=self.pkg_manager,
components=preq_components,
**self.kargs)
preq_runner.run()
def _pre_run(self, instances, component_order):
if not sh.isdir(self.directory):
sh.mkdir(self.directory)
LOG.info("Verifying that the components are ready to rock-n-roll.")
for component in component_order:
inst = instances[component]
inst.verify()
LOG.info("Warming up your component configurations (ie so you won't be prompted later)") LOG.info("Warming up your component configurations (ie so you won't be prompted later)")
for component in component_order: for c in component_order:
inst = instances[component] instance = instances[c]
inst.warm_configs() instance.warm_configs()
if self.gen_rc:
writer = env_rc.RcWriter(self.cfg, self.pw_gen, self.directory) def _write_rc_file(self, root_dir):
if not sh.isfile(settings.OSRC_FN): writer = env_rc.RcWriter(self.cfg, self.pw_gen, root_dir)
LOG.info("Generating a file at [%s] that will contain your environment settings." % (settings.OSRC_FN)) if not sh.isfile(settings.OSRC_FN):
writer.write(settings.OSRC_FN) LOG.info("Generating a file at [%s] that will contain your environment settings." % (settings.OSRC_FN))
else: writer.write(settings.OSRC_FN)
LOG.info("Updating a file at [%s] that contains your environment settings." % (settings.OSRC_FN)) else:
am_upd = writer.update(settings.OSRC_FN) LOG.info("Updating a file at [%s] that contains your environment settings." % (settings.OSRC_FN))
LOG.info("Updated [%s] settings in rc file [%s]" % (am_upd, settings.OSRC_FN)) am_upd = writer.update(settings.OSRC_FN)
LOG.info("Updated [%s] settings in rc file [%s]" % (am_upd, settings.OSRC_FN))
def _run_instances(self, instances, component_order):
component_order = self._apply_reverse(component_order) def _run_instances(self, action, component_order, instances):
LOG.info("Running in the following order: %s" % ("->".join(component_order))) for (start_msg, functor, end_msg) in ACTION_MP[action]:
for (start_msg, functor, end_msg) in ACTION_MP[self.action]:
for c in component_order: for c in component_order:
instance = instances[c] instance = instances[c]
if start_msg: if start_msg:
@ -271,19 +240,30 @@ class ActionRunner(object):
else: else:
raise raise
def _apply_reverse(self, component_order): def _run_action(self, persona, action, root_dir):
adjusted_order = list(component_order) LOG.info("Running action [%s] using root directory [%s]" % (action, root_dir))
if self.action in _REVERSE_ACTIONS: instances = self._construct_instances(persona, action, root_dir)
adjusted_order.reverse() if action in PREQ_ACTIONS:
return adjusted_order (check_functor, preq_action) = PREQ_ACTIONS[action]
checks_passed_components = list()
def _start(self, components, component_order): for (c, instance) in instances.items():
LOG.info("Activating components required to complete action [%s]" % (self.action)) if check_functor(instance):
instances = self._instantiate_components(components) checks_passed_components.append(c)
self._pre_run(instances, component_order) if checks_passed_components:
self._run_preqs(components, component_order) LOG.info("Activating prerequisite action [%s] requested by (%s) components."
self._run_instances(instances, component_order) % (preq_action, ", ".join(checks_passed_components)))
self._run_action(persona, preq_action, root_dir)
def run(self): component_order = self._apply_reverse(action, persona['components'])
(components, component_order) = self._order_components(self._get_components()) LOG.info("Activating components [%s] (in that order) for action [%s]" %
self._start(self._inject_references(components), component_order) ("->".join(component_order), action))
self._verify_components(component_order, instances)
self._warm_components(component_order, instances)
if action in RC_FILE_MAKE_ACTIONS:
self._write_rc_file(root_dir)
self._run_instances(action, component_order, instances)
def run(self, persona_fn, root_dir):
persona = self._load_persona(persona_fn)
if not sh.isdir(root_dir):
sh.mkdir(root_dir)
self._run_action(persona, self.action, root_dir)

View File

@ -1,190 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import tempfile
from devstack import cfg
from devstack import exceptions as excp
from devstack import settings
from devstack import shell as sh
from devstack.components import db
from devstack.components import glance
from devstack.components import horizon
from devstack.components import keystone
from devstack.components import keystone_client
from devstack.components import melange
from devstack.components import melange_client
from devstack.components import nova
from devstack.components import nova_client
from devstack.components import novnc
from devstack.components import quantum
from devstack.components import quantum_client
from devstack.components import rabbit
from devstack.components import swift
from devstack.packaging import apt
from devstack.packaging import yum
# This determines what classes to use to install/uninstall/...
# ACTION_CLASSES = {
# settings.INSTALL: {
# settings.DB: db.DBInstaller,
# settings.GLANCE: glance.GlanceInstaller,
# settings.HORIZON: horizon.HorizonInstaller,
# settings.KEYSTONE: keystone.KeystoneInstaller,
# settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientInstaller,
# settings.MELANGE: melange.MelangeInstaller,
# settings.MELANGE_CLIENT: melange_client.MelangeClientInstaller,
# settings.NOVA: nova.NovaInstaller,
# settings.NOVA_CLIENT: nova_client.NovaClientInstaller,
# settings.NOVNC: novnc.NoVNCInstaller,
# settings.QUANTUM: quantum.QuantumInstaller,
# settings.QUANTUM_CLIENT: quantum_client.QuantumClientInstaller,
# settings.RABBIT: rabbit.RabbitInstaller,
# settings.SWIFT: swift.SwiftInstaller,
# },
# settings.UNINSTALL: {
# settings.DB: db.DBUninstaller,
# settings.GLANCE: glance.GlanceUninstaller,
# settings.HORIZON: horizon.HorizonUninstaller,
# settings.KEYSTONE: keystone.KeystoneUninstaller,
# settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientUninstaller,
# settings.MELANGE: melange.MelangeUninstaller,
# settings.MELANGE_CLIENT: melange_client.MelangeClientUninstaller,
# settings.NOVA: nova.NovaUninstaller,
# settings.NOVA_CLIENT: nova_client.NovaClientUninstaller,
# settings.NOVNC: novnc.NoVNCUninstaller,
# settings.QUANTUM: quantum.QuantumUninstaller,
# settings.QUANTUM_CLIENT: quantum_client.QuantumClientUninstaller,
# settings.RABBIT: rabbit.RabbitUninstaller,
# settings.SWIFT: swift.SwiftUninstaller,
# },
# settings.START: {
# settings.DB: db.DBRuntime,
# settings.GLANCE: glance.GlanceRuntime,
# settings.HORIZON: horizon.HorizonRuntime,
# settings.KEYSTONE: keystone.KeystoneRuntime,
# settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientRuntime,
# settings.MELANGE: melange.MelangeRuntime,
# settings.MELANGE_CLIENT: melange_client.MelangeClientRuntime,
# settings.NOVA: nova.NovaRuntime,
# settings.NOVA_CLIENT: nova_client.NovaClientRuntime,
# settings.NOVNC: novnc.NoVNCRuntime,
# settings.QUANTUM: quantum.QuantumRuntime,
# settings.QUANTUM_CLIENT: quantum_client.QuantumClientRuntime,
# settings.RABBIT: rabbit.RabbitRuntime,
# settings.SWIFT: swift.SwiftRuntime,
# },
# }
# # Just a copy
# ACTION_CLASSES[settings.STOP] = ACTION_CLASSES[settings.START]
# Used only for figuring out deps
_FAKE_ROOT_DIR = tempfile.gettempdir()
# This map controls which distro has
# which package management class
_PKGR_MAP = {
settings.UBUNTU11: apt.AptPackager,
settings.RHEL6: yum.YumPackager,
settings.FEDORA16: yum.YumPackager,
}
def get_default_components():
def_components = dict()
def_components[settings.GLANCE] = [
glance.GAPI,
glance.GREG,
]
def_components[settings.KEYSTONE] = []
def_components[settings.NOVA] = [
nova.NAPI,
nova.NCAUTH,
nova.NCERT,
nova.NCPU,
nova.NNET,
nova.NOBJ,
nova.NSCHED,
nova.NXVNC,
nova.NVOL,
]
def_components[settings.NOVNC] = []
def_components[settings.HORIZON] = []
def_components[settings.DB] = []
def_components[settings.RABBIT] = []
return def_components
def format_secs_taken(secs):
output = "%.03f seconds" % (secs)
output += " or %.02f minutes" % (secs / 60.0)
return output
# def get_action_cls(action_name, component_name, distro=None):
# action_cls_map = ACTION_CLASSES.get(action_name)
# if not action_cls_map:
# raise excp.StackException("Action %s has no component to class mapping" % (action_name))
# cls = action_cls_map.get(component_name)
# if not cls:
# raise excp.StackException("Action %s has no class entry for component %s" % (action_name, component_name))
# return cls
def get_packager(distro, keep_packages):
cls = _PKGR_MAP.get(distro)
if not cls:
msg = "No package manager found for distro %s!" % (distro)
raise excp.StackException(msg)
return cls(distro, keep_packages)
def get_config(cfg_fn=None):
if not cfg_fn:
cfg_fn = sh.canon_path(settings.STACK_CONFIG_LOCATION)
config_instance = cfg.StackConfigParser()
config_instance.read(cfg_fn)
return config_instance
# def get_components_deps(runner,
# action_name,
# base_components,
# root_dir=None,
# distro=None,
# ):
# all_components = dict()
# active_names = list(base_components)
# root_dir = root_dir or _FAKE_ROOT_DIR
# while len(active_names):
# component = active_names.pop()
# component_opts = base_components.get(component) or list()
# cls = get_action_cls(action_name, component, distro)
# instance = cls(instances=list(),
# runner=runner,
# root_dir=root_dir,
# component_options=component_opts,
# keep_old=False
# )
# deps = instance.get_dependencies() or set()
# all_components[component] = set(deps)
# for d in deps:
# if d not in all_components and d not in active_names:
# active_names.append(d)
# return all_components

View File

@ -18,13 +18,6 @@ import os
import re import re
import sys import sys
# These also have meaning outside python,
# ie in the pkg/pip listings so update there also!
# FIXME: Delete
UBUNTU11 = "ubuntu-oneiric"
RHEL6 = "rhel-6"
FEDORA16 = "fedora-16"
# What this program is called # What this program is called
PROG_NICE_NAME = "DEVSTACKpy" PROG_NICE_NAME = "DEVSTACKpy"
@ -36,7 +29,7 @@ POST_INSTALL = 'post-install'
IPV4 = 'IPv4' IPV4 = 'IPv4'
IPV6 = 'IPv6' IPV6 = 'IPv6'
#how long to wait for a service to startup # How long to wait for a service to startup
WAIT_ALIVE_SECS = 5 WAIT_ALIVE_SECS = 5
# Component name mappings # Component name mappings
@ -68,29 +61,6 @@ COMPONENT_NAMES = [
MELANGE, MELANGE_CLIENT, MELANGE, MELANGE_CLIENT,
] ]
# When a component is asked for it may
# need another component, that dependency
# mapping is listed here. A topological sort
# will be applied to determine the exact order.
# COMPONENT_DEPENDENCIES = {
# DB: [],
# KEYSTONE_CLIENT: [],
# RABBIT: [],
# GLANCE: [KEYSTONE, DB],
# KEYSTONE: [DB, KEYSTONE_CLIENT],
# NOVA: [KEYSTONE, GLANCE, DB, RABBIT, NOVA_CLIENT],
# SWIFT: [KEYSTONE_CLIENT],
# NOVA_CLIENT: [],
# # Horizon depends on glances client (which should really be a client package)
# HORIZON: [KEYSTONE_CLIENT, GLANCE, NOVA_CLIENT, QUANTUM_CLIENT],
# # More of quantums deps come from its module function get_dependencies
# QUANTUM: [],
# NOVNC: [NOVA],
# QUANTUM_CLIENT: [],
# MELANGE: [DB],
# MELANGE_CLIENT: [],
# }
# Different run types supported # Different run types supported
RUN_TYPE_FORK = "FORK" RUN_TYPE_FORK = "FORK"
RUN_TYPE_UPSTART = "UPSTART" RUN_TYPE_UPSTART = "UPSTART"
@ -126,6 +96,4 @@ ACTIONS = [INSTALL, UNINSTALL, START, STOP]
STACK_BIN_DIR = os.path.abspath(os.path.dirname(sys.argv[0])) STACK_BIN_DIR = os.path.abspath(os.path.dirname(sys.argv[0]))
STACK_CONFIG_DIR = os.path.join(STACK_BIN_DIR, "conf") STACK_CONFIG_DIR = os.path.join(STACK_BIN_DIR, "conf")
STACK_TEMPLATE_DIR = os.path.join(STACK_CONFIG_DIR, "templates") STACK_TEMPLATE_DIR = os.path.join(STACK_CONFIG_DIR, "templates")
STACK_PKG_DIR = os.path.join(STACK_CONFIG_DIR, "pkgs")
STACK_PIP_DIR = os.path.join(STACK_CONFIG_DIR, "pips")
STACK_CONFIG_LOCATION = os.path.join(STACK_CONFIG_DIR, "stack.ini") STACK_CONFIG_LOCATION = os.path.join(STACK_CONFIG_DIR, "stack.ini")

View File

@ -257,79 +257,10 @@ def get_interfaces():
return interfaces return interfaces
def get_components_order(components): def format_secs_taken(secs):
if not components: output = "%.03f seconds" % (secs)
return dict() output += " or %.02f minutes" % (secs / 60.0)
#deep copy so components isn't messed with return output
all_components = dict()
for (name, deps) in components.items():
all_components[name] = set(deps)
#figure out which ones have no one depending on them
no_deps_components = set()
for (name, deps) in all_components.items():
referenced = False
for (_name, _deps) in all_components.items():
if _name == name:
continue
else:
if name in _deps:
referenced = True
break
if not referenced:
no_deps_components.add(name)
if not no_deps_components:
msg = "Components specifed have no root components, there is most likely a dependency cycle!"
raise excp.DependencyException(msg)
#now we have to do a quick check to ensure no component is causing a cycle
for (root, deps) in all_components.items():
#DFS down through the "roots" deps and there deps and so on and
#ensure that nobody is referencing the "root" component name,
#that would mean there is a cycle if a dependency of the "root" is.
active_deps = list(deps)
checked_deps = dict()
while len(active_deps):
dep = active_deps.pop()
itsdeps = all_components.get(dep)
checked_deps[dep] = True
if root in itsdeps:
msg = "Circular dependency between component %s and component %s!" % (root, dep)
raise excp.DependencyException(msg)
else:
for d in itsdeps:
if d not in checked_deps and d not in active_deps:
active_deps.append(d)
#now form the order
#basically a topological sorting
#https://en.wikipedia.org/wiki/Topological_sorting
ordering = list()
no_edges = set(no_deps_components)
while len(no_edges):
node = no_edges.pop()
ordering.append(node)
its_deps = all_components.get(node)
while len(its_deps):
name = its_deps.pop()
referenced = False
for (_name, _deps) in all_components.items():
if _name == name:
continue
else:
if name in _deps:
referenced = True
break
if not referenced:
no_edges.add(name)
#should now be no edges else something bad happended
for (_, deps) in all_components.items():
if len(deps):
msg = "Your specified components have at least one cycle!"
raise excp.DependencyException(msg)
#reverse so its in the right order for us since we just determined
#the pkgs that have no one depending on them (which should be installed
#last and those that have incoming edges that packages are depending on need
#to go first, but those were inserted last), so this reverse fixes that
ordering.reverse()
return ordering
def joinlinesep(*pieces): def joinlinesep(*pieces):
@ -707,28 +638,6 @@ def goodbye(worked):
print(msg) print(msg)
def parse_components(components):
if not components:
return dict()
adjusted_components = dict()
for c in components:
mtch = EXT_COMPONENT.match(c)
if mtch:
component_name = mtch.group(1).lower().strip()
if component_name in settings.COMPONENT_NAMES:
component_opts = mtch.group(2)
components_opts_cleaned = None
if component_opts:
components_opts_cleaned = list()
sp_component_opts = component_opts.split(",")
for co in sp_component_opts:
cleaned_opt = co.strip()
if cleaned_opt:
components_opts_cleaned.append(cleaned_opt)
adjusted_components[component_name] = components_opts_cleaned
return adjusted_components
def welcome(ident): def welcome(ident):
lower = "| %s %s |" % (ident, version.version_string()) lower = "| %s %s |" % (ident, version.version_string())
welcome_header = _get_welcome_stack() welcome_header = _get_welcome_stack()

59
stack
View File

@ -20,6 +20,7 @@ import sys
import time import time
import traceback import traceback
from devstack import cfg
from devstack import cfg_helpers from devstack import cfg_helpers
from devstack import date from devstack import date
from devstack import distro from devstack import distro
@ -33,7 +34,6 @@ from devstack import shell as sh
from devstack import utils from devstack import utils
from devstack.progs import actions from devstack.progs import actions
from devstack.progs import common
LOG = logging.getLogger("devstack.stack") LOG = logging.getLogger("devstack.stack")
@ -50,7 +50,7 @@ _WELCOME_MAP = {
_CFG_GROUPS = { _CFG_GROUPS = {
cfg_helpers.make_id('passwords', None): 'Passwords', cfg_helpers.make_id('passwords', None): 'Passwords',
cfg_helpers.make_id('db', None): 'Database info', cfg_helpers.make_id('db', None): 'Database info',
#catch all # Catch all
cfg_helpers.make_id(None, None): 'Misc configs', cfg_helpers.make_id(None, None): 'Misc configs',
} }
@ -68,12 +68,12 @@ def dump_config(config_cache):
value = mp.get(key) value = mp.get(key)
LOG.info(item_format(key, value)) LOG.info(item_format(key, value))
#first partition into our groups # First partition into our groups
partitions = dict() partitions = dict()
for name in _CFG_ORDERING: for name in _CFG_ORDERING:
partitions[name] = dict() partitions[name] = dict()
#now put the config cached values into there partition # Now put the config cached values into there partitions
for (k, v) in config_cache.items(): for (k, v) in config_cache.items():
for name in _CFG_ORDERING: for name in _CFG_ORDERING:
entries = partitions[name] entries = partitions[name]
@ -81,7 +81,7 @@ def dump_config(config_cache):
entries[k] = v entries[k] = v
break break
#now print them.. # Now print them..
for name in _CFG_ORDERING: for name in _CFG_ORDERING:
nice_name = _CFG_GROUPS.get(name) nice_name = _CFG_GROUPS.get(name)
LOG.info(nice_name + ":") LOG.info(nice_name + ":")
@ -103,49 +103,52 @@ def load_rc_files():
def run(args): def run(args):
action = args.pop("action").strip().lower() action = args.pop("action", '').strip().lower()
if not (action in settings.ACTIONS): if not (action in settings.ACTIONS):
print(utils.color_text("No valid action specified!", "red")) print(utils.color_text("No valid action specified!", "red"))
return False return False
loaded_rcs = False loaded_rcs = False
rootdir = args.pop("dir") root_dir = args.pop("dir")
if not rootdir: if not root_dir:
load_rc_files() load_rc_files()
loaded_rcs = True loaded_rcs = True
rootdir = env.get_key(env_rc.INSTALL_ROOT) root_dir = env.get_key(env_rc.INSTALL_ROOT)
if not rootdir: if not root_dir:
print(utils.color_text("No root directory specified!", "red")) print(utils.color_text("No root directory specified!", "red"))
return False return False
#welcome! persona_fn = args.pop('persona_fn')
if not persona_fn or not sh.isfile(persona_fn):
print(utils.color_text("No valid persona file name specified!", "red"))
return False
# Welcome!
(repeat_string, line_max_len) = utils.welcome(_WELCOME_MAP.get(action)) (repeat_string, line_max_len) = utils.welcome(_WELCOME_MAP.get(action))
print(utils.center_text("Action Runner", repeat_string, line_max_len)) print(utils.center_text("Action Runner", repeat_string, line_max_len))
#here on out we should be using the logger (and not print) # Here on out we should be using the logger (and not print)!!
start_time = time.time()
# if we didn't load them before, load them now # If we didn't load them before, load them now
if not loaded_rcs: if not loaded_rcs:
load_rc_files() load_rc_files()
loaded_rcs = True loaded_rcs = True
# Stash the dryrun value (if any) into the global configuration # Stash the dryrun value (if any) into the global configuration
sh.set_dryrun(args['dryrun']) sh.set_dryrun(args.pop('dryrun'))
dist = distro.Distro.get_current() dist = distro.Distro.get_current()
config = common.get_config() config = cfg.get_config()
pw_gen = passwords.PasswordGenerator(config, args['prompt_for_passwords']) runner = actions.ActionRunner(dist, action, config, **args)
pkg_factory = dist.get_packager_factory()
pkg_manager = pkg_factory(dist, args['keep_old'])
components = utils.parse_components(args.pop("components"))
runner = actions.ActionRunner(dist, action, rootdir, config, pw_gen,
pkg_manager, components=components, **args)
LOG.info("Starting action [%s] on %s for distro [%s]" % (action, date.rcf8222date(), dist)) LOG.info("Starting action [%s] on %s for distro [%s]" % (action, date.rcf8222date(), dist))
runner.run()
LOG.info("It took (%s) to complete action [%s]" % (common.format_secs_taken((time.time() - start_time)), action)) start_time = time.time()
runner.run(persona_fn, root_dir)
end_time = time.time()
LOG.info("It took (%s) to complete action [%s]" %
(utils.format_secs_taken((end_time - start_time)), action))
LOG.info("After action [%s] your settings which were created or read are:" % (action)) LOG.info("After action [%s] your settings which were created or read are:" % (action))
dump_config(config.configs_fetched) dump_config(config.configs_fetched)
@ -154,7 +157,7 @@ def run(args):
def main(): def main():
#do this first so people can see the help message... # Do this first so people can see the help message...
args = opts.parse() args = opts.parse()
prog_name = sys.argv[0] prog_name = sys.argv[0]
@ -163,7 +166,7 @@ def main():
LOG.debug("Command line options %s" % (args)) LOG.debug("Command line options %s" % (args))
#will need root to setup openstack # Will need root to setup openstack
if not sh.got_root(): if not sh.got_root():
rest_args = sys.argv[1:] rest_args = sys.argv[1:]
print("This program requires a user with sudo access.") print("This program requires a user with sudo access.")
@ -173,7 +176,7 @@ def main():
return 1 return 1
try: try:
#drop to usermode # Drop to usermode
sh.user_mode(False) sh.user_mode(False)
started_ok = run(args) started_ok = run(args)
if not started_ok: if not started_ok: