From 687551a694833f2885f5d39a376c6e06a03d5e04 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Sun, 22 Jan 2012 16:09:47 -0800 Subject: [PATCH] Renamed constants to settings which is more appropriate. Had a little fun with figlet :-) --- devstack/component.py | 16 +- devstack/components/db.py | 4 +- devstack/components/glance.py | 4 +- devstack/components/horizon.py | 8 +- devstack/components/keystone.py | 12 +- devstack/components/keystone_client.py | 4 +- devstack/components/nova.py | 4 +- devstack/components/nova_client.py | 4 +- devstack/components/nova_conf.py | 7 +- devstack/components/openstack_x.py | 4 +- devstack/components/quantum.py | 4 +- devstack/components/rabbit.py | 6 +- devstack/components/swift.py | 3 +- devstack/image/creator.py | 2 +- devstack/opts.py | 10 +- devstack/packager.py | 6 +- devstack/packaging/apt.py | 6 +- devstack/packaging/yum.py | 2 +- devstack/progs/actions.py | 172 ++++++++++++--------- devstack/progs/deps.py | 6 +- devstack/{constants.py => settings.py} | 76 ++++++++++ devstack/shell.py | 4 +- devstack/trace.py | 2 +- devstack/utils.py | 202 ++++++++++--------------- stack | 1 - 25 files changed, 312 insertions(+), 257 deletions(-) rename devstack/{constants.py => settings.py} (64%) diff --git a/devstack/component.py b/devstack/component.py index 1c4ced3c..c3a6c211 100644 --- a/devstack/component.py +++ b/devstack/component.py @@ -13,17 +13,16 @@ # License for the specific language governing permissions and limitations # under the License. -import os - -from devstack import constants as c from devstack import downloader as down from devstack import exceptions as excp from devstack import log as logging from devstack import pip from devstack import runner +from devstack import settings from devstack import shell as sh from devstack import trace as tr from devstack import utils + from devstack.runners import fork from devstack.runners import screen @@ -175,7 +174,7 @@ class PkgInstallComponent(ComponentBase, InstallComponent): return sh.joinpths(self.cfgdir, name) def _get_source_config_name(self, name): - return sh.joinpths(c.STACK_CONFIG_DIR, self.component_name, name) + return sh.joinpths(settings.STACK_CONFIG_DIR, self.component_name, name) def _configure_files(self): configs = self._get_config_files() @@ -187,7 +186,7 @@ class PkgInstallComponent(ComponentBase, InstallComponent): sourcefn = self._get_source_config_name(fn) tgtfn = self._get_target_config_name(fn) #ensure directory is there (if not created previously) - self.tracewriter.make_dir(os.path.dirname(tgtfn)) + self.tracewriter.make_dir(sh.dirname(tgtfn)) #now configure it LOG.info("Configuring template file %s" % (sourcefn)) contents = sh.load_file(sourcefn) @@ -234,11 +233,8 @@ class PythonInstallComponent(PkgInstallComponent): stdout = '' if(stderr == None): stderr = '' - combined_output = "===STDOUT===" + os.linesep - combined_output += stdout + os.linesep - combined_output += "===STDERR===" + os.linesep - combined_output += stderr + os.linesep - return combined_output + combined = ["===STDOUT===", str(stdout), "===STDERR===", str(stderr)] + return utils.joinlinesep(*combined) def _format_trace_name(self, name): return "%s-%s" % (tr.PY_TRACE, name) diff --git a/devstack/components/db.py b/devstack/components/db.py index b8516efe..b6943971 100644 --- a/devstack/components/db.py +++ b/devstack/components/db.py @@ -14,7 +14,7 @@ # under the License. from devstack import component as comp -from devstack import constants +from devstack import settings from devstack import exceptions as excp from devstack import log as logging from devstack import shell as sh @@ -23,7 +23,7 @@ from devstack import utils LOG = logging.getLogger("devstack.components.db") -TYPE = constants.DB +TYPE = settings.DB MYSQL = 'mysql' DB_ACTIONS = { MYSQL: { diff --git a/devstack/components/glance.py b/devstack/components/glance.py index 9c882a68..f14ddc79 100644 --- a/devstack/components/glance.py +++ b/devstack/components/glance.py @@ -17,7 +17,7 @@ import io from devstack import cfg from devstack import component as comp -from devstack import constants +from devstack import settings from devstack import log as logging from devstack import shell as sh from devstack.components import db @@ -26,7 +26,7 @@ from devstack.image import creator LOG = logging.getLogger("devstack.components.glance") #naming + config files -TYPE = constants.GLANCE +TYPE = settings.GLANCE API_CONF = "glance-api.conf" REG_CONF = "glance-registry.conf" CONFIGS = [API_CONF, REG_CONF] diff --git a/devstack/components/horizon.py b/devstack/components/horizon.py index 478a35af..1eeeb07c 100644 --- a/devstack/components/horizon.py +++ b/devstack/components/horizon.py @@ -15,11 +15,11 @@ from devstack import component as comp -from devstack import constants from devstack import log as logging +from devstack import settings from devstack import shell as sh -TYPE = constants.HORIZON +TYPE = settings.HORIZON ROOT_HORIZON = 'horizon' HORIZON_NAME = 'horizon' @@ -100,7 +100,7 @@ class HorizonInstaller(comp.PythonInstallComponent): #Horizon currently imports quantum even if you aren't using it. #Instead of installing quantum we can create a simple module #that will pass the initial imports. - if(constants.QUANTUM in self.all_components): + if(settings.QUANTUM in self.all_components): return else: #Make the fake quantum @@ -132,7 +132,7 @@ class HorizonInstaller(comp.PythonInstallComponent): mp['HORIZON_DIR'] = self.appdir else: #Enable quantum in dashboard, if requested - mp['QUANTUM_ENABLED'] = "%s" % (constants.QUANTUM in self.all_components) + mp['QUANTUM_ENABLED'] = "%s" % (settings.QUANTUM in self.all_components) mp['OPENSTACK_HOST'] = self.cfg.get('host', 'ip') return mp diff --git a/devstack/components/keystone.py b/devstack/components/keystone.py index a9d4126d..f30d0826 100644 --- a/devstack/components/keystone.py +++ b/devstack/components/keystone.py @@ -17,15 +17,15 @@ import io from devstack import cfg from devstack import component as comp -from devstack import constants from devstack import log as logging +from devstack import settings from devstack import shell as sh from devstack import utils from devstack.components import db LOG = logging.getLogger("devstack.components.keystone") -TYPE = constants.KEYSTONE +TYPE = settings.KEYSTONE ROOT_CONF = "keystone.conf" CONFIGS = [ROOT_CONF] BIN_DIR = "bin" @@ -81,7 +81,7 @@ class KeystoneInstaller(comp.PythonInstallComponent): def _setup_data(self): #load the json file which has the keystone setup commands - cmds_pth = sh.joinpths(constants.STACK_CONFIG_DIR, TYPE, MANAGE_JSON_CONF) + cmds_pth = sh.joinpths(settings.STACK_CONFIG_DIR, TYPE, MANAGE_JSON_CONF) cmd_map = utils.load_json(cmds_pth) #order matters here @@ -105,13 +105,13 @@ class KeystoneInstaller(comp.PythonInstallComponent): endpoint_cmds = cmd_map.get('endpoints', list()) base_cmds.extend(endpoint_cmds) - if(constants.GLANCE in self.all_components): + if(settings.GLANCE in self.all_components): glance_cmds = cmd_map.get('glance', list()) base_cmds.extend(glance_cmds) - if(constants.NOVA in self.all_components): + if(settings.NOVA in self.all_components): nova_cmds = cmd_map.get('nova', list()) base_cmds.extend(nova_cmds) - if(constants.SWIFT in self.all_components): + if(settings.SWIFT in self.all_components): swift_cmds = cmd_map.get('swift', list()) base_cmds.extend(swift_cmds) diff --git a/devstack/components/keystone_client.py b/devstack/components/keystone_client.py index f68a67f2..eb510db2 100644 --- a/devstack/components/keystone_client.py +++ b/devstack/components/keystone_client.py @@ -15,10 +15,10 @@ from devstack import component as comp -from devstack import constants from devstack import log as logging +from devstack import settings -TYPE = constants.KEYSTONE_CLIENT +TYPE = settings.KEYSTONE_CLIENT LOG = logging.getLogger("devstack.components.keystone_client") diff --git a/devstack/components/nova.py b/devstack/components/nova.py index b970f767..5b3178c1 100644 --- a/devstack/components/nova.py +++ b/devstack/components/nova.py @@ -14,8 +14,8 @@ # under the License. from devstack import component as comp -from devstack import constants as co from devstack import log as logging +from devstack import settings from devstack import shell as sh from devstack.components import nova_conf as nc @@ -27,7 +27,7 @@ CONFIGS = [API_CONF] DB_NAME = "nova" BIN_DIR = 'bin' -TYPE = co.NOVA +TYPE = settings.NOVA class NovaUninstaller(comp.PythonUninstallComponent): diff --git a/devstack/components/nova_client.py b/devstack/components/nova_client.py index 0deeef71..30c604d3 100644 --- a/devstack/components/nova_client.py +++ b/devstack/components/nova_client.py @@ -14,11 +14,11 @@ # under the License. from devstack import component as comp -from devstack import constants from devstack import log as logging +from devstack import settings LOG = logging.getLogger("devstack.components.nova_client") -TYPE = constants.NOVA_CLIENT +TYPE = settings.NOVA_CLIENT class NovaClientUninstaller(comp.PythonUninstallComponent): diff --git a/devstack/components/nova_conf.py b/devstack/components/nova_conf.py index 92d7f54e..07aa2f78 100644 --- a/devstack/components/nova_conf.py +++ b/devstack/components/nova_conf.py @@ -13,13 +13,12 @@ # under the License. from devstack import component as comp -from devstack import constants as co from devstack import log as logging +from devstack import settings from devstack import shell as sh from devstack import utils LOG = logging.getLogger("devstack.components.nova_conf") - QUANTUM_MANAGER = 'nova.network.quantum.manager.QuantumManager' NET_MANAGER_TEMPLATE = 'nova.network.manager.%s' DEF_IMAGE_SERVICE = 'nova.image.glance.GlanceImageService' @@ -79,7 +78,7 @@ class NovaConfigurator(): #whats the network fixed range? nova_conf.add('fixed_range', self._getstr('fixed_range')) - if(co.QUANTUM in self.active_components): + if(settings.QUANTUM in self.active_components): #setup quantum config nova_conf.add('network_manager', QUANTUM_MANAGER) nova_conf.add('quantum_connection_host', self.cfg.get('quantum', 'q_host')) @@ -120,7 +119,7 @@ class NovaConfigurator(): self._getstr('instance_name_postfix')) nova_conf.add('instance_name_template', instance_template) - if(co.OPENSTACK_X in self.active_components): + if(settings.OPENSTACK_X in self.active_components): nova_conf.add('osapi_compute_extension', 'nova.api.openstack.compute.contrib.standard_extensions') nova_conf.add('osapi_compute_extension', 'extensions.admin.Admin') diff --git a/devstack/components/openstack_x.py b/devstack/components/openstack_x.py index 7c80ecce..5c57353f 100644 --- a/devstack/components/openstack_x.py +++ b/devstack/components/openstack_x.py @@ -14,13 +14,13 @@ # under the License. from devstack import component as comp -from devstack import constants from devstack import log as logging +from devstack import settings from devstack import shell as sh from devstack import utils LOG = logging.getLogger("devstack.components.openstackx") -TYPE = constants.OPENSTACK_X +TYPE = settings.OPENSTACK_X class OpenstackXUninstaller(comp.PythonUninstallComponent): diff --git a/devstack/components/quantum.py b/devstack/components/quantum.py index 587daf9d..8b7c3fa4 100644 --- a/devstack/components/quantum.py +++ b/devstack/components/quantum.py @@ -14,13 +14,13 @@ # under the License. from devstack import component as comp -from devstack import constants from devstack import log as logging +from devstack import settings from devstack import shell as sh from devstack import utils LOG = logging.getLogger("devstack.components.quantum") -TYPE = constants.QUANTUM +TYPE = settings.QUANTUM class QuantumUninstaller(comp.UninstallComponent): diff --git a/devstack/components/rabbit.py b/devstack/components/rabbit.py index 5dfd14df..a42db99e 100644 --- a/devstack/components/rabbit.py +++ b/devstack/components/rabbit.py @@ -17,14 +17,14 @@ from tempfile import TemporaryFile from devstack import component as comp -from devstack import constants from devstack import exceptions as excp from devstack import log as logging +from devstack import settings from devstack import shell as sh from devstack import trace as tr LOG = logging.getLogger("devstack.components.rabbit") -TYPE = constants.RABBIT +TYPE = settings.RABBIT #hopefully these are distro independent.. START_CMD = ['service', "rabbitmq-server", "start"] @@ -79,7 +79,7 @@ class RabbitRuntime(comp.NullRuntime): return sysout.strip().lower() def _run_cmd(self, cmd): - if(self.distro == constants.UBUNTU11): + if(self.distro == settings.UBUNTU11): with TemporaryFile() as f: sh.execute(*cmd, run_as_root=True, stdout_fh=f, stderr_fh=f) diff --git a/devstack/components/swift.py b/devstack/components/swift.py index bf60550b..c2539a7b 100644 --- a/devstack/components/swift.py +++ b/devstack/components/swift.py @@ -15,12 +15,13 @@ from devstack import component as comp -from devstack import constants from devstack import log as logging +from devstack import settings from devstack import shell as sh from devstack import utils LOG = logging.getLogger("devstack.components.swift") +TYPE = settings.SWIFT class SwiftUninstaller(comp.UninstallComponent): diff --git a/devstack/image/creator.py b/devstack/image/creator.py index d47d020e..4361d62d 100644 --- a/devstack/image/creator.py +++ b/devstack/image/creator.py @@ -209,7 +209,7 @@ class ImageCreationService: if(len(url)): Image(url, self.token).install() except (IOError, tarfile.TarError): - #these are the known exceptions we will catch and all that + #these are the known exceptions we will catch and all that #should be emitted (except core python errors, catching all #exceptions is not good...), since this service is not critical #just log them and carry on. diff --git a/devstack/opts.py b/devstack/opts.py index 7c2c5072..4f8d0113 100644 --- a/devstack/opts.py +++ b/devstack/opts.py @@ -13,14 +13,16 @@ # License for the specific language governing permissions and limitations # under the License. -from optparse import OptionParser, OptionGroup from optparse import IndentedHelpFormatter +from optparse import OptionParser, OptionGroup -from devstack import constants +from devstack import log as logging +from devstack import settings from devstack import utils from devstack import version HELP_WIDTH = 80 +LOG = logging.getLogger("devstack.opts") def parse(): @@ -31,7 +33,7 @@ def parse(): parser = OptionParser(version=version_str, formatter=help_formatter) base_group = OptionGroup(parser, "Install/uninstall/start/stop options") - known_actions = sorted(constants.ACTIONS) + known_actions = sorted(settings.ACTIONS) actions = "(" + ", ".join(known_actions) + ")" base_group.add_option("-a", "--action", action="store", @@ -46,7 +48,7 @@ def parse(): metavar="DIR", help="empty root DIR for install or "\ "DIR with existing components for start/stop/uninstall") - known_components = sorted(constants.COMPONENT_NAMES) + known_components = sorted(settings.COMPONENT_NAMES) components = "(" + ", ".join(known_components) + ")" base_group.add_option("-c", "--component", action="append", diff --git a/devstack/packager.py b/devstack/packager.py index aeafdeec..f702be95 100644 --- a/devstack/packager.py +++ b/devstack/packager.py @@ -13,8 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. -from devstack import constants from devstack import log as logging +from devstack import settings from devstack import utils LOG = logging.getLogger("devstack.packager") @@ -34,7 +34,7 @@ class Packager(): pkgnames = sorted(pkgs.keys()) for name in pkgnames: packageinfo = pkgs.get(name) - preinstallcmds = packageinfo.get(constants.PRE_INSTALL) + preinstallcmds = packageinfo.get(settings.PRE_INSTALL) if(preinstallcmds and len(preinstallcmds)): LOG.info("Running pre-install commands for package %s." % (name)) utils.execute_template(*preinstallcmds, params=installparams) @@ -43,7 +43,7 @@ class Packager(): pkgnames = sorted(pkgs.keys()) for name in pkgnames: packageinfo = pkgs.get(name) - postinstallcmds = packageinfo.get(constants.POST_INSTALL) + postinstallcmds = packageinfo.get(settings.POST_INSTALL) if(postinstallcmds and len(postinstallcmds)): LOG.info("Running post-install commands for package %s." % (name)) utils.execute_template(*postinstallcmds, params=installparams) diff --git a/devstack/packaging/apt.py b/devstack/packaging/apt.py index 46852db4..1f3e73e5 100644 --- a/devstack/packaging/apt.py +++ b/devstack/packaging/apt.py @@ -16,9 +16,9 @@ from tempfile import TemporaryFile import time -from devstack import constants as co from devstack import log as logging from devstack import packager as pack +from devstack import settings from devstack import shell as sh LOG = logging.getLogger("devstack.packaging.apt") @@ -100,7 +100,7 @@ class AptPackager(pack.Packager): self._execute_apt(cmd) def _pkg_remove_special(self, name, pkginfo): - if(name == 'rabbitmq-server' and self.distro == co.UBUNTU11): + if(name == 'rabbitmq-server' and self.distro == settings.UBUNTU11): #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597 #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 LOG.info("Handling special remove of %s." % (name)) @@ -116,7 +116,7 @@ class AptPackager(pack.Packager): return False def _pkg_install_special(self, name, pkginfo): - if(name == 'rabbitmq-server' and self.distro == co.UBUNTU11): + if(name == 'rabbitmq-server' and self.distro == settings.UBUNTU11): #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878597 #https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 LOG.info("Handling special install of %s." % (name)) diff --git a/devstack/packaging/yum.py b/devstack/packaging/yum.py index 29a06b70..7032ae6b 100644 --- a/devstack/packaging/yum.py +++ b/devstack/packaging/yum.py @@ -13,9 +13,9 @@ # License for the specific language governing permissions and limitations # under the License. +from devstack import log as logging from devstack import packager as pack from devstack import shell as sh -from devstack import log as logging LOG = logging.getLogger("devstack.packaging.yum") YUM_CMD = ['yum'] diff --git a/devstack/progs/actions.py b/devstack/progs/actions.py index f3ee3b76..868e479f 100644 --- a/devstack/progs/actions.py +++ b/devstack/progs/actions.py @@ -13,12 +13,13 @@ # License for the specific language governing permissions and limitations # under the License. -from devstack import constants as c -from devstack import utils -from devstack import shell as sh -from devstack import log as logging -from devstack import exceptions as excp +from devstack import cfg from devstack import date +from devstack import exceptions as excp +from devstack import log as logging +from devstack import settings +from devstack import shell as sh +from devstack import utils from devstack.components import db from devstack.components import glance @@ -32,61 +33,71 @@ from devstack.components import quantum from devstack.components import rabbit from devstack.components import swift +from devstack.packaging import apt +from devstack.packaging import yum + LOG = logging.getLogger("devstack.progs.actions") +#this map controls which distro has +#which package management class +_PKGR_MAP = { + settings.UBUNTU11: apt.AptPackager, + settings.RHEL6: yum.YumPackager, +} + # This determines what classes to use to install/uninstall/... _ACTION_CLASSES = { - c.INSTALL: { - c.NOVA: nova.NovaInstaller, - c.GLANCE: glance.GlanceInstaller, - c.QUANTUM: quantum.QuantumInstaller, - c.SWIFT: swift.SwiftInstaller, - c.HORIZON: horizon.HorizonInstaller, - c.KEYSTONE: keystone.KeystoneInstaller, - c.DB: db.DBInstaller, - c.RABBIT: rabbit.RabbitInstaller, - c.KEYSTONE_CLIENT: keystone_client.KeyStoneClientInstaller, - c.NOVA_CLIENT: nova_client.NovaClientInstaller, - c.OPENSTACK_X: openstack_x.OpenstackXInstaller, + settings.INSTALL: { + settings.NOVA: nova.NovaInstaller, + settings.GLANCE: glance.GlanceInstaller, + settings.QUANTUM: quantum.QuantumInstaller, + settings.SWIFT: swift.SwiftInstaller, + settings.HORIZON: horizon.HorizonInstaller, + settings.KEYSTONE: keystone.KeystoneInstaller, + settings.DB: db.DBInstaller, + settings.RABBIT: rabbit.RabbitInstaller, + settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientInstaller, + settings.NOVA_CLIENT: nova_client.NovaClientInstaller, + settings.OPENSTACK_X: openstack_x.OpenstackXInstaller, }, - c.UNINSTALL: { - c.NOVA: nova.NovaUninstaller, - c.GLANCE: glance.GlanceUninstaller, - c.QUANTUM: quantum.QuantumUninstaller, - c.SWIFT: swift.SwiftUninstaller, - c.HORIZON: horizon.HorizonUninstaller, - c.KEYSTONE: keystone.KeystoneUninstaller, - c.DB: db.DBUninstaller, - c.RABBIT: rabbit.RabbitUninstaller, - c.KEYSTONE_CLIENT: keystone_client.KeyStoneClientUninstaller, - c.NOVA_CLIENT: nova_client.NovaClientUninstaller, - c.OPENSTACK_X: openstack_x.OpenstackXUninstaller, + settings.UNINSTALL: { + settings.NOVA: nova.NovaUninstaller, + settings.GLANCE: glance.GlanceUninstaller, + settings.QUANTUM: quantum.QuantumUninstaller, + settings.SWIFT: swift.SwiftUninstaller, + settings.HORIZON: horizon.HorizonUninstaller, + settings.KEYSTONE: keystone.KeystoneUninstaller, + settings.DB: db.DBUninstaller, + settings.RABBIT: rabbit.RabbitUninstaller, + settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientUninstaller, + settings.NOVA_CLIENT: nova_client.NovaClientUninstaller, + settings.OPENSTACK_X: openstack_x.OpenstackXUninstaller, }, - c.START: { - c.NOVA: nova.NovaRuntime, - c.GLANCE: glance.GlanceRuntime, - c.QUANTUM: quantum.QuantumRuntime, - c.SWIFT: swift.SwiftRuntime, - c.HORIZON: horizon.HorizonRuntime, - c.KEYSTONE: keystone.KeystoneRuntime, - c.DB: db.DBRuntime, - c.RABBIT: rabbit.RabbitRuntime, - c.KEYSTONE_CLIENT: keystone_client.KeyStoneClientRuntime, - c.NOVA_CLIENT: nova_client.NovaClientRuntime, - c.OPENSTACK_X: openstack_x.OpenstackXRuntime, + settings.START: { + settings.NOVA: nova.NovaRuntime, + settings.GLANCE: glance.GlanceRuntime, + settings.QUANTUM: quantum.QuantumRuntime, + settings.SWIFT: swift.SwiftRuntime, + settings.HORIZON: horizon.HorizonRuntime, + settings.KEYSTONE: keystone.KeystoneRuntime, + settings.DB: db.DBRuntime, + settings.RABBIT: rabbit.RabbitRuntime, + settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientRuntime, + settings.NOVA_CLIENT: nova_client.NovaClientRuntime, + settings.OPENSTACK_X: openstack_x.OpenstackXRuntime, }, - c.STOP: { - c.NOVA: nova.NovaRuntime, - c.GLANCE: glance.GlanceRuntime, - c.QUANTUM: quantum.QuantumRuntime, - c.SWIFT: swift.SwiftRuntime, - c.HORIZON: horizon.HorizonRuntime, - c.KEYSTONE: keystone.KeystoneRuntime, - c.DB: db.DBRuntime, - c.RABBIT: rabbit.RabbitRuntime, - c.KEYSTONE_CLIENT: keystone_client.KeyStoneClientRuntime, - c.NOVA_CLIENT: nova_client.NovaClientRuntime, - c.OPENSTACK_X: openstack_x.OpenstackXRuntime, + settings.STOP: { + settings.NOVA: nova.NovaRuntime, + settings.GLANCE: glance.GlanceRuntime, + settings.QUANTUM: quantum.QuantumRuntime, + settings.SWIFT: swift.SwiftRuntime, + settings.HORIZON: horizon.HorizonRuntime, + settings.KEYSTONE: keystone.KeystoneRuntime, + settings.DB: db.DBRuntime, + settings.RABBIT: rabbit.RabbitRuntime, + settings.KEYSTONE_CLIENT: keystone_client.KeyStoneClientRuntime, + settings.NOVA_CLIENT: nova_client.NovaClientRuntime, + settings.OPENSTACK_X: openstack_x.OpenstackXRuntime, }, } @@ -95,11 +106,16 @@ def _clean_action(action): if(action == None): return None action = action.strip().lower() - if(not (action in c.ACTIONS)): + if(not (action in settings.ACTIONS)): return None return action +def _get_pkg_manager(distro): + cls = _PKGR_MAP.get(distro) + return cls(distro) + + def _get_action_cls(action_name, component_name): action_cls_map = _ACTION_CLASSES.get(action_name) if(not action_cls_map): @@ -110,23 +126,25 @@ def _get_action_cls(action_name, component_name): def _check_root(action, rootdir): if(rootdir == None or len(rootdir) == 0): return False - if(action == c.INSTALL): - if(sh.isdir(rootdir) and len(sh.listdir(rootdir)) != 0): - LOG.error("Root directory [%s] already exists (and it's not empty)! "\ - "Please remove it or uninstall components!" % (rootdir)) - return False + if(action == settings.INSTALL): + if(sh.isdir(rootdir)): + dir_list = sh.listdir(rootdir) + if(len(dir_list) > 0): + LOG.error("Root directory [%s] already exists (and it's not empty)! "\ + "Please remove it or uninstall components!" % (rootdir)) + return False return True def _pre_run(action_name, **kargs): - if(action_name == c.INSTALL): + if(action_name == settings.INSTALL): root_dir = kargs.get("root_dir") if(root_dir): sh.mkdir(root_dir) def _post_run(action_name, **kargs): - if(action_name == c.UNINSTALL): + if(action_name == settings.UNINSTALL): root_dir = kargs.get("root_dir") if(root_dir): sh.rmdir(root_dir) @@ -230,10 +248,18 @@ def _uninstall(component_name, instance, skip_notrace): raise +def _get_config(): + cfg_fn = sh.canon_path(settings.STACK_CONFIG_LOCATION) + LOG.info("Loading config from [%s]" % (cfg_fn)) + config_instance = cfg.EnvConfigParser() + config_instance.read(cfg_fn) + return config_instance + + def _run_components(action_name, component_order, components_info, distro, root_dir, program_args): LOG.info("Will %s [%s] (in that order) using root directory \"%s\"" % (action_name, ", ".join(component_order), root_dir)) - pkg_manager = utils.get_pkg_manager(distro) - config = utils.get_config() + pkg_manager = _get_pkg_manager(distro) + config = _get_config() results = list() #this key list may be different than the order due to reference components active_components = components_info.keys() @@ -247,24 +273,28 @@ def _run_components(action_name, component_order, components_info, distro, root_ cfg=config, root=root_dir, component_opts=components_info.get(component, list())) - if(action_name == c.INSTALL): + #activate the correct function for the given action + if(action_name == settings.INSTALL): install_result = _install(component, instance) if install_result: if type(install_result) == list: results += install_result else: results.append(str(install_result)) - elif(action_name == c.STOP): + elif(action_name == settings.STOP): _stop(component, instance, program_args.get('force', False)) - elif(action_name == c.START): + elif(action_name == settings.START): start_result = _start(component, instance) if start_result: if type(start_result) == list: results += start_result else: results.append(str(start_result)) - elif(action_name == c.UNINSTALL): + elif(action_name == settings.UNINSTALL): _uninstall(component, instance, program_args.get('force', False)) + else: + #TODO throw? + pass #display any configs touched... _print_cfgs(config, action_name) #any post run actions go now @@ -273,7 +303,7 @@ def _run_components(action_name, component_order, components_info, distro, root_ def _run_action(args): - components = utils.parse_components(args.pop("components")) + components = settings.parse_components(args.pop("components")) if(len(components) == 0): LOG.error("No components specified!") return False @@ -295,18 +325,18 @@ def _run_action(args): #need to figure out dependencies for components (if any) ignore_deps = args.pop('ignore_deps', False) if(not ignore_deps): - new_components = utils.resolve_dependencies(components.keys()) + new_components = settings.resolve_dependencies(components.keys()) component_diff = new_components.difference(components.keys()) if(len(component_diff)): LOG.info("Having to activate dependent components: [%s]" % (", ".join(component_diff))) for new_component in component_diff: components[new_component] = list() #get the right component order (by priority) - component_order = utils.prioritize_components(components.keys()) + component_order = settings.prioritize_components(components.keys()) #now do it! LOG.info("Starting action [%s] on %s for distro [%s]" % (action, date.rcf8222date(), distro)) #add in any that will just be referenced but which will not actually do anything - ref_components = utils.parse_components(args.pop("ref_components")) + ref_components = settings.parse_components(args.pop("ref_components")) for c in ref_components.keys(): if(c not in components): components[c] = ref_components.get(c) diff --git a/devstack/progs/deps.py b/devstack/progs/deps.py index d7cc1f9d..b202843f 100644 --- a/devstack/progs/deps.py +++ b/devstack/progs/deps.py @@ -13,8 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. -from devstack import utils from devstack import log as logging +from devstack import settings LOG = logging.getLogger("devstack.progs.deps") @@ -24,7 +24,7 @@ def log_deps(components): left_show = list(components) while(len(left_show) != 0): c = left_show.pop() - deps = utils.get_dependencies(c) + deps = settings.get_dependencies(c) dep_str = "" dep_len = len(deps) if(dep_len >= 1): @@ -45,7 +45,7 @@ def log_deps(components): def _run_list_deps(args): - components = utils.parse_components(args.pop("components"), True).keys() + components = settings.parse_components(args.pop("components"), True).keys() components = sorted(components) components.reverse() return log_deps(components) diff --git a/devstack/constants.py b/devstack/settings.py similarity index 64% rename from devstack/constants.py rename to devstack/settings.py index 7b02735f..ee9861db 100644 --- a/devstack/constants.py +++ b/devstack/settings.py @@ -13,9 +13,14 @@ # License for the specific language governing permissions and limitations # under the License. +import operator import os.path import re +from devstack import log as logging + +LOG = logging.getLogger("devstack.settings") + # These also have meaning outside python, # ie in the pkg/pip listings so update there also! UBUNTU11 = "ubuntu-oneiric" @@ -93,6 +98,9 @@ COMPONENT_TRACE_DIR = "traces" COMPONENT_APP_DIR = "app" COMPONENT_CONFIG_DIR = "config" +# This regex is used to extract a components options (if any) and its name +EXT_COMPONENT = re.compile(r"^\s*([\w-]+)(?:\((.*)\))?\s*$") + # Program # actions INSTALL = "install" @@ -201,3 +209,71 @@ PKG_MAP = { os.path.join(STACK_PKG_DIR, 'openstackx.json'), ], } + + +def get_dependencies(component): + return sorted(COMPONENT_DEPENDENCIES.get(component, list())) + + +def resolve_dependencies(components): + active_components = list(components) + new_components = set() + while(len(active_components)): + curr_comp = active_components.pop() + component_deps = get_dependencies(curr_comp) + new_components.add(curr_comp) + for c in component_deps: + if(c in new_components or c in active_components): + pass + else: + active_components.append(c) + return new_components + + +def prioritize_components(components): + #get the right component order (by priority) + mporder = dict() + for c in components: + priority = COMPONENT_NAMES_PRIORITY.get(c) + if(priority == None): + priority = sys.maxint + mporder[c] = priority + #sort by priority value + priority_order = sorted(mporder.iteritems(), key=operator.itemgetter(1)) + #extract the final list ordering + component_order = [x[0] for x in priority_order] + return component_order + + +def parse_components(components, assume_all=False): + #none provided, init it + if(not components): + components = list() + adjusted_components = dict() + for c in components: + mtch = EXT_COMPONENT.match(c) + if(mtch): + component_name = mtch.group(1).lower().strip() + if(component_name not in COMPONENT_NAMES): + LOG.warn("Unknown component named %s" % (component_name)) + else: + component_opts = mtch.group(2) + components_opts_cleaned = list() + if(component_opts == None or len(component_opts) == 0): + pass + else: + sp_component_opts = component_opts.split(",") + for co in sp_component_opts: + cleaned_opt = co.strip() + if(len(cleaned_opt)): + components_opts_cleaned.append(cleaned_opt) + adjusted_components[component_name] = components_opts_cleaned + else: + LOG.warn("Unparseable component %s" % (c)) + #should we adjust them to be all the components? + if(len(adjusted_components) == 0 and assume_all): + all_components = dict() + for c in COMPONENT_NAMES: + all_components[c] = list() + adjusted_components = all_components + return adjusted_components diff --git a/devstack/shell.py b/devstack/shell.py index 5f4680c5..a0599cd3 100644 --- a/devstack/shell.py +++ b/devstack/shell.py @@ -19,9 +19,9 @@ import os.path import shutil import subprocess -from devstack import log as logging -from devstack import exceptions as excp from devstack import env +from devstack import exceptions as excp +from devstack import log as logging ROOT_HELPER = ["sudo"] MKPW_CMD = ["openssl", 'rand', '-hex'] diff --git a/devstack/trace.py b/devstack/trace.py index 7c56db60..f054147b 100644 --- a/devstack/trace.py +++ b/devstack/trace.py @@ -15,9 +15,9 @@ import json +from devstack import date from devstack import exceptions as excp from devstack import shell as sh -from devstack import date #trace per line output and file extension formats TRACE_FMT = "%s - %s\n" diff --git a/devstack/utils.py b/devstack/utils.py index aca07ec6..33a03707 100644 --- a/devstack/utils.py +++ b/devstack/utils.py @@ -15,17 +15,18 @@ import json import netifaces -import operator import os import platform +import random import re -import sys +#requires http://pypi.python.org/pypi/termcolor +#but the colors make it worth it :-) from termcolor import colored -from devstack import constants from devstack import exceptions as excp from devstack import log as logging +from devstack import settings from devstack import shell as sh from devstack import version @@ -34,52 +35,8 @@ PARAM_SUB_REGEX = re.compile(r"%([\w\d]+?)%") LOG = logging.getLogger("devstack.util") -def get_pkg_manager(distro): - from devstack.packaging import apt - from devstack.packaging import yum - #this map controls which distro has - #which package management class - PKGR_MAP = { - constants.UBUNTU11: apt.AptPackager, - constants.RHEL6: yum.YumPackager, - } - cls = PKGR_MAP.get(distro) - return cls(distro) - - -def get_config(): - from devstack import cfg - cfg_fn = sh.canon_path(constants.STACK_CONFIG_LOCATION) - LOG.info("Loading config from [%s]" % (cfg_fn)) - config_instance = cfg.EnvConfigParser() - config_instance.read(cfg_fn) - return config_instance - - -def get_dependencies(component): - deps = constants.COMPONENT_DEPENDENCIES.get(component, list()) - return sorted(deps) - - -def resolve_dependencies(components): - active_components = list(components) - new_components = set() - while(len(active_components)): - curr_comp = active_components.pop() - component_deps = get_dependencies(curr_comp) - new_components.add(curr_comp) - for c in component_deps: - if(c in new_components or c in active_components): - pass - else: - active_components.append(c) - return new_components - - def execute_template(*cmds, **kargs): - if(not cmds or len(cmds) == 0): - return - params_replacements = kargs.pop('params') + params_replacements = kargs.pop('params', None) ignore_missing = kargs.pop('ignore_missing', False) cmd_results = list() for cmdinfo in cmds: @@ -108,63 +65,11 @@ def execute_template(*cmds, **kargs): return cmd_results -def parse_components(components, assume_all=False): - #none provided, init it - if(components == None): - components = list() - #this regex is used to extract a components options (if any) and its name - EXT_COMPONENT = re.compile(r"^\s*([\w-]+)(?:\((.*)\))?\s*$") - adjusted_components = dict() - for c in components: - mtch = EXT_COMPONENT.match(c) - if(mtch): - component_name = mtch.group(1).lower().strip() - if(component_name not in constants.COMPONENT_NAMES): - LOG.warn("Unknown component named %s" % (component_name)) - else: - component_opts = mtch.group(2) - components_opts_cleaned = list() - if(component_opts == None or len(component_opts) == 0): - pass - else: - sp_component_opts = component_opts.split(",") - for co in sp_component_opts: - cleaned_opt = co.strip() - if(len(cleaned_opt)): - components_opts_cleaned.append(cleaned_opt) - adjusted_components[component_name] = components_opts_cleaned - else: - LOG.warn("Unparseable component %s" % (c)) - #should we adjust them to be all the components? - if(len(adjusted_components) == 0 and assume_all): - all_components = dict() - for c in constants.COMPONENT_NAMES: - all_components[c] = list() - adjusted_components = all_components - return adjusted_components - - -def prioritize_components(components): - #get the right component order (by priority) - mporder = dict() - priorities = constants.COMPONENT_NAMES_PRIORITY - for c in components: - priority = priorities.get(c) - if(priority == None): - priority = sys.maxint - mporder[c] = priority - #sort by priority value - priority_order = sorted(mporder.iteritems(), key=operator.itemgetter(1)) - #extract the right order - component_order = [x[0] for x in priority_order] - return component_order - - def component_paths(root, component_name): component_root = sh.joinpths(root, component_name) - tracedir = sh.joinpths(component_root, constants.COMPONENT_TRACE_DIR) - appdir = sh.joinpths(component_root, constants.COMPONENT_APP_DIR) - cfgdir = sh.joinpths(component_root, constants.COMPONENT_CONFIG_DIR) + tracedir = sh.joinpths(component_root, settings.COMPONENT_TRACE_DIR) + appdir = sh.joinpths(component_root, settings.COMPONENT_APP_DIR) + cfgdir = sh.joinpths(component_root, settings.COMPONENT_CONFIG_DIR) return (component_root, tracedir, appdir, cfgdir) @@ -183,9 +88,9 @@ def load_json(fn): def get_host_ip(): ip = None interfaces = get_interfaces() - def_info = interfaces.get(constants.DEFAULT_NET_INTERFACE) + def_info = interfaces.get(settings.DEFAULT_NET_INTERFACE) if(def_info): - ipinfo = def_info.get(constants.DEFAULT_NET_INTERFACE_IP_VERSION) + ipinfo = def_info.get(settings.DEFAULT_NET_INTERFACE_IP_VERSION) if(ipinfo): ip = ipinfo.get('addr') if(ip == None): @@ -202,11 +107,11 @@ def get_interfaces(): ip6 = interface_addresses.get(netifaces.AF_INET6) if(ip6 and len(ip6)): #just take the first - interface_info[constants.IPV6] = ip6[0] + interface_info[settings.IPV6] = ip6[0] ip4 = interface_addresses.get(netifaces.AF_INET) if(ip4 and len(ip4)): #just take the first - interface_info[constants.IPV4] = ip4[0] + interface_info[settings.IPV4] = ip4[0] #there are others but this is good for now interfaces[intfc] = interface_info return interfaces @@ -220,7 +125,7 @@ def determine_distro(): return (None, plt) #attempt to match it to our platforms found_os = None - for (known_os, pattern) in constants.KNOWN_DISTROS.items(): + for (known_os, pattern) in settings.KNOWN_DISTROS.items(): if(pattern.search(plt)): found_os = known_os break @@ -230,7 +135,7 @@ def determine_distro(): def get_pip_list(distro, component): LOG.info("Getting pip packages for distro %s and component %s." % (distro, component)) all_pkgs = dict() - fns = constants.PIP_MAP.get(component) + fns = settings.PIP_MAP.get(component) if(fns == None): return all_pkgs #load + merge them @@ -249,7 +154,7 @@ def get_pip_list(distro, component): def get_pkg_list(distro, component): LOG.info("Getting packages for distro %s and component %s." % (distro, component)) all_pkgs = dict() - fns = constants.PKG_MAP.get(component) + fns = settings.PKG_MAP.get(component) if(fns == None): return all_pkgs #load + merge them @@ -265,7 +170,7 @@ def get_pkg_list(distro, component): for (infokey, infovalue) in pkginfo.items(): #this is expected to be a list of cmd actions #so merge that accordingly - if(infokey == constants.PRE_INSTALL or infokey == constants.POST_INSTALL): + if(infokey == settings.PRE_INSTALL or infokey == settings.POST_INSTALL): oldinstalllist = oldpkginfo.get(infokey) or [] infovalue = oldinstalllist + infovalue newpkginfo[infokey] = infovalue @@ -309,8 +214,58 @@ def param_replace(text, replacements, ignore_missing=False): return PARAM_SUB_REGEX.sub(replacer, text) +def _get_welcome_stack(): + possibles = list() + #thank you figlet ;) + possibles.append(r''' + ___ ____ _____ _ _ ____ _____ _ ____ _ __ + / _ \| _ \| ____| \ | / ___|_ _|/ \ / ___| |/ / +| | | | |_) | _| | \| \___ \ | | / _ \| | | ' / +| |_| | __/| |___| |\ |___) || |/ ___ \ |___| . \ + \___/|_| |_____|_| \_|____/ |_/_/ \_\____|_|\_\ + +''') + possibles.append(r''' + ___ ___ ___ _ _ ___ _____ _ ___ _ __ + / _ \| _ \ __| \| / __|_ _/_\ / __| |/ / +| (_) | _/ _|| .` \__ \ | |/ _ \ (__| ' < + \___/|_| |___|_|\_|___/ |_/_/ \_\___|_|\_\ + +''') + possibles.append(r''' +____ ___ ____ _ _ ____ ___ ____ ____ _ _ +| | |__] |___ |\ | [__ | |__| | |_/ +|__| | |___ | \| ___] | | | |___ | \_ + +''') + possibles.append(r''' + _ ___ ___ _ _ __ ___ _ __ _ _ + / \| o \ __|| \| |/ _||_ _|/ \ / _|| |// +( o ) _/ _| | \\ |\_ \ | || o ( (_ | ( + \_/|_| |___||_|\_||__/ |_||_n_|\__||_|\\ + +''') + possibles.append(r''' + _ ___ ___ _ __ ___ _____ _ __ _ + ,' \ / o |/ _/ / |/ /,' _//_ _/.' \ ,'_/ / //7 +/ o |/ _,'/ _/ / || /_\ `. / / / o // /_ / ,' +|_,'/_/ /___//_/|_//___,' /_/ /_n_/ |__//_/\\ + +''') + possibles.append(r''' + _____ ___ ___ _ _ ___ _____ _____ ___ _ _ +( _ )( _`\ ( _`\ ( ) ( )( _`\(_ _)( _ )( _`\ ( ) ( ) +| ( ) || |_) )| (_(_)| `\| || (_(_) | | | (_) || ( (_)| |/'/' +| | | || ,__/'| _)_ | , ` |`\__ \ | | | _ || | _ | , < +| (_) || | | (_( )| |`\ |( )_) | | | | | | || (_( )| |\`\ +(_____)(_) (____/'(_) (_)`\____) (_) (_) (_)(____/'(_) (_) + +''') + return random.choice(possibles) + + def welcome(action): - formatted_action = constants.WELCOME_MAP.get(action, "") + formatted_action = settings.WELCOME_MAP.get(action, "") ver_str = version.version_string() lower = "|" if(formatted_action): @@ -318,19 +273,16 @@ def welcome(action): lower += " " lower += ver_str lower += "|" - welcome_ = r''' - ___ ____ _____ _ _ ____ _____ _ ____ _ __ - / _ \| _ \| ____| \ | / ___|_ _|/ \ / ___| |/ / -| | | | |_) | _| | \| \___ \ | | / _ \| | | ' / -| |_| | __/| |___| |\ |___) || |/ ___ \ |___| . \ - \___/|_| |_____|_| \_|____/ |_/_/ \_\____|_|\_\ - -''' + welcome_ = _get_welcome_stack() welcome_ = welcome_.strip("\n\r") - max_len = len(max(welcome_.splitlines(), key=len)) - lower_out = colored(constants.PROG_NICE_NAME, 'green') + \ + max_line_len = len(max(welcome_.splitlines(), key=len)) + lower_out = colored(settings.PROG_NICE_NAME, 'green') + \ ": " + colored(lower, 'blue') - uncolored_lower_len = (len(constants.PROG_NICE_NAME + ": " + lower)) - center_len = max_len + (max_len - uncolored_lower_len) - lower_out = lower_out.center(center_len) + uncolored_lower = (settings.PROG_NICE_NAME + ": " + lower) + if(max_line_len - len(uncolored_lower) > 0): + #this format string wil center the uncolored text which + #we will then replace + #with the color text equivalent + centered_str = '{0:{fill}{align}{size}}'.format(uncolored_lower, fill=" ", align="^", size=max_line_len) + lower_out = centered_str.replace(uncolored_lower, lower_out) print((welcome_ + os.linesep + lower_out)) diff --git a/stack b/stack index 3298c774..ac131496 100755 --- a/stack +++ b/stack @@ -23,7 +23,6 @@ logging.setup() #this handles our option parsing from devstack import opts -from devstack import constants #these are the program runtimes that actually do the running from devstack.progs import actions