diff --git a/conf/distros/fedora-16.yaml b/conf/distros/fedora-16.yaml index f0bc487f..29b9ab2a 100644 --- a/conf/distros/fedora-16.yaml +++ b/conf/distros/fedora-16.yaml @@ -22,6 +22,8 @@ commands: mysql: # NOTE: we aren't stopping any sql injection... create_db: mysql --user=%USER% --password=%PASSWORD% -e + "CREATE DATABASE %DB%;" + create_db_utf8: mysql --user=%USER% --password=%PASSWORD% -e "CREATE DATABASE %DB% CHARACTER SET utf8;" drop_db: mysql --user=%USER% --password=%PASSWORD% -e "DROP DATABASE IF EXISTS %DB%;" @@ -43,12 +45,12 @@ commands: start: service rabbitmq-server start status: service rabbitmq-server status stop: service rabbitmq-server stop + redirect-outs: true components: db: action_classes: install: devstack.distros.fedora16:DBInstaller - start: devstack.components.db:DBRuntime - stop: devstack.components.db:DBRuntime + running: devstack.components.db:DBRuntime uninstall: devstack.components.db:DBUninstaller packages: - name: mysql @@ -60,8 +62,7 @@ components: general: action_classes: install: devstack.components.pkglist:Installer - start: devstack.component:EmptyRuntime - stop: devstack.component:EmptyRuntime + running: devstack.component:EmptyRuntime uninstall: devstack.components.pkglist:Uninstaller packages: - name: curl @@ -151,8 +152,7 @@ components: glance: action_classes: install: devstack.components.glance:GlanceInstaller - start: devstack.components.glance:GlanceRuntime - stop: devstack.components.glance:GlanceRuntime + running: devstack.components.glance:GlanceRuntime uninstall: devstack.components.glance:GlanceUninstaller packages: - name: MySQL-python @@ -191,8 +191,7 @@ components: horizon: action_classes: install: devstack.distros.fedora16:HorizonInstaller - start: devstack.components.horizon:HorizonRuntime - stop: devstack.components.horizon:HorizonRuntime + running: devstack.components.horizon:HorizonRuntime uninstall: devstack.components.horizon:HorizonUninstaller packages: - name: Django @@ -261,8 +260,7 @@ components: keystone: action_classes: install: devstack.components.keystone:KeystoneInstaller - start: devstack.components.keystone:KeystoneRuntime - stop: devstack.components.keystone:KeystoneRuntime + running: devstack.components.keystone:KeystoneRuntime uninstall: devstack.components.keystone:KeystoneUninstaller packages: - name: MySQL-python @@ -325,25 +323,25 @@ components: keystone-client: action_classes: install: devstack.components.keystone_client:KeyStoneClientInstaller - start: devstack.components.keystone_client:KeyStoneClientRuntime - stop: devstack.components.keystone_client:KeyStoneClientRuntime + running: devstack.components.keystone_client:KeyStoneClientRuntime uninstall: devstack.components.keystone_client:KeyStoneClientUninstaller packages: - name: python-prettytable removable: true version: 0.5* + - name: python-paste-deploy + removable: true + version: 1.5.0* melange: action_classes: install: devstack.components.melange:MelangeInstaller - start: devstack.components.melange:MelangeRuntime - stop: devstack.components.melange:MelangeRuntime + running: devstack.components.melange:MelangeRuntime uninstall: devstack.components.melange:MelangeUninstaller packages: null no-vnc: action_classes: install: devstack.components.novnc:NoVNCInstaller - start: devstack.components.novnc:NoVNCRuntime - stop: devstack.components.novnc:NoVNCRuntime + running: devstack.components.novnc:NoVNCRuntime uninstall: devstack.components.novnc:NoVNCUninstaller packages: - name: numpy @@ -352,8 +350,7 @@ components: nova: action_classes: install: devstack.distros.fedora16:NovaInstaller - start: devstack.components.nova:NovaRuntime - stop: devstack.components.nova:NovaRuntime + running: devstack.components.nova:NovaRuntime uninstall: devstack.components.nova:NovaUninstaller packages: - name: MySQL-python @@ -525,8 +522,7 @@ components: nova-client: action_classes: install: devstack.components.nova_client:NovaClientInstaller - start: devstack.components.nova_client:NovaClientRuntime - stop: devstack.components.nova_client:NovaClientRuntime + running: devstack.components.nova_client:NovaClientRuntime uninstall: devstack.components.nova_client:NovaClientUninstaller packages: - name: python-prettytable @@ -535,8 +531,7 @@ components: quantum: action_classes: install: devstack.components.quantum:QuantumInstaller - start: devstack.components.quantum:QuantumRuntime - stop: devstack.components.quantum:QuantumRuntime + running: devstack.components.quantum:QuantumRuntime uninstall: devstack.components.quantum:QuantumUninstaller packages: - name: libxml2-python @@ -581,8 +576,7 @@ components: quantum-client: action_classes: install: devstack.components.quantum_client:QuantumClientInstaller - start: devstack.components.quantum_client:QuantumClientRuntime - stop: devstack.components.quantum_client:QuantumClientRuntime + running: devstack.components.quantum_client:QuantumClientRuntime uninstall: devstack.components.quantum_client:QuantumClientUninstaller packages: - name: python-gflags @@ -591,8 +585,7 @@ components: rabbit-mq: action_classes: install: devstack.components.rabbit:RabbitInstaller - start: devstack.components.rabbit:RabbitRuntime - stop: devstack.components.rabbit:RabbitRuntime + running: devstack.distros.fedora16:RabbitRuntime uninstall: devstack.components.rabbit:RabbitUninstaller packages: - name: rabbitmq-server @@ -613,8 +606,7 @@ components: swift: action_classes: install: devstack.components.swift:SwiftInstaller - start: devstack.components.swift:SwiftRuntime - stop: devstack.components.swift:SwiftRuntime + running: devstack.components.swift:SwiftRuntime uninstall: devstack.components.swift:SwiftUninstaller packages: - name: memcached diff --git a/conf/distros/rhel-6.yaml b/conf/distros/rhel-6.yaml index 03cf9ad0..6d6490d3 100644 --- a/conf/distros/rhel-6.yaml +++ b/conf/distros/rhel-6.yaml @@ -22,6 +22,8 @@ commands: mysql: # NOTE: we aren't stopping any sql injection... create_db: mysql --user=%USER% --password=%PASSWORD% -e + "CREATE DATABASE %DB%;" + create_db_utf8: mysql --user=%USER% --password=%PASSWORD% -e "CREATE DATABASE %DB% CHARACTER SET utf8;" drop_db: mysql --user=%USER% --password=%PASSWORD% -e "DROP DATABASE IF EXISTS %DB%;" @@ -43,12 +45,12 @@ commands: start: service rabbitmq-server start status: service rabbitmq-server status stop: service rabbitmq-server stop + redirect-outs: true components: db: action_classes: install: devstack.distros.rhel6:DBInstaller - start: devstack.components.db:DBRuntime - stop: devstack.components.db:DBRuntime + running: devstack.components.db:DBRuntime uninstall: devstack.components.db:DBUninstaller packages: - name: mysql @@ -60,8 +62,7 @@ components: general: action_classes: install: devstack.components.pkglist:Installer - start: devstack.component:EmptyRuntime - stop: devstack.component:EmptyRuntime + running: devstack.component:EmptyRuntime uninstall: devstack.components.pkglist:Uninstaller packages: - name: coreutils @@ -171,8 +172,7 @@ components: glance: action_classes: install: devstack.components.glance:GlanceInstaller - start: devstack.components.glance:GlanceRuntime - stop: devstack.components.glance:GlanceRuntime + running: devstack.components.glance:GlanceRuntime uninstall: devstack.components.glance:GlanceUninstaller packages: - name: MySQL-python @@ -226,8 +226,7 @@ components: horizon: action_classes: install: devstack.distros.rhel6:HorizonInstaller - start: devstack.components.horizon:HorizonRuntime - stop: devstack.components.horizon:HorizonRuntime + running: devstack.components.horizon:HorizonRuntime uninstall: devstack.components.horizon:HorizonUninstaller packages: - name: httpd @@ -295,8 +294,7 @@ components: keystone: action_classes: install: devstack.components.keystone:KeystoneInstaller - start: devstack.components.keystone:KeystoneRuntime - stop: devstack.components.keystone:KeystoneRuntime + running: devstack.components.keystone:KeystoneRuntime uninstall: devstack.components.keystone:KeystoneUninstaller packages: - name: MySQL-python @@ -373,8 +371,7 @@ components: keystone-client: action_classes: install: devstack.components.keystone_client:KeyStoneClientInstaller - start: devstack.components.keystone_client:KeyStoneClientRuntime - stop: devstack.components.keystone_client:KeyStoneClientRuntime + running: devstack.components.keystone_client:KeyStoneClientRuntime uninstall: devstack.components.keystone_client:KeyStoneClientUninstaller packages: - meta: @@ -390,14 +387,12 @@ components: melange: action_classes: install: devstack.components.melange:MelangeInstaller - start: devstack.components.melange:MelangeRuntime - stop: devstack.components.melange:MelangeRuntime + running: devstack.components.melange:MelangeRuntime uninstall: devstack.components.melange:MelangeUninstaller no-vnc: action_classes: install: devstack.components.novnc:NoVNCInstaller - start: devstack.components.novnc:NoVNCRuntime - stop: devstack.components.novnc:NoVNCRuntime + running: devstack.components.novnc:NoVNCRuntime uninstall: devstack.components.novnc:NoVNCUninstaller pips: - name: numpy @@ -405,8 +400,7 @@ components: nova: action_classes: install: devstack.distros.rhel6:NovaInstaller - start: devstack.components.nova:NovaRuntime - stop: devstack.components.nova:NovaRuntime + running: devstack.components.nova:NovaRuntime uninstall: devstack.components.nova:NovaUninstaller packages: - name: MySQL-python @@ -574,8 +568,7 @@ components: nova-client: action_classes: install: devstack.components.nova_client:NovaClientInstaller - start: devstack.components.nova_client:NovaClientRuntime - stop: devstack.components.nova_client:NovaClientRuntime + running: devstack.components.nova_client:NovaClientRuntime uninstall: devstack.components.nova_client:NovaClientUninstaller packages: - meta: @@ -591,8 +584,7 @@ components: quantum: action_classes: install: devstack.components.quantum:QuantumInstaller - start: devstack.components.quantum:QuantumRuntime - stop: devstack.components.quantum:QuantumRuntime + running: devstack.components.quantum:QuantumRuntime uninstall: devstack.components.quantum:QuantumUninstaller packages: - name: libxml2-python @@ -629,8 +621,7 @@ components: quantum-client: action_classes: install: devstack.components.quantum_client:QuantumClientInstaller - start: devstack.components.quantum_client:QuantumClientRuntime - stop: devstack.components.quantum_client:QuantumClientRuntime + running: devstack.components.quantum_client:QuantumClientRuntime uninstall: devstack.components.quantum_client:QuantumClientUninstaller packages: - meta: @@ -641,8 +632,7 @@ components: rabbit-mq: action_classes: install: devstack.components.rabbit:RabbitInstaller - start: devstack.components.rabbit:RabbitRuntime - stop: devstack.components.rabbit:RabbitRuntime + running: devstack.distros.rhel6:RabbitRuntime uninstall: devstack.components.rabbit:RabbitUninstaller packages: - meta: @@ -666,8 +656,7 @@ components: swift: action_classes: install: devstack.components.swift:SwiftInstaller - start: devstack.components.swift:SwiftRuntime - stop: devstack.components.swift:SwiftRuntime + running: devstack.components.swift:SwiftRuntime uninstall: devstack.components.swift:SwiftUninstaller ... diff --git a/conf/distros/ubuntu-oneiric.yaml b/conf/distros/ubuntu-oneiric.yaml index 13f87b42..9648e6d8 100644 --- a/conf/distros/ubuntu-oneiric.yaml +++ b/conf/distros/ubuntu-oneiric.yaml @@ -27,6 +27,8 @@ commands: mysql: # NOTE: we aren't stopping any sql injection... create_db: mysql --user=%USER% --password=%PASSWORD% -e + "CREATE DATABASE %DB%;" + create_db_utf8: mysql --user=%USER% --password=%PASSWORD% -e "CREATE DATABASE %DB% CHARACTER SET utf8;" drop_db: mysql --user=%USER% --password=%PASSWORD% -e "DROP DATABASE IF EXISTS %DB%;" @@ -48,13 +50,12 @@ commands: status: service rabbitmq-server status restart: service rabbitmq-server restart change_password: rabbitmqctl change_password guest - + redirect-outs: true components: db: action_classes: install: devstack.distros.oneiric:DBInstaller - start: devstack.components.db:DBRuntime - stop: devstack.components.db:DBRuntime + running: devstack.components.db:DBRuntime uninstall: devstack.components.db:DBUninstaller packages: - name: mysql-client-5.1 @@ -81,8 +82,7 @@ components: general: action_classes: install: devstack.components.pkglist:Installer - start: devstack.component:EmptyRuntime - stop: devstack.component:EmptyRuntime + running: devstack.component:EmptyRuntime uninstall: devstack.components.pkglist:Uninstaller packages: - name: curl @@ -166,8 +166,7 @@ components: glance: action_classes: install: devstack.components.glance:GlanceInstaller - start: devstack.components.glance:GlanceRuntime - stop: devstack.components.glance:GlanceRuntime + running: devstack.components.glance:GlanceRuntime uninstall: devstack.components.glance:GlanceUninstaller packages: - name: python-eventlet @@ -209,8 +208,7 @@ components: horizon: action_classes: install: devstack.components.horizon:HorizonInstaller - start: devstack.components.horizon:HorizonRuntime - stop: devstack.components.horizon:HorizonRuntime + running: devstack.components.horizon:HorizonRuntime uninstall: devstack.components.horizon:HorizonUninstaller packages: - name: apache2 @@ -283,8 +281,7 @@ components: keystone: action_classes: install: devstack.components.keystone:KeystoneInstaller - start: devstack.components.keystone:KeystoneRuntime - stop: devstack.components.keystone:KeystoneRuntime + running: devstack.components.keystone:KeystoneRuntime uninstall: devstack.components.keystone:KeystoneUninstaller packages: - name: libldap2-dev @@ -347,8 +344,7 @@ components: keystone-client: action_classes: install: devstack.components.keystone_client:KeyStoneClientInstaller - start: devstack.components.keystone_client:KeyStoneClientRuntime - stop: devstack.components.keystone_client:KeyStoneClientRuntime + running: devstack.components.keystone_client:KeyStoneClientRuntime uninstall: devstack.components.keystone_client:KeyStoneClientUninstaller packages: - name: python-argparse @@ -360,8 +356,7 @@ components: melange: action_classes: install: devstack.components.melange:MelangeInstaller - start: devstack.components.melange:MelangeRuntime - stop: devstack.components.melange:MelangeRuntime + running: devstack.components.melange:MelangeRuntime uninstall: devstack.components.melange:MelangeUninstaller packages: - name: python-eventlet @@ -391,8 +386,7 @@ components: no-vnc: action_classes: install: devstack.components.novnc:NoVNCInstaller - start: devstack.components.novnc:NoVNCRuntime - stop: devstack.components.novnc:NoVNCRuntime + running: devstack.components.novnc:NoVNCRuntime uninstall: devstack.components.novnc:NoVNCUninstaller packages: - name: python-numpy @@ -401,8 +395,7 @@ components: nova: action_classes: install: devstack.components.nova:NovaInstaller - start: devstack.components.nova:NovaRuntime - stop: devstack.components.nova:NovaRuntime + running: devstack.components.nova:NovaRuntime uninstall: devstack.components.nova:NovaUninstaller packages: - name: dnsmasq-base @@ -550,8 +543,7 @@ components: nova-client: action_classes: install: devstack.components.nova_client:NovaClientInstaller - start: devstack.components.nova_client:NovaClientRuntime - stop: devstack.components.nova_client:NovaClientRuntime + running: devstack.components.nova_client:NovaClientRuntime uninstall: devstack.components.nova_client:NovaClientUninstaller packages: - name: python-argparse @@ -563,8 +555,7 @@ components: quantum: action_classes: install: devstack.components.quantum:QuantumInstaller - start: devstack.components.quantum:QuantumRuntime - stop: devstack.components.quantum:QuantumRuntime + running: devstack.components.quantum:QuantumRuntime uninstall: devstack.components.quantum:QuantumUninstaller packages: - name: python-eventlet @@ -608,8 +599,7 @@ components: quantum-client: action_classes: install: devstack.components.quantum_client:QuantumClientInstaller - start: devstack.components.quantum_client:QuantumClientRuntime - stop: devstack.components.quantum_client:QuantumClientRuntime + running: devstack.components.quantum_client:QuantumClientRuntime uninstall: devstack.components.quantum_client:QuantumClientUninstaller packages: - name: python-gflags @@ -618,8 +608,7 @@ components: rabbit-mq: action_classes: install: devstack.components.rabbit:RabbitInstaller - start: devstack.components.rabbit:RabbitRuntime - stop: devstack.components.rabbit:RabbitRuntime + running: devstack.components.rabbit:RabbitRuntime uninstall: devstack.components.rabbit:RabbitUninstaller packages: - name: rabbitmq-server @@ -629,8 +618,7 @@ components: swift: action_classes: install: devstack.components.swift:SwiftInstaller - start: devstack.components.swift:SwiftRuntime - stop: devstack.components.swift:SwiftRuntime + running: devstack.components.swift:SwiftRuntime uninstall: devstack.components.swift:SwiftUninstaller packages: - name: memcached diff --git a/devstack/component.py b/devstack/component.py index d9bfd46b..98e8d17b 100644 --- a/devstack/component.py +++ b/devstack/component.py @@ -560,7 +560,7 @@ class ProgramRuntime(ComponentBase): self._get_param_map(app_name), ) # Configure it with the given settings - LOG.debug("Configuring runner for program %r", app_name) + LOG.debug("Configuring runner (%s) for program %r", cls, app_name) cfg_am = instance.configure(app_name, (app_pth, app_dir, program_opts)) LOG.debug("Configured %s files for runner for program %r", diff --git a/devstack/components/db.py b/devstack/components/db.py index 068028dc..ec7ee617 100644 --- a/devstack/components/db.py +++ b/devstack/components/db.py @@ -45,7 +45,11 @@ WARMUP_PWS = [('sql', PASSWORD_PROMPT)] class DBUninstaller(comp.PkgUninstallComponent): def __init__(self, *args, **kargs): comp.PkgUninstallComponent.__init__(self, *args, **kargs) - self.runtime = DBRuntime(*args, **kargs) + (runtime_cls, _) = self.distro.extract_component(self.component_name, 'running') + if not runtime_cls: + self.runtime = DBRuntime(*args, **kargs) + else: + self.runtime = runtime_cls(*args, **kargs) def warm_configs(self): for key, prompt in WARMUP_PWS: @@ -81,7 +85,11 @@ class DBInstaller(comp.PkgInstallComponent): def __init__(self, *args, **kargs): comp.PkgInstallComponent.__init__(self, *args, **kargs) - self.runtime = DBRuntime(*args, **kargs) + (runtime_cls, _) = self.distro.extract_component(self.component_name, 'running') + if not runtime_cls: + self.runtime = DBRuntime(*args, **kargs) + else: + self.runtime = runtime_cls(*args, **kargs) def _get_param_map(self, config_fn): # This dictionary will be used for parameter replacement @@ -233,9 +241,12 @@ def drop_db(cfg, pw_gen, distro, dbname): raise NotImplementedError(msg) -def create_db(cfg, pw_gen, distro, dbname): +def create_db(cfg, pw_gen, distro, dbname, utf8=False): dbtype = cfg.get("db", "type") - createcmd = distro.get_command(dbtype, 'create_db', silent=True) + if not utf8: + createcmd = distro.get_command(dbtype, 'create_db', silent=True) + else: + createcmd = distro.get_command(dbtype, 'create_db_utf8', silent=True) if createcmd: params = dict() params['PASSWORD'] = pw_gen.get_password("sql", PASSWORD_PROMPT) @@ -252,7 +263,7 @@ def create_db(cfg, pw_gen, distro, dbname): raise NotImplementedError(msg) -def fetch_dbdsn(config, pw_gen, dbname=''): +def fetch_dbdsn(config, pw_gen, dbname, utf8=False): """Return the database connection string, including password.""" user = config.get("db", "sql_user") host = config.get("db", "sql_host") @@ -267,19 +278,22 @@ def fetch_dbdsn(config, pw_gen, dbname=''): if not driver: msg = "Unable to fetch a database dsn - no db driver type found" raise excp.BadParamException(msg) - dsn = driver + "://" + dsn = str(driver) + "://" if user: - dsn += user + dsn += str(user) if pw: - dsn += ":" + pw + dsn += ":" + str(pw) if user or pw: dsn += "@" - dsn += host + dsn += str(host) if port: dsn += ":" + str(port) if dbname: - dsn += "/" + dbname + dsn += "/" + str(dbname) + if utf8: + # WHY U NOT SET EVERYWHERE... + dsn += "?charset=utf8" else: dsn += "/" - LOG.debug("For database [%s] fetched dsn [%s]" % (dbname, dsn)) + LOG.debug("For database %r fetched dsn %r" % (dbname, dsn)) return dsn diff --git a/devstack/components/glance.py b/devstack/components/glance.py index aaa31f33..82c773f3 100644 --- a/devstack/components/glance.py +++ b/devstack/components/glance.py @@ -106,7 +106,7 @@ class GlanceInstaller(GlanceMixin, comp.PythonInstallComponent): def _setup_db(self): LOG.info("Fixing up database named %r", DB_NAME) db.drop_db(self.cfg, self.pw_gen, self.distro, DB_NAME) - db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME) + db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME, utf8=True) def _get_source_config(self, config_fn): if config_fn == POLICY_JSON: @@ -176,7 +176,7 @@ class GlanceInstaller(GlanceMixin, comp.PythonInstallComponent): mp = comp.PythonInstallComponent._get_param_map(self, config_fn) mp['IMG_DIR'] = self._get_image_dir() mp['SYSLOG'] = self.cfg.getboolean("default", "syslog") - mp['SQL_CONN'] = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME) + mp['SQL_CONN'] = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME, utf8=True) mp['SERVICE_HOST'] = self.cfg.get('host', 'ip') mp['HOST_IP'] = self.cfg.get('host', 'ip') mp.update(keystone.get_shared_params(self.cfg, self.pw_gen, 'glance')) diff --git a/devstack/components/keystone.py b/devstack/components/keystone.py index 79d71975..2c03d7f4 100644 --- a/devstack/components/keystone.py +++ b/devstack/components/keystone.py @@ -123,7 +123,7 @@ class KeystoneInstaller(comp.PythonInstallComponent): def _setup_db(self): LOG.info("Fixing up database named %r", DB_NAME) db.drop_db(self.cfg, self.pw_gen, self.distro, DB_NAME) - db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME) + db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME, utf8=True) def _setup_initer(self): LOG.info("Configuring keystone initializer template %r", MANAGE_DATA_CONF) @@ -193,7 +193,7 @@ class KeystoneInstaller(comp.PythonInstallComponent): mp['BIN_DIR'] = self.bin_dir mp['CONFIG_FILE'] = sh.joinpths(self.cfg_dir, ROOT_CONF) if config_fn == ROOT_CONF: - mp['SQL_CONN'] = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME) + mp['SQL_CONN'] = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME, utf8=True) mp['KEYSTONE_DIR'] = self.app_dir mp.update(get_shared_params(self.cfg, self.pw_gen)) elif config_fn == MANAGE_DATA_CONF: diff --git a/devstack/components/melange.py b/devstack/components/melange.py index e6578bba..db76a35d 100644 --- a/devstack/components/melange.py +++ b/devstack/components/melange.py @@ -77,7 +77,7 @@ class MelangeInstaller(comp.PythonInstallComponent): def _setup_db(self): LOG.info("Fixing up database named %r", DB_NAME) db.drop_db(self.cfg, self.pw_gen, self.distro, DB_NAME) - db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME) + db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME, utf8=True) def post_install(self): comp.PythonInstallComponent.post_install(self) @@ -103,7 +103,7 @@ class MelangeInstaller(comp.PythonInstallComponent): with io.BytesIO(contents) as stream: config = cfg.IgnoreMissingConfigParser(cs=False) config.readfp(stream) - db_dsn = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME) + db_dsn = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME, utf8=True) old_dbsn = config.get('default', 'sql_connection') if db_dsn != old_dbsn: config.set('default', 'sql_connection', db_dsn) diff --git a/devstack/components/quantum.py b/devstack/components/quantum.py index 756fc3e0..5b054a3f 100644 --- a/devstack/components/quantum.py +++ b/devstack/components/quantum.py @@ -115,7 +115,7 @@ class QuantumInstaller(QuantumMixin, comp.PkgInstallComponent): config.readfp(stream) db_dsn = config.get("database", "sql_connection") if db_dsn: - generated_dsn = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME) + generated_dsn = db.fetch_dbdsn(self.cfg, self.pw_gen, DB_NAME, utf8=True) if generated_dsn != db_dsn: config.set("database", "sql_connection", generated_dsn) with io.BytesIO() as outputstream: @@ -155,7 +155,7 @@ class QuantumInstaller(QuantumMixin, comp.PkgInstallComponent): return LOG.info("Fixing up database named %r", DB_NAME) db.drop_db(self.cfg, self.pw_gen, self.distro, DB_NAME) - db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME) + db.create_db(self.cfg, self.pw_gen, self.distro, DB_NAME, utf8=True) def _get_source_config(self, config_fn): if config_fn == PLUGIN_CONF: diff --git a/devstack/components/rabbit.py b/devstack/components/rabbit.py index a7532d47..32b6e5e5 100644 --- a/devstack/components/rabbit.py +++ b/devstack/components/rabbit.py @@ -19,6 +19,7 @@ from tempfile import TemporaryFile from devstack import component as comp from devstack import log as logging from devstack import shell as sh +from devstack import utils LOG = logging.getLogger("devstack.components.rabbit") @@ -36,22 +37,31 @@ class RabbitUninstaller(comp.PkgUninstallComponent): def __init__(self, *args, **kargs): comp.PkgUninstallComponent.__init__(self, *args, **kargs) self.runtime = RabbitRuntime(*args, **kargs) + (runtime_cls, _) = self.distro.extract_component(self.component_name, 'running') + if not runtime_cls: + self.runtime = RabbitRuntime(*args, **kargs) + else: + self.runtime = runtime_cls(*args, **kargs) def pre_uninstall(self): try: self.runtime.restart() - LOG.info("Attempting to reset the rabbit-mq guest password to \"%s\"", RESET_BASE_PW) + LOG.info("Attempting to reset the rabbit-mq guest password to %r", RESET_BASE_PW) cmd = self.distro.get_command('rabbit-mq', 'change_password') + [RESET_BASE_PW] sh.execute(*cmd, run_as_root=True) except IOError: LOG.warn(("Could not reset the rabbit-mq password. You might have to manually " - "reset the password to \"%s\" before the next install") % (RESET_BASE_PW)) + "reset the password to %r before the next install") % (RESET_BASE_PW)) class RabbitInstaller(comp.PkgInstallComponent): def __init__(self, *args, **kargs): comp.PkgInstallComponent.__init__(self, *args, **kargs) - self.runtime = RabbitRuntime(*args, **kargs) + (runtime_cls, _) = self.distro.extract_component(self.component_name, 'running') + if not runtime_cls: + self.runtime = RabbitRuntime(*args, **kargs) + else: + self.runtime = runtime_cls(*args, **kargs) def warm_configs(self): for pw_key in WARMUP_PWS: @@ -75,6 +85,7 @@ class RabbitRuntime(comp.EmptyRuntime): def __init__(self, *args, **kargs): comp.EmptyRuntime.__init__(self, *args, **kargs) self.wait_time = max(self.cfg.getint('default', 'service_wait_seconds'), 1) + self.redir_out = utils.make_bool(self.distro.get_command_config('rabbit-mq', 'redirect-outs')) def start(self): if self.status() != comp.STATUS_STARTED: @@ -113,12 +124,14 @@ class RabbitRuntime(comp.EmptyRuntime): # See: https://bugs.launchpad.net/ubuntu/+source/rabbitmq-server/+bug/878600 # # RHEL seems to have this bug also... - # - # TODO: Move to distro dir... - with TemporaryFile() as f: + if self.redir_out: + with TemporaryFile() as f: + return sh.execute(*cmd, run_as_root=True, + stdout_fh=f, stderr_fh=f, + check_exit_code=check_exit) + else: return sh.execute(*cmd, run_as_root=True, - stdout_fh=f, stderr_fh=f, - check_exit_code=check_exit) + check_exit_code=check_exit) def restart(self): LOG.info("Restarting rabbit-mq.") diff --git a/devstack/distro.py b/devstack/distro.py index 46cdafd3..403c0e33 100644 --- a/devstack/distro.py +++ b/devstack/distro.py @@ -40,17 +40,17 @@ class Distro(object): input_files = glob.glob(sh.joinpths(path, '*.yaml')) if not input_files: raise RuntimeError( - 'Did not find any distro definition files in %s' % + 'Did not find any distro definition files in %r' % path) for fn in input_files: cls_kvs = None filename = sh.abspth(fn) - LOG.audit("Attempting to load distro definition from [%s]" % (filename)) + LOG.audit("Attempting to load distro definition from %r" % (filename)) try: with open(filename, 'r') as f: cls_kvs = yaml.load(f) except (IOError, yaml.YAMLError) as err: - LOG.warning('Could not load distro definition from %s: %s', + LOG.warning('Could not load distro definition from %r: %s', filename, err) if cls_kvs is not None: try: @@ -66,15 +66,15 @@ class Distro(object): plt = platform.platform() distname = platform.linux_distribution()[0] if not distname: - raise RuntimeError('Unsupported platform %s' % plt) - LOG.debug('Looking for distro data for %s (%s)', plt, distname) + raise RuntimeError('Unsupported linux (?) platform %r' % plt) + LOG.debug('Looking for distro data for %r (%s)', plt, distname) for p in cls.load_all(): if p.supports_distro(plt): - LOG.info('Using distro "%s" for platform "%s"', p.name, plt) + LOG.info('Using distro %r for platform %r', p.name, plt) return p else: raise RuntimeError( - 'No platform configuration data for %s (%s)' % + 'No platform configuration data for %r (%s)' % (plt, distname)) @decorators.log_debug diff --git a/devstack/distros/fedora16.py b/devstack/distros/fedora16.py index 050f81e1..f7382bf4 100644 --- a/devstack/distros/fedora16.py +++ b/devstack/distros/fedora16.py @@ -30,6 +30,10 @@ LOG = logging.getLogger(__name__) LIBVIRT_POLICY_FN = "/etc/polkit-1/localauthority/50-local.d/50-libvirt-access.pkla" +class RabbitRuntime(rhel6.RabbitRuntime): + pass + + class DBInstaller(rhel6.DBInstaller): pass diff --git a/devstack/distros/rhel6.py b/devstack/distros/rhel6.py index 4f1ce13c..63d06b5e 100644 --- a/devstack/distros/rhel6.py +++ b/devstack/distros/rhel6.py @@ -18,6 +18,8 @@ """Platform-specific logic for RedHat Enterprise Linux v6 components. """ +import re + from devstack import log as logging from devstack import shell as sh from devstack import utils @@ -25,6 +27,7 @@ from devstack import utils from devstack.components import db from devstack.components import horizon from devstack.components import nova +from devstack.components import rabbit from devstack.packaging import yum @@ -85,6 +88,36 @@ class HorizonInstaller(horizon.HorizonInstaller): sh.write_file(HTTPD_CONF, utils.joinlinesep(*new_lines)) +class RabbitRuntime(rabbit.RabbitRuntime): + + def _fix_log_dir(self): + # This seems needed... + # + # Due to the following: + # <<< Restarting rabbitmq-server: RabbitMQ is not running + # <<< sh: /var/log/rabbitmq/startup_log: Permission denied + # <<< FAILED - check /var/log/rabbitmq/startup_{log, _err} + # + # See: http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-March/011916.html + # This seems like a bug, since we are just using service init and service restart... + # And not trying to run this service directly... + base_dir = sh.joinpths("/", 'var', 'log', 'rabbitmq') + if sh.isdir(base_dir): + with sh.Rooted(True): + # Seems like we need root perms to list that directory... + for fn in sh.listdir(base_dir): + if re.match("(.*?)(err|log)$", fn, re.I): + sh.chmod(sh.joinpths(base_dir, fn), 0666) + + def start(self): + self._fix_log_dir() + return rabbit.RabbitRuntime.start(self) + + def restart(self): + self._fix_log_dir() + return rabbit.RabbitRuntime.restart(self) + + class NovaInstaller(nova.NovaInstaller): def _get_policy(self, ident_users): diff --git a/devstack/image/uploader.py b/devstack/image/uploader.py index e071cd18..6c1fab2d 100644 --- a/devstack/image/uploader.py +++ b/devstack/image/uploader.py @@ -31,11 +31,6 @@ from devstack.components import keystone LOG = log.getLogger("devstack.image.uploader") -# These are used when looking inside archives -KERNEL_FN_MATCH = re.compile(r"(.*)-vmlinuz$", re.I) -RAMDISK_FN_MATCH = re.compile(r"(.*)-initrd$", re.I) -IMAGE_FN_MATCH = re.compile(r"(.*)img$", re.I) - # Glance commands IMAGE_ADD = ['glance', 'add', '-A', '%TOKEN%', '--silent-upload', @@ -63,28 +58,39 @@ NAME_CLEANUPS.reverse() class Unpacker(object): - def __init__(self): - pass - - def _unpack_tar(self, file_name, file_location, tmp_dir): - (root_name, _) = os.path.splitext(file_name) + def _find_pieces(self, arc_fn): kernel_fn = None ramdisk_fn = None - root_img_fn = None - with contextlib.closing(tarfile.open(file_location, 'r')) as tfh: + img_fn = None + + def is_kernel(fn): + return re.match(r"(.*)-vmlinuz$", fn, re.I) or re.match(r'(.*?)aki-tty/image$', fn, re.I) + + def is_root(fn): + return re.match(r"(.*)img$", fn, re.I) or re.match(r'(.*?)ami-tty/image$', fn, re.I) + + def is_ramdisk(fn): + return re.match(r"(.*)-initrd$", fn, re.I) or re.match(r'(.*?)ari-tty/image$', fn, re.I) + + with contextlib.closing(tarfile.open(arc_fn, 'r')) as tfh: for tmemb in tfh.getmembers(): fn = tmemb.name - if KERNEL_FN_MATCH.match(fn): + if is_kernel(fn): kernel_fn = fn LOG.debug("Found kernel: %r" % (fn)) - elif RAMDISK_FN_MATCH.match(fn): + elif is_ramdisk(fn): ramdisk_fn = fn LOG.debug("Found ram disk: %r" % (fn)) - elif IMAGE_FN_MATCH.match(fn): - root_img_fn = fn + elif is_root(fn): + img_fn = fn LOG.debug("Found root image: %r" % (fn)) else: LOG.debug("Unknown member %r - skipping" % (fn)) + return (img_fn, ramdisk_fn, kernel_fn) + + def _unpack_tar(self, file_name, file_location, tmp_dir): + (root_name, _) = os.path.splitext(file_name) + (root_img_fn, ramdisk_fn, kernel_fn) = self._find_pieces(file_location) if not root_img_fn: msg = "Image %r has no root image member" % (file_name) raise RuntimeError(msg) diff --git a/devstack/progs/actions.py b/devstack/progs/actions.py index 27942a18..cf836a06 100644 --- a/devstack/progs/actions.py +++ b/devstack/progs/actions.py @@ -212,7 +212,7 @@ class InstallRunner(ActionRunner): class StartRunner(ActionRunner): - NAME = 'start' + NAME = 'running' PREREQ = InstallRunner def _instance_needs_prereq(self, instance): @@ -220,7 +220,7 @@ class StartRunner(ActionRunner): def _run(self, persona, root_dir, component_order, instances): self._run_phase( - 'Configuring runner for {name}', + None, lambda i: i.configure(), None, component_order, @@ -250,7 +250,7 @@ class StartRunner(ActionRunner): class StopRunner(ActionRunner): - NAME = 'stop' + NAME = 'running' def _instance_needs_prereq(self, instance): return False diff --git a/devstack/utils.py b/devstack/utils.py index 512d6c4f..e3daabb0 100644 --- a/devstack/utils.py +++ b/devstack/utils.py @@ -83,6 +83,17 @@ def construct_log_level(verbosity_level, dry_run=False): return log_level +def make_bool(val): + if not val: + return False + if type(val) is bool: + return val + sval = str(val).lower().strip() + if sval in ['true', '1', 'on', 'yes', 't']: + return True + return False + + def configure_logging(log_level, cli_args): root_logger = logging.getLogger().logger console_logger = logging.StreamHandler(sys.stdout)