Making good use of component options to get rid of all the weird cross component checks

This commit is contained in:
Joshua Harlow 2012-03-16 23:06:21 -07:00
parent 31c4d3301b
commit 8180624032
13 changed files with 95 additions and 108 deletions

View File

@ -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

View File

@ -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()

View File

@ -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:

View File

@ -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):

View File

@ -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")

View File

@ -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()

View File

@ -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))

View File

@ -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):

View File

@ -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)

View File

@ -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.
# under the License.

View File

@ -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:

View File

@ -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"

View File

@ -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: