Merge branch 'master' of github.com:yahoo/Openstack-Devstack2
Conflicts: devstack/components/nova_conf.py
This commit is contained in:
commit
dfb9d6d51b
conf
devstack
stack@ -1,3 +1,6 @@
|
||||
## Based off of split glance-api-paste.ini commit 30439a6dc4
|
||||
## And split glance-api.conf commit 30439a6dc4
|
||||
|
||||
[DEFAULT]
|
||||
# Show more verbose log output (sets INFO log level output)
|
||||
verbose = True
|
||||
@ -120,7 +123,7 @@ image_cache_enabled = False
|
||||
|
||||
# Directory that the Image Cache writes data to
|
||||
# Make sure this is also set in glance-pruner.conf
|
||||
image_cache_datadir = /var/lib/glance/image-cache
|
||||
image_cache_datadir = /var/lib/glance/image-cache/
|
||||
|
||||
# Number of seconds after which we should consider an incomplete image to be
|
||||
# stalled and eligible for reaping
|
||||
@ -138,6 +141,10 @@ scrub_time = 43200
|
||||
# Make sure this is also set in glance-scrubber.conf
|
||||
scrubber_datadir = /var/lib/glance/scrubber
|
||||
|
||||
## SPLIT HERE ##
|
||||
## SPLIT HERE ##
|
||||
## SPLIT HERE ##
|
||||
|
||||
[pipeline:glance-api]
|
||||
#pipeline = versionnegotiation context apiv1app
|
||||
# NOTE: use the following pipeline for keystone
|
||||
@ -170,13 +177,13 @@ glance.filter_factory = glance.common.context:ContextMiddleware
|
||||
|
||||
[filter:authtoken]
|
||||
paste.filter_factory = keystone.middleware.auth_token:filter_factory
|
||||
service_protocol = http
|
||||
service_host = 127.0.0.1
|
||||
service_port = 5000
|
||||
auth_host = 127.0.0.1
|
||||
auth_port = 35357
|
||||
auth_protocol = http
|
||||
auth_uri = http://127.0.0.1:5000/
|
||||
service_host = %KEYSTONE_SERVICE_HOST%
|
||||
service_port = %KEYSTONE_SERVICE_PORT%
|
||||
service_protocol = %KEYSTONE_SERVICE_PROTOCOL%
|
||||
auth_host = %KEYSTONE_AUTH_HOST%
|
||||
auth_port = %KEYSTONE_AUTH_PORT%
|
||||
auth_protocol = %KEYSTONE_AUTH_PROTOCOL%
|
||||
auth_uri = %KEYSTONE_SERVICE_PROTOCOL%://%KEYSTONE_SERVICE_HOST%:%KEYSTONE_SERVICE_PORT%/
|
||||
admin_token = %SERVICE_TOKEN%
|
||||
|
||||
[filter:auth-context]
|
||||
|
@ -1,3 +1,6 @@
|
||||
## Based off of split glance-registry-paste.ini commit 30439a6dc4
|
||||
## And split glance-registry.conf commit 30439a6dc4
|
||||
|
||||
[DEFAULT]
|
||||
# Show more verbose log output (sets INFO log level output)
|
||||
verbose = True
|
||||
@ -43,6 +46,11 @@ api_limit_max = 1000
|
||||
# default to `limit_param_default`
|
||||
limit_param_default = 25
|
||||
|
||||
|
||||
## SPLIT HERE ##
|
||||
## SPLIT HERE ##
|
||||
## SPLIT HERE ##
|
||||
|
||||
[pipeline:glance-registry]
|
||||
#pipeline = context registryapp
|
||||
# NOTE: use the following pipeline for keystone
|
||||
@ -59,13 +67,13 @@ glance.filter_factory = glance.common.context:ContextMiddleware
|
||||
|
||||
[filter:authtoken]
|
||||
paste.filter_factory = keystone.middleware.auth_token:filter_factory
|
||||
service_protocol = http
|
||||
service_host = 127.0.0.1
|
||||
service_port = 5000
|
||||
auth_host = 127.0.0.1
|
||||
auth_port = 35357
|
||||
auth_protocol = http
|
||||
auth_uri = http://127.0.0.1:5000/
|
||||
service_host = %KEYSTONE_SERVICE_HOST%
|
||||
service_port = %KEYSTONE_SERVICE_PORT%
|
||||
service_protocol = %KEYSTONE_SERVICE_PROTOCOL%
|
||||
auth_host = %KEYSTONE_AUTH_HOST%
|
||||
auth_port = %KEYSTONE_AUTH_PORT%
|
||||
auth_protocol = %KEYSTONE_AUTH_PROTOCOL%
|
||||
auth_uri = %KEYSTONE_SERVICE_PROTOCOL%://%KEYSTONE_SERVICE_HOST%:%KEYSTONE_SERVICE_PORT%/
|
||||
admin_token = %SERVICE_TOKEN%
|
||||
|
||||
[filter:auth-context]
|
||||
|
@ -1,3 +1,7 @@
|
||||
# Based off of horizon_settings.py from commit 30439a6dc4
|
||||
# With a change to allow OPENSTACK_HOST to come in from
|
||||
# the new script instead of being fixed.
|
||||
|
||||
import os
|
||||
|
||||
DEBUG = True
|
||||
@ -50,7 +54,7 @@ OPENSTACK_KEYSTONE_DEFAULT_ROLE = "Member"
|
||||
SWIFT_PAGINATE_LIMIT = 100
|
||||
|
||||
# Configure quantum connection details for networking
|
||||
QUANTUM_ENABLED = %QUANTUM_ENABLED%
|
||||
QUANTUM_ENABLED = False
|
||||
QUANTUM_URL = '%s' % OPENSTACK_HOST
|
||||
QUANTUM_PORT = '9696'
|
||||
QUANTUM_TENANT = '1234'
|
||||
|
@ -7,6 +7,8 @@
|
||||
# Options like %ADMIN_PASSWORD% will be filled in with an actual value.
|
||||
#
|
||||
# Command ordering may matter, so be careful!
|
||||
#
|
||||
# Based off of commit 30439a6dc4 of keystone_data.sh
|
||||
{
|
||||
# Users
|
||||
"users": [
|
||||
@ -123,7 +125,7 @@
|
||||
"add",
|
||||
"swift",
|
||||
"object-store",
|
||||
"Swift Service"
|
||||
"\"Swift Service\""
|
||||
],
|
||||
# Endpoint template for swift
|
||||
[
|
||||
@ -145,7 +147,7 @@
|
||||
"add",
|
||||
"nova",
|
||||
"compute",
|
||||
"Nova Compute Service"
|
||||
"\"Nova Compute Service\""
|
||||
],
|
||||
# EC2 service
|
||||
[
|
||||
@ -153,7 +155,7 @@
|
||||
"add",
|
||||
"ec2",
|
||||
"ec2",
|
||||
"EC2 Compatability Layer"
|
||||
"\"EC2 Compatability Layer\""
|
||||
],
|
||||
# Endpoint template for nova
|
||||
[
|
||||
@ -220,7 +222,7 @@
|
||||
"add",
|
||||
"keystone",
|
||||
"identity",
|
||||
"Keystone Identity Service"
|
||||
"\"Keystone Identity Service\""
|
||||
]
|
||||
],
|
||||
"glance": [
|
||||
@ -230,7 +232,7 @@
|
||||
"add",
|
||||
"glance",
|
||||
"image",
|
||||
"Glance Image Service"
|
||||
"\"Glance Image Service\""
|
||||
],
|
||||
# Endpoint template for glance
|
||||
[
|
||||
|
@ -1,9 +1,11 @@
|
||||
# Based on keystone.conf commit 30439a6dc4
|
||||
|
||||
[DEFAULT]
|
||||
# Show more verbose log output (sets INFO log level output)
|
||||
verbose = False
|
||||
verbose = True
|
||||
|
||||
# Show debugging output in logs (sets DEBUG log level output)
|
||||
debug = False
|
||||
debug = True
|
||||
|
||||
# Which backend store should Keystone use by default.
|
||||
# Default: 'sqlite'
|
||||
@ -29,7 +31,7 @@ extensions= osksadm,oskscatalog
|
||||
|
||||
# Address to bind the API server
|
||||
# TODO Properties defined within app not available via pipeline.
|
||||
service_host = 0.0.0.0
|
||||
service_host = %SERVICE_HOST%
|
||||
|
||||
# Port the bind the API server to
|
||||
service_port = 5000
|
||||
@ -38,7 +40,7 @@ service_port = 5000
|
||||
service_ssl = False
|
||||
|
||||
# Address to bind the Admin API server
|
||||
admin_host = 0.0.0.0
|
||||
admin_host = %ADMIN_HOST%
|
||||
|
||||
# Port the bind the Admin API server to
|
||||
admin_port = 35357
|
||||
@ -71,6 +73,90 @@ keystone-service-admin-role = KeystoneServiceAdmin
|
||||
#Tells whether password user need to be hashed in the backend
|
||||
hash-password = True
|
||||
|
||||
[keystone.backends.sqlalchemy]
|
||||
# SQLAlchemy connection string for the reference implementation registry
|
||||
# server. Any valid SQLAlchemy connection string is fine.
|
||||
# See: http://bit.ly/ideIpI
|
||||
sql_connection = %SQL_CONN%
|
||||
backend_entities = ['UserRoleAssociation', 'Endpoints', 'Role', 'Tenant',
|
||||
'User', 'Credentials', 'EndpointTemplates', 'Token',
|
||||
'Service']
|
||||
|
||||
# Period in seconds after which SQLAlchemy should reestablish its connection
|
||||
# to the database.[DEFAULT]
|
||||
# Show more verbose log output (sets INFO log level output)
|
||||
verbose = False
|
||||
|
||||
# Show debugging output in logs (sets DEBUG log level output)
|
||||
debug = False
|
||||
|
||||
# Which backend store should Keystone use by default.
|
||||
# Default: 'sqlite'
|
||||
# Available choices are 'sqlite' [future will include LDAP, PAM, etc]
|
||||
default_store = sqlite
|
||||
|
||||
# Log to this file. Make sure you do not set the same log
|
||||
# file for both the API and registry servers!
|
||||
log_file = %DEST%/keystone/keystone.log
|
||||
|
||||
# List of backends to be configured
|
||||
backends = keystone.backends.sqlalchemy
|
||||
#For LDAP support, add: ,keystone.backends.ldap
|
||||
|
||||
# Dictionary Maps every service to a header.Missing services would get header
|
||||
# X_(SERVICE_NAME) Key => Service Name, Value => Header Name
|
||||
service-header-mappings = {
|
||||
'nova' : 'X-Server-Management-Url',
|
||||
'swift' : 'X-Storage-Url',
|
||||
'cdn' : 'X-CDN-Management-Url'}
|
||||
|
||||
#List of extensions currently supported
|
||||
extensions= osksadm,oskscatalog
|
||||
|
||||
# Address to bind the API server
|
||||
# TODO Properties defined within app not available via pipeline.
|
||||
service_host = %SERVICE_HOST%
|
||||
|
||||
# Port the bind the API server to
|
||||
service_port = 5000
|
||||
|
||||
# SSL for API server
|
||||
service_ssl = False
|
||||
|
||||
# Address to bind the Admin API server
|
||||
admin_host = %ADMIN_HOST%
|
||||
|
||||
# Port the bind the Admin API server to
|
||||
admin_port = 35357
|
||||
|
||||
# SSL for API Admin server
|
||||
admin_ssl = False
|
||||
|
||||
# Keystone certificate file (modify as needed)
|
||||
# Only required if *_ssl is set to True
|
||||
certfile = /etc/keystone/ssl/certs/keystone.pem
|
||||
|
||||
# Keystone private key file (modify as needed)
|
||||
# Only required if *_ssl is set to True
|
||||
keyfile = /etc/keystone/ssl/private/keystonekey.pem
|
||||
|
||||
# Keystone trusted CA certificates (modify as needed)
|
||||
# Only required if *_ssl is set to True
|
||||
ca_certs = /etc/keystone/ssl/certs/ca.pem
|
||||
|
||||
# Client certificate required
|
||||
# Only relevant if *_ssl is set to True
|
||||
cert_required = True
|
||||
|
||||
#Role that allows to perform admin operations.
|
||||
keystone-admin-role = admin
|
||||
|
||||
#Role that allows to perform service admin operations.
|
||||
keystone-service-admin-role = KeystoneServiceAdmin
|
||||
|
||||
#Tells whether password user need to be hashed in the backend
|
||||
hash-password = True
|
||||
|
||||
[keystone.backends.sqlalchemy]
|
||||
# SQLAlchemy connection string for the reference implementation registry
|
||||
# server. Any valid SQLAlchemy connection string is fine.
|
||||
@ -84,6 +170,33 @@ backend_entities = ['UserRoleAssociation', 'Endpoints', 'Role', 'Tenant',
|
||||
# to the database.
|
||||
sql_idle_timeout = 30
|
||||
|
||||
[pipeline:admin]
|
||||
pipeline =
|
||||
urlrewritefilter
|
||||
admin_api
|
||||
|
||||
[pipeline:keystone-legacy-auth]
|
||||
pipeline =
|
||||
urlrewritefilter
|
||||
legacy_auth
|
||||
service_api
|
||||
|
||||
[app:service_api]
|
||||
paste.app_factory = keystone.server:service_app_factory
|
||||
|
||||
[app:admin_api]
|
||||
paste.app_factory = keystone.server:admin_app_factory
|
||||
|
||||
[filter:urlrewritefilter]
|
||||
paste.filter_factory = keystone.middleware.url:filter_factory
|
||||
|
||||
[filter:legacy_auth]
|
||||
paste.filter_factory = keystone.frontends.legacy_token_auth:filter_factory
|
||||
|
||||
[filter:debug]
|
||||
paste.filter_factory = keystone.common.wsgi:debug_filter_factory
|
||||
sql_idle_timeout = 30
|
||||
|
||||
[pipeline:admin]
|
||||
pipeline =
|
||||
urlrewritefilter
|
||||
|
@ -1,3 +1,5 @@
|
||||
# Based on api-paste.ini commit 57cf8312b8
|
||||
|
||||
############
|
||||
# Metadata #
|
||||
############
|
||||
@ -36,16 +38,18 @@ use = egg:Paste#urlmap
|
||||
/services/Admin: ec2admin
|
||||
|
||||
[pipeline:ec2cloud]
|
||||
pipeline = ec2faultwrap logrequest totoken authtoken keystonecontext cloudrequest authorizer ec2executor
|
||||
pipeline = ec2faultwrap logrequest ec2noauth cloudrequest authorizer validator ec2executor
|
||||
# NOTE(vish): use the following pipeline for deprecated auth
|
||||
# pipeline = ec2faultwrap logrequest authenticate cloudrequest authorizer validator ec2executor
|
||||
# NOTE(vish): use the following pipeline for keystone auth
|
||||
# pipeline = ec2faultwrap logrequest totoken authtoken keystonecontext cloudrequest authorizer validator ec2executor
|
||||
|
||||
[pipeline:ec2admin]
|
||||
pipeline = ec2faultwrap logrequest totoken authtoken keystonecontext adminrequest authorizer ec2executor
|
||||
|
||||
[pipeline:ec2metadata]
|
||||
pipeline = ec2faultwrap logrequest ec2md
|
||||
|
||||
[pipeline:ec2versions]
|
||||
pipeline = ec2faultwrap logrequest ec2ver
|
||||
pipeline = ec2faultwrap logrequest ec2noauth adminrequest authorizer ec2executor
|
||||
# NOTE(vish): use the following pipeline for deprecated auth
|
||||
# pipeline = ec2faultwrap logrequest authenticate adminrequest authorizer ec2executor
|
||||
# NOTE(vish): use the following pipeline for keystone auth
|
||||
# pipeline = ec2faultwrap logrequest totoken authtoken keystonecontext adminrequest authorizer ec2executor
|
||||
|
||||
[filter:ec2faultwrap]
|
||||
paste.filter_factory = nova.api.ec2:FaultWrapper.factory
|
||||
@ -57,7 +61,7 @@ paste.filter_factory = nova.api.ec2:RequestLogging.factory
|
||||
paste.filter_factory = nova.api.ec2:Lockout.factory
|
||||
|
||||
[filter:totoken]
|
||||
paste.filter_factory = keystone.middleware.ec2_token:EC2Token.factory
|
||||
paste.filter_factory = nova.api.ec2:EC2Token.factory
|
||||
|
||||
[filter:ec2noauth]
|
||||
paste.filter_factory = nova.api.ec2:NoAuth.factory
|
||||
@ -76,6 +80,9 @@ paste.filter_factory = nova.api.ec2:Requestify.factory
|
||||
[filter:authorizer]
|
||||
paste.filter_factory = nova.api.ec2:Authorizer.factory
|
||||
|
||||
[filter:validator]
|
||||
paste.filter_factory = nova.api.ec2:Validator.factory
|
||||
|
||||
[app:ec2executor]
|
||||
paste.app_factory = nova.api.ec2:Executor.factory
|
||||
|
||||
@ -83,48 +90,67 @@ paste.app_factory = nova.api.ec2:Executor.factory
|
||||
# Openstack #
|
||||
#############
|
||||
|
||||
[composite:osapi]
|
||||
use = call:nova.api.openstack.v2.urlmap:urlmap_factory
|
||||
/: osversions
|
||||
/v1.1: openstack_api_v2
|
||||
/v2: openstack_api_v2
|
||||
[composite:osapi_compute]
|
||||
use = call:nova.api.openstack.urlmap:urlmap_factory
|
||||
/: oscomputeversions
|
||||
/v1.1: openstack_compute_api_v2
|
||||
/v2: openstack_compute_api_v2
|
||||
|
||||
[pipeline:openstack_api_v2]
|
||||
pipeline = faultwrap authtoken keystonecontext ratelimit serialize extensions osapi_app_v2
|
||||
[composite:osapi_volume]
|
||||
use = call:nova.api.openstack.urlmap:urlmap_factory
|
||||
/: osvolumeversions
|
||||
/v1: openstack_volume_api_v1
|
||||
|
||||
[pipeline:openstack_compute_api_v2]
|
||||
pipeline = faultwrap noauth ratelimit osapi_compute_app_v2
|
||||
# NOTE(vish): use the following pipeline for deprecated auth
|
||||
# pipeline = faultwrap auth ratelimit osapi_compute_app_v2
|
||||
# NOTE(vish): use the following pipeline for keystone auth
|
||||
# pipeline = faultwrap authtoken keystonecontext ratelimit osapi_compute_app_v2
|
||||
|
||||
[pipeline:openstack_volume_api_v1]
|
||||
pipeline = faultwrap noauth ratelimit osapi_volume_app_v1
|
||||
# NOTE(vish): use the following pipeline for deprecated auth
|
||||
# pipeline = faultwrap auth ratelimit osapi_volume_app_v1
|
||||
# NOTE(vish): use the following pipeline for keystone auth
|
||||
# pipeline = faultwrap authtoken keystonecontext ratelimit osapi_volume_app_v1
|
||||
|
||||
[filter:faultwrap]
|
||||
paste.filter_factory = nova.api.openstack.v2:FaultWrapper.factory
|
||||
paste.filter_factory = nova.api.openstack:FaultWrapper.factory
|
||||
|
||||
[filter:auth]
|
||||
paste.filter_factory = nova.api.openstack.v2.auth:AuthMiddleware.factory
|
||||
paste.filter_factory = nova.api.openstack.auth:AuthMiddleware.factory
|
||||
|
||||
[filter:noauth]
|
||||
paste.filter_factory = nova.api.openstack.v2.auth:NoAuthMiddleware.factory
|
||||
paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory
|
||||
|
||||
[filter:ratelimit]
|
||||
paste.filter_factory = nova.api.openstack.v2.limits:RateLimitingMiddleware.factory
|
||||
paste.filter_factory = nova.api.openstack.compute.limits:RateLimitingMiddleware.factory
|
||||
|
||||
[filter:serialize]
|
||||
paste.filter_factory = nova.api.openstack.wsgi:LazySerializationMiddleware.factory
|
||||
[app:osapi_compute_app_v2]
|
||||
paste.app_factory = nova.api.openstack.compute:APIRouter.factory
|
||||
|
||||
[filter:extensions]
|
||||
paste.filter_factory = nova.api.openstack.v2.extensions:ExtensionMiddleware.factory
|
||||
[pipeline:oscomputeversions]
|
||||
pipeline = faultwrap oscomputeversionapp
|
||||
|
||||
[app:osapi_app_v2]
|
||||
paste.app_factory = nova.api.openstack.v2:APIRouter.factory
|
||||
[app:osapi_volume_app_v1]
|
||||
paste.app_factory = nova.api.openstack.volume:APIRouter.factory
|
||||
|
||||
[pipeline:osversions]
|
||||
pipeline = faultwrap osversionapp
|
||||
[app:oscomputeversionapp]
|
||||
paste.app_factory = nova.api.openstack.compute.versions:Versions.factory
|
||||
|
||||
[app:osversionapp]
|
||||
paste.app_factory = nova.api.openstack.v2.versions:Versions.factory
|
||||
[pipeline:osvolumeversions]
|
||||
pipeline = faultwrap osvolumeversionapp
|
||||
|
||||
[app:osvolumeversionapp]
|
||||
paste.app_factory = nova.api.openstack.volume.versions:Versions.factory
|
||||
|
||||
##########
|
||||
# Shared #
|
||||
##########
|
||||
|
||||
[filter:keystonecontext]
|
||||
paste.filter_factory = keystone.middleware.nova_keystone_context:NovaKeystoneContext.factory
|
||||
paste.filter_factory = nova.api.auth:NovaKeystoneContext.factory
|
||||
|
||||
[filter:authtoken]
|
||||
paste.filter_factory = keystone.middleware.auth_token:filter_factory
|
||||
@ -135,4 +161,5 @@ auth_host = 127.0.0.1
|
||||
auth_port = 35357
|
||||
auth_protocol = http
|
||||
auth_uri = http://127.0.0.1:5000/
|
||||
# NOTE(vish): you will have to replace the value below with an actual admin token
|
||||
admin_token = %SERVICE_TOKEN%
|
||||
|
@ -57,7 +57,7 @@
|
||||
},
|
||||
# Only really needed if you plan on using kvm
|
||||
"kvm": {
|
||||
"version": "1:84+dfsg-0ubuntu16+0.14.1+noroms+0ubuntu6.1",
|
||||
"version": "1:84+dfsg-0ubuntu16+0.14.1+noroms+0ubuntu6.2",
|
||||
"allowed": ">=",
|
||||
"removable": true
|
||||
},
|
||||
|
@ -130,6 +130,7 @@ multi_host = ${MULTI_HOST:-0}
|
||||
# Virtualization settings
|
||||
virt_driver = ${VIRT_DRIVER:-libvirt}
|
||||
libvirt_type = ${LIBVIRT_TYPE:-kvm}
|
||||
connection_type = ${CONNECTION_TYPE:-libvirt}
|
||||
|
||||
# What tyoe of image service will be used?
|
||||
img_service = ${IMG_SERVICE:-nova.image.glance.GlanceImageService}
|
||||
@ -138,6 +139,11 @@ glance_server = ${GLANCE_SERVER:-$(host:ip):9292}
|
||||
# Used however you want - ensure you know nova's conf file format if you use this!
|
||||
extra_flags = ${NOVA_EXTRA_FLAGS:-}
|
||||
|
||||
|
||||
floating_range=${FLOATING_RANGE:-172.24.4.224/28}
|
||||
test_floating_pool=${TEST_FLOATING_POOL:-test}
|
||||
test_floating_range=${TEST_FLOATING_RANGE:-192.168.253.0/29}
|
||||
|
||||
[EC2]
|
||||
|
||||
# Set the ec2 url so euca2ools works
|
||||
|
@ -17,10 +17,11 @@ import io
|
||||
|
||||
from devstack import cfg
|
||||
from devstack import component as comp
|
||||
from devstack import settings
|
||||
from devstack import log as logging
|
||||
from devstack import settings
|
||||
from devstack import shell as sh
|
||||
from devstack.components import db
|
||||
from devstack.components import keystone
|
||||
from devstack.image import creator
|
||||
|
||||
LOG = logging.getLogger("devstack.components.glance")
|
||||
@ -33,6 +34,9 @@ CONFIGS = [API_CONF, REG_CONF]
|
||||
DB_NAME = "glance"
|
||||
CFG_SECTION = 'DEFAULT'
|
||||
|
||||
#special subcomponents that is used in starting to know that images should be uploaded
|
||||
IMG_START = "upload-images"
|
||||
|
||||
#what to start
|
||||
APP_OPTIONS = {
|
||||
'glance-api': ['--config-file', sh.joinpths('%ROOT%', "etc", API_CONF)],
|
||||
@ -67,8 +71,9 @@ class GlanceRuntime(comp.PythonRuntime):
|
||||
|
||||
def post_start(self):
|
||||
comp.PythonRuntime.post_start(self)
|
||||
#install any images that need activating...
|
||||
creator.ImageCreationService(self.cfg).install()
|
||||
if(IMG_START in self.component_opts):
|
||||
#install any images that need activating...
|
||||
creator.ImageCreationService(self.cfg).install()
|
||||
|
||||
|
||||
class GlanceInstaller(comp.PythonInstallComponent):
|
||||
@ -152,8 +157,8 @@ class GlanceInstaller(comp.PythonInstallComponent):
|
||||
mp = dict()
|
||||
mp['DEST'] = self.appdir
|
||||
mp['SYSLOG'] = self.cfg.getboolean("default", "syslog")
|
||||
mp['SERVICE_TOKEN'] = self.cfg.get("passwords", "service_token")
|
||||
mp['SQL_CONN'] = self.cfg.get_dbdsn(DB_NAME)
|
||||
mp['SERVICE_HOST'] = self.cfg.get('host', 'ip')
|
||||
mp['HOST_IP'] = self.cfg.get('host', 'ip')
|
||||
mp.update(keystone.get_shared_params(self.cfg))
|
||||
return mp
|
||||
|
@ -162,27 +162,18 @@ class KeystoneInstaller(comp.PythonInstallComponent):
|
||||
#params with actual values
|
||||
mp = dict()
|
||||
if(config_fn == ROOT_CONF):
|
||||
host_ip = self.cfg.get('host', 'ip')
|
||||
mp['DEST'] = self.appdir
|
||||
mp['SQL_CONN'] = self.cfg.get_dbdsn(DB_NAME)
|
||||
mp['SERVICE_HOST'] = host_ip
|
||||
mp['ADMIN_HOST'] = host_ip
|
||||
elif(config_fn == MANAGE_JSON_CONF):
|
||||
host_ip = self.cfg.get('host', 'ip')
|
||||
mp['ADMIN_PASSWORD'] = self.cfg.get('passwords', 'horizon_keystone_admin')
|
||||
mp['SERVICE_HOST'] = host_ip
|
||||
mp['SERVICE_TOKEN'] = self.cfg.get("passwords", "service_token")
|
||||
mp['BIN_DIR'] = self.bindir
|
||||
mp['CONFIG_FILE'] = sh.joinpths(self.cfgdir, ROOT_CONF)
|
||||
keystone_auth_host = self.cfg.get('keystone', 'keystone_auth_host')
|
||||
if(not keystone_auth_host):
|
||||
keystone_auth_host = host_ip
|
||||
mp['KEYSTONE_AUTH_HOST'] = keystone_auth_host
|
||||
mp['KEYSTONE_AUTH_PORT'] = self.cfg.get('keystone', 'keystone_auth_port')
|
||||
mp['KEYSTONE_AUTH_PROTOCOL'] = self.cfg.get('keystone', 'keystone_auth_protocol')
|
||||
keystone_service_host = self.cfg.get('keystone', 'keystone_service_host')
|
||||
if(not keystone_service_host):
|
||||
keystone_service_host = host_ip
|
||||
mp['KEYSTONE_SERVICE_HOST'] = keystone_service_host
|
||||
mp['KEYSTONE_SERVICE_PORT'] = self.cfg.get('keystone', 'keystone_service_port')
|
||||
mp['KEYSTONE_SERVICE_PROTOCOL'] = self.cfg.get('keystone', 'keystone_service_protocol')
|
||||
mp.update(get_shared_params(self.cfg))
|
||||
else:
|
||||
mp['DEST'] = self.appdir
|
||||
mp['BIN_DIR'] = self.bindir
|
||||
@ -207,3 +198,21 @@ class KeystoneRuntime(comp.PythonRuntime):
|
||||
|
||||
def _get_app_options(self, app):
|
||||
return APP_OPTIONS.get(app)
|
||||
|
||||
def get_shared_params(cfg):
|
||||
mp = dict()
|
||||
host_ip = cfg.get('host', 'ip')
|
||||
keystone_auth_host = cfg.get('keystone', 'keystone_auth_host')
|
||||
if(not keystone_auth_host):
|
||||
keystone_auth_host = host_ip
|
||||
mp['KEYSTONE_AUTH_HOST'] = keystone_auth_host
|
||||
mp['KEYSTONE_AUTH_PORT'] = cfg.get('keystone', 'keystone_auth_port')
|
||||
mp['KEYSTONE_AUTH_PROTOCOL'] = cfg.get('keystone', 'keystone_auth_protocol')
|
||||
keystone_service_host = cfg.get('keystone', 'keystone_service_host')
|
||||
if(not keystone_service_host):
|
||||
keystone_service_host = host_ip
|
||||
mp['KEYSTONE_SERVICE_HOST'] = keystone_service_host
|
||||
mp['KEYSTONE_SERVICE_PORT'] = cfg.get('keystone', 'keystone_service_port')
|
||||
mp['KEYSTONE_SERVICE_PROTOCOL'] = cfg.get('keystone', 'keystone_service_protocol')
|
||||
mp['SERVICE_TOKEN'] = cfg.get("passwords", "service_token")
|
||||
return mp
|
||||
|
@ -13,48 +13,70 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
from devstack import component as comp
|
||||
from devstack import log as logging
|
||||
from devstack import settings
|
||||
from devstack import utils
|
||||
from devstack import shell as sh
|
||||
from devstack.components import db
|
||||
from devstack.components import nova_conf as nc
|
||||
|
||||
LOG = logging.getLogger("devstack.components.nova")
|
||||
LOG = logging.getLogger('devstack.components.nova')
|
||||
|
||||
API_CONF = "nova.conf"
|
||||
API_CONF = 'nova.conf'
|
||||
PASTE_CONF = 'nova-api-paste.ini'
|
||||
CONFIGS = [API_CONF]
|
||||
|
||||
DB_NAME = "nova"
|
||||
DB_NAME = 'nova'
|
||||
BIN_DIR = 'bin'
|
||||
TYPE = settings.NOVA
|
||||
|
||||
#what to start
|
||||
APP_OPTIONS = {
|
||||
'nova-api': [],
|
||||
settings.NCPU: [],
|
||||
settings.NVOL: [],
|
||||
'nova-network': [],
|
||||
'nova-scheduler': []
|
||||
'nova-api': ['--flagfile', '%CFGFILE%'],
|
||||
settings.NCPU: ['--flagfile', '%CFGFILE%'],
|
||||
settings.NVOL: ['--flagfile', '%CFGFILE%'],
|
||||
'nova-network': ['--flagfile', '%CFGFILE%'],
|
||||
'nova-scheduler': ['--flagfile', '%CFGFILE%']
|
||||
}
|
||||
|
||||
POST_INSTALL_CMDS = [
|
||||
{'cmd': ['%BINDIR%nova-manage', '--flagfile', '%CFGFILE%',
|
||||
'db', 'sync']},
|
||||
{'cmd': ['%BINDIR%nova-manage', '--flagfile', '%CFGFILE%',
|
||||
'floating', 'create', '%FLOATING_RANGE%']},
|
||||
{'cmd': ['%BINDIR%nova-manage', '--flagfile', '%CFGFILE%',
|
||||
'floating', 'create', '--ip_range=%TEST_FLOATING_RANGE%',
|
||||
'--pool=%TEST_FLOATING_POOL%']}
|
||||
]
|
||||
|
||||
# In case we need to map names to the image to run
|
||||
APP_NAME_MAP = {
|
||||
settings.NCPU: 'nova-compute',
|
||||
settings.NVOL: 'nova-volume',
|
||||
}
|
||||
CONFIG_ACTUAL_DIR = 'etc'
|
||||
BIN_DIR = 'bin'
|
||||
# FIXME, need base bin dir
|
||||
DB_SYNC = ['/bin/nova-manage', 'db', 'sync']
|
||||
|
||||
#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
|
||||
|
||||
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):
|
||||
def __init__(self, *args, **kargs):
|
||||
comp.PythonUninstallComponent.__init__(self, TYPE, *args, **kargs)
|
||||
#self.cfgdir = joinpths(self.appdir, CONFIG_ACTUAL_DIR)
|
||||
|
||||
|
||||
class NovaInstaller(comp.PythonInstallComponent):
|
||||
@ -66,9 +88,8 @@ class NovaInstaller(comp.PythonInstallComponent):
|
||||
|
||||
def get_pkglist(self):
|
||||
pkgs = comp.PkgInstallComponent.get_pkglist(self)
|
||||
LOG.debug("pkg list from parent: %s" % (pkgs))
|
||||
# Walk through the subcomponents (like 'vol' and 'cpu') and add those
|
||||
# those packages as well. (Let utils.get_pkg_list handle any missing
|
||||
# those packages as well. (Let utils.get_pkglist handle any missing
|
||||
# entries
|
||||
LOG.debug("get_pkglist looking for extras: %s" % (self.component_opts))
|
||||
for cname in self.component_opts:
|
||||
@ -83,17 +104,24 @@ class NovaInstaller(comp.PythonInstallComponent):
|
||||
})
|
||||
return places
|
||||
|
||||
def _get_config_files(self):
|
||||
return list(CONFIGS)
|
||||
|
||||
def post_install(self):
|
||||
parent_result = comp.PkgInstallComponent.post_install(self)
|
||||
LOG.debug("Parent post_install results:%s" % (parent_result))
|
||||
#extra actions to do nova setup
|
||||
LOG.debug("Setting up our database")
|
||||
self._setup_db()
|
||||
# Need to do db sync
|
||||
# Need to do nova-managber create private
|
||||
# TBD, do we need to so nova-api start first?
|
||||
# If using q-qvc, skip
|
||||
# $NOVA_DIR/bin/nova-manage floating create $FLOATING_RANGE
|
||||
# $NOVA_DIR/bin/nova-manage floating create --ip_range=$TEST_FLOATING_RANGE --pool=$TEST_FLOATING_POOL
|
||||
# Need to do db sync and other post install commands
|
||||
# set up replacement map for CFGFILE, BINDIR, FLOATING_RANGE,
|
||||
# TEST_FLOATING_RANGE, TEST_FLOATING_POOL
|
||||
mp = dict()
|
||||
mp['BINDIR'] = self.bindir + os.sep
|
||||
mp['CFGFILE'] = self.cfgdir + os.sep + API_CONF
|
||||
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')
|
||||
utils.execute_template(*POST_INSTALL_CMDS, params=mp, tracewriter=self.tracewriter)
|
||||
return parent_result
|
||||
|
||||
def _setup_db(self):
|
||||
@ -107,12 +135,11 @@ class NovaInstaller(comp.PythonInstallComponent):
|
||||
dirs['app'] = self.appdir
|
||||
dirs['cfg'] = self.cfgdir
|
||||
dirs['bin'] = self.bindir
|
||||
conf_gen = nc.NovaConfigurator(self.cfg, self.instances)
|
||||
conf_gen = NovaConfigurator(self.cfg, self.instances)
|
||||
nova_conf = conf_gen.configure(dirs)
|
||||
tgtfn = self.get_target_config_name(API_CONF)
|
||||
LOG.info("Created nova configuration:")
|
||||
LOG.info("Writing conf to %s" % (tgtfn))
|
||||
LOG.info(nova_conf)
|
||||
LOG.debug("Placing it in %s" % (tgtfn))
|
||||
sh.write_file(tgtfn, nova_conf)
|
||||
#we configured one file, return that we did that
|
||||
return 1
|
||||
@ -124,31 +151,256 @@ class NovaInstaller(comp.PythonInstallComponent):
|
||||
class NovaRuntime(comp.PythonRuntime):
|
||||
def __init__(self, *args, **kargs):
|
||||
comp.PythonRuntime.__init__(self, TYPE, *args, **kargs)
|
||||
self.run_tokens = dict()
|
||||
self.run_tokens['CFGFILE'] = self.cfgdir + os.sep + API_CONF
|
||||
LOG.debug("Setting CFGFILE run_token to:%s" % (self.run_tokens['CFGFILE']))
|
||||
|
||||
def _get_aps_to_start(self):
|
||||
# Check if component_opts was set to a subset of apps to be started
|
||||
apps = list()
|
||||
if (not self.component_opts and len(self.component_opts) > 0):
|
||||
if not self.component_opts and len(self.component_opts) > 0:
|
||||
LOG.debug("Attempt to use subset of components:%s" % (self.component_opts))
|
||||
# check if the specified sub components exist
|
||||
delta = set(self.component_opts) - set(APP_OPTIONS.keys())
|
||||
if (delta):
|
||||
if delta:
|
||||
# FIXME, error, something was specified that we don't have
|
||||
LOG.error("sub items that we don't know about:%s" % delta)
|
||||
else:
|
||||
apps = self.component_opts
|
||||
LOG.debug("Using specified subcomponents:%s" % (apps))
|
||||
else:
|
||||
apps = APP_OPTIONS.keys()
|
||||
LOG.debug("Using the keys from APP_OPTIONS:%s" % (apps))
|
||||
|
||||
result = list()
|
||||
for app_name in apps:
|
||||
if (app_name in APP_NAME_MAP):
|
||||
if app_name in APP_NAME_MAP:
|
||||
app_name = APP_NAME_MAP.get(app_name)
|
||||
LOG.debug("Renamed app_name to:" + app_name)
|
||||
list.append({
|
||||
'name': app_name,
|
||||
'path': sh.joinpths(self.appdir, BIN_DIR, app_name),
|
||||
})
|
||||
LOG.debug("exiting _get_aps_to_start with:%s" % (result))
|
||||
return result
|
||||
|
||||
def _get_app_options(self, app):
|
||||
return APP_OPTIONS.get(app)
|
||||
result = list()
|
||||
for opt_str in APP_OPTIONS.get(app):
|
||||
LOG.debug("Checking opt_str for tokens: %s" % (opt_str))
|
||||
result.append(utils.param_replace(opt_str, self.run_tokens))
|
||||
|
||||
LOG.debug("_get_app_options returning with:%s" % (result))
|
||||
return result
|
||||
|
||||
|
||||
# This class has the smarts to build the configuration file based on
|
||||
# various runtime values
|
||||
class NovaConfigurator(object):
|
||||
def __init__(self, cfg, instances):
|
||||
self.cfg = cfg
|
||||
self.instances = instances
|
||||
|
||||
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 = NovaConf()
|
||||
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?
|
||||
scheduler = self._getstr('scheduler')
|
||||
if not scheduler:
|
||||
scheduler = DEF_SCHEDULER
|
||||
nova_conf.add('scheduler_driver', scheduler)
|
||||
|
||||
flag_conf_fn = sh.joinpths(dirs.get('bin'), API_CONF)
|
||||
nova_conf.add('dhcpbridge_flagfile', flag_conf_fn)
|
||||
|
||||
#whats the network fixed range?
|
||||
nova_conf.add('fixed_range', self._getstr('fixed_range'))
|
||||
|
||||
if settings.QUANTUM in self.instances:
|
||||
#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 add q-svc support
|
||||
#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_MANAGER_TEMPLATE % (self._getstr('network_manager')))
|
||||
|
||||
# TODO add n-vol support
|
||||
# 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)
|
||||
|
||||
#setup your sql connection and what type of virt u will be doing
|
||||
nova_conf.add('sql_connection', self.cfg.get_dbdsn('nova'))
|
||||
|
||||
#configure anything libvirt releated?
|
||||
self._configure_libvirt(self._getstr('libvirt_type'), nova_conf)
|
||||
|
||||
#how instances will be presented
|
||||
instance_template = (self._getstr('instance_name_prefix') +
|
||||
self._getstr('instance_name_postfix'))
|
||||
nova_conf.add('instance_name_template', instance_template)
|
||||
|
||||
if settings.OPENSTACK_X in self.instances:
|
||||
nova_conf.add('osapi_compute_extension', 'nova.api.openstack.compute.contrib.standard_extensions')
|
||||
nova_conf.add('osapi_compute_extension', 'extensions.admin.Admin')
|
||||
|
||||
if settings.NOVNC in self.instances:
|
||||
vncproxy_url = self._getstr('vncproxy_url')
|
||||
if not vncproxy_url:
|
||||
vncproxy_url = 'http://' + hostip + ':6080/vnc_auto.html'
|
||||
nova_conf.add('vncproxy_url', vncproxy_url)
|
||||
|
||||
paste_conf_fn = sh.joinpths(dirs.get('bin'), PASTE_CONF)
|
||||
nova_conf.add('api_paste_config', paste_conf_fn)
|
||||
|
||||
img_service = self._getstr('img_service')
|
||||
if not img_service:
|
||||
img_service = DEF_IMAGE_SERVICE
|
||||
nova_conf.add('image_service', img_service)
|
||||
|
||||
ec2_dmz_host = self._getstr('ec2_dmz_host')
|
||||
if not ec2_dmz_host:
|
||||
ec2_dmz_host = hostip
|
||||
nova_conf.add('ec2_dmz_host', ec2_dmz_host)
|
||||
|
||||
#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 is glance located?
|
||||
glance_api_server = self._getstr('glance_server')
|
||||
if not glance_api_server:
|
||||
glance_api_server = "%s:%d" % (hostip, DEF_GLANCE_PORT)
|
||||
nova_conf.add('glance_api_servers', glance_api_server)
|
||||
nova_conf.add_simple('force_dhcp_release')
|
||||
|
||||
#where instances will be stored
|
||||
instances_path = self._getstr('instances_path')
|
||||
if instances_path:
|
||||
nova_conf.add('instances_path', instances_path)
|
||||
|
||||
#is this a multihost setup?
|
||||
if self._getbool('multi_host'):
|
||||
nova_conf.add_simple('multi_host')
|
||||
nova_conf.add_simple('send_arp_for_ha')
|
||||
|
||||
#enable syslog??
|
||||
if self.cfg.getboolean('default', 'syslog'):
|
||||
nova_conf.add_simple('use_syslog')
|
||||
|
||||
#handle any virt driver specifics
|
||||
virt_driver = self._getstr('virt_driver')
|
||||
self._configure_virt_driver(virt_driver, nova_conf)
|
||||
|
||||
#now make it
|
||||
conf_lines = sorted(nova_conf.generate())
|
||||
complete_file = utils.joinlinesep(*conf_lines)
|
||||
|
||||
#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
|
||||
|
||||
def _configure_libvirt(self, virt_type, nova_conf):
|
||||
if not virt_type:
|
||||
return
|
||||
nova_conf.add('libvirt_type', virt_type)
|
||||
|
||||
#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')
|
||||
nova_conf.add('xenapi_connection_password', self.cfg.get("passwords", "xenapi_connection"))
|
||||
nova_conf.add_simple('noflat_injected')
|
||||
nova_conf.add('flat_interface', 'eth1')
|
||||
nova_conf.add('flat_network_bridge', 'xapi1')
|
||||
else:
|
||||
nova_conf.add('connection_type', self._getstr('connection_type'))
|
||||
nova_conf.add('flat_network_bridge', self._getstr('flat_network_bridge'))
|
||||
nova_conf.add('flat_interface', self._getstr('flat_interface'))
|
||||
|
||||
|
||||
# This class represents the data in the nova config file
|
||||
class NovaConf(object):
|
||||
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):
|
||||
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 gen_lines
|
||||
|
@ -1,250 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# 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.
|
||||
|
||||
from devstack import log as logging
|
||||
from devstack import settings
|
||||
from devstack import shell as sh
|
||||
from devstack import utils
|
||||
|
||||
LOG = logging.getLogger("devstack.components.nova_conf")
|
||||
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
|
||||
|
||||
#TODO use this
|
||||
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 NovaConfigurator():
|
||||
def __init__(self, cfg, instances):
|
||||
self.cfg = cfg
|
||||
self.instances = instances
|
||||
|
||||
def _getbool(self, name):
|
||||
return self.cfg.getboolean('nova', name)
|
||||
|
||||
def _getstr(self, name):
|
||||
return self.cfg.get('nova', name)
|
||||
|
||||
def configure(self, dirs):
|
||||
|
||||
#need to do this late
|
||||
from devstack.components import nova
|
||||
|
||||
#TODO split up into sections??
|
||||
|
||||
nova_conf = NovaConf()
|
||||
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?
|
||||
scheduler = self._getstr('scheduler')
|
||||
if(not scheduler):
|
||||
scheduler = DEF_SCHEDULER
|
||||
nova_conf.add('scheduler_driver', scheduler)
|
||||
|
||||
# TODO is this the right directory?
|
||||
flag_conf_fn = sh.joinpths(dirs.get('bin'), nova.API_CONF)
|
||||
nova_conf.add('dhcpbridge_flagfile', flag_conf_fn)
|
||||
|
||||
#whats the network fixed range?
|
||||
nova_conf.add('fixed_range', self._getstr('fixed_range'))
|
||||
|
||||
if(settings.QUANTUM in self.instances):
|
||||
#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_MANAGER_TEMPLATE % (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)
|
||||
|
||||
#setup your sql connection and what type of virt u will be doing
|
||||
nova_conf.add('sql_connection', self.cfg.get_dbdsn('nova'))
|
||||
|
||||
#configure anything libvirt releated?
|
||||
self._configure_libvirt(self._getstr('libvirt_type'), nova_conf)
|
||||
|
||||
#how instances will be presented
|
||||
instance_template = (self._getstr('instance_name_prefix') +
|
||||
self._getstr('instance_name_postfix'))
|
||||
nova_conf.add('instance_name_template', instance_template)
|
||||
|
||||
if(settings.OPENSTACK_X in self.instances):
|
||||
nova_conf.add('osapi_compute_extension', 'nova.api.openstack.compute.contrib.standard_extensions')
|
||||
nova_conf.add('osapi_compute_extension', 'extensions.admin.Admin')
|
||||
|
||||
if(settings.NOVNC in self.instances):
|
||||
vncproxy_url = self._getstr('vncproxy_url')
|
||||
if (not vncproxy_url):
|
||||
vncproxy_url = 'http://' + hostip + ':6080/vnc_auto.html'
|
||||
self.add('vncproxy_url', vncproxy_url)
|
||||
|
||||
# TODO is this the right directory
|
||||
paste_conf_fn = sh.joinpths(dirs.get('bin'), nova.PASTE_CONF)
|
||||
nova_conf.add('api_paste_config', paste_conf_fn)
|
||||
|
||||
img_service = self._getstr('img_service')
|
||||
if(not img_service):
|
||||
img_service = DEF_IMAGE_SERVICE
|
||||
nova_conf.add('image_service', img_service)
|
||||
|
||||
ec2_dmz_host = self._getstr('ec2_dmz_host')
|
||||
if(not ec2_dmz_host):
|
||||
ec2_dmz_host = hostip
|
||||
nova_conf.add('ec2_dmz_host', ec2_dmz_host)
|
||||
|
||||
#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 is glance located?
|
||||
glance_api_server = self._getstr('glance_server')
|
||||
if(not glance_api_server):
|
||||
glance_api_server = "%s:%d" % (hostip, DEF_GLANCE_PORT)
|
||||
nova_conf.add('glance_api_servers', glance_api_server)
|
||||
|
||||
#??
|
||||
nova_conf.add_simple('force_dhcp_release')
|
||||
|
||||
#where instances will be stored
|
||||
instances_path = self._getstr('instances_path')
|
||||
if(instances_path):
|
||||
nova_conf.add('instances_path', instances_path)
|
||||
|
||||
#is this a multihost setup?
|
||||
if(self._getbool('multi_host')):
|
||||
nova_conf.add_simple('multi_host')
|
||||
nova_conf.add_simple('send_arp_for_ha')
|
||||
|
||||
#enable syslog??
|
||||
if(self.cfg.getboolean('default', 'syslog')):
|
||||
nova_conf.add_simple('use_syslog')
|
||||
|
||||
#handle any virt driver specifics
|
||||
virt_driver = self._getstr('virt_driver')
|
||||
self._configure_virt_driver(virt_driver, nova_conf)
|
||||
|
||||
#now make it
|
||||
conf_lines = sorted(nova_conf.generate())
|
||||
complete_file = utils.joinlinesep(*conf_lines)
|
||||
|
||||
#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
|
||||
|
||||
def _configure_libvirt(self, virt_type, nova_conf):
|
||||
if(not virt_type):
|
||||
return
|
||||
nova_conf.add('libvirt_type', virt_type)
|
||||
|
||||
#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')
|
||||
nova_conf.add('xenapi_connection_password', self.cfg.get("passwords", "xenapi_connection"))
|
||||
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 NovaConf():
|
||||
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):
|
||||
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, True)
|
||||
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 gen_lines
|
@ -272,6 +272,9 @@ def _get_config():
|
||||
|
||||
def _run_components(action_name, component_order, components, distro, root_dir, program_args):
|
||||
LOG.info("Will %s [%s] (in that order) using root directory \"%s\"" % (action_name, ", ".join(component_order), root_dir))
|
||||
non_components = set(components.keys()).difference(set(component_order))
|
||||
if(non_components):
|
||||
LOG.info("Using reference components [%s]" % (", ".join(sorted(non_components))))
|
||||
pkg_manager = _get_pkg_manager(distro)
|
||||
config = _get_config()
|
||||
#form the active instances (this includes ones we won't use)
|
||||
|
@ -13,16 +13,17 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import errno
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import resource
|
||||
import signal
|
||||
import errno
|
||||
import sys
|
||||
import time
|
||||
|
||||
from devstack import exceptions as excp
|
||||
from devstack import log as logging
|
||||
from devstack import shell as sh
|
||||
from devstack import shell as sh
|
||||
from devstack import trace as tr
|
||||
|
||||
# Maximum for the number of available file descriptors (when not found)
|
||||
@ -38,6 +39,7 @@ RUN_TYPE = "FORK"
|
||||
PID_FN = "PID_FN"
|
||||
STDOUT_FN = "STDOUT_FN"
|
||||
STDERR_FN = "STDERR_FN"
|
||||
ARGS = "ARGS"
|
||||
NAME = "NAME"
|
||||
FORK_TEMPL = "%s.fork"
|
||||
|
||||
@ -139,7 +141,8 @@ class ForkRunner(object):
|
||||
#now exec...
|
||||
#the arguments to the child process should
|
||||
#start with the name of the command being run
|
||||
actualargs = [program] + list(args)
|
||||
prog_little = os.path.basename(program)
|
||||
actualargs = [prog_little] + list(args)
|
||||
os.execlp(program, *actualargs)
|
||||
else:
|
||||
#write out the child pid
|
||||
@ -162,6 +165,7 @@ class ForkRunner(object):
|
||||
runtrace.trace(PID_FN, pidfile)
|
||||
runtrace.trace(STDERR_FN, stderrfn)
|
||||
runtrace.trace(STDOUT_FN, stdoutfn)
|
||||
runtrace.trace(ARGS, json.dumps(args))
|
||||
LOG.info("Forking [%s] by running command [%s]" % (name, program))
|
||||
self._fork_start(program, appdir, pidfile, stdoutfn, stderrfn, *args)
|
||||
return tracefn
|
||||
|
@ -79,9 +79,9 @@ COMPONENT_NAMES_PRIORITY = {
|
||||
GLANCE: 4,
|
||||
QUANTUM: 4,
|
||||
SWIFT: 4,
|
||||
NOVA_CLIENT: 4,
|
||||
NOVA: 5,
|
||||
KEYSTONE_CLIENT: 6,
|
||||
NOVA_CLIENT: 6,
|
||||
OPENSTACK_X: 6,
|
||||
NOVNC: 6,
|
||||
HORIZON: 10,
|
||||
@ -96,7 +96,7 @@ COMPONENT_DEPENDENCIES = {
|
||||
RABBIT: [],
|
||||
GLANCE: [KEYSTONE, DB],
|
||||
KEYSTONE: [DB],
|
||||
NOVA: [KEYSTONE, GLANCE, DB, RABBIT],
|
||||
NOVA: [KEYSTONE, GLANCE, DB, RABBIT, NOVA_CLIENT],
|
||||
SWIFT: [],
|
||||
NOVA_CLIENT: [],
|
||||
HORIZON: [KEYSTONE_CLIENT, GLANCE, NOVA_CLIENT, OPENSTACK_X],
|
||||
|
@ -32,6 +32,7 @@ FILE_TOUCHED = "FILE_TOUCHED"
|
||||
DOWNLOADED = "DOWNLOADED"
|
||||
AP_STARTED = "AP_STARTED"
|
||||
PIP_INSTALL = 'PIP_INSTALL'
|
||||
EXEC_CMD = 'EXEC_CMD'
|
||||
|
||||
#trace file types
|
||||
PY_TRACE = "python"
|
||||
@ -139,6 +140,13 @@ class TraceWriter(object):
|
||||
data['trace_fn'] = info_fn
|
||||
self.tracer.trace(AP_STARTED, json.dumps(data))
|
||||
|
||||
def exec_cmd(self, cmd, result):
|
||||
self._start()
|
||||
data = dict()
|
||||
data['cmd'] = cmd
|
||||
data['result'] = result
|
||||
self.tracer.trace(EXEC_CMD, json.dumps(data))
|
||||
|
||||
|
||||
class TraceReader(object):
|
||||
def __init__(self, root, name):
|
||||
|
@ -37,6 +37,7 @@ LOG = logging.getLogger("devstack.util")
|
||||
|
||||
def execute_template(*cmds, **kargs):
|
||||
params_replacements = kargs.pop('params', None)
|
||||
tracewriter = kargs.pop('tracewriter', None)
|
||||
ignore_missing = kargs.pop('ignore_missing', False)
|
||||
cmd_results = list()
|
||||
for cmdinfo in cmds:
|
||||
@ -61,6 +62,8 @@ def execute_template(*cmds, **kargs):
|
||||
stdin = joinlinesep(*stdin_full)
|
||||
root_run = cmdinfo.get('run_as_root', False)
|
||||
exec_res = sh.execute(*cmd_to_run, run_as_root=root_run, process_input=stdin, **kargs)
|
||||
if tracewriter:
|
||||
tracewriter.exec_cmd(cmd_to_run, exec_res)
|
||||
cmd_results.append(exec_res)
|
||||
return cmd_results
|
||||
|
||||
@ -220,36 +223,36 @@ def _get_welcome_stack():
|
||||
possibles.append(r'''
|
||||
___ ___ ___ _ _ ___ _____ _ ___ _ __
|
||||
/ _ \| _ \ __| \| / __|_ _/_\ / __| |/ /
|
||||
| (_) | _/ _|| .` \__ \ | |/ _ \ (__| ' <
|
||||
| (_) | _/ _|| .` \__ \ | |/ _ \ (__| ' <
|
||||
\___/|_| |___|_|\_|___/ |_/_/ \_\___|_|\_\
|
||||
|
||||
''')
|
||||
''')
|
||||
possibles.append(r'''
|
||||
____ ___ ____ _ _ ____ ___ ____ ____ _ _
|
||||
| | |__] |___ |\ | [__ | |__| | |_/
|
||||
|__| | |___ | \| ___] | | | |___ | \_
|
||||
____ ___ ____ _ _ ____ ___ ____ ____ _ _
|
||||
| | |__] |___ |\ | [__ | |__| | |_/
|
||||
|__| | |___ | \| ___] | | | |___ | \_
|
||||
|
||||
''')
|
||||
possibles.append(r'''
|
||||
_ ___ ___ _ _ __ ___ _ __ _ _
|
||||
/ \| o \ __|| \| |/ _||_ _|/ \ / _|| |//
|
||||
( o ) _/ _| | \\ |\_ \ | || o ( (_ | (
|
||||
( o ) _/ _| | \\ |\_ \ | || o ( (_ | (
|
||||
\_/|_| |___||_|\_||__/ |_||_n_|\__||_|\\
|
||||
|
||||
''')
|
||||
possibles.append(r'''
|
||||
_ ___ ___ _ __ ___ _____ _ __ _
|
||||
_ ___ ___ _ __ ___ _____ _ __ _
|
||||
,' \ / o |/ _/ / |/ /,' _//_ _/.' \ ,'_/ / //7
|
||||
/ o |/ _,'/ _/ / || /_\ `. / / / o // /_ / ,'
|
||||
|_,'/_/ /___//_/|_//___,' /_/ /_n_/ |__//_/\\
|
||||
/ o |/ _,'/ _/ / || /_\ `. / / / o // /_ / ,'
|
||||
|_,'/_/ /___//_/|_//___,' /_/ /_n_/ |__//_/\\
|
||||
|
||||
''')
|
||||
possibles.append(r'''
|
||||
_____ ___ ___ _ _ ___ _____ _____ ___ _ _
|
||||
_____ ___ ___ _ _ ___ _____ _____ ___ _ _
|
||||
( _ )( _`\ ( _`\ ( ) ( )( _`\(_ _)( _ )( _`\ ( ) ( )
|
||||
| ( ) || |_) )| (_(_)| `\| || (_(_) | | | (_) || ( (_)| |/'/'
|
||||
| | | || ,__/'| _)_ | , ` |`\__ \ | | | _ || | _ | , <
|
||||
| (_) || | | (_( )| |`\ |( )_) | | | | | | || (_( )| |\`\
|
||||
| | | || ,__/'| _)_ | , ` |`\__ \ | | | _ || | _ | , <
|
||||
| (_) || | | (_( )| |`\ |( )_) | | | | | | || (_( )| |\`\
|
||||
(_____)(_) (____/'(_) (_)`\____) (_) (_) (_)(____/'(_) (_)
|
||||
|
||||
''')
|
||||
|
2
stack
2
stack
@ -22,6 +22,8 @@ import sys
|
||||
#this needs to happen immediately (or thats what it seems)
|
||||
LOG_FN_ENV = 'LOG_FILE'
|
||||
LOG_FILE_DEF = os.path.join("conf", 'logging.ini')
|
||||
|
||||
|
||||
def setupLogging():
|
||||
logfn = os.getenv(LOG_FN_ENV)
|
||||
if(logfn == None):
|
||||
|
Loading…
x
Reference in New Issue
Block a user