Merge branch 'master' of github.com:yahoo/Openstack-Devstack2

Conflicts:
	devstack/components/nova_conf.py
This commit is contained in:
Joshua Harlow 2012-01-24 15:42:32 -08:00
commit dfb9d6d51b
18 changed files with 574 additions and 371 deletions

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

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