Cleaned up how nova is configured.
This commit is contained in:
parent
b850a406c1
commit
05677956dd
@ -27,6 +27,12 @@ type = mysql
|
||||
|
||||
[nova]
|
||||
|
||||
# Should nova be in verbose mode?
|
||||
verbose = ${NOVA_VERBOSE:-1}
|
||||
|
||||
# Allow the admin api to be accessible?
|
||||
allow_admin_api = 1
|
||||
|
||||
# Nova original used project_id as the *account* that owned resources (servers,
|
||||
# ip address, ...) With the addition of Keystone we have standardized on the
|
||||
# term **tenant** as the entity that owns the resources. **novaclient** still
|
||||
@ -56,7 +62,7 @@ nova_url = ${NOVA_URL:-http://$HOST_IP:5000/v2.0/}
|
||||
# needs to match the config of your catalog returned by Keystone.
|
||||
nova_version = ${NOVA_VERSION:-1.1}
|
||||
|
||||
scheduler = ${NOVA_SCHEDULER:--nova.scheduler.simple.SimpleScheduler}
|
||||
scheduler = ${NOVA_SCHEDULER:-nova.scheduler.simple.SimpleScheduler}
|
||||
fixed_range = ${NOVA_FIXED_RANGE:-10.0.0.0/24}
|
||||
network_manager = ${NET_MAN:-FlatDHCPManager}
|
||||
volume_group = ${VOLUME_GROUP:-nova-volumes}
|
||||
|
@ -13,27 +13,34 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from devstack import component as comp
|
||||
from devstack import constants
|
||||
from devstack import constants as co
|
||||
from devstack import log as logging
|
||||
from devstack import shell as sh
|
||||
from devstack import utils
|
||||
from devstack.components import nova_conf as nc
|
||||
|
||||
LOG = logging.getLogger("devstack.components.nova")
|
||||
API_CONF = "nova.conf"
|
||||
CONFIGS = [API_CONF]
|
||||
DB_NAME = "nova"
|
||||
TYPE = constants.NOVA
|
||||
|
||||
#what to start
|
||||
# Does this start nova-compute, nova-volume, nova-network, nova-scheduler
|
||||
# and optionally nova-wsproxy?
|
||||
#APP_OPTIONS = {
|
||||
# 'glance-api': ['--config-file', joinpths('%ROOT%', "etc", API_CONF)],
|
||||
# 'glance-registry': ['--config-file', joinpths('%ROOT%', "etc", REG_CONF)]
|
||||
#}
|
||||
API_CONF = "nova.conf"
|
||||
PASTE_CONF = 'nova-api-paste.ini'
|
||||
CONFIGS = [API_CONF]
|
||||
|
||||
DB_NAME = "nova"
|
||||
BIN_DIR = 'bin'
|
||||
TYPE = co.NOVA
|
||||
QUANTUM_MANAGER = 'nova.network.quantum.manager.QuantumManager'
|
||||
NET_MAN_TEMPL = 'nova.network.manager.%s'
|
||||
IMG_SVC = 'nova.image.glance.GlanceImageService'
|
||||
|
||||
QUANTUM_OPENSWITCH_OPS = [
|
||||
{
|
||||
'libvirt_vif_type': ['ethernet'],
|
||||
'libvirt_vif_driver': ['nova.virt.libvirt.vif.LibvirtOpenVswitchDriver'],
|
||||
'linuxnet_interface_driver': ['nova.network.linux_net.LinuxOVSInterfaceDriver'],
|
||||
'quantum_use_dhcp': [],
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
class NovaUninstaller(comp.PythonUninstallComponent):
|
||||
@ -41,43 +48,184 @@ class NovaUninstaller(comp.PythonUninstallComponent):
|
||||
comp.PythonUninstallComponent.__init__(self, TYPE, *args, **kargs)
|
||||
#self.cfgdir = joinpths(self.appdir, CONFIG_ACTUAL_DIR)
|
||||
|
||||
class NovaConfigurator():
|
||||
def __init__(self, cfg, active_components):
|
||||
self.cfg = cfg
|
||||
self.active_components = active_components
|
||||
|
||||
def _getbool(self, name):
|
||||
return self.cfg.getboolean('nova', name)
|
||||
|
||||
def _getstr(self, name):
|
||||
return self.cfg.get('nova', name)
|
||||
|
||||
def configure(self, dirs):
|
||||
|
||||
#TODO split up into sections??
|
||||
|
||||
nova_conf = nc.NovaConf()
|
||||
hostip = utils.get_host_ip()
|
||||
|
||||
#verbose on?
|
||||
if(self._getbool('verbose')):
|
||||
nova_conf.add_simple('verbose')
|
||||
|
||||
#allow the admin api?
|
||||
if(self._getbool('allow_admin_api')):
|
||||
nova_conf.add_simple('allow_admin_api')
|
||||
|
||||
#which sheculder do u want
|
||||
nova_conf.add('scheduler_driver', self._getstr('scheduler'))
|
||||
|
||||
#???
|
||||
nova_conf.add('dhcpbridge_flagfile', utils.joinpths(dirs.get('bin'), API_CONF))
|
||||
|
||||
#whats the network fixed range?
|
||||
nova_conf.add('fixed_range', self._getstr('fixed_range'))
|
||||
|
||||
if(co.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'))
|
||||
nova_conf.add('quantum_connection_port', self.cfg.get('quantum', 'q_port'))
|
||||
# TODO
|
||||
#if ('q-svc' in self.othercomponents and
|
||||
# self.cfg.get('quantum', 'q_plugin') == 'openvswitch'):
|
||||
# self.lines.extend(QUANTUM_OPENSWITCH_OPS)
|
||||
else:
|
||||
nova_conf.add('network_manager', NET_MAN_TEMPL % (self._getstr('network_manager')))
|
||||
|
||||
# TODO
|
||||
# if ('n-vol' in self.othercomponents):
|
||||
# self._resolve('--volume_group=', 'nova', 'volume_group')
|
||||
# self._resolve('--volume_name_template=',
|
||||
# 'nova', 'volume_name_prefix', '%08x')
|
||||
# self._add('--iscsi_helper=tgtadm')
|
||||
|
||||
nova_conf.add('my_ip', hostip)
|
||||
|
||||
# The value for vlan_interface may default to the the current value
|
||||
# of public_interface. We'll grab the value and keep it handy.
|
||||
public_interface = self._getstr('public_interface')
|
||||
vlan_interface = self._getstr('vlan_interface')
|
||||
if(not vlan_interface):
|
||||
vlan_interface = public_interface
|
||||
nova_conf.add('public_interface', public_interface)
|
||||
nova_conf.add('vlan_interface', vlan_interface)
|
||||
|
||||
|
||||
nova_conf.add('sql_connection', self.cfg.get_dbdsn('nova'))
|
||||
nova_conf.add('libvirt_type', self._getstr('libvirt_type'))
|
||||
|
||||
instance_template = self._getstr('instance_name_prefix') + '%08x';
|
||||
nova_conf.add('instance_name_template', instance_template)
|
||||
|
||||
if(co.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')
|
||||
|
||||
# TODO
|
||||
# if ('n-vnc' in self.othercomponents):
|
||||
# vncproxy_url = self.cfg.get("nova", "vncproxy_url")
|
||||
# if (not vncproxy_url):
|
||||
# vncproxy_url = 'http://' + hostip + ':6080'
|
||||
# self._add('--vncproxy_url=' + vncproxy_url)
|
||||
# self._add('vncproxy_wwwroot=' + nova_dir + '/')
|
||||
#
|
||||
|
||||
# TODO is this right?
|
||||
nova_conf.add('api_paste_config', utils.joinpths(dirs.get('bin'), PASTE_CONF))
|
||||
|
||||
nova_conf.add('image_service', IMG_SVC)
|
||||
|
||||
ec2_dmz_host = self._getstr('ec2_dmz_host')
|
||||
if(not ec2_dmz_host):
|
||||
ec2_dmz_host = utils.get_host_ip()
|
||||
|
||||
nova_conf.add('ec2_dmz_host', ec2_dmz_host)
|
||||
|
||||
nova_conf.add('rabbit_host', self.cfg.get('default', 'rabbit_host'))
|
||||
nova_conf.add('rabbit_password', self.cfg.getpw("passwords", "rabbit"))
|
||||
|
||||
glance_svr = "%s:9292" % (hostip)
|
||||
nova_conf.add('glance_api_servers', glance_svr)
|
||||
|
||||
nova_conf.add_simple('force_dhcp_release')
|
||||
|
||||
instances_path = self._getstr('instances_path')
|
||||
if(instances_path):
|
||||
nova_conf.add('instances_path', instances_path)
|
||||
|
||||
if(self._getbool('multi_host')):
|
||||
nova_conf.add_simple('multi_host')
|
||||
nova_conf.add_simple('send_arp_for_ha')
|
||||
|
||||
if(self.cfg.getboolean('default', 'syslog')):
|
||||
nova_conf.add_simple('use_syslog')
|
||||
|
||||
virt_driver = self._getstr('virt_driver')
|
||||
self._configure_virt_driver(virt_driver, nova_conf)
|
||||
|
||||
#now make it
|
||||
complete_file = nova_conf.generate()
|
||||
|
||||
#add any extra flags in?
|
||||
extra_flags = self._getstr('extra_flags')
|
||||
if(extra_flags and len(extra_flags)):
|
||||
full_file = [complete_file, extra_flags]
|
||||
complete_file = utils.joinlinesep(*full_file)
|
||||
|
||||
return complete_file
|
||||
|
||||
#configures any virt driver settings
|
||||
def _configure_virt_driver(self, driver, nova_conf):
|
||||
if(not driver):
|
||||
return
|
||||
drive_canon = driver.lower().strip()
|
||||
if(drive_canon == 'xenserver'):
|
||||
nova_conf.add('connection_type', 'xenapi')
|
||||
nova_conf.add('xenapi_connection_url', 'http://169.254.0.1')
|
||||
nova_conf.add('xenapi_connection_username', 'root')
|
||||
# TODO, check that this is the right way to get the password
|
||||
nova_conf.add('xenapi_connection_password', self.cfg.getpw("passwords", "xenapi"))
|
||||
nova_conf.add_simple('noflat_injected')
|
||||
nova_conf.add('flat_interface', 'eth1')
|
||||
nova_conf.add('flat_network_bridge', 'xapi1')
|
||||
else:
|
||||
nova_conf.add('flat_network_bridge', self._getstr('flat_network_bridge'))
|
||||
nova_conf.add('flat_interface', self._getstr('flat_interface'))
|
||||
|
||||
|
||||
class NovaInstaller(comp.PythonInstallComponent):
|
||||
def __init__(self, *args, **kargs):
|
||||
comp.PythonInstallComponent.__init__(self, TYPE, *args, **kargs)
|
||||
self.gitloc = self.cfg.get("git", "nova_repo")
|
||||
self.brch = self.cfg.get("git", "nova_branch")
|
||||
# TBD is this the install location of the conf file?
|
||||
#self.cfgdir = joinpths(self.appdir, CONFIG_ACTUAL_DIR)
|
||||
self.git_repo = self.cfg.get("git", "nova_repo")
|
||||
self.git_branch = self.cfg.get("git", "nova_branch")
|
||||
self.bindir = utils.joinpths(self.appdir, BIN_DIR)
|
||||
|
||||
def _get_download_location(self):
|
||||
places = comp.PythonInstallComponent._get_download_locations(self)
|
||||
places.append({
|
||||
'uri': self.gitloc,
|
||||
'branch': self.brch,
|
||||
'uri': self.git_repo,
|
||||
'branch': self.git_branch,
|
||||
})
|
||||
return places
|
||||
|
||||
def configure(self):
|
||||
# FIXME, is this necessary? Is it for the template source?
|
||||
dirsmade = sh.mkdirslist(self.cfgdir)
|
||||
self.tracewriter.dir_made(*dirsmade)
|
||||
nconf = nc.NovaConf(self)
|
||||
LOG.info("Getting dynamic content for nova.conf")
|
||||
# Get dynamic content for nova.conf
|
||||
lines = nconf.generate()
|
||||
LOG.debug("Got conf lines, %s" % (lines))
|
||||
# Set up and write lines to the file
|
||||
fn = API_CONF
|
||||
tgtfn = self._get_full_config_name(fn)
|
||||
dirsmade = sh.mkdirslist(os.path.dirname(tgtfn))
|
||||
self.tracewriter.dir_made(*dirsmade)
|
||||
LOG.info("Writing configuration file %s" % (tgtfn))
|
||||
#this trace is used to remove the files configured
|
||||
sh.write_file(tgtfn, os.linesep.join(lines))
|
||||
self.tracewriter.cfg_write(tgtfn)
|
||||
|
||||
def _generate_nova_conf(self):
|
||||
LOG.debug("Generating dynamic content for nova.conf")
|
||||
dirs = dict()
|
||||
dirs['app'] = self.appdir
|
||||
dirs['cfg'] = self.cfgdir
|
||||
dirs['bin'] = self.bindir
|
||||
conf_gen = NovaConfigurator(self.cfg, self.all_components, dirs)
|
||||
nova_conf = conf_gen.configure(dirs)
|
||||
tgtfn = self._get_target_config_name(API_CONF)
|
||||
sh.write_file(tgtfn, nova_conf)
|
||||
return 1
|
||||
|
||||
def _configure_files(self):
|
||||
return self._generate_nova_conf()
|
||||
|
||||
|
||||
class NovaRuntime(comp.PythonRuntime):
|
||||
def __init__(self, *args, **kargs):
|
||||
|
@ -20,139 +20,44 @@ from devstack import utils
|
||||
|
||||
LOG = logging.getLogger("devstack.components.nova_conf")
|
||||
|
||||
QUANTUM_OPENSWITCH_OPS = [
|
||||
'--libvirt_vif_type=ethernet',
|
||||
'--libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtOpenVswitchDriver',
|
||||
'--linuxnet_interface_driver=nova.network.linux_net.LinuxOVSInterfaceDriver',
|
||||
'--quantum_use_dhcp']
|
||||
|
||||
OS_EXTENSIONS = [
|
||||
'--osapi_compute_extension='
|
||||
'nova.api.openstack.compute.contrib.standard_extensions',
|
||||
'--osapi_compute_extension=extensions.admin.Admin']
|
||||
class NovaConf():
|
||||
def __init__(self):
|
||||
self.lines = list()
|
||||
|
||||
MULTI_HOST_OPS = ['--multi_host', '--send_arp_for_ha']
|
||||
def add_list(self, key, *params):
|
||||
self.lines.append({'key': key, 'options': params})
|
||||
LOG.debug("Added nova conf key %s with values [%s]" % (key, ",".join(params)))
|
||||
|
||||
def add_simple(self, key):
|
||||
self.lines.append({'key': key, 'options': None})
|
||||
LOG.debug("Added nova conf key %s" % (key))
|
||||
|
||||
class NovaConf:
|
||||
# Our accumlator for lines that will go into nova.conf
|
||||
lines = []
|
||||
def add(self, key, value):
|
||||
self.lines.append({'key': key, 'options': [value]})
|
||||
LOG.debug("Added nova conf key %s with value [%s]" % (key, value))
|
||||
|
||||
# We should be passed the config object that holds all the values we need
|
||||
def __init__(self, nova_component):
|
||||
# Get handles to info from the main Nova component that we'll need
|
||||
self.nova_component = nova_component
|
||||
# This is a handy short cut to get to the Nova config data
|
||||
self.cfg = nova_component.cfg
|
||||
# This is a handy short cut to get to the Nova othercomponents data
|
||||
self.othercomponents = nova_component.othercomponents
|
||||
def _form_key(self, key, has_opts):
|
||||
key_str = "--" + str(key)
|
||||
if(has_opts):
|
||||
key_str += "="
|
||||
return key_str
|
||||
|
||||
# Add a line to the output that contains one value from the config
|
||||
def _resolve(self, prefix, section, variable, postfix=''):
|
||||
value = self.cfg.get(section, variable)
|
||||
self._add(prefix + value + postfix)
|
||||
|
||||
# Just a convience method to have the list appending in one place
|
||||
def _add(self, ldata):
|
||||
self.lines.append(ldata)
|
||||
|
||||
def generate(self):
|
||||
self.lines = []
|
||||
self._add('--verbose')
|
||||
self._add('--allow_admin_api')
|
||||
self._resolve('--scheduler_driver=', 'nova', 'scheduler')
|
||||
nova_dir = self.nova_component.appdir # FIXME, is this correct?
|
||||
self._add('--dhcpbridge_flagfile=' + nova_dir + '/bin/nova.conf')
|
||||
self._resolve('--fixed_range=', 'nova', 'fixed_range')
|
||||
|
||||
# Check if quantum is enabled, and if so, add all the necessary
|
||||
# config magic that goes with it
|
||||
if (QUANTUM in self.othercomponents):
|
||||
# Set network manager to multi lines
|
||||
self._add(
|
||||
'--network_manager=nova.network.quantum.manager.QuantumManager')
|
||||
self._add(
|
||||
'--network_manager=nova.network.quantum.manager.QuantumManager')
|
||||
self._resolve('--quantum_connection_host=', 'quantum', 'q_host')
|
||||
self._resolve('--quantum_connection_port=', 'quantum', 'q_port')
|
||||
if ('q-svc' in self.othercomponents and
|
||||
self.cfg.get('quantum', 'q_plugin') == 'openvswitch'):
|
||||
self.lines.extend(QUANTUM_OPENSWITCH_OPS)
|
||||
else:
|
||||
self._resolve('--network_manager=nova.network.manager.',
|
||||
'nova', 'network_manager')
|
||||
if ('n-vol' in self.othercomponents):
|
||||
self._resolve('--volume_group=', 'nova', 'volume_group')
|
||||
self._resolve('--volume_name_template=',
|
||||
'nova', 'volume_name_prefix', '%08x')
|
||||
self._add('--iscsi_helper=tgtadm')
|
||||
|
||||
hostip = get_host_ip(self.cfg)
|
||||
self._add('--my_ip=' + hostip)
|
||||
|
||||
# The value for vlan_interface may default to the the current value
|
||||
# of public_interface. We'll grab the value and keep it handy
|
||||
public_interface = self.cfg.get("nova", "public_interface")
|
||||
vlan_interface = self.cfg.get("nova", "vlan_interface")
|
||||
# If there's no vlan_interface value, use public_interface
|
||||
if (not vlan_interface):
|
||||
vlan_interface = public_interface
|
||||
self._add('--public_interface=' + public_interface)
|
||||
self._add('--vlan_interface=' + vlan_interface)
|
||||
self._add('--sql_connection=' + self.cfg.get_dbdsn('nova'))
|
||||
self._resolve('--libvirt_type=', 'nova', 'libvirt_type')
|
||||
self._resolve('--instance_name_template=',
|
||||
'nova', 'instance_name_prefix', '%08x')
|
||||
if ('openstackx' in self.othercomponents):
|
||||
self.lines.extend(OS_EXTENSIONS)
|
||||
|
||||
if ('n-vnc' in self.othercomponents):
|
||||
vncproxy_url = self.cfg.get("nova", "vncproxy_url")
|
||||
if (not vncproxy_url):
|
||||
vncproxy_url = 'http://' + hostip + ':6080'
|
||||
self._add('--vncproxy_url=' + vncproxy_url)
|
||||
self._add('vncproxy_wwwroot=' + nova_dir + '/')
|
||||
|
||||
self._add('--api_paste_config=' + nova_dir + '/bin/nova-api-paste.ini')
|
||||
self._add('--image_service=nova.image.glance.GlanceImageService')
|
||||
ec2_dmz_host = self.cfg.get("nova", "ec2_dmz_host")
|
||||
if (not ec2_dmz_host):
|
||||
ec2_dmz_host = hostip
|
||||
self._add('--ec2_dmz_host=' + ec2_dmz_host)
|
||||
self._resolve('--rabbit_host=', 'default', 'rabbit_host')
|
||||
self._add('--rabbit_password=' + self.cfg.getpw("passwords", "rabbit"))
|
||||
self._add('--glance_api_servers=' + hostip + ':9292')
|
||||
self._add('--force_dhcp_release')
|
||||
|
||||
instances_path = self.cfg.get("nova", "instances_path")
|
||||
if (instances_path):
|
||||
self._add('--instances_path=' + instances_path)
|
||||
|
||||
multi_host = self.cfg.getboolean("nova", "multi_host")
|
||||
if (multi_host == 1):
|
||||
self.lines.extend(MULTI_HOST_OPS)
|
||||
|
||||
if (self.cfg.getboolean("default", "syslog")):
|
||||
self._add('--use_syslog')
|
||||
|
||||
extra_flags = self.cfg.get("nova", "extra_flags")
|
||||
if (extra_flags):
|
||||
# FIXME, this is assuming that multiple flags are newline delimited
|
||||
self._add(extra_flags)
|
||||
|
||||
virt_driver = self.cfg.get("nova", "virt_driver")
|
||||
if (virt_driver == 'xenserver'):
|
||||
self._add('--connection_type=xenapi')
|
||||
self._add('--xenapi_connection_url=http://169.254.0.1')
|
||||
self._add('--xenapi_connection_username=root')
|
||||
# TBD, check that this is the right way to get the password
|
||||
self._add('--xenapi_connection_password=' +
|
||||
self.cfg.getpw("passwords", "xenapi"))
|
||||
self._add('--noflat_injected')
|
||||
self._add('--flat_interface=eth1')
|
||||
self._add('--flat_network_bridge=xapi1')
|
||||
else:
|
||||
self._resolve('--flat_network_bridge=',
|
||||
'nova', 'flat_network_bridge')
|
||||
self._resolve('--flat_interface=', 'nova', 'flat_interface')
|
||||
return self.lines
|
||||
def generate(self, param_dict=None):
|
||||
gen_lines = list()
|
||||
for line_entry in self.lines:
|
||||
key = line_entry.get('key')
|
||||
opts = line_entry.get('options')
|
||||
if(not key or len(key) == 0):
|
||||
continue
|
||||
if(opts == None):
|
||||
key_str = self._form_key(key, False)
|
||||
full_line = key_str
|
||||
else:
|
||||
key_str = self._form_key(key, len(opts))
|
||||
filled_opts = list()
|
||||
for opt in opts:
|
||||
filled_opts.append(utils.param_replace(str(opt), param_dict))
|
||||
full_line = key_str + ",".join(filled_opts)
|
||||
gen_lines.append(full_line)
|
||||
return utils.joinlinesep(*gen_lines)
|
||||
|
Loading…
x
Reference in New Issue
Block a user