2012-01-11 12:47:33 -08:00
|
|
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
|
2012-01-26 12:54:36 -08:00
|
|
|
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
|
2012-01-11 12:47:33 -08:00
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
|
|
# not use this file except in compliance with the License. You may obtain
|
|
|
|
# a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# 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.
|
|
|
|
|
2012-02-14 10:27:07 -08:00
|
|
|
from urlparse import urlunparse
|
2012-01-27 17:37:16 -08:00
|
|
|
import io
|
2012-01-31 16:05:00 -08:00
|
|
|
import os
|
2012-01-27 17:37:16 -08:00
|
|
|
|
|
|
|
from devstack import cfg
|
2012-01-20 14:12:20 -08:00
|
|
|
from devstack import component as comp
|
2012-01-27 17:37:16 -08:00
|
|
|
from devstack import exceptions
|
2012-02-07 20:56:50 -08:00
|
|
|
from devstack import libvirt as virsh
|
2012-01-20 14:12:20 -08:00
|
|
|
from devstack import log as logging
|
2012-01-22 16:09:47 -08:00
|
|
|
from devstack import settings
|
2012-01-20 14:12:20 -08:00
|
|
|
from devstack import shell as sh
|
2012-01-27 17:37:16 -08:00
|
|
|
from devstack import utils
|
2012-01-28 21:05:54 -08:00
|
|
|
|
2012-01-23 14:45:09 -08:00
|
|
|
from devstack.components import db
|
2012-01-27 14:51:18 -08:00
|
|
|
from devstack.components import keystone
|
2012-01-20 14:12:20 -08:00
|
|
|
|
2012-02-06 21:12:00 -08:00
|
|
|
|
|
|
|
#id
|
|
|
|
TYPE = settings.NOVA
|
2012-01-24 12:53:52 -08:00
|
|
|
LOG = logging.getLogger('devstack.components.nova')
|
2012-01-20 17:00:23 -08:00
|
|
|
|
2012-01-27 17:37:16 -08:00
|
|
|
#special generatedconf
|
2012-01-24 12:53:52 -08:00
|
|
|
API_CONF = 'nova.conf'
|
2012-01-27 17:37:16 -08:00
|
|
|
|
|
|
|
#normal conf
|
2012-01-24 18:10:38 -08:00
|
|
|
PASTE_CONF = 'nova-api-paste.ini'
|
2012-01-27 17:37:16 -08:00
|
|
|
CONFIGS = [PASTE_CONF]
|
2012-01-24 18:10:38 -08:00
|
|
|
|
|
|
|
#this db will be dropped then created
|
2012-01-24 12:53:52 -08:00
|
|
|
DB_NAME = 'nova'
|
2012-01-24 18:10:38 -08:00
|
|
|
|
2012-02-06 21:12:00 -08:00
|
|
|
#this makes the database be in sync with nova
|
2012-01-27 23:14:16 -08:00
|
|
|
DB_SYNC_CMD = [
|
2012-01-25 13:52:23 -08:00
|
|
|
{'cmd': ['%BINDIR%/nova-manage', '--flagfile', '%CFGFILE%',
|
2012-01-24 12:53:52 -08:00
|
|
|
'db', 'sync']},
|
2012-01-27 23:14:16 -08:00
|
|
|
]
|
|
|
|
|
2012-02-06 21:12:00 -08:00
|
|
|
#these setup your dev network
|
2012-01-27 23:14:16 -08:00
|
|
|
NETWORK_SETUP_CMDS = [
|
2012-02-01 16:27:49 -08:00
|
|
|
#this always happens (even in quantum mode)
|
2012-01-27 23:14:16 -08:00
|
|
|
{'cmd': ['%BINDIR%/nova-manage', '--flagfile', '%CFGFILE%',
|
2012-02-01 16:27:49 -08:00
|
|
|
'network', 'create', 'private', '%FIXED_RANGE%', 1, '%FIXED_NETWORK_SIZE%']},
|
|
|
|
#these only happen if not in quantum mode
|
2012-01-25 13:52:23 -08:00
|
|
|
{'cmd': ['%BINDIR%/nova-manage', '--flagfile', '%CFGFILE%',
|
2012-01-24 12:53:52 -08:00
|
|
|
'floating', 'create', '%FLOATING_RANGE%']},
|
2012-01-25 13:52:23 -08:00
|
|
|
{'cmd': ['%BINDIR%/nova-manage', '--flagfile', '%CFGFILE%',
|
2012-01-24 12:53:52 -08:00
|
|
|
'floating', 'create', '--ip_range=%TEST_FLOATING_RANGE%',
|
|
|
|
'--pool=%TEST_FLOATING_POOL%']}
|
2012-01-24 10:16:51 -08:00
|
|
|
]
|
|
|
|
|
2012-02-06 21:12:00 -08:00
|
|
|
#these are used for nova volumens
|
2012-01-25 16:16:09 -08:00
|
|
|
VG_CHECK_CMD = [
|
2012-01-26 12:43:51 -08:00
|
|
|
{'cmd': ['vgs', '%VOLUME_GROUP%'],
|
|
|
|
'run_as_root': True}
|
|
|
|
]
|
|
|
|
VG_DEV_CMD = [
|
|
|
|
{'cmd': ['losetup', '-f', '--show', '%VOLUME_BACKING_FILE%'],
|
|
|
|
'run_as_root': True}
|
|
|
|
]
|
|
|
|
VG_CREATE_CMD = [
|
|
|
|
{'cmd': ['vgcreate', '%VOLUME_GROUP%', '%DEV%'],
|
|
|
|
'run_as_root': True}
|
|
|
|
]
|
2012-01-26 15:13:45 -08:00
|
|
|
VG_LVS_CMD = [
|
|
|
|
{'cmd': ['lvs', '--noheadings', '-o', 'lv_name', '%VOLUME_GROUP%'],
|
|
|
|
'run_as_root': True}
|
|
|
|
]
|
|
|
|
VG_LVREMOVE_CMD = [
|
|
|
|
{'cmd': ['lvremove', '-f', '%VOLUME_GROUP%/%LV%'],
|
|
|
|
'run_as_root': True}
|
|
|
|
]
|
2012-01-26 12:43:51 -08:00
|
|
|
RESTART_TGT_CMD = [
|
|
|
|
{'cmd': ['stop', 'tgt'], 'run_as_root': True},
|
|
|
|
{'cmd': ['start', 'tgt'], 'run_as_root': True}
|
2012-01-25 16:16:09 -08:00
|
|
|
]
|
|
|
|
|
2012-01-27 23:14:16 -08:00
|
|
|
# NCPU, NVOL, NAPI ... are here as possible subcomponents of nova
|
2012-01-27 11:08:49 -08:00
|
|
|
NCPU = "cpu"
|
|
|
|
NVOL = "vol"
|
|
|
|
NAPI = "api"
|
2012-01-27 18:07:07 -08:00
|
|
|
NOBJ = "obj"
|
|
|
|
NNET = "net"
|
|
|
|
NCERT = "cert"
|
|
|
|
NSCHED = "sched"
|
|
|
|
NCAUTH = "cauth"
|
2012-02-06 13:09:37 -08:00
|
|
|
NXVNC = "xvnc"
|
2012-01-27 18:07:07 -08:00
|
|
|
SUBCOMPONENTS = [NCPU, NVOL, NAPI,
|
2012-02-06 13:09:37 -08:00
|
|
|
NOBJ, NNET, NCERT, NSCHED, NCAUTH, NXVNC]
|
2012-01-27 11:08:49 -08:00
|
|
|
|
2012-01-28 21:05:54 -08:00
|
|
|
#the pkg json files nova requires for installation
|
|
|
|
REQ_PKGS = ['general.json', 'nova.json']
|
|
|
|
|
2012-01-27 11:08:49 -08:00
|
|
|
# Additional packages for subcomponents
|
|
|
|
ADD_PKGS = {
|
|
|
|
NAPI:
|
|
|
|
[
|
2012-01-28 21:05:54 -08:00
|
|
|
'n-api.json',
|
2012-01-27 11:08:49 -08:00
|
|
|
],
|
|
|
|
NCPU:
|
|
|
|
[
|
2012-01-28 21:05:54 -08:00
|
|
|
'n-cpu.json',
|
2012-01-27 11:08:49 -08:00
|
|
|
],
|
|
|
|
NVOL:
|
|
|
|
[
|
2012-01-28 21:05:54 -08:00
|
|
|
'n-vol.json',
|
2012-01-27 11:08:49 -08:00
|
|
|
],
|
|
|
|
}
|
|
|
|
|
2012-01-27 17:37:16 -08:00
|
|
|
# Adjustments to nova paste pipeline for keystone
|
|
|
|
PASTE_PIPELINE_KEYSTONE_ADJUST = {
|
2012-02-02 18:09:13 -08:00
|
|
|
'pipeline:ec2cloud': {'pipeline': 'ec2faultwrap logrequest totoken authtoken keystonecontext cloudrequest authorizer ec2executor'},
|
|
|
|
'pipeline:ec2admin': {'pipeline': "ec2faultwrap logrequest totoken authtoken keystonecontext adminrequest authorizer ec2executor"},
|
|
|
|
'pipeline:openstack_compute_api_v2': {'pipeline': "faultwrap authtoken keystonecontext ratelimit osapi_compute_app_v2"},
|
|
|
|
'pipeline:openstack_volume_api_v1': {'pipeline': "faultwrap authtoken keystonecontext ratelimit osapi_volume_app_v1"},
|
|
|
|
'pipeline:openstack_api_v2': {'pipeline': 'faultwrap authtoken keystonecontext ratelimit osapi_app_v2'},
|
2012-01-27 17:37:16 -08:00
|
|
|
}
|
|
|
|
|
2012-01-27 11:08:49 -08:00
|
|
|
# What to start
|
|
|
|
APP_OPTIONS = {
|
2012-01-27 17:37:16 -08:00
|
|
|
#these are currently the core components/applications
|
|
|
|
'nova-api': ['--flagfile', '%CFGFILE%'],
|
|
|
|
'nova-compute': ['--flagfile', '%CFGFILE%'],
|
|
|
|
'nova-volume': ['--flagfile', '%CFGFILE%'],
|
2012-01-27 11:08:49 -08:00
|
|
|
'nova-network': ['--flagfile', '%CFGFILE%'],
|
2012-01-27 17:37:16 -08:00
|
|
|
'nova-scheduler': ['--flagfile', '%CFGFILE%'],
|
|
|
|
'nova-cert': ['--flagfile', '%CFGFILE%'],
|
|
|
|
'nova-objectstore': ['--flagfile', '%CFGFILE%'],
|
2012-01-27 18:08:38 -08:00
|
|
|
'nova-consoleauth': [],
|
2012-02-06 13:09:37 -08:00
|
|
|
'nova-xvpvncproxy': ['--flagfile', '%CFGFILE%'],
|
2012-01-23 14:45:09 -08:00
|
|
|
}
|
2012-01-24 18:10:38 -08:00
|
|
|
|
2012-01-27 18:07:07 -08:00
|
|
|
# Sub component names to actual app names (matching previous dict)
|
|
|
|
SUB_COMPONENT_NAME_MAP = {
|
|
|
|
NCPU: 'nova-compute',
|
|
|
|
NVOL: 'nova-volume',
|
|
|
|
NAPI: 'nova-api',
|
|
|
|
NOBJ: 'nova-objectstore',
|
|
|
|
NNET: 'nova-network',
|
|
|
|
NCERT: 'nova-cert',
|
|
|
|
NSCHED: 'nova-scheduler',
|
|
|
|
NCAUTH: 'nova-consoleauth',
|
2012-02-06 13:50:10 -08:00
|
|
|
NXVNC: 'nova-xvpvncproxy',
|
2012-01-27 18:07:07 -08:00
|
|
|
}
|
|
|
|
|
2012-01-24 18:10:38 -08:00
|
|
|
#subdirs of the checkout/download
|
2012-01-23 14:45:09 -08:00
|
|
|
BIN_DIR = 'bin'
|
2012-02-09 16:58:00 -08:00
|
|
|
CONFIG_DIR = "etc"
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
#These are used by NovaConf
|
|
|
|
QUANTUM_MANAGER = 'nova.network.quantum.manager.QuantumManager'
|
|
|
|
NET_MANAGER_TEMPLATE = 'nova.network.manager.%s'
|
|
|
|
DEF_IMAGE_SERVICE = 'nova.image.glance.GlanceImageService'
|
|
|
|
DEF_SCHEDULER = 'nova.scheduler.simple.SimpleScheduler'
|
|
|
|
DEF_GLANCE_PORT = 9292
|
|
|
|
|
2012-01-26 18:24:35 -08:00
|
|
|
#only turned on if vswitch enabled
|
|
|
|
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': None,
|
|
|
|
}
|
2012-01-23 14:45:09 -08:00
|
|
|
|
2012-02-07 20:56:50 -08:00
|
|
|
#this is a special conf
|
2012-02-13 18:07:57 -08:00
|
|
|
CLEANER_DATA_CONF = 'nova-clean.sh'
|
2012-02-07 20:56:50 -08:00
|
|
|
CLEANER_CMD_ROOT = [sh.joinpths("/", "bin", 'bash')]
|
|
|
|
|
2012-02-14 10:27:07 -08:00
|
|
|
#xenserver specific
|
|
|
|
XS_DEF_INTERFACE = 'eth1'
|
2012-02-14 10:43:40 -08:00
|
|
|
XA_CONNECTION_ADDR = '169.254.0.1'
|
2012-02-15 10:18:58 -08:00
|
|
|
XS_VNC_ADDR = XA_CONNECTION_ADDR
|
2012-02-14 10:27:07 -08:00
|
|
|
XA_CONNECTION_PORT = 80
|
2012-02-14 11:01:43 -08:00
|
|
|
XA_DEF_USER = 'root'
|
2012-02-14 10:27:07 -08:00
|
|
|
|
2012-02-15 10:18:58 -08:00
|
|
|
#vnc specific
|
|
|
|
VNC_DEF_ADDR = '127.0.0.1'
|
|
|
|
|
2012-02-15 10:35:13 -08:00
|
|
|
#def virt driver
|
|
|
|
DEF_VIRT_DRIVER = virsh.VIRT_TYPE
|
|
|
|
|
2012-02-15 16:16:25 -08:00
|
|
|
#def firewall driver
|
|
|
|
DEF_FIREWALL_DRIVER = 'nova.virt.firewall.IptablesFirewallDriver'
|
|
|
|
|
|
|
|
#default instance template
|
|
|
|
DEF_INSTANCE_TEMPL = 'instance-%08x'
|
|
|
|
|
2012-01-31 17:26:26 -08:00
|
|
|
#pip files that nova requires
|
2012-02-03 17:23:54 -08:00
|
|
|
REQ_PIPS = ['general.json', 'nova.json']
|
2012-01-31 17:26:26 -08:00
|
|
|
|
2012-01-11 12:47:33 -08:00
|
|
|
|
2012-02-15 10:37:00 -08:00
|
|
|
def _canon_virt_driver(virt_driver):
|
2012-02-15 10:35:13 -08:00
|
|
|
if not virt_driver:
|
|
|
|
return DEF_VIRT_DRIVER
|
|
|
|
return virt_driver.strip().lower()
|
|
|
|
|
|
|
|
|
2012-01-20 14:12:20 -08:00
|
|
|
class NovaUninstaller(comp.PythonUninstallComponent):
|
2012-01-11 12:47:33 -08:00
|
|
|
def __init__(self, *args, **kargs):
|
2012-01-20 14:12:20 -08:00
|
|
|
comp.PythonUninstallComponent.__init__(self, TYPE, *args, **kargs)
|
2012-02-07 20:56:50 -08:00
|
|
|
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
2012-02-10 12:59:06 -08:00
|
|
|
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
2012-01-11 12:47:33 -08:00
|
|
|
|
2012-02-07 16:46:36 -08:00
|
|
|
def pre_uninstall(self):
|
2012-02-07 20:56:50 -08:00
|
|
|
self._clear_libvirt_domains()
|
2012-02-13 18:07:57 -08:00
|
|
|
self._clean_it()
|
|
|
|
|
|
|
|
def _clean_it(self):
|
|
|
|
#these environment additions are important
|
|
|
|
#in that they eventually affect how this script runs
|
|
|
|
sub_components = self.component_opts or SUBCOMPONENTS
|
|
|
|
env = dict()
|
|
|
|
env['ENABLED_SERVICES'] = ",".join(sub_components)
|
|
|
|
env['BIN_DIR'] = self.bindir
|
|
|
|
env['VOLUME_NAME_PREFIX'] = self.cfg.get('nova', 'volume_name_prefix')
|
2012-02-13 23:02:22 -08:00
|
|
|
cleaner_fn = sh.joinpths(self.bindir, CLEANER_DATA_CONF)
|
|
|
|
if sh.isfile(cleaner_fn):
|
2012-02-14 17:29:19 -08:00
|
|
|
LOG.info("Cleaning up your system by running nova cleaner script [%s]." % (cleaner_fn))
|
2012-02-13 23:02:22 -08:00
|
|
|
cmd = CLEANER_CMD_ROOT + [cleaner_fn]
|
|
|
|
sh.execute(*cmd, run_as_root=True, env_overrides=env)
|
2012-02-07 17:18:44 -08:00
|
|
|
|
2012-02-07 20:56:50 -08:00
|
|
|
def _clear_libvirt_domains(self):
|
2012-02-15 10:35:13 -08:00
|
|
|
virt_driver = _canon_virt_driver(self.cfg.get('nova', 'virt_driver'))
|
2012-02-07 20:56:50 -08:00
|
|
|
if virt_driver == virsh.VIRT_TYPE:
|
2012-02-08 19:53:08 -08:00
|
|
|
inst_prefix = self.cfg.get('nova', 'instance_name_prefix')
|
2012-02-08 12:55:23 -08:00
|
|
|
libvirt_type = virsh.default(self.cfg.get('nova', 'libvirt_type'))
|
2012-02-09 18:03:28 -08:00
|
|
|
virsh.clear_libvirt_domains(self.distro, libvirt_type, inst_prefix)
|
2012-02-07 16:46:36 -08:00
|
|
|
|
2012-01-20 17:11:50 -08:00
|
|
|
|
2012-01-20 14:12:20 -08:00
|
|
|
class NovaInstaller(comp.PythonInstallComponent):
|
2012-01-11 12:47:33 -08:00
|
|
|
def __init__(self, *args, **kargs):
|
2012-01-20 14:12:20 -08:00
|
|
|
comp.PythonInstallComponent.__init__(self, TYPE, *args, **kargs)
|
2012-01-20 19:05:13 -08:00
|
|
|
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
2012-02-09 16:58:00 -08:00
|
|
|
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
2012-01-25 13:52:23 -08:00
|
|
|
self.paste_conf_fn = self._get_target_config_name(PASTE_CONF)
|
2012-02-07 20:56:50 -08:00
|
|
|
self.volumes_enabled = False
|
|
|
|
if not self.component_opts or NVOL in self.component_opts:
|
|
|
|
self.volumes_enabled = True
|
2012-02-10 10:28:49 -08:00
|
|
|
self.xvnc_enabled = False
|
|
|
|
if not self.component_opts or NXVNC in self.component_opts:
|
|
|
|
self.xvnc_enabled = True
|
2012-01-19 14:04:37 -08:00
|
|
|
|
2012-01-28 21:05:54 -08:00
|
|
|
def _get_pkgs(self):
|
2012-01-31 22:05:38 -08:00
|
|
|
pkgs = list(REQ_PKGS)
|
|
|
|
sub_components = self.component_opts or SUBCOMPONENTS
|
2012-01-28 21:05:54 -08:00
|
|
|
for c in sub_components:
|
2012-02-07 20:56:50 -08:00
|
|
|
fns = ADD_PKGS.get(c)
|
|
|
|
if fns:
|
|
|
|
pkgs.extend(fns)
|
2012-01-23 14:45:09 -08:00
|
|
|
return pkgs
|
|
|
|
|
2012-02-03 00:11:41 -08:00
|
|
|
def _get_symlinks(self):
|
2012-02-09 16:58:00 -08:00
|
|
|
links = dict()
|
|
|
|
for fn in self._get_config_files():
|
|
|
|
source_fn = self._get_target_config_name(fn)
|
|
|
|
links[source_fn] = sh.joinpths("/", "etc", "nova", fn)
|
|
|
|
source_fn = sh.joinpths(self.cfgdir, API_CONF)
|
|
|
|
links[source_fn] = sh.joinpths("/", "etc", "nova", API_CONF)
|
|
|
|
return links
|
2012-02-03 00:11:41 -08:00
|
|
|
|
2012-01-31 17:26:26 -08:00
|
|
|
def _get_pips(self):
|
2012-01-31 22:05:38 -08:00
|
|
|
return list(REQ_PIPS)
|
2012-01-31 17:26:26 -08:00
|
|
|
|
2012-01-20 19:05:13 -08:00
|
|
|
def _get_download_locations(self):
|
2012-01-31 22:05:38 -08:00
|
|
|
places = list()
|
2012-01-19 17:47:16 -08:00
|
|
|
places.append({
|
2012-01-31 22:05:38 -08:00
|
|
|
'uri': ("git", "nova_repo"),
|
|
|
|
'branch': ("git", "nova_branch"),
|
2012-01-19 17:47:16 -08:00
|
|
|
})
|
|
|
|
return places
|
2012-01-20 17:11:50 -08:00
|
|
|
|
2012-02-03 10:42:39 -08:00
|
|
|
def warm_configs(self):
|
|
|
|
pws = ['rabbit']
|
|
|
|
for pw_key in pws:
|
|
|
|
self.cfg.get("passwords", pw_key)
|
2012-02-03 01:09:31 -08:00
|
|
|
|
2012-01-24 12:53:52 -08:00
|
|
|
def _get_config_files(self):
|
|
|
|
return list(CONFIGS)
|
|
|
|
|
2012-01-27 23:14:16 -08:00
|
|
|
def _setup_network(self):
|
|
|
|
LOG.info("Creating your nova network to be used with instances.")
|
2012-01-24 10:16:51 -08:00
|
|
|
mp = dict()
|
2012-01-25 13:52:23 -08:00
|
|
|
mp['BINDIR'] = self.bindir
|
|
|
|
mp['CFGFILE'] = sh.joinpths(self.cfgdir, API_CONF)
|
2012-01-24 10:16:51 -08:00
|
|
|
mp['FLOATING_RANGE'] = self.cfg.get('nova', 'floating_range')
|
|
|
|
mp['TEST_FLOATING_RANGE'] = self.cfg.get('nova', 'test_floating_range')
|
|
|
|
mp['TEST_FLOATING_POOL'] = self.cfg.get('nova', 'test_floating_pool')
|
2012-01-27 23:14:16 -08:00
|
|
|
mp['FIXED_NETWORK_SIZE'] = self.cfg.get('nova', 'fixed_network_size')
|
|
|
|
mp['FIXED_RANGE'] = self.cfg.get('nova', 'fixed_range')
|
2012-02-01 16:27:49 -08:00
|
|
|
if settings.QUANTUM in self.instances:
|
|
|
|
cmds = NETWORK_SETUP_CMDS[0:1]
|
|
|
|
else:
|
|
|
|
cmds = NETWORK_SETUP_CMDS
|
2012-02-09 17:16:48 -08:00
|
|
|
utils.execute_template(*cmds, params=mp)
|
2012-01-27 23:14:16 -08:00
|
|
|
|
|
|
|
def _sync_db(self):
|
|
|
|
LOG.info("Syncing the database with nova.")
|
|
|
|
mp = dict()
|
|
|
|
mp['BINDIR'] = self.bindir
|
|
|
|
mp['CFGFILE'] = sh.joinpths(self.cfgdir, API_CONF)
|
2012-02-09 17:16:48 -08:00
|
|
|
utils.execute_template(*DB_SYNC_CMD, params=mp)
|
2012-01-27 23:14:16 -08:00
|
|
|
|
|
|
|
def post_install(self):
|
2012-02-04 21:08:20 -08:00
|
|
|
comp.PkgInstallComponent.post_install(self)
|
2012-01-27 23:14:16 -08:00
|
|
|
#extra actions to do nova setup
|
|
|
|
self._setup_db()
|
|
|
|
self._sync_db()
|
|
|
|
self._setup_network()
|
2012-02-07 20:56:50 -08:00
|
|
|
self._setup_cleaner()
|
2012-01-25 16:16:09 -08:00
|
|
|
# check if we need to do the vol subcomponent
|
2012-02-07 20:56:50 -08:00
|
|
|
if self.volumes_enabled:
|
2012-02-10 10:28:49 -08:00
|
|
|
vol_maker = NovaVolumeConfigurator(self)
|
2012-02-09 19:30:30 -08:00
|
|
|
vol_maker.setup_volumes()
|
2012-01-23 14:45:09 -08:00
|
|
|
|
2012-02-07 20:56:50 -08:00
|
|
|
def _setup_cleaner(self):
|
|
|
|
LOG.info("Configuring cleaner template %s.", CLEANER_DATA_CONF)
|
|
|
|
(_, contents) = utils.load_template(self.component_name, CLEANER_DATA_CONF)
|
|
|
|
tgt_fn = sh.joinpths(self.bindir, CLEANER_DATA_CONF)
|
|
|
|
sh.write_file(tgt_fn, contents)
|
2012-02-13 18:25:45 -08:00
|
|
|
sh.chmod(tgt_fn, 0755)
|
2012-02-10 21:16:23 -08:00
|
|
|
self.tracewriter.file_touched(tgt_fn)
|
2012-02-07 20:56:50 -08:00
|
|
|
|
2012-01-23 14:45:09 -08:00
|
|
|
def _setup_db(self):
|
2012-01-31 22:05:38 -08:00
|
|
|
LOG.info("Fixing up database named %s.", DB_NAME)
|
2012-01-23 14:45:09 -08:00
|
|
|
db.drop_db(self.cfg, DB_NAME)
|
|
|
|
db.create_db(self.cfg, DB_NAME)
|
|
|
|
|
2012-01-20 17:00:23 -08:00
|
|
|
def _generate_nova_conf(self):
|
2012-01-27 23:14:16 -08:00
|
|
|
LOG.info("Generating dynamic content for nova configuration (%s)." % (API_CONF))
|
2012-02-10 10:28:49 -08:00
|
|
|
conf_gen = NovaConfConfigurator(self)
|
2012-02-13 18:25:45 -08:00
|
|
|
nova_conf = conf_gen.configure()
|
2012-01-24 22:06:05 -08:00
|
|
|
tgtfn = self._get_target_config_name(API_CONF)
|
2012-02-05 21:00:52 -08:00
|
|
|
LOG.info("Writing nova configuration to %s" % (tgtfn))
|
|
|
|
LOG.debug(nova_conf)
|
2012-02-03 19:47:08 -08:00
|
|
|
self.tracewriter.make_dir(sh.dirname(tgtfn))
|
2012-01-20 17:00:23 -08:00
|
|
|
sh.write_file(tgtfn, nova_conf)
|
2012-01-25 13:52:23 -08:00
|
|
|
self.tracewriter.cfg_write(tgtfn)
|
|
|
|
|
2012-01-27 17:37:16 -08:00
|
|
|
def _config_adjust(self, contents, config_fn):
|
|
|
|
if config_fn == PASTE_CONF and settings.KEYSTONE in self.instances:
|
2012-02-02 21:45:42 -08:00
|
|
|
newcontents = contents
|
|
|
|
with io.BytesIO(contents) as stream:
|
|
|
|
config = cfg.IgnoreMissingConfigParser()
|
|
|
|
config.readfp(stream)
|
|
|
|
mods = 0
|
|
|
|
for section in PASTE_PIPELINE_KEYSTONE_ADJUST.keys():
|
|
|
|
if config.has_section(section):
|
|
|
|
section_vals = PASTE_PIPELINE_KEYSTONE_ADJUST.get(section)
|
|
|
|
for (k, v) in section_vals.items():
|
|
|
|
config.set(section, k, v)
|
|
|
|
mods += 1
|
|
|
|
if mods > 0:
|
|
|
|
with io.BytesIO() as outputstream:
|
|
|
|
config.write(outputstream)
|
|
|
|
outputstream.flush()
|
2012-02-05 21:00:52 -08:00
|
|
|
newcontents = cfg.add_header(config_fn, outputstream.getvalue())
|
2012-02-02 21:45:42 -08:00
|
|
|
contents = newcontents
|
2012-01-27 17:37:16 -08:00
|
|
|
return contents
|
|
|
|
|
2012-01-27 14:51:18 -08:00
|
|
|
def _get_source_config(self, config_fn):
|
|
|
|
if config_fn == PASTE_CONF:
|
2012-01-27 17:37:16 -08:00
|
|
|
#this is named differently than what it will be stored as... arg...
|
2012-01-27 15:27:44 -08:00
|
|
|
srcfn = sh.joinpths(self.appdir, "etc", "nova", 'api-paste.ini')
|
2012-01-27 15:20:16 -08:00
|
|
|
contents = sh.load_file(srcfn)
|
2012-01-27 14:51:18 -08:00
|
|
|
return (srcfn, contents)
|
|
|
|
else:
|
|
|
|
return comp.PythonInstallComponent._get_source_config(self, config_fn)
|
|
|
|
|
2012-01-27 17:37:16 -08:00
|
|
|
def _get_param_map(self, config_fn):
|
|
|
|
return keystone.get_shared_params(self.cfg)
|
|
|
|
|
|
|
|
def configure(self):
|
|
|
|
am = comp.PythonInstallComponent.configure(self)
|
|
|
|
#this is a special conf so we handle it ourselves
|
2012-01-25 13:52:23 -08:00
|
|
|
self._generate_nova_conf()
|
2012-01-27 17:37:16 -08:00
|
|
|
return am + 1
|
2012-01-20 17:00:23 -08:00
|
|
|
|
2012-01-19 17:47:16 -08:00
|
|
|
|
2012-01-20 14:12:20 -08:00
|
|
|
class NovaRuntime(comp.PythonRuntime):
|
2012-01-11 12:47:33 -08:00
|
|
|
def __init__(self, *args, **kargs):
|
2012-01-20 14:12:20 -08:00
|
|
|
comp.PythonRuntime.__init__(self, TYPE, *args, **kargs)
|
2012-02-10 12:59:06 -08:00
|
|
|
self.cfgdir = sh.joinpths(self.appdir, CONFIG_DIR)
|
|
|
|
self.bindir = sh.joinpths(self.appdir, BIN_DIR)
|
2012-01-23 14:45:09 -08:00
|
|
|
|
2012-01-25 13:52:23 -08:00
|
|
|
def _get_apps_to_start(self):
|
2012-01-23 14:45:09 -08:00
|
|
|
result = list()
|
2012-01-27 18:07:07 -08:00
|
|
|
if not self.component_opts:
|
|
|
|
apps = sorted(APP_OPTIONS.keys())
|
|
|
|
for app_name in apps:
|
|
|
|
result.append({
|
|
|
|
'name': app_name,
|
2012-02-10 12:59:06 -08:00
|
|
|
'path': sh.joinpths(self.bindir, app_name),
|
2012-01-27 18:07:07 -08:00
|
|
|
})
|
|
|
|
else:
|
|
|
|
for short_name in self.component_opts:
|
|
|
|
full_name = SUB_COMPONENT_NAME_MAP.get(short_name)
|
|
|
|
if full_name and full_name in APP_OPTIONS:
|
|
|
|
result.append({
|
|
|
|
'name': full_name,
|
2012-02-10 12:59:06 -08:00
|
|
|
'path': sh.joinpths(self.bindir, full_name),
|
2012-01-27 18:07:07 -08:00
|
|
|
})
|
2012-01-23 14:45:09 -08:00
|
|
|
return result
|
|
|
|
|
2012-02-03 14:59:28 -08:00
|
|
|
def pre_start(self):
|
2012-02-15 10:35:13 -08:00
|
|
|
virt_driver = _canon_virt_driver(self.cfg.get('nova', 'virt_driver'))
|
2012-02-08 12:55:23 -08:00
|
|
|
if virt_driver == virsh.VIRT_TYPE:
|
|
|
|
virt_type = virsh.default(self.cfg.get('nova', 'libvirt_type'))
|
2012-02-08 15:13:32 -08:00
|
|
|
LOG.info("Checking that your selected libvirt virtualization type [%s] is working and running." % (virt_type))
|
2012-02-08 12:55:23 -08:00
|
|
|
if not virsh.virt_ok(virt_type, self.distro):
|
|
|
|
msg = ("Libvirt type %s for distro %s does not seem to be active or configured correctly, "
|
|
|
|
"perhaps you should be using %s instead." % (virt_type, self.distro, virsh.DEFAULT_VIRT))
|
|
|
|
raise exceptions.StartException(msg)
|
|
|
|
virsh.restart(self.distro)
|
2012-02-03 14:59:28 -08:00
|
|
|
|
2012-01-27 17:37:16 -08:00
|
|
|
def _get_param_map(self, app_name):
|
|
|
|
params = comp.PythonRuntime._get_param_map(self, app_name)
|
|
|
|
params['CFGFILE'] = sh.joinpths(self.cfgdir, API_CONF)
|
|
|
|
return params
|
2012-01-24 15:19:21 -08:00
|
|
|
|
2012-01-27 17:37:16 -08:00
|
|
|
def _get_app_options(self, app):
|
|
|
|
return APP_OPTIONS.get(app)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
|
2012-02-09 19:30:30 -08:00
|
|
|
#this will configure nova volumes which in a developer box
|
|
|
|
#is a volume group (lvm) that are backed by a loopback file
|
|
|
|
class NovaVolumeConfigurator(object):
|
2012-02-10 10:28:49 -08:00
|
|
|
def __init__(self, ni):
|
|
|
|
self.cfg = ni.cfg
|
|
|
|
self.appdir = ni.appdir
|
2012-02-09 19:30:30 -08:00
|
|
|
|
|
|
|
def setup_volumes(self):
|
|
|
|
self._setup_vol_groups()
|
|
|
|
|
|
|
|
def _setup_vol_groups(self):
|
|
|
|
LOG.info("Attempting to setup volume groups for nova volume management.")
|
|
|
|
mp = dict()
|
|
|
|
backing_file = self.cfg.get('nova', 'volume_backing_file')
|
|
|
|
# check if we need to have a default backing file
|
|
|
|
if not backing_file:
|
|
|
|
backing_file = sh.joinpths(self.appdir, 'nova-volumes-backing-file')
|
|
|
|
vol_group = self.cfg.get('nova', 'volume_group')
|
|
|
|
backing_file_size = utils.to_bytes(self.cfg.get('nova', 'volume_backing_file_size'))
|
|
|
|
mp['VOLUME_GROUP'] = vol_group
|
|
|
|
mp['VOLUME_BACKING_FILE'] = backing_file
|
|
|
|
mp['VOLUME_BACKING_FILE_SIZE'] = backing_file_size
|
|
|
|
try:
|
|
|
|
utils.execute_template(*VG_CHECK_CMD, params=mp)
|
|
|
|
LOG.warn("Volume group already exists: %s" % (vol_group))
|
|
|
|
except exceptions.ProcessExecutionError as err:
|
|
|
|
# Check that the error from VG_CHECK is an expected error
|
|
|
|
if err.exit_code != 5:
|
|
|
|
raise
|
|
|
|
LOG.info("Need to create volume group: %s" % (vol_group))
|
|
|
|
sh.touch_file(backing_file, die_if_there=False, file_size=backing_file_size)
|
|
|
|
vg_dev_result = utils.execute_template(*VG_DEV_CMD, params=mp)
|
|
|
|
if vg_dev_result and vg_dev_result[0]:
|
|
|
|
LOG.debug("VG dev result: %s" % (vg_dev_result))
|
|
|
|
# Strip the newlines out of the stdout (which is in the first
|
|
|
|
# element of the first (and only) tuple in the response
|
|
|
|
(sysout, _) = vg_dev_result[0]
|
|
|
|
mp['DEV'] = sysout.replace('\n', '')
|
|
|
|
utils.execute_template(*VG_CREATE_CMD, params=mp)
|
|
|
|
# One way or another, we should have the volume group, Now check the
|
|
|
|
# logical volumes
|
|
|
|
self._process_lvs(mp)
|
|
|
|
# Finish off by restarting tgt, and ignore any errors
|
|
|
|
utils.execute_template(*RESTART_TGT_CMD, check_exit_code=False)
|
|
|
|
|
|
|
|
def _process_lvs(self, mp):
|
|
|
|
LOG.info("Attempting to setup logical volumes for nova volume management.")
|
|
|
|
lvs_result = utils.execute_template(*VG_LVS_CMD, params=mp)
|
|
|
|
if lvs_result and lvs_result[0]:
|
|
|
|
LOG.debug("LVS result: %s" % (lvs_result))
|
|
|
|
vol_name_prefix = self.cfg.get('nova', 'volume_name_prefix')
|
|
|
|
LOG.debug("Using volume name prefix: %s" % (vol_name_prefix))
|
|
|
|
(sysout, _) = lvs_result[0]
|
|
|
|
for stdout_line in sysout.split('\n'):
|
|
|
|
stdout_line = stdout_line.strip()
|
|
|
|
if stdout_line:
|
|
|
|
# Ignore blank lines
|
|
|
|
LOG.debug("Processing LVS output line: %s" % (stdout_line))
|
|
|
|
if stdout_line.startswith(vol_name_prefix):
|
|
|
|
# TODO still need to implement the following:
|
|
|
|
# tid=`egrep "^tid.+$lv" /proc/net/iet/volume | cut -f1 -d' ' | tr ':' '='`
|
|
|
|
# if [[ -n "$tid" ]]; then
|
|
|
|
# lun=`egrep "lun.+$lv" /proc/net/iet/volume | cut -f1 -d' ' | tr ':' '=' | tr -d '\t'`
|
|
|
|
# sudo ietadm --op delete --$tid --$lun
|
|
|
|
# fi
|
|
|
|
# sudo lvremove -f $VOLUME_GROUP/$lv
|
|
|
|
raise NotImplementedError("LVS magic not yet implemented!")
|
|
|
|
mp['LV'] = stdout_line
|
|
|
|
utils.execute_template(*VG_LVREMOVE_CMD, params=mp)
|
|
|
|
|
|
|
|
|
2012-01-24 12:53:52 -08:00
|
|
|
# This class has the smarts to build the configuration file based on
|
2012-02-03 19:21:35 -08:00
|
|
|
# various runtime values. A useful reference for figuring out this
|
|
|
|
# is at http://docs.openstack.org/diablo/openstack-compute/admin/content/ch_configuring-openstack-compute.html
|
2012-02-10 10:28:49 -08:00
|
|
|
class NovaConfConfigurator(object):
|
|
|
|
def __init__(self, ni):
|
|
|
|
self.cfg = ni.cfg
|
|
|
|
self.instances = ni.instances
|
|
|
|
self.component_root = ni.component_root
|
|
|
|
self.appdir = ni.appdir
|
|
|
|
self.tracewriter = ni.tracewriter
|
|
|
|
self.paste_conf_fn = ni.paste_conf_fn
|
|
|
|
self.distro = ni.distro
|
2012-02-13 18:25:45 -08:00
|
|
|
self.cfgdir = ni.cfgdir
|
2012-02-10 10:28:49 -08:00
|
|
|
self.xvnc_enabled = ni.xvnc_enabled
|
|
|
|
self.volumes_enabled = ni.volumes_enabled
|
2012-02-15 16:16:25 -08:00
|
|
|
self.novnc_enabled = settings.NOVNC in self.instances
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
def _getbool(self, name):
|
|
|
|
return self.cfg.getboolean('nova', name)
|
|
|
|
|
2012-02-14 21:11:57 -08:00
|
|
|
def _getstr(self, name, default=''):
|
|
|
|
val = self.cfg.get('nova', name)
|
2012-02-15 10:35:13 -08:00
|
|
|
if not val:
|
2012-02-14 21:11:57 -08:00
|
|
|
return default
|
|
|
|
return val
|
2012-02-15 10:37:00 -08:00
|
|
|
|
2012-02-15 10:35:13 -08:00
|
|
|
def _get_canon_virt_driver(self):
|
|
|
|
virt_driver = self._getstr('virt_driver')
|
|
|
|
return _canon_virt_driver(virt_driver)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-13 18:25:45 -08:00
|
|
|
def configure(self):
|
2012-01-24 12:53:52 -08:00
|
|
|
nova_conf = NovaConf()
|
2012-02-03 19:21:35 -08:00
|
|
|
|
|
|
|
#use more than once
|
2012-01-24 12:53:52 -08:00
|
|
|
hostip = self.cfg.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 scheduler do u want?
|
2012-02-15 16:16:25 -08:00
|
|
|
scheduler = self._getstr('scheduler', DEF_SCHEDULER)
|
2012-01-24 12:53:52 -08:00
|
|
|
nova_conf.add('scheduler_driver', scheduler)
|
|
|
|
|
2012-02-03 19:21:35 -08:00
|
|
|
#setup network settings
|
2012-02-13 18:25:45 -08:00
|
|
|
self._configure_network_settings(nova_conf)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-03 19:21:35 -08:00
|
|
|
#setup nova volume settings
|
2012-02-03 19:57:38 -08:00
|
|
|
if self.volumes_enabled:
|
2012-02-03 19:21:35 -08:00
|
|
|
self._configure_vols(nova_conf)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-03 19:21:35 -08:00
|
|
|
#where we are running
|
|
|
|
nova_conf.add('my_ip', hostip)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-03 19:21:35 -08:00
|
|
|
#setup your sql connection
|
2012-01-24 12:53:52 -08:00
|
|
|
nova_conf.add('sql_connection', self.cfg.get_dbdsn('nova'))
|
|
|
|
|
|
|
|
#configure anything libvirt releated?
|
2012-02-15 10:35:13 -08:00
|
|
|
virt_driver = self._get_canon_virt_driver()
|
2012-02-08 12:55:23 -08:00
|
|
|
if virt_driver == virsh.VIRT_TYPE:
|
|
|
|
libvirt_type = virsh.default(self._getstr('libvirt_type'))
|
2012-02-03 19:49:52 -08:00
|
|
|
self._configure_libvirt(libvirt_type, nova_conf)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
#how instances will be presented
|
2012-01-25 16:16:09 -08:00
|
|
|
instance_template = self._getstr('instance_name_prefix') + self._getstr('instance_name_postfix')
|
2012-02-15 16:16:25 -08:00
|
|
|
if not instance_template:
|
|
|
|
instance_template = DEF_INSTANCE_TEMPL
|
2012-01-24 12:53:52 -08:00
|
|
|
nova_conf.add('instance_name_template', instance_template)
|
|
|
|
|
2012-02-15 16:16:25 -08:00
|
|
|
#enable the standard extensions
|
2012-02-01 18:50:48 -08:00
|
|
|
nova_conf.add('osapi_compute_extension', 'nova.api.openstack.compute.contrib.standard_extensions')
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-03 19:21:35 -08:00
|
|
|
#vnc settings
|
|
|
|
self._configure_vnc(nova_conf)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-03 19:21:35 -08:00
|
|
|
#where our paste config is
|
2012-01-25 13:52:23 -08:00
|
|
|
nova_conf.add('api_paste_config', self.paste_conf_fn)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-03 19:40:25 -08:00
|
|
|
#what our imaging service will be
|
2012-02-15 16:16:25 -08:00
|
|
|
self._configure_image_service(nova_conf, hostip)
|
2012-02-03 19:21:35 -08:00
|
|
|
|
|
|
|
#ec2 / s3 stuff
|
2012-02-15 16:16:25 -08:00
|
|
|
ec2_dmz_host = self._getstr('ec2_dmz_host', hostip)
|
2012-01-24 12:53:52 -08:00
|
|
|
nova_conf.add('ec2_dmz_host', ec2_dmz_host)
|
2012-02-03 19:21:35 -08:00
|
|
|
nova_conf.add('s3_host', hostip)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
#how is your rabbit setup?
|
|
|
|
nova_conf.add('rabbit_host', self.cfg.get('default', 'rabbit_host'))
|
|
|
|
nova_conf.add('rabbit_password', self.cfg.get("passwords", "rabbit"))
|
|
|
|
|
|
|
|
#where instances will be stored
|
2012-02-15 10:35:13 -08:00
|
|
|
instances_path = self._getstr('instances_path', sh.joinpths(self.component_root, 'instances'))
|
2012-02-03 19:21:35 -08:00
|
|
|
self._configure_instances_path(instances_path, nova_conf)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
#is this a multihost setup?
|
2012-02-03 19:21:35 -08:00
|
|
|
self._configure_multihost(nova_conf)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
#enable syslog??
|
2012-02-03 19:21:35 -08:00
|
|
|
self._configure_syslog(nova_conf)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
#handle any virt driver specifics
|
2012-02-03 19:21:35 -08:00
|
|
|
self._configure_virt_driver(nova_conf)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
#now make it
|
2012-02-15 10:53:38 -08:00
|
|
|
generated_content = nova_conf.generate()
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-15 10:53:38 -08:00
|
|
|
#add any extra flags/lines in?
|
2012-01-24 12:53:52 -08:00
|
|
|
extra_flags = self._getstr('extra_flags')
|
2012-02-03 19:40:25 -08:00
|
|
|
if extra_flags:
|
2012-02-15 10:53:38 -08:00
|
|
|
new_contents = list()
|
|
|
|
new_contents.append(generated_content)
|
2012-02-15 16:16:25 -08:00
|
|
|
#Lines that start with a # are ignored as comments. Leading whitespace is also ignored in flagfiles, as are blank lines.
|
|
|
|
new_contents.append("")
|
|
|
|
new_contents.append("# Extra FLAGS")
|
2012-02-15 10:53:38 -08:00
|
|
|
new_contents.append("")
|
|
|
|
extra_lines = extra_flags.splitlines()
|
|
|
|
for line in extra_lines:
|
|
|
|
cleaned_line = line.strip()
|
|
|
|
if len(cleaned_line):
|
|
|
|
new_contents.append(cleaned_line)
|
|
|
|
generated_content = utils.joinlinesep(*new_contents)
|
|
|
|
|
|
|
|
return generated_content
|
2012-01-24 12:53:52 -08:00
|
|
|
|
2012-02-15 16:16:25 -08:00
|
|
|
def _configure_image_service(self, nova_conf, hostip):
|
2012-02-03 19:40:25 -08:00
|
|
|
#what image service we will use
|
2012-02-15 10:35:13 -08:00
|
|
|
img_service = self._getstr('img_service', DEF_IMAGE_SERVICE)
|
2012-02-03 19:40:25 -08:00
|
|
|
nova_conf.add('image_service', img_service)
|
|
|
|
|
|
|
|
#where is glance located?
|
|
|
|
if img_service.lower().find("glance") != -1:
|
2012-02-15 10:35:13 -08:00
|
|
|
glance_api_server = self._getstr('glance_server',
|
2012-02-15 16:16:25 -08:00
|
|
|
("%s:%d" % (hostip, DEF_GLANCE_PORT)))
|
2012-02-03 19:40:25 -08:00
|
|
|
nova_conf.add('glance_api_servers', glance_api_server)
|
|
|
|
|
2012-02-03 19:21:35 -08:00
|
|
|
def _configure_vnc(self, nova_conf):
|
2012-02-15 16:16:25 -08:00
|
|
|
if self.novnc_enabled:
|
|
|
|
nova_conf.add('novncproxy_base_url', self._getstr('vncproxy_url'))
|
2012-02-06 13:09:37 -08:00
|
|
|
|
|
|
|
if self.xvnc_enabled:
|
|
|
|
nova_conf.add('xvpvncproxy_base_url', self._getstr('xvpvncproxy_url'))
|
2012-02-15 10:18:58 -08:00
|
|
|
|
2012-02-15 16:16:25 -08:00
|
|
|
nova_conf.add('vncserver_listen', self._getstr('vncserver_listen', VNC_DEF_ADDR))
|
2012-02-15 10:18:58 -08:00
|
|
|
|
2012-02-15 10:37:00 -08:00
|
|
|
# If no vnc proxy address was specified,
|
2012-02-15 10:18:58 -08:00
|
|
|
# pick a default based on which
|
|
|
|
# driver we're using.
|
2012-02-15 10:35:13 -08:00
|
|
|
vncserver_proxyclient_address = self._getstr('vncserver_proxyclient_address')
|
2012-02-03 19:21:35 -08:00
|
|
|
if not vncserver_proxyclient_address:
|
2012-02-15 10:35:13 -08:00
|
|
|
drive_canon = self._get_canon_virt_driver()
|
2012-02-15 10:18:58 -08:00
|
|
|
if drive_canon == 'xenserver':
|
|
|
|
vncserver_proxyclient_address = XS_VNC_ADDR
|
2012-02-03 19:21:35 -08:00
|
|
|
else:
|
2012-02-15 10:18:58 -08:00
|
|
|
vncserver_proxyclient_address = VNC_DEF_ADDR
|
2012-02-03 19:21:35 -08:00
|
|
|
|
2012-02-15 10:35:13 -08:00
|
|
|
nova_conf.add('vncserver_proxyclient_address', vncserver_proxyclient_address)
|
2012-02-03 19:21:35 -08:00
|
|
|
|
|
|
|
def _configure_vols(self, nova_conf):
|
|
|
|
nova_conf.add('volume_group', self._getstr('volume_group'))
|
2012-02-15 16:16:25 -08:00
|
|
|
nova_conf.add('volume_name_template', self._getstr('volume_name_prefix') + self._getstr('volume_name_postfix'))
|
2012-02-03 19:21:35 -08:00
|
|
|
nova_conf.add('iscsi_help', 'tgtadm')
|
|
|
|
|
2012-02-13 18:25:45 -08:00
|
|
|
def _configure_network_settings(self, nova_conf):
|
2012-02-03 19:21:35 -08:00
|
|
|
if settings.QUANTUM in self.instances:
|
|
|
|
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'))
|
|
|
|
if self.cfg.get('quantum', 'q_plugin') == 'openvswitch':
|
|
|
|
for (key, value) in QUANTUM_OPENSWITCH_OPS.items():
|
|
|
|
if value is None:
|
|
|
|
nova_conf.add_simple(key)
|
|
|
|
else:
|
|
|
|
nova_conf.add(key, value)
|
2012-02-04 21:39:20 -08:00
|
|
|
if settings.MELANGE_CLIENT in self.instances:
|
|
|
|
nova_conf.add('quantum_ipam_lib', 'nova.network.quantum.melange_ipam_lib')
|
|
|
|
nova_conf.add_simple('use_melange_mac_generation')
|
|
|
|
nova_conf.add('melange_host', self.cfg.get('melange', 'm_host'))
|
|
|
|
nova_conf.add('melange_port', self.cfg.get('melange', 'm_port'))
|
2012-02-03 19:21:35 -08:00
|
|
|
else:
|
|
|
|
nova_conf.add('network_manager', NET_MANAGER_TEMPLATE % (self._getstr('network_manager')))
|
|
|
|
|
2012-02-03 19:40:25 -08:00
|
|
|
#dhcp bridge stuff???
|
2012-02-13 18:25:45 -08:00
|
|
|
flag_conf_fn = sh.joinpths(self.cfgdir, API_CONF)
|
2012-02-03 19:21:35 -08:00
|
|
|
nova_conf.add('dhcpbridge_flagfile', flag_conf_fn)
|
|
|
|
|
2012-02-03 19:40:25 -08:00
|
|
|
#Network prefix for the IP network that all the projects for future VM guests reside on. Example: 192.168.0.0/12
|
2012-02-03 19:21:35 -08:00
|
|
|
nova_conf.add('fixed_range', self._getstr('fixed_range'))
|
|
|
|
|
|
|
|
# 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')
|
2012-02-15 10:35:13 -08:00
|
|
|
vlan_interface = self._getstr('vlan_interface', public_interface)
|
2012-02-03 19:40:25 -08:00
|
|
|
|
|
|
|
#do a little check to make sure actually have that interface set...
|
2012-02-14 10:27:07 -08:00
|
|
|
if not utils.is_interface(public_interface):
|
2012-02-03 19:40:25 -08:00
|
|
|
msg = "Public interface %s is not a known interface" % (public_interface)
|
|
|
|
raise exceptions.ConfigException(msg)
|
2012-02-14 10:27:07 -08:00
|
|
|
if not utils.is_interface(vlan_interface):
|
2012-02-03 19:40:25 -08:00
|
|
|
msg = "VLAN interface %s is not a known interface" % (vlan_interface)
|
|
|
|
raise exceptions.ConfigException(msg)
|
2012-02-03 19:21:35 -08:00
|
|
|
nova_conf.add('public_interface', public_interface)
|
|
|
|
nova_conf.add('vlan_interface', vlan_interface)
|
|
|
|
|
2012-02-03 19:40:25 -08:00
|
|
|
#This forces dnsmasq to update its leases table when an instance is terminated.
|
2012-02-03 19:21:35 -08:00
|
|
|
nova_conf.add_simple('force_dhcp_release')
|
|
|
|
|
|
|
|
def _configure_syslog(self, nova_conf):
|
|
|
|
if self.cfg.getboolean('default', 'syslog'):
|
|
|
|
nova_conf.add_simple('use_syslog')
|
|
|
|
|
|
|
|
def _configure_multihost(self, nova_conf):
|
|
|
|
if self._getbool('multi_host'):
|
|
|
|
nova_conf.add_simple('multi_host')
|
|
|
|
nova_conf.add_simple('send_arp_for_ha')
|
|
|
|
|
|
|
|
def _configure_instances_path(self, instances_path, nova_conf):
|
|
|
|
nova_conf.add('instances_path', instances_path)
|
|
|
|
LOG.debug("Attempting to create instance directory: %s" % (instances_path))
|
|
|
|
self.tracewriter.make_dir(instances_path)
|
|
|
|
LOG.debug("Adjusting permissions of instance directory: %s" % (instances_path))
|
2012-02-13 18:25:45 -08:00
|
|
|
os.chmod(instances_path, 0777)
|
2012-02-03 19:21:35 -08:00
|
|
|
|
2012-01-24 12:53:52 -08:00
|
|
|
def _configure_libvirt(self, virt_type, nova_conf):
|
2012-02-02 14:50:51 -08:00
|
|
|
if virt_type == 'lxc':
|
2012-02-08 12:55:23 -08:00
|
|
|
#TODO need to add some goodies here
|
2012-02-02 14:50:51 -08:00
|
|
|
pass
|
2012-01-24 12:53:52 -08:00
|
|
|
nova_conf.add('libvirt_type', virt_type)
|
|
|
|
|
|
|
|
#configures any virt driver settings
|
2012-02-03 19:21:35 -08:00
|
|
|
def _configure_virt_driver(self, nova_conf):
|
2012-02-15 10:35:13 -08:00
|
|
|
drive_canon = self._get_canon_virt_driver()
|
2012-01-24 12:53:52 -08:00
|
|
|
if drive_canon == 'xenserver':
|
|
|
|
nova_conf.add('connection_type', 'xenapi')
|
2012-02-15 10:35:13 -08:00
|
|
|
xa_url = self._getstr('xa_connection_url',
|
|
|
|
urlunparse(('http', "%s:%s" % (XA_CONNECTION_ADDR, XA_CONNECTION_PORT), "", '', '', '')))
|
2012-02-14 10:27:07 -08:00
|
|
|
nova_conf.add('xenapi_connection_url', xa_url)
|
2012-02-15 10:35:13 -08:00
|
|
|
xs_user = self._getstr('xa_connection_username', XA_DEF_USER)
|
2012-02-14 11:01:43 -08:00
|
|
|
nova_conf.add('xenapi_connection_username', xs_user)
|
2012-01-24 12:53:52 -08:00
|
|
|
nova_conf.add('xenapi_connection_password', self.cfg.get("passwords", "xenapi_connection"))
|
|
|
|
nova_conf.add_simple('noflat_injected')
|
2012-02-15 10:35:13 -08:00
|
|
|
xs_flat_ifc = self._getstr('xs_flat_interface', XS_DEF_INTERFACE)
|
2012-02-14 11:01:43 -08:00
|
|
|
if not utils.is_interface(xs_flat_ifc):
|
|
|
|
msg = "Xenserver flat interface %s is not a known interface" % (xs_flat_ifc)
|
2012-02-14 10:27:07 -08:00
|
|
|
raise exceptions.ConfigException(msg)
|
2012-02-14 11:01:43 -08:00
|
|
|
nova_conf.add('flat_interface', xs_flat_ifc)
|
2012-02-15 16:16:25 -08:00
|
|
|
nova_conf.add('firewall_driver', self._getstr('xs_firewall_driver', DEF_FIREWALL_DRIVER))
|
2012-02-14 11:01:43 -08:00
|
|
|
nova_conf.add('flat_network_bridge', self._getstr('xs_flat_network_bridge'))
|
2012-02-15 15:50:24 -08:00
|
|
|
elif drive_canon == virsh.VIRT_TYPE:
|
2012-02-02 13:35:00 -08:00
|
|
|
nova_conf.add('connection_type', 'libvirt')
|
2012-02-15 16:16:25 -08:00
|
|
|
nova_conf.add('firewall_driver', self._getstr('libvirt_firewall_driver', DEF_FIREWALL_DRIVER))
|
2012-01-24 12:53:52 -08:00
|
|
|
nova_conf.add('flat_network_bridge', self._getstr('flat_network_bridge'))
|
2012-01-27 23:14:16 -08:00
|
|
|
flat_interface = self._getstr('flat_interface')
|
|
|
|
if flat_interface:
|
2012-02-14 10:27:07 -08:00
|
|
|
if not utils.is_interface(flat_interface):
|
|
|
|
msg = "Libvirt flat interface %s is not a known interface" % (flat_interface)
|
2012-02-14 10:48:59 -08:00
|
|
|
raise exceptions.ConfigException(msg)
|
2012-01-27 23:14:16 -08:00
|
|
|
nova_conf.add('flat_interface', flat_interface)
|
2012-01-24 12:53:52 -08:00
|
|
|
|
|
|
|
|
|
|
|
# This class represents the data in the nova config file
|
2012-01-24 13:48:13 -08:00
|
|
|
class NovaConf(object):
|
2012-01-24 12:53:52 -08:00
|
|
|
def __init__(self):
|
|
|
|
self.lines = list()
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
|
|
|
def add(self, key, value):
|
|
|
|
self.lines.append({'key': key, 'options': [value]})
|
|
|
|
LOG.debug("Added nova conf key %s with value [%s]" % (key, value))
|
|
|
|
|
|
|
|
def _form_key(self, key, has_opts):
|
|
|
|
key_str = "--" + str(key)
|
|
|
|
if has_opts:
|
|
|
|
key_str += "="
|
|
|
|
return key_str
|
|
|
|
|
|
|
|
def generate(self, param_dict=None):
|
2012-02-13 18:25:45 -08:00
|
|
|
conf_lines = sorted(self.generate_lines(param_dict))
|
|
|
|
return utils.joinlinesep(*conf_lines)
|
|
|
|
|
|
|
|
def generate_lines(self, param_dict=None):
|
2012-01-24 12:53:52 -08:00
|
|
|
gen_lines = list()
|
|
|
|
for line_entry in self.lines:
|
|
|
|
key = line_entry.get('key')
|
|
|
|
opts = line_entry.get('options')
|
2012-01-25 14:58:45 -08:00
|
|
|
if not key:
|
2012-01-24 12:53:52 -08:00
|
|
|
continue
|
2012-01-25 13:30:43 -08:00
|
|
|
if opts is None:
|
2012-01-24 12:53:52 -08:00
|
|
|
key_str = self._form_key(key, False)
|
|
|
|
full_line = key_str
|
|
|
|
else:
|
2012-01-24 18:01:36 -08:00
|
|
|
key_str = self._form_key(key, True)
|
2012-01-24 12:53:52 -08:00
|
|
|
filled_opts = list()
|
|
|
|
for opt in opts:
|
2012-02-15 10:18:58 -08:00
|
|
|
if opt is not None:
|
|
|
|
filled_opts.append(utils.param_replace(str(opt), param_dict))
|
2012-01-24 12:53:52 -08:00
|
|
|
full_line = key_str + ",".join(filled_opts)
|
|
|
|
gen_lines.append(full_line)
|
|
|
|
return gen_lines
|