diff --git a/conf/personas/devstack.sh.yaml b/conf/personas/devstack.sh.yaml index 76a7ef65..73065047 100644 --- a/conf/personas/devstack.sh.yaml +++ b/conf/personas/devstack.sh.yaml @@ -13,7 +13,11 @@ components: - nova-client - horizon description: Devstack.sh matching component installation. -options: null +options: + no-vnc: + nova: nova + nova: + - no-vnc subsystems: glance: - api diff --git a/devstack/component.py b/devstack/component.py index c48521dc..c226d668 100644 --- a/devstack/component.py +++ b/devstack/component.py @@ -60,6 +60,7 @@ class ComponentBase(object): runner, component_dir, all_instances, + options, name, *args, **kargs): @@ -68,6 +69,7 @@ class ComponentBase(object): self.instances = all_instances self.component_name = name self.subsystem_info = subsystem_info + self.options = options # The runner has a reference to us, so use a weakref here to # avoid breaking garbage collection. @@ -97,16 +99,22 @@ class ComponentBase(object): for s in self.subsystem_info.keys(): if s not in knowns: raise ValueError("Unknown subsystem %r provided" % (s)) + known_options = self.known_options() + for s in self.options: + if s not in known_options: + LOG.warning("Unknown option %r provided" % (s)) def known_subsystems(self): - return list() + return set() + + def known_options(self): + return set() def warm_configs(self): pass def is_started(self): - reader = tr.TraceReader(tr.trace_fn(self.trace_dir, tr.START_TRACE)) - return reader.exists() + return tr.TraceReader(tr.trace_fn(self.trace_dir, tr.START_TRACE)) def is_installed(self): return tr.TraceReader(tr.trace_fn(self.trace_dir, tr.IN_TRACE)).exists() diff --git a/devstack/components/glance.py b/devstack/components/glance.py index 539b64ba..01422874 100644 --- a/devstack/components/glance.py +++ b/devstack/components/glance.py @@ -187,7 +187,6 @@ class GlanceRuntime(comp.PythonRuntime): comp.PythonRuntime.__init__(self, *args, **kargs) self.cfg_dir = sh.joinpths(self.app_dir, CONFIG_DIR) self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR) - self.options = kargs.get('options', set()) def known_subsystems(self): return SUB_TO_APP.keys() @@ -204,6 +203,9 @@ class GlanceRuntime(comp.PythonRuntime): def _get_app_options(self, app): return APP_OPTIONS.get(app) + def known_options(self): + return set(['no-load-images']) + def post_start(self): comp.PythonRuntime.post_start(self) if 'no-load-images' in self.options: diff --git a/devstack/components/horizon.py b/devstack/components/horizon.py index 7c26f38c..117b078b 100644 --- a/devstack/components/horizon.py +++ b/devstack/components/horizon.py @@ -17,7 +17,6 @@ from devstack import component as comp 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 @@ -75,20 +74,28 @@ class HorizonInstaller(comp.PythonInstallComponent): }) return places + def known_options(self): + return set(['quantum-client']) + def verify(self): comp.PythonInstallComponent.verify(self) self._check_ug() def _get_symlinks(self): links = comp.PythonInstallComponent._get_symlinks(self) - src = self._get_target_config_name(HORIZON_APACHE_CONF) - links[src] = self.distro.get_command('apache', 'settings', 'conf-link-target') - if utils.service_enabled(settings.QUANTUM_CLIENT, self.instances, False): - # TODO remove this junk, blah, puke that we have to do this - qc = self.instances[settings.QUANTUM_CLIENT] - src_pth = sh.joinpths(qc.app_dir, 'quantum') - tgt_dir = sh.joinpths(self.dash_dir, 'quantum') - links[src_pth] = tgt_dir + link_tgt = self.distro.get_command('apache', 'settings', + 'conf-link-target', quiet=True) + if link_tgt: + src = self._get_target_config_name(HORIZON_APACHE_CONF) + links[src] = link_tgt + if 'quantum-client' in self.options: + q_name = self.options['quantum-client'] + if q_name in self.instances: + # TODO remove this junk, blah, puke that we have to do this + qc = self.instances[q_name] + src_pth = sh.joinpths(qc.app_dir, 'quantum') + tgt_dir = sh.joinpths(self.dash_dir, 'quantum') + links[src_pth] = tgt_dir return links def _check_ug(self): @@ -100,7 +107,9 @@ class HorizonInstaller(comp.PythonInstallComponent): msg = "No group named %s exists on this system!" % (group) raise excp.ConfigException(msg) if user in BAD_APACHE_USERS: - msg = "You may want to adjust your configuration, (user=%s, group=%s) will not work with apache!" % (user, group) + msg = ("You may want to adjust your configuration, " + "(user=%s, group=%s) will not work with apache!" + % (user, group)) raise excp.ConfigException(msg) def _get_target_config_name(self, config_name): diff --git a/devstack/components/keystone.py b/devstack/components/keystone.py index 945a1d8c..8c82e0b3 100644 --- a/devstack/components/keystone.py +++ b/devstack/components/keystone.py @@ -109,6 +109,9 @@ class KeystoneInstaller(comp.PythonInstallComponent): self._sync_db() self._setup_initer() + def known_options(self): + return set(['swift', 'quantum']) + def _sync_db(self): LOG.info("Syncing keystone to database named %s.", DB_NAME) params = dict() @@ -154,14 +157,13 @@ class KeystoneInstaller(comp.PythonInstallComponent): self.tracewriter.file_touched(sh.touch_file(log_filename)) elif name == CATALOG_CONF: nlines = list() - if utils.service_enabled(settings.SWIFT, self.instances): + if 'swift' in self.options: mp = dict() mp['SERVICE_HOST'] = self.cfg.get('host', 'ip') nlines.append("# Swift additions") nlines.extend(utils.param_replace_list(SWIFT_TEMPL_ADDS, mp)) nlines.append("") - if utils.service_enabled(settings.QUANTUM, self.instances) or \ - utils.service_enabled(settings.QUANTUM_CLIENT, self.instances): + if 'quantum' in self.options: mp = dict() mp['SERVICE_HOST'] = self.cfg.get('host', 'ip') nlines.append("# Quantum additions") diff --git a/devstack/components/melange.py b/devstack/components/melange.py index 06fc2010..82810bce 100644 --- a/devstack/components/melange.py +++ b/devstack/components/melange.py @@ -57,8 +57,7 @@ APP_OPTIONS = { 'melange-server': ['--config-file', '%CFG_FILE%'], } -# Special option that specifies we should make the network cidr using melange -CREATE_CIDR = "create-cidr" +# Wait time before we try to init melanges cidr (waiting for the server to start...) WAIT_ONLINE_TO = settings.WAIT_ALIVE_SECS @@ -156,11 +155,12 @@ class MelangeRuntime(comp.PythonRuntime): pmap['CFG_FILE'] = sh.joinpths(self.cfg_dir, ROOT_CONF_REAL_NAME) return pmap + def known_options(self): + return set(["create-cidr"]) + def post_start(self): comp.PythonRuntime.post_start(self) - # FIXME: This is a bit of a hack. How do we document "flags" like this? - flags = [] - if CREATE_CIDR in flags: + if "create-cidr" in self.options: LOG.info("Waiting %s seconds so that the melange server can start up before cidr range creation." % (WAIT_ONLINE_TO)) sh.sleep(WAIT_ONLINE_TO) mp = dict() diff --git a/devstack/components/nova.py b/devstack/components/nova.py index 28efefe9..9f3e9b80 100644 --- a/devstack/components/nova.py +++ b/devstack/components/nova.py @@ -272,6 +272,9 @@ class NovaInstaller(comp.PythonInstallComponent): if NXVNC in self.desired_subsystems: self.xvnc_enabled = True + def known_options(self): + return set(['no-vnc', 'quantum', 'melange']) + def known_subsystems(self): return SUBSYSTEMS @@ -408,7 +411,7 @@ class NovaRuntime(comp.PythonRuntime): # If still there, run it # these environment additions are important # in that they eventually affect how this script runs - if utils.service_enabled(settings.QUANTUM, self.instances, False): + if 'quantum' in self.options: LOG.info("Waiting %s seconds so that quantum can start up before running first time init." % (WAIT_ONLINE_TO)) sh.sleep(WAIT_ONLINE_TO) env = dict() @@ -422,6 +425,9 @@ class NovaRuntime(comp.PythonRuntime): def post_start(self): self._setup_network_init() + def known_options(self): + return set(['quantum']) + def known_subsystems(self): return SUBSYSTEMS @@ -545,7 +551,8 @@ class NovaConfConfigurator(object): self.cfg_dir = ni.cfg_dir self.xvnc_enabled = ni.xvnc_enabled self.volumes_enabled = ni.volumes_enabled - self.novnc_enabled = utils.service_enabled(settings.NOVNC, self.instances) + self.options = ni.options + self.novnc_enabled = 'no-vnc' in self.options def _getbool(self, name): return self.cfg.getboolean('nova', name) @@ -737,7 +744,7 @@ class NovaConfConfigurator(object): def _configure_network_settings(self, nova_conf): # TODO this might not be right.... - if utils.service_enabled(settings.QUANTUM, self.instances, False): + if 'quantum' in self.options: nova_conf.add('network_manager', QUANTUM_MANAGER) hostip = self.cfg.get('host', 'ip') nova_conf.add('quantum_connection_host', self.cfg.getdefaulted('quantum', 'q_host', hostip)) @@ -745,7 +752,7 @@ class NovaConfConfigurator(object): if self.cfg.get('quantum', 'q_plugin') == 'openvswitch': for (key, value) in QUANTUM_OPENSWITCH_OPS.items(): nova_conf.add(key, value) - if utils.service_enabled(settings.MELANGE_CLIENT, self.instances, False): + if 'melange' in self.options: nova_conf.add('quantum_ipam_lib', QUANTUM_IPAM_LIB) nova_conf.add('use_melange_mac_generation', True) nova_conf.add('melange_host', self.cfg.getdefaulted('melange', 'm_host', hostip)) diff --git a/devstack/components/novnc.py b/devstack/components/novnc.py index d938f97b..977d77be 100644 --- a/devstack/components/novnc.py +++ b/devstack/components/novnc.py @@ -16,9 +16,7 @@ from devstack import component as comp from devstack import log as logging -from devstack import settings from devstack import shell as sh -from devstack import utils from devstack.components import nova @@ -69,12 +67,17 @@ class NoVNCRuntime(comp.ProgramRuntime): }) return apps + def known_options(self): + return set(['nova']) + def _get_param_map(self, app_name): root_params = comp.ProgramRuntime._get_param_map(self, app_name) - if app_name == VNC_PROXY_APP and utils.service_enabled(settings.NOVA, self.instances, False): - # FIXME: Have to reach into the nova conf (puke) - nova_runtime = self.instances[settings.NOVA] - root_params['NOVA_CONF'] = sh.joinpths(nova_runtime.cfg_dir, nova.API_CONF) + if app_name == VNC_PROXY_APP and 'nova' in self.options: + nova_name = self.options['nova'] + if nova_name in self.instances: + # FIXME: Have to reach into the nova conf (puke) + nova_runtime = self.instances[nova_name] + root_params['NOVA_CONF'] = sh.joinpths(nova_runtime.cfg_dir, nova.API_CONF) return root_params def _get_app_options(self, app): diff --git a/devstack/components/quantum.py b/devstack/components/quantum.py index 95c8fa58..5751e82e 100644 --- a/devstack/components/quantum.py +++ b/devstack/components/quantum.py @@ -19,7 +19,6 @@ import io from devstack import cfg from devstack import component as comp from devstack import log as logging -from devstack import settings from devstack import shell as sh from devstack import utils @@ -85,6 +84,9 @@ class QuantumInstaller(comp.PkgInstallComponent): }) return places + def known_options(self): + return set(['no-ovs-db-init', 'no-ovs-bridge-init']) + def _get_config_files(self): return list(CONFIG_FILES) @@ -133,30 +135,32 @@ class QuantumInstaller(comp.PkgInstallComponent): return comp.PkgInstallComponent._config_adjust(self, contents, config_fn) def _setup_bridge(self): + if not self.q_vswitch_agent or \ + 'no-ovs-bridge-init' in self.options: + return bridge = self.cfg.getdefaulted("quantum", "ovs_bridge", 'br-int') - if bridge: - LOG.info("Fixing up ovs bridge named %s.", bridge) - external_id = self.cfg.getdefaulted("quantum", 'ovs_bridge_external_name', bridge) - params = dict() - params['OVS_BRIDGE'] = bridge - params['OVS_EXTERNAL_ID'] = external_id - cmds = list() - for cmd_templ in OVS_BRIDGE_CMDS: - cmds.append({ - 'cmd': cmd_templ, - 'run_as_root': True, - }) - if cmds: - utils.execute_template(*cmds, params=params) + LOG.info("Fixing up ovs bridge named %s.", bridge) + external_id = self.cfg.getdefaulted("quantum", 'ovs_bridge_external_name', bridge) + params = dict() + params['OVS_BRIDGE'] = bridge + params['OVS_EXTERNAL_ID'] = external_id + cmds = list() + for cmd_templ in OVS_BRIDGE_CMDS: + cmds.append({ + 'cmd': cmd_templ, + 'run_as_root': True, + }) + utils.execute_template(*cmds, params=params) def post_install(self): comp.PkgInstallComponent.post_install(self) - if self.q_vswitch_service and utils.service_enabled(settings.DB, self.instances, False): - self._setup_db() - if self.q_vswitch_agent: - self._setup_bridge() + self._setup_db() + self._setup_bridge() def _setup_db(self): + if not self.q_vswitch_service or \ + 'no-ovs-db-init' in self.options: + return LOG.info("Fixing up database named %s.", 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) diff --git a/devstack/distros/__init__.py b/devstack/distros/__init__.py index e80f4375..7bcdb0a5 100644 --- a/devstack/distros/__init__.py +++ b/devstack/distros/__init__.py @@ -13,4 +13,4 @@ # 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. \ No newline at end of file +# under the License. diff --git a/devstack/progs/actions.py b/devstack/progs/actions.py index 1bf6d543..95ce48ee 100644 --- a/devstack/progs/actions.py +++ b/devstack/progs/actions.py @@ -163,12 +163,12 @@ class ActionRunner(object): cls_kvs = dict() cls_kvs['runner'] = self cls_kvs['component_dir'] = sh.joinpths(root_dir, c) - cls_kvs['subsystem_info'] = my_info.pop('subsystems', dict()) + cls_kvs['subsystem_info'] = my_info.pop('subsystems') or dict() cls_kvs['all_instances'] = instances cls_kvs['name'] = c cls_kvs['keep_old'] = self.keep_old - cls_kvs['desired_subsystems'] = set(desired_subsystems.get(c, list())) - cls_kvs['options'] = set(component_opts.get(c, list())) + cls_kvs['desired_subsystems'] = set(desired_subsystems.get(c) or list()) + cls_kvs['options'] = component_opts.get(c) or dict() # The above is not overrideable... for (k, v) in my_info.items(): if k not in cls_kvs: diff --git a/devstack/settings.py b/devstack/settings.py index a7f7b16d..5f0c709f 100644 --- a/devstack/settings.py +++ b/devstack/settings.py @@ -27,36 +27,6 @@ IPV6 = 'IPv6' # How long to wait for a service to startup WAIT_ALIVE_SECS = 5 -# Component names -# FIXME: move?? remove?? -NOVA = "nova" -NOVA_CLIENT = 'nova-client' -GLANCE = "glance" -QUANTUM = "quantum-server" -QUANTUM_CLIENT = 'quantum-client' -SWIFT = "swift" -HORIZON = "horizon" -KEYSTONE = "keystone" -KEYSTONE_CLIENT = 'keystone-client' -DB = "db" -RABBIT = "rabbit" -NOVNC = 'no-vnc' -XVNC = 'xvnc' -MELANGE = 'melange' -MELANGE_CLIENT = 'melange-client' -COMPONENT_NAMES = [ - NOVA, NOVA_CLIENT, - GLANCE, - QUANTUM, QUANTUM_CLIENT, - SWIFT, - HORIZON, - KEYSTONE, KEYSTONE_CLIENT, - DB, - RABBIT, - NOVNC, - MELANGE, MELANGE_CLIENT, -] - # Different run types supported RUN_TYPE_FORK = "FORK" RUN_TYPE_UPSTART = "UPSTART" diff --git a/devstack/utils.py b/devstack/utils.py index 15b5a3f8..931facc8 100644 --- a/devstack/utils.py +++ b/devstack/utils.py @@ -150,18 +150,6 @@ def import_module(module_name, quiet=True): raise -def load_json(fn): - data = sh.load_file(fn) - lines = data.splitlines() - new_lines = list() - for line in lines: - if line.lstrip().startswith('#'): - continue - new_lines.append(line) - data = joinlinesep(*new_lines) - return json.loads(data) - - def versionize(input_version): segments = input_version.split(".") cleaned_segments = list() @@ -272,16 +260,6 @@ def joinlinesep(*pieces): return os.linesep.join(pieces) -def service_enabled(name, components, empty_true=True): - if not components and empty_true: - return True - if not components: - return False - if name in components: - return True - return False - - def param_replace_list(values, replacements, ignore_missing=False): new_values = list() if not values: