Merge "Basic support of Ironic"
diff --git a/README.md b/README.md
index 6426e9a..99e9838 100644
--- a/README.md
+++ b/README.md
@@ -12,10 +12,14 @@
IMPORTANT: Be sure to carefully read `stack.sh` and any other scripts you execute before you run them, as they install software and may alter your networking configuration. We strongly recommend that you run `stack.sh` in a clean and disposable vm when you are first getting started.
-# Devstack on Xenserver
+# DevStack on Xenserver
If you would like to use Xenserver as the hypervisor, please refer to the instructions in `./tools/xen/README.md`.
+# DevStack on Docker
+
+If you would like to use Docker as the hypervisor, please refer to the instructions in `./tools/docker/README.md`.
+
# Versions
The devstack master branch generally points to trunk versions of OpenStack components. For older, stable versions, look for branches named stable/[release] in the DevStack repo. For example, you can do the following to create a diablo OpenStack cloud:
diff --git a/clean.sh b/clean.sh
index f7d15df..a443ac8 100755
--- a/clean.sh
+++ b/clean.sh
@@ -64,6 +64,11 @@
cleanup_neutron
cleanup_swift
+# Do the hypervisor cleanup until this can be moved back into lib/nova
+if [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+ cleanup_nova_hypervisor
+fi
+
# cinder doesn't always clean up the volume group as it might be used elsewhere...
# clean it up if it is a loop device
VG_DEV=$(sudo losetup -j $DATA_DIR/${VOLUME_GROUP}-backing-file | awk -F':' '/backing-file/ { print $1}')
diff --git a/exercises/boot_from_volume.sh b/exercises/boot_from_volume.sh
index 36524ed..fe27bd0 100755
--- a/exercises/boot_from_volume.sh
+++ b/exercises/boot_from_volume.sh
@@ -44,6 +44,9 @@
# the exercise is skipped
is_service_enabled cinder || exit 55
+# Also skip if the hypervisor is Docker
+[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
+
# Instance type to create
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
diff --git a/exercises/docker.sh b/exercises/docker.sh
new file mode 100755
index 0000000..0672bc0
--- /dev/null
+++ b/exercises/docker.sh
@@ -0,0 +1,105 @@
+#!/usr/bin/env bash
+
+# **docker**
+
+# Test Docker hypervisor
+
+echo "*********************************************************************"
+echo "Begin DevStack Exercise: $0"
+echo "*********************************************************************"
+
+# This script exits on an error so that errors don't compound and you see
+# only the first error that occurred.
+set -o errexit
+
+# Print the commands being run so that we can see the command that triggers
+# an error. It is also useful for following allowing as the install occurs.
+set -o xtrace
+
+
+# Settings
+# ========
+
+# Keep track of the current directory
+EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
+TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
+
+# Import common functions
+source $TOP_DIR/functions
+
+# Import configuration
+source $TOP_DIR/openrc
+
+# Import exercise configuration
+source $TOP_DIR/exerciserc
+
+# Skip if the hypervisor is not Docker
+[[ "$VIRT_DRIVER" == "docker" ]] || exit 55
+
+# Import docker functions and declarations
+source $TOP_DIR/lib/nova_plugins/hypervisor-docker
+
+# Image and flavor are ignored but the CLI requires them...
+
+# Instance type to create
+DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
+
+# Boot this image, use first AMI image if unset
+DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-ami}
+
+# Instance name
+VM_NAME=ex-docker
+
+
+# Launching a server
+# ==================
+
+# Grab the id of the image to launch
+IMAGE=$(glance image-list | egrep " $DOCKER_IMAGE_NAME:latest " | get_field 1)
+die_if_not_set $LINENO IMAGE "Failure getting image $DOCKER_IMAGE_NAME"
+
+# Select a flavor
+INSTANCE_TYPE=$(nova flavor-list | grep $DEFAULT_INSTANCE_TYPE | get_field 1)
+if [[ -z "$INSTANCE_TYPE" ]]; then
+ # grab the first flavor in the list to launch if default doesn't exist
+ INSTANCE_TYPE=$(nova flavor-list | head -n 4 | tail -n 1 | get_field 1)
+fi
+
+# Clean-up from previous runs
+nova delete $VM_NAME || true
+if ! timeout $ACTIVE_TIMEOUT sh -c "while nova show $VM_NAME; do sleep 1; done"; then
+ die $LINENO "server didn't terminate!"
+fi
+
+# Boot instance
+# -------------
+
+VM_UUID=$(nova boot --flavor $INSTANCE_TYPE --image $IMAGE $VM_NAME | grep ' id ' | get_field 2)
+die_if_not_set $LINENO VM_UUID "Failure launching $VM_NAME"
+
+# Check that the status is active within ACTIVE_TIMEOUT seconds
+if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova show $VM_UUID | grep status | grep -q ACTIVE; do sleep 1; done"; then
+ die $LINENO "server didn't become active!"
+fi
+
+# Get the instance IP
+IP=$(nova show $VM_UUID | grep "$PRIVATE_NETWORK_NAME" | get_field 2)
+die_if_not_set $LINENO IP "Failure retrieving IP address"
+
+# Private IPs can be pinged in single node deployments
+ping_check "$PRIVATE_NETWORK_NAME" $IP $BOOT_TIMEOUT
+
+# Clean up
+# --------
+
+# Delete instance
+nova delete $VM_UUID || die $LINENO "Failure deleting instance $VM_NAME"
+if ! timeout $TERMINATE_TIMEOUT sh -c "while nova list | grep -q $VM_UUID; do sleep 1; done"; then
+ die $LINENO "Server $VM_NAME not deleted"
+fi
+
+set +o xtrace
+echo "*********************************************************************"
+echo "SUCCESS: End DevStack Exercise: $0"
+echo "*********************************************************************"
+
diff --git a/exercises/euca.sh b/exercises/euca.sh
index b8b283a..64c0014 100755
--- a/exercises/euca.sh
+++ b/exercises/euca.sh
@@ -41,6 +41,9 @@
# Import exercise configuration
source $TOP_DIR/exerciserc
+# Skip if the hypervisor is Docker
+[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
+
# Instance type to create
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
diff --git a/exercises/floating_ips.sh b/exercises/floating_ips.sh
index f93a727..2833b65 100755
--- a/exercises/floating_ips.sh
+++ b/exercises/floating_ips.sh
@@ -38,6 +38,9 @@
# Import exercise configuration
source $TOP_DIR/exerciserc
+# Skip if the hypervisor is Docker
+[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
+
# Instance type to create
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
diff --git a/exercises/sec_groups.sh b/exercises/sec_groups.sh
index 6b67291..7d80570 100755
--- a/exercises/sec_groups.sh
+++ b/exercises/sec_groups.sh
@@ -33,6 +33,9 @@
# Import exercise configuration
source $TOP_DIR/exerciserc
+# Skip if the hypervisor is Docker
+[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
+
# Testing Security Groups
# =======================
diff --git a/exercises/volumes.sh b/exercises/volumes.sh
index 028d19b..e536d16 100755
--- a/exercises/volumes.sh
+++ b/exercises/volumes.sh
@@ -42,6 +42,9 @@
# exercise is skipped.
is_service_enabled cinder || exit 55
+# Also skip if the hypervisor is Docker
+[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
+
# Instance type to create
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
diff --git a/files/apts/glance b/files/apts/glance
index a05e9f2..26826a5 100644
--- a/files/apts/glance
+++ b/files/apts/glance
@@ -1,5 +1,10 @@
gcc
+libffi-dev # testonly
+libmysqlclient-dev # testonly
+libpq-dev # testonly
+libssl-dev # testonly
libxml2-dev
+libxslt1-dev # testonly
python-dev
python-eventlet
python-routes
@@ -10,3 +15,4 @@
python-pastedeploy
python-xattr
python-iso8601
+zlib1g-dev # testonly
diff --git a/files/rpms/glance b/files/rpms/glance
index 0f113ea..dd66171 100644
--- a/files/rpms/glance
+++ b/files/rpms/glance
@@ -1,5 +1,10 @@
gcc
+libffi-devel # testonly
libxml2-devel
+libxslt-devel # testonly
+mysql-devel # testonly
+openssl-devel # testonly
+postgresql-devel # testonly
python-argparse
python-devel
python-eventlet
@@ -9,3 +14,4 @@
python-sqlalchemy
python-wsgiref
pyxattr
+zlib-devel # testonly
diff --git a/files/sources.list b/files/sources.list
deleted file mode 100644
index 77a1bfb..0000000
--- a/files/sources.list
+++ /dev/null
@@ -1,9 +0,0 @@
-deb http://mirror.rackspace.com/ubuntu/ %DIST% main restricted
-deb http://mirror.rackspace.com/ubuntu/ %DIST%-updates main restricted
-deb http://mirror.rackspace.com/ubuntu/ %DIST% universe
-deb http://mirror.rackspace.com/ubuntu/ %DIST%-updates universe
-deb http://mirror.rackspace.com/ubuntu/ %DIST% multiverse
-deb http://mirror.rackspace.com/ubuntu/ %DIST%-updates multiverse
-deb http://security.ubuntu.com/ubuntu %DIST%-security main restricted
-deb http://security.ubuntu.com/ubuntu %DIST%-security universe
-deb http://security.ubuntu.com/ubuntu %DIST%-security multiverse
diff --git a/functions b/functions
index 41f008e..f24cc89 100644
--- a/functions
+++ b/functions
@@ -317,16 +317,36 @@
continue
fi
+ # Assume we want this package
+ package=${line%#*}
+ inst_pkg=1
+
+ # Look for # dist:xxx in comment
if [[ $line =~ (.*)#.*dist:([^ ]*) ]]; then
# We are using BASH regexp matching feature.
package=${BASH_REMATCH[1]}
distros=${BASH_REMATCH[2]}
# In bash ${VAR,,} will lowecase VAR
- [[ ${distros,,} =~ ${DISTRO,,} ]] && echo $package
- continue
+ # Look for a match in the distro list
+ if [[ ! ${distros,,} =~ ${DISTRO,,} ]]; then
+ # If no match then skip this package
+ inst_pkg=0
+ fi
fi
- echo ${line%#*}
+ # Look for # testonly in comment
+ if [[ $line =~ (.*)#.*testonly.* ]]; then
+ package=${BASH_REMATCH[1]}
+ # Are we installing test packages? (test for the default value)
+ if [[ $INSTALL_TESTONLY_PACKAGES = "False" ]]; then
+ # If not installing test packages the skip this package
+ inst_pkg=0
+ fi
+ fi
+
+ if [[ $inst_pkg = 1 ]]; then
+ echo $package
+ fi
done
IFS=$OIFS
done
@@ -912,7 +932,7 @@
fi
if [[ "$os_PACKAGE" = "deb" ]]; then
- dpkg -l "$@" > /dev/null 2> /dev/null
+ dpkg -s "$@" > /dev/null 2> /dev/null
elif [[ "$os_PACKAGE" = "rpm" ]]; then
rpm --quiet -q "$@"
else
@@ -1240,7 +1260,7 @@
return
fi
- # XenServer-ovf-format images are provided as .vhd.tgz as well
+ # XenServer-vhd-ovf-format images are provided as .vhd.tgz
# and should not be decompressed prior to loading
if [[ "$image_url" =~ '.vhd.tgz' ]]; then
IMAGE="$FILES/${IMAGE_FNAME}"
@@ -1249,6 +1269,22 @@
return
fi
+ # .xen-raw.tgz suggests a Xen capable raw image inside a tgz.
+ # and should not be decompressed prior to loading.
+ # Setting metadata, so PV mode is used.
+ if [[ "$image_url" =~ '.xen-raw.tgz' ]]; then
+ IMAGE="$FILES/${IMAGE_FNAME}"
+ IMAGE_NAME="${IMAGE_FNAME%.xen-raw.tgz}"
+ glance \
+ --os-auth-token $token \
+ --os-image-url http://$GLANCE_HOSTPORT \
+ image-create \
+ --name "$IMAGE_NAME" --is-public=True \
+ --container-format=tgz --disk-format=raw \
+ --property vm_mode=xen < "${IMAGE}"
+ return
+ fi
+
KERNEL=""
RAMDISK=""
DISK_FORMAT=""
diff --git a/lib/cinder b/lib/cinder
index 54cf844..826b958 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -289,12 +289,11 @@
fi
elif [ "$CINDER_DRIVER" == "vsphere" ]; then
echo_summary "Using VMware vCenter driver"
- iniset $CINDER_CONF DEFAULT enabled_backends vmware
- iniset $CINDER_CONF vmware host_ip "$VMWAREAPI_IP"
- iniset $CINDER_CONF vmware host_username "$VMWAREAPI_USER"
- iniset $CINDER_CONF vmware host_password "$VMWAREAPI_PASSWORD"
- iniset $CINDER_CONF vmware cluster_name "$VMWAREAPI_CLUSTER"
- iniset $CINDER_CONF vmware volume_driver "cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver"
+ iniset $CINDER_CONF DEFAULT vmware_host_ip "$VMWAREAPI_IP"
+ iniset $CINDER_CONF DEFAULT vmware_host_username "$VMWAREAPI_USER"
+ iniset $CINDER_CONF DEFAULT vmware_host_password "$VMWAREAPI_PASSWORD"
+ iniset $CINDER_CONF DEFAULT vmware_cluster_name "$VMWAREAPI_CLUSTER"
+ iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver"
fi
if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
@@ -468,6 +467,7 @@
function install_cinderclient() {
git_clone $CINDERCLIENT_REPO $CINDERCLIENT_DIR $CINDERCLIENT_BRANCH
setup_develop $CINDERCLIENT_DIR
+ sudo install -D -m 0644 -o $STACK_USER {$CINDERCLIENT_DIR/tools/,/etc/bash_completion.d/}cinder.bash_completion
}
# apply config.d approach for cinder volumes directory
diff --git a/lib/glance b/lib/glance
index a18189f..64d8b06 100644
--- a/lib/glance
+++ b/lib/glance
@@ -108,6 +108,10 @@
fi
iniset_rpc_backend glance $GLANCE_API_CONF DEFAULT
iniset $GLANCE_API_CONF keystone_authtoken signing_dir $GLANCE_AUTH_CACHE_DIR/api
+ if [ "$VIRT_DRIVER" = 'xenserver' ]; then
+ iniset $GLANCE_API_CONF DEFAULT container_formats "ami,ari,aki,bare,ovf,tgz"
+ iniset $GLANCE_API_CONF DEFAULT disk_formats "ami,ari,aki,vhd,raw,iso"
+ fi
# Store the images in swift if enabled.
if is_service_enabled s-proxy; then
diff --git a/lib/heat b/lib/heat
index fb4002b..67509bc 100644
--- a/lib/heat
+++ b/lib/heat
@@ -31,6 +31,10 @@
HEATCLIENT_DIR=$DEST/python-heatclient
HEAT_AUTH_CACHE_DIR=${HEAT_AUTH_CACHE_DIR:-/var/cache/heat}
HEAT_STANDALONE=`trueorfalse False $HEAT_STANDALONE`
+HEAT_CONF_DIR=/etc/heat
+HEAT_CONF=$HEAT_CONF_DIR/heat.conf
+HEAT_ENV_DIR=$HEAT_CONF_DIR/environment.d
+HEAT_TEMPLATES_DIR=$HEAT_CONF_DIR/templates
# Functions
# ---------
@@ -39,17 +43,20 @@
# runs that a clean run would need to clean up
function cleanup_heat() {
sudo rm -rf $HEAT_AUTH_CACHE_DIR
+ sudo rm -rf $HEAT_ENV_DIR
+ sudo rm -rf $HEAT_TEMPLATES_DIR
}
# configure_heat() - Set config files, create data dirs, etc
function configure_heat() {
setup_develop $HEAT_DIR
- HEAT_CONF_DIR=/etc/heat
if [[ ! -d $HEAT_CONF_DIR ]]; then
sudo mkdir -p $HEAT_CONF_DIR
fi
sudo chown $STACK_USER $HEAT_CONF_DIR
+ # remove old config files
+ rm -f $HEAT_CONF_DIR/heat-*.conf
HEAT_API_CFN_HOST=${HEAT_API_CFN_HOST:-$SERVICE_HOST}
HEAT_API_CFN_PORT=${HEAT_API_CFN_PORT:-8000}
@@ -64,96 +71,67 @@
cp $HEAT_DIR/etc/heat/api-paste.ini $HEAT_API_PASTE_FILE
cp $HEAT_DIR/etc/heat/policy.json $HEAT_POLICY_FILE
+ cp $HEAT_DIR/etc/heat/heat.conf.sample $HEAT_CONF
- # Cloudformation API
- HEAT_API_CFN_CONF=$HEAT_CONF_DIR/heat-api-cfn.conf
- cp $HEAT_DIR/etc/heat/heat-api-cfn.conf $HEAT_API_CFN_CONF
- iniset $HEAT_API_CFN_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
- inicomment $HEAT_API_CFN_CONF DEFAULT log_file
- iniset $HEAT_API_CFN_CONF DEFAULT use_syslog $SYSLOG
- iniset $HEAT_API_CFN_CONF DEFAULT bind_host $HEAT_API_CFN_HOST
- iniset $HEAT_API_CFN_CONF DEFAULT bind_port $HEAT_API_CFN_PORT
- iniset $HEAT_API_CFN_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
- iniset $HEAT_API_CFN_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
- iniset $HEAT_API_CFN_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
- iniset $HEAT_API_CFN_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
- iniset $HEAT_API_CFN_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
- iniset $HEAT_API_CFN_CONF keystone_authtoken admin_user heat
- iniset $HEAT_API_CFN_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
- iniset $HEAT_API_CFN_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR/api-cfn
- iniset $HEAT_API_CFN_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
- iniset $HEAT_API_CFN_CONF ec2authtoken keystone_ec2_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/ec2tokens
- [[ "$HEAT_STANDALONE" = "True" ]] && iniset $HEAT_API_CFN_CONF paste_deploy flavor standalone
+ # common options
+ iniset_rpc_backend heat $HEAT_CONF DEFAULT
+ iniset $HEAT_CONF DEFAULT heat_metadata_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT
+ iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1/waitcondition
+ iniset $HEAT_CONF DEFAULT heat_watch_server_url http://$HEAT_API_CW_HOST:$HEAT_API_CW_PORT
+ iniset $HEAT_CONF DEFAULT sql_connection `database_connection_url heat`
+ iniset $HEAT_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/random`
- iniset_rpc_backend heat $HEAT_API_CFN_CONF DEFAULT
-
- # OpenStack API
- HEAT_API_CONF=$HEAT_CONF_DIR/heat-api.conf
- cp $HEAT_DIR/etc/heat/heat-api.conf $HEAT_API_CONF
- iniset $HEAT_API_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
- inicomment $HEAT_API_CONF DEFAULT log_file
- iniset $HEAT_API_CONF DEFAULT use_syslog $SYSLOG
- iniset $HEAT_API_CONF DEFAULT bind_host $HEAT_API_HOST
- iniset $HEAT_API_CONF DEFAULT bind_port $HEAT_API_PORT
- iniset $HEAT_API_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
- iniset $HEAT_API_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
- iniset $HEAT_API_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
- iniset $HEAT_API_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
- iniset $HEAT_API_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
- iniset $HEAT_API_CONF keystone_authtoken admin_user heat
- iniset $HEAT_API_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
- iniset $HEAT_API_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR/api
- iniset $HEAT_API_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
- iniset $HEAT_API_CONF ec2authtoken keystone_ec2_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/ec2tokens
- [[ "$HEAT_STANDALONE" = "True" ]] && iniset $HEAT_API_CONF paste_deploy flavor standalone
- iniset_rpc_backend heat $HEAT_API_CONF DEFAULT
-
-
- # engine
- HEAT_ENGINE_CONF=$HEAT_CONF_DIR/heat-engine.conf
- cp $HEAT_DIR/etc/heat/heat-engine.conf $HEAT_ENGINE_CONF
- iniset $HEAT_ENGINE_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
- inicomment $HEAT_ENGINE_CONF DEFAULT log_file
- iniset $HEAT_ENGINE_CONF DEFAULT use_syslog $SYSLOG
- iniset $HEAT_ENGINE_CONF DEFAULT bind_host $HEAT_ENGINE_HOST
- iniset $HEAT_ENGINE_CONF DEFAULT bind_port $HEAT_ENGINE_PORT
- iniset $HEAT_ENGINE_CONF DEFAULT heat_metadata_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT
- iniset $HEAT_ENGINE_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1/waitcondition
- iniset $HEAT_ENGINE_CONF DEFAULT heat_watch_server_url http://$HEAT_API_CW_HOST:$HEAT_API_CW_PORT
- iniset $HEAT_ENGINE_CONF DEFAULT sql_connection `database_connection_url heat`
- iniset $HEAT_ENGINE_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/random`
-
- iniset_rpc_backend heat $HEAT_ENGINE_CONF DEFAULT
-
+ # logging
+ iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
+ iniset $HEAT_CONF DEFAULT use_syslog $SYSLOG
if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
# Add color to logging output
- iniset $HEAT_ENGINE_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [[01;36m%(request_id)s [00;36m%(user_name)s %(project_name)s%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
- iniset $HEAT_ENGINE_CONF DEFAULT logging_default_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [[00;36m-%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
- iniset $HEAT_ENGINE_CONF DEFAULT logging_debug_format_suffix "[00;33mfrom (pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d[00m"
- iniset $HEAT_ENGINE_CONF DEFAULT logging_exception_prefix "%(color)s%(asctime)s.%(msecs)03d TRACE %(name)s [01;35m%(instance)s[00m"
+ iniset $HEAT_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [[01;36m%(request_id)s [00;36m%(user_name)s %(project_name)s%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
+ iniset $HEAT_CONF DEFAULT logging_default_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [[00;36m-%(color)s] [01;35m%(instance)s%(color)s%(message)s[00m"
+ iniset $HEAT_CONF DEFAULT logging_debug_format_suffix "[00;33mfrom (pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d[00m"
+ iniset $HEAT_CONF DEFAULT logging_exception_prefix "%(color)s%(asctime)s.%(msecs)03d TRACE %(name)s [01;35m%(instance)s[00m"
fi
- # Cloudwatch API
- HEAT_API_CW_CONF=$HEAT_CONF_DIR/heat-api-cloudwatch.conf
- cp $HEAT_DIR/etc/heat/heat-api-cloudwatch.conf $HEAT_API_CW_CONF
- iniset $HEAT_API_CW_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
- inicomment $HEAT_API_CW_CONF DEFAULT log_file
- iniset $HEAT_API_CW_CONF DEFAULT use_syslog $SYSLOG
- iniset $HEAT_API_CW_CONF DEFAULT bind_host $HEAT_API_CW_HOST
- iniset $HEAT_API_CW_CONF DEFAULT bind_port $HEAT_API_CW_PORT
- iniset $HEAT_API_CW_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
- iniset $HEAT_API_CW_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
- iniset $HEAT_API_CW_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
- iniset $HEAT_API_CW_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
- iniset $HEAT_API_CW_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
- iniset $HEAT_API_CW_CONF keystone_authtoken admin_user heat
- iniset $HEAT_API_CW_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
- iniset $HEAT_API_CW_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR/api-cloudwatch
- iniset $HEAT_API_CW_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
- iniset $HEAT_API_CW_CONF ec2authtoken keystone_ec2_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/ec2tokens
- [[ "$HEAT_STANDALONE" = "True" ]] && iniset $HEAT_API_CW_CONF paste_deploy flavor standalone
+ # keystone authtoken
+ iniset $HEAT_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
+ iniset $HEAT_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
+ iniset $HEAT_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
+ iniset $HEAT_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
+ iniset $HEAT_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
+ iniset $HEAT_CONF keystone_authtoken admin_user heat
+ iniset $HEAT_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
+ iniset $HEAT_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR/api-cfn
- iniset_rpc_backend heat $HEAT_API_CW_CONF DEFAULT
+ # ec2authtoken
+ iniset $HEAT_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
+ iniset $HEAT_CONF ec2authtoken keystone_ec2_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/ec2tokens
+
+ # paste_deploy
+ [[ "$HEAT_STANDALONE" = "True" ]] && iniset $HEAT_CONF paste_deploy flavor standalone
+
+ # OpenStack API
+ iniset $HEAT_CONF heat_api bind_host $HEAT_API_HOST
+ iniset $HEAT_CONF heat_api bind_port $HEAT_API_PORT
+
+ # Cloudformation API
+ iniset $HEAT_CONF heat_api_cfn bind_host $HEAT_API_CFN_HOST
+ iniset $HEAT_CONF heat_api_cfn bind_port $HEAT_API_CFN_PORT
+
+ # Cloudwatch API
+ iniset $HEAT_CONF heat_api_cloudwatch bind_host $HEAT_API_CW_HOST
+ iniset $HEAT_CONF heat_api_cloudwatch bind_port $HEAT_API_CW_PORT
+
+ # heat environment
+ sudo mkdir -p $HEAT_ENV_DIR
+ sudo chown $STACK_USER $HEAT_ENV_DIR
+ # copy the default environment
+ cp $HEAT_DIR/etc/heat/environment.d/* $HEAT_ENV_DIR/
+
+ # heat template resources.
+ sudo mkdir -p $HEAT_TEMPLATES_DIR
+ sudo chown $STACK_USER $HEAT_TEMPLATES_DIR
+ # copy the default templates
+ cp $HEAT_DIR/etc/heat/templates/* $HEAT_TEMPLATES_DIR/
}
@@ -191,10 +169,10 @@
# start_heat() - Start running processes, including screen
function start_heat() {
- screen_it h-eng "cd $HEAT_DIR; bin/heat-engine --config-file=$HEAT_CONF_DIR/heat-engine.conf"
- screen_it h-api "cd $HEAT_DIR; bin/heat-api --config-dir=$HEAT_CONF_DIR/heat-api.conf"
- screen_it h-api-cfn "cd $HEAT_DIR; bin/heat-api-cfn --config-dir=$HEAT_CONF_DIR/heat-api-cfn.conf"
- screen_it h-api-cw "cd $HEAT_DIR; bin/heat-api-cloudwatch --config-dir=$HEAT_CONF_DIR/heat-api-cloudwatch.conf"
+ screen_it h-eng "cd $HEAT_DIR; bin/heat-engine --config-file=$HEAT_CONF"
+ screen_it h-api "cd $HEAT_DIR; bin/heat-api --config-file=$HEAT_CONF"
+ screen_it h-api-cfn "cd $HEAT_DIR; bin/heat-api-cfn --config-file=$HEAT_CONF"
+ screen_it h-api-cw "cd $HEAT_DIR; bin/heat-api-cloudwatch --config-file=$HEAT_CONF"
}
# stop_heat() - Stop running processes
diff --git a/lib/horizon b/lib/horizon
index a879d1e..f6bb9f5 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -50,7 +50,7 @@
if [ -n "$line" ]; then
sed -i -e "/^$section/,/^}/ s/^\( *'$option'\) *:.*$/\1: $value,/" $file
else
- sed -i -e "/^$section/ a\n '$option': $value,\n" $file
+ sed -i -e "/^$section/a\ '$option': $value," $file
fi
else
echo -e "\n\n$section = {\n '$option': $value,\n}" >> $file
@@ -96,6 +96,11 @@
_horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_lb True
fi
+ # enable firewall dashboard in case service is enabled
+ if is_service_enabled q-fwaas; then
+ _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_firewall True
+ fi
+
# Initialize the horizon database (it stores sessions and notices shown to
# users). The user system is external (keystone).
cd $HORIZON_DIR
diff --git a/lib/keystone b/lib/keystone
index e7e0544..0a35dd5 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -289,6 +289,7 @@
function install_keystoneclient() {
git_clone $KEYSTONECLIENT_REPO $KEYSTONECLIENT_DIR $KEYSTONECLIENT_BRANCH
setup_develop $KEYSTONECLIENT_DIR
+ sudo install -D -m 0644 -o $STACK_USER {$KEYSTONECLIENT_DIR/tools/,/etc/bash_completion.d/}keystone.bash_completion
}
# install_keystone() - Collect source and prepare
diff --git a/lib/neutron b/lib/neutron
index 31876de..01fe3ea 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -207,6 +207,10 @@
# Hardcoding for 1 service plugin for now
source $TOP_DIR/lib/neutron_plugins/services/vpn
+# Firewall Service Plugin functions
+# --------------------------------
+source $TOP_DIR/lib/neutron_plugins/services/firewall
+
# Use security group or not
if has_neutron_plugin_security_group; then
Q_USE_SECGROUP=${Q_USE_SECGROUP:-True}
@@ -230,6 +234,9 @@
if is_service_enabled q-vpn; then
_configure_neutron_vpn
fi
+ if is_service_enabled q-fwaas; then
+ _configure_neutron_fwaas
+ fi
if is_service_enabled q-svc; then
_configure_neutron_service
fi
@@ -250,18 +257,18 @@
}
function create_nova_conf_neutron() {
- iniset $NOVA_CONF DEFAULT network_api_class "nova.network.quantumv2.api.API"
- iniset $NOVA_CONF DEFAULT quantum_admin_username "$Q_ADMIN_USERNAME"
- iniset $NOVA_CONF DEFAULT quantum_admin_password "$SERVICE_PASSWORD"
- iniset $NOVA_CONF DEFAULT quantum_admin_auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v2.0"
- iniset $NOVA_CONF DEFAULT quantum_auth_strategy "$Q_AUTH_STRATEGY"
- iniset $NOVA_CONF DEFAULT quantum_admin_tenant_name "$SERVICE_TENANT_NAME"
- iniset $NOVA_CONF DEFAULT quantum_region_name "RegionOne"
- iniset $NOVA_CONF DEFAULT quantum_url "http://$Q_HOST:$Q_PORT"
+ iniset $NOVA_CONF DEFAULT network_api_class "nova.network.neutronv2.api.API"
+ iniset $NOVA_CONF DEFAULT neutron_admin_username "$Q_ADMIN_USERNAME"
+ iniset $NOVA_CONF DEFAULT neutron_admin_password "$SERVICE_PASSWORD"
+ iniset $NOVA_CONF DEFAULT neutron_admin_auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v2.0"
+ iniset $NOVA_CONF DEFAULT neutron_auth_strategy "$Q_AUTH_STRATEGY"
+ iniset $NOVA_CONF DEFAULT neutron_admin_tenant_name "$SERVICE_TENANT_NAME"
+ iniset $NOVA_CONF DEFAULT neutron_region_name "RegionOne"
+ iniset $NOVA_CONF DEFAULT neutron_url "http://$Q_HOST:$Q_PORT"
if [[ "$Q_USE_SECGROUP" == "True" ]]; then
LIBVIRT_FIREWALL_DRIVER=nova.virt.firewall.NoopFirewallDriver
- iniset $NOVA_CONF DEFAULT security_group_api quantum
+ iniset $NOVA_CONF DEFAULT security_group_api neutron
fi
# set NOVA_VIF_DRIVER and optionally set options in nova_conf
@@ -270,7 +277,7 @@
iniset $NOVA_CONF DEFAULT libvirt_vif_driver "$NOVA_VIF_DRIVER"
iniset $NOVA_CONF DEFAULT linuxnet_interface_driver "$LINUXNET_VIF_DRIVER"
if is_service_enabled q-meta; then
- iniset $NOVA_CONF DEFAULT service_quantum_metadata_proxy "True"
+ iniset $NOVA_CONF DEFAULT service_neutron_metadata_proxy "True"
fi
}
@@ -382,6 +389,7 @@
function install_neutronclient() {
git_clone $NEUTRONCLIENT_REPO $NEUTRONCLIENT_DIR $NEUTRONCLIENT_BRANCH
setup_develop $NEUTRONCLIENT_DIR
+ sudo install -D -m 0644 -o $STACK_USER {$NEUTRONCLIENT_DIR/tools/,/etc/bash_completion.d/}neutron.bash_completion
}
# install_neutron_agent_packages() - Collect source and prepare
@@ -418,11 +426,17 @@
screen_it q-agt "cd $NEUTRON_DIR && python $AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE"
screen_it q-dhcp "cd $NEUTRON_DIR && python $AGENT_DHCP_BINARY --config-file $NEUTRON_CONF --config-file=$Q_DHCP_CONF_FILE"
- if is_service_enabled q-vpn; then
- screen_it q-vpn "cd $NEUTRON_DIR && $AGENT_VPN_BINARY --config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE"
- else
- screen_it q-l3 "cd $NEUTRON_DIR && python $AGENT_L3_BINARY --config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE"
+ L3_CONF_FILES="--config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE"
+
+ if is_service_enabled q-fwaas; then
+ L3_CONF_FILES="$L3_CONF_FILES --config-file $Q_FWAAS_CONF_FILE"
fi
+ if is_service_enabled q-vpn; then
+ screen_it q-vpn "cd $NEUTRON_DIR && $AGENT_VPN_BINARY $L3_CONF_FILES"
+ else
+ screen_it q-l3 "cd $NEUTRON_DIR && python $AGENT_L3_BINARY $L3_CONF_FILES"
+ fi
+
screen_it q-meta "cd $NEUTRON_DIR && python $AGENT_META_BINARY --config-file $NEUTRON_CONF --config-file=$Q_META_CONF_FILE"
if [ "$VIRT_DRIVER" = 'xenserver' ]; then
@@ -541,6 +555,14 @@
iniset $Q_DHCP_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
iniset $Q_DHCP_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND"
+ # Define extra "DEFAULT" configuration options when q-dhcp is configured by
+ # defining the array ``Q_DHCP_EXTRA_DEFAULT_OPTS``.
+ # For Example: ``Q_DHCP_EXTRA_DEFAULT_OPTS=(foo=true bar=2)``
+ for I in "${Q_DHCP_EXTRA_DEFAULT_OPTS[@]}"; do
+ # Replace the first '=' with ' ' for iniset syntax
+ iniset $Q_DHCP_CONF_FILE DEFAULT ${I/=/ }
+ done
+
_neutron_setup_interface_driver $Q_DHCP_CONF_FILE
neutron_plugin_configure_dhcp_agent
@@ -554,6 +576,10 @@
AGENT_L3_BINARY=${AGENT_L3_BINARY:-"$NEUTRON_BIN_DIR/neutron-l3-agent"}
Q_L3_CONF_FILE=$NEUTRON_CONF_DIR/l3_agent.ini
+ if is_service_enabled q-fwaas; then
+ Q_FWAAS_CONF_FILE=$NEUTRON_CONF_DIR/fwaas_driver.ini
+ fi
+
cp $NEUTRON_DIR/etc/l3_agent.ini $Q_L3_CONF_FILE
iniset $Q_L3_CONF_FILE DEFAULT verbose True
@@ -577,7 +603,7 @@
iniset $Q_META_CONF_FILE DEFAULT nova_metadata_ip $Q_META_DATA_IP
iniset $Q_META_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND"
- _neutron_setup_keystone $Q_META_CONF_FILE DEFAULT True True
+ _neutron_setup_keystone $Q_META_CONF_FILE DEFAULT True True True
}
@@ -586,6 +612,11 @@
neutron_agent_lbaas_configure_agent
}
+function _configure_neutron_fwaas() {
+ neutron_fwaas_configure_common
+ neutron_fwaas_configure_driver
+}
+
function _configure_neutron_vpn()
{
neutron_vpn_install_agent_packages
@@ -690,11 +721,16 @@
local section=$2
local use_auth_url=$3
local skip_auth_cache=$4
+ local use_service_port=$5
+ local keystone_port=$KEYSTONE_AUTH_PORT
+ if [[ -n $use_service_port ]]; then
+ keystone_port=$KEYSTONE_SERVICE_PORT
+ fi
if [[ -n $use_auth_url ]]; then
- iniset $conf_file $section auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v2.0"
+ iniset $conf_file $section auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_AUTH_HOST:$keystone_port/v2.0"
else
iniset $conf_file $section auth_host $KEYSTONE_SERVICE_HOST
- iniset $conf_file $section auth_port $KEYSTONE_AUTH_PORT
+ iniset $conf_file $section auth_port $keystone_port
iniset $conf_file $section auth_protocol $KEYSTONE_SERVICE_PROTOCOL
fi
iniset $conf_file $section admin_tenant_name $SERVICE_TENANT_NAME
diff --git a/lib/neutron_plugins/services/firewall b/lib/neutron_plugins/services/firewall
new file mode 100644
index 0000000..1597e85
--- /dev/null
+++ b/lib/neutron_plugins/services/firewall
@@ -0,0 +1,27 @@
+# Neutron firewall plugin
+# ---------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+FWAAS_PLUGIN=neutron.services.firewall.fwaas_plugin.FirewallPlugin
+
+function neutron_fwaas_configure_common() {
+ if [[ $Q_SERVICE_PLUGIN_CLASSES == '' ]]; then
+ Q_SERVICE_PLUGIN_CLASSES=$FWAAS_PLUGIN
+ else
+ Q_SERVICE_PLUGIN_CLASSES="$Q_SERVICE_PLUGIN_CLASSES,$FWAAS_PLUGIN"
+ fi
+}
+
+function neutron_fwaas_configure_driver() {
+ FWAAS_DRIVER_CONF_FILENAME=/etc/neutron/fwaas_driver.ini
+ cp $NEUTRON_DIR/etc/fwaas_driver.ini $FWAAS_DRIVER_CONF_FILENAME
+
+ iniset_multiline $FWAAS_DRIVER_CONF_FILENAME fwaas enabled True
+ iniset_multiline $FWAAS_DRIVER_CONF_FILENAME fwaas driver "neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver"
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/nova b/lib/nova
index 842c098..0b65f84 100644
--- a/lib/nova
+++ b/lib/nova
@@ -169,6 +169,13 @@
fi
sudo rm -rf $NOVA_STATE_PATH $NOVA_AUTH_CACHE_DIR
+
+ # NOTE(dtroyer): This really should be called from here but due to the way
+ # nova abuses the _cleanup() function we're moving it
+ # directly into cleanup.sh until this can be fixed.
+ #if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+ # cleanup_nova_hypervisor
+ #fi
}
# configure_nova_rootwrap() - configure Nova's rootwrap
@@ -451,6 +458,7 @@
if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
iniset $NOVA_CONF DEFAULT libvirt_type "$LIBVIRT_TYPE"
iniset $NOVA_CONF DEFAULT libvirt_cpu_mode "none"
+ iniset $NOVA_CONF DEFAULT use_usb_tablet "False"
fi
iniset $NOVA_CONF DEFAULT instance_name_template "${INSTANCE_NAME_PREFIX}%08x"
iniset $NOVA_CONF osapi_v3 enabled "True"
@@ -645,12 +653,15 @@
function install_novaclient() {
git_clone $NOVACLIENT_REPO $NOVACLIENT_DIR $NOVACLIENT_BRANCH
setup_develop $NOVACLIENT_DIR
+ sudo install -D -m 0644 -o $STACK_USER {$NOVACLIENT_DIR/tools/,/etc/bash_completion.d/}nova.bash_completion
}
# install_nova() - Collect source and prepare
function install_nova() {
if is_service_enabled n-cpu; then
- if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
+ if [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+ install_nova_hypervisor
+ elif [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
if is_ubuntu; then
install_package kvm
install_package libvirt-bin
@@ -682,6 +693,7 @@
git_clone $NOVA_REPO $NOVA_DIR $NOVA_BRANCH
setup_develop $NOVA_DIR
+ sudo install -D -m 0644 -o $STACK_USER {$NOVA_DIR/tools/,/etc/bash_completion.d/}nova-manage.bash_completion
}
# start_nova_api() - Start the API process ahead of other things
@@ -728,6 +740,9 @@
screen_it n-cpu "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-compute --config-file $NOVA_CONF_BOTTOM"
done
else
+ if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+ start_nova_hypervisor
+ fi
screen_it n-cpu "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-compute --config-file $NOVA_CONF_BOTTOM"
fi
screen_it n-crt "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-cert"
@@ -754,6 +769,9 @@
for serv in n-api n-cpu n-crt n-net n-sch n-novnc n-xvnc n-cauth n-spice n-cond n-cond n-cell n-cell n-api-meta; do
screen -S $SCREEN_NAME -p $serv -X kill
done
+ if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+ stop_nova_hypervisor
+ fi
}
diff --git a/lib/nova_plugins/hypervisor-docker b/lib/nova_plugins/hypervisor-docker
new file mode 100644
index 0000000..4c8fc27
--- /dev/null
+++ b/lib/nova_plugins/hypervisor-docker
@@ -0,0 +1,132 @@
+# lib/nova_plugins/docker
+# Configure the Docker hypervisor
+
+# Enable with:
+# VIRT_DRIVER=docker
+
+# Dependencies:
+# ``functions`` file
+# ``nova`` and ``glance`` configurations
+
+# install_nova_hypervisor - install any external requirements
+# configure_nova_hypervisor - make configuration changes, including those to other services
+# start_nova_hypervisor - start any external services
+# stop_nova_hypervisor - stop any external services
+# cleanup_nova_hypervisor - remove transient data and cache
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+DOCKER_DIR=$DEST/docker
+DOCKER_REPO=${DOCKER_REPO:-https://github.com/dotcloud/openstack-docker.git}
+DOCKER_BRANCH=${DOCKER_BRANCH:-master}
+
+DOCKER_UNIX_SOCKET=/var/run/docker.sock
+DOCKER_PID_FILE=/var/run/docker.pid
+DOCKER_REGISTRY_PORT=${DOCKER_REGISTRY_PORT:-5042}
+
+DOCKER_IMAGE=${DOCKER_IMAGE:-http://get.docker.io/images/openstack/docker-ut.tar.gz}
+DOCKER_IMAGE_NAME=docker-busybox
+DOCKER_REGISTRY_IMAGE=${DOCKER_REGISTRY_IMAGE:-http://get.docker.io/images/openstack/docker-registry.tar.gz}
+DOCKER_REGISTRY_IMAGE_NAME=docker-registry
+DOCKER_REPOSITORY_NAME=${SERVICE_HOST}:${DOCKER_REGISTRY_PORT}/${DOCKER_IMAGE_NAME}
+
+DOCKER_PACKAGE_VERSION=${DOCKER_PACKAGE_VERSION:-0.6.1}
+DOCKER_APT_REPO=${DOCKER_APT_REPO:-https://get.docker.io/ubuntu}
+
+
+# Entry Points
+# ------------
+
+# clean_nova_hypervisor - Clean up an installation
+function cleanup_nova_hypervisor() {
+ stop_service docker
+
+ # Clean out work area
+ sudo rm -rf /var/lib/docker
+}
+
+# configure_nova_hypervisor - Set config files, create data dirs, etc
+function configure_nova_hypervisor() {
+ git_clone $DOCKER_REPO $DOCKER_DIR $DOCKER_BRANCH
+
+ ln -snf ${DOCKER_DIR}/nova-driver $NOVA_DIR/nova/virt/docker
+
+ iniset $NOVA_CONF DEFAULT compute_driver docker.DockerDriver
+ iniset $GLANCE_API_CONF DEFAULT container_formats ami,ari,aki,bare,ovf,docker
+
+ sudo cp -p ${DOCKER_DIR}/nova-driver/docker.filters $NOVA_CONF_DIR/rootwrap.d
+}
+
+# install_nova_hypervisor() - Install external components
+function install_nova_hypervisor() {
+ # So far this is Ubuntu only
+ if ! is_ubuntu; then
+ die $LINENO "Docker is only supported on Ubuntu at this time"
+ fi
+
+ # Make sure Docker is installed
+ if ! is_package_installed lxc-docker; then
+ die $LINENO "Docker is not installed. Please run tools/docker/install_docker.sh"
+ fi
+
+ local docker_pid
+ read docker_pid <$DOCKER_PID_FILE
+ if [[ -z $docker_pid ]] || ! ps -p $docker_pid | grep [d]ocker; then
+ die $LINENO "Docker not running"
+ fi
+}
+
+# start_nova_hypervisor - Start any required external services
+function start_nova_hypervisor() {
+ local docker_pid
+ read docker_pid <$DOCKER_PID_FILE
+ if [[ -z $docker_pid ]] || ! ps -p $docker_pid | grep [d]ocker; then
+ die $LINENO "Docker not running, start the daemon"
+ fi
+
+ # Start the Docker registry container
+ docker run -d -p ${DOCKER_REGISTRY_PORT}:5000 \
+ -e SETTINGS_FLAVOR=openstack -e OS_USERNAME=${OS_USERNAME} \
+ -e OS_PASSWORD=${OS_PASSWORD} -e OS_TENANT_NAME=${OS_TENANT_NAME} \
+ -e OS_GLANCE_URL="${SERVICE_PROTOCOL}://${GLANCE_HOSTPORT}" \
+ -e OS_AUTH_URL=${OS_AUTH_URL} \
+ $DOCKER_REGISTRY_IMAGE_NAME ./docker-registry/run.sh
+
+ echo "Waiting for docker registry to start..."
+ DOCKER_REGISTRY=${SERVICE_HOST}:${DOCKER_REGISTRY_PORT}
+ if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl -s $DOCKER_REGISTRY; do sleep 1; done"; then
+ die $LINENO "docker-registry did not start"
+ fi
+
+ # Tag image if not already tagged
+ if ! docker images | grep $DOCKER_REPOSITORY_NAME; then
+ docker tag $DOCKER_IMAGE_NAME $DOCKER_REPOSITORY_NAME
+ fi
+
+ # Make sure we copied the image in Glance
+ DOCKER_IMAGE=$(glance image-list | egrep " $DOCKER_IMAGE_NAME ")
+ if ! is_set DOCKER_IMAGE ; then
+ docker push $DOCKER_REPOSITORY_NAME
+ fi
+}
+
+# stop_nova_hypervisor - Stop any external services
+function stop_nova_hypervisor() {
+ # Stop the docker registry container
+ docker kill $(docker ps | grep docker-registry | cut -d' ' -f1)
+}
+
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/tempest b/lib/tempest
index 0d4f370..50289b6 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -282,6 +282,9 @@
# Scenario
iniset $TEMPEST_CONF scenario img_dir "$FILES/images/cirros-0.3.1-x86_64-uec"
+ # Large Ops Number
+ iniset $TEMPEST_CONF scenario large_ops_number ${TEMPEST_LARGE_OPS_NUMBER:-0}
+
# Volume
CINDER_MULTI_LVM_BACKEND=$(trueorfalse False $CINDER_MULTI_LVM_BACKEND)
if [ $CINDER_MULTI_LVM_BACKEND == "True" ]; then
diff --git a/openrc b/openrc
index a23c6e9..3de7e39 100644
--- a/openrc
+++ b/openrc
@@ -63,21 +63,19 @@
# should be listening on HOST_IP. If its running elsewhere, it can be set here
GLANCE_HOST=${GLANCE_HOST:-$HOST_IP}
+# Identity API version
+export OS_IDENTITY_API_VERSION=${IDENTITY_API_VERSION:-2.0}
+
# Authenticating against an Openstack cloud using Keystone returns a **Token**
# and **Service Catalog**. The catalog contains the endpoints for all services
# the user/tenant has access to - including nova, glance, keystone, swift, ...
# We currently recommend using the 2.0 *identity api*.
#
-# *NOTE*: Using the 2.0 *identity api* does not mean that compute api is 2.0. We
-# will use the 1.1 *compute api*
-export OS_AUTH_URL=$SERVICE_PROTOCOL://$SERVICE_HOST:5000/v2.0
+export OS_AUTH_URL=$SERVICE_PROTOCOL://$SERVICE_HOST:5000/v${OS_IDENTITY_API_VERSION}
# Set the pointer to our CA certificate chain. Harmless if TLS is not used.
export OS_CACERT=$INT_CA_DIR/ca-chain.pem
-# Identity API version
-export OS_IDENTITY_API_VERSION=${IDENTITY_API_VERSION:-2.0}
-
# Currently novaclient needs you to specify the *compute api* version. This
# needs to match the config of your catalog returned by Keystone.
export NOVA_VERSION=${NOVA_VERSION:-1.1}
diff --git a/stack.sh b/stack.sh
index 5094e25..503866a 100755
--- a/stack.sh
+++ b/stack.sh
@@ -320,6 +320,13 @@
source $TOP_DIR/lib/ldap
source $TOP_DIR/lib/ironic
+# Look for Nova hypervisor plugin
+NOVA_PLUGINS=$TOP_DIR/lib/nova_plugins
+if is_service_enabled nova && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+ # Load plugin
+ source $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER
+fi
+
# Set the destination directories for other OpenStack projects
OPENSTACKCLIENT_DIR=$DEST/python-openstackclient
@@ -1028,6 +1035,10 @@
init_cinder
fi
+
+# Compute Service
+# ---------------
+
if is_service_enabled nova; then
echo_summary "Configuring Nova"
# Rebuild the config file from scratch
@@ -1042,10 +1053,15 @@
fi
+ if [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+ # Configure hypervisor plugin
+ configure_nova_hypervisor
+
+
# XenServer
# ---------
- if [ "$VIRT_DRIVER" = 'xenserver' ]; then
+ elif [ "$VIRT_DRIVER" = 'xenserver' ]; then
echo_summary "Using XenServer virtualization driver"
if [ -z "$XENAPI_CONNECTION_URL" ]; then
die $LINENO "XENAPI_CONNECTION_URL is not specified"
diff --git a/stackrc b/stackrc
index b3e2e14..f9a977c 100644
--- a/stackrc
+++ b/stackrc
@@ -279,6 +279,9 @@
# Set default screen name
SCREEN_NAME=${SCREEN_NAME:-stack}
+# Do not install packages tagged with 'testonly' by default
+INSTALL_TESTONLY_PACKAGES=${INSTALL_TESTONLY_PACKAGES:-False}
+
# Local variables:
# mode: shell-script
# End:
diff --git a/tests/functions.sh b/tests/functions.sh
index 27a6cfe..7d486d4 100755
--- a/tests/functions.sh
+++ b/tests/functions.sh
@@ -367,3 +367,25 @@
else
echo "is_package_installed() on non-existing package failed"
fi
+
+# test against removed package...was a bug on Ubuntu
+if is_ubuntu; then
+ PKG=cowsay
+ if ! (dpkg -s $PKG >/dev/null 2>&1); then
+ # it was never installed...set up the condition
+ sudo apt-get install -y cowsay >/dev/null 2>&1
+ fi
+ if (dpkg -s $PKG >/dev/null 2>&1); then
+ # remove it to create the 'un' status
+ sudo dpkg -P $PKG >/dev/null 2>&1
+ fi
+
+ # now test the installed check on a deleted package
+ is_package_installed $PKG
+ VAL=$?
+ if [[ "$VAL" -ne 0 ]]; then
+ echo "OK"
+ else
+ echo "is_package_installed() on deleted package failed"
+ fi
+fi
diff --git a/tools/docker/README.md b/tools/docker/README.md
new file mode 100644
index 0000000..976111f
--- /dev/null
+++ b/tools/docker/README.md
@@ -0,0 +1,13 @@
+# DevStack on Docker
+
+Using Docker as Nova's hypervisor requries two steps:
+
+* Configure DevStack by adding the following to `localrc`::
+
+ VIRT_DRIVER=docker
+
+* Download and install the Docker service and images::
+
+ tools/docker/install_docker.sh
+
+After this, `stack.sh` should run as normal.
diff --git a/tools/docker/install_docker.sh b/tools/docker/install_docker.sh
new file mode 100755
index 0000000..d659ad1
--- /dev/null
+++ b/tools/docker/install_docker.sh
@@ -0,0 +1,75 @@
+#!/usr/bin/env bash
+
+# **install_docker.sh** - Do the initial Docker installation and configuration
+
+# install_docker.sh
+#
+# Install docker package and images
+# * downloads a base busybox image and a glance registry image if necessary
+# * install the images in Docker's image cache
+
+
+# Keep track of the current directory
+SCRIPT_DIR=$(cd $(dirname "$0") && pwd)
+TOP_DIR=$(cd $SCRIPT_DIR/../..; pwd)
+
+# Import common functions
+source $TOP_DIR/functions
+
+# Load local configuration
+source $TOP_DIR/stackrc
+
+FILES=$TOP_DIR/files
+
+# Get our defaults
+source $TOP_DIR/lib/nova_plugins/hypervisor-docker
+
+SERVICE_TIMEOUT=${SERVICE_TIMEOUT:-60}
+
+
+# Install Docker Service
+# ======================
+
+# Stop the auto-repo updates and do it when required here
+NO_UPDATE_REPOS=True
+
+# Set up home repo
+curl https://get.docker.io/gpg | sudo apt-key add -
+install_package python-software-properties && \
+ sudo sh -c "echo deb $DOCKER_APT_REPO docker main > /etc/apt/sources.list.d/docker.list"
+apt_get update
+install_package --force-yes lxc-docker=${DOCKER_PACKAGE_VERSION}
+
+# Start the daemon - restart just in case the package ever auto-starts...
+restart_service docker
+
+echo "Waiting for docker daemon to start..."
+DOCKER_GROUP=$(groups | cut -d' ' -f1)
+CONFIGURE_CMD="while ! /bin/echo -e 'GET /v1.3/version HTTP/1.0\n\n' | socat - unix-connect:$DOCKER_UNIX_SOCKET | grep -q '200 OK'; do
+ # Set the right group on docker unix socket before retrying
+ sudo chgrp $DOCKER_GROUP $DOCKER_UNIX_SOCKET
+ sudo chmod g+rw $DOCKER_UNIX_SOCKET
+ sleep 1
+done"
+if ! timeout $SERVICE_TIMEOUT sh -c "$CONFIGURE_CMD"; then
+ die $LINENO "docker did not start"
+fi
+
+
+# Get Docker image
+if [[ ! -r $FILES/docker-ut.tar.gz ]]; then
+ (cd $FILES; curl -OR $DOCKER_IMAGE)
+fi
+if [[ ! -r $FILES/docker-ut.tar.gz ]]; then
+ die $LINENO "Docker image unavailable"
+fi
+docker import - $DOCKER_IMAGE_NAME <$FILES/docker-ut.tar.gz
+
+# Get Docker registry image
+if [[ ! -r $FILES/docker-registry.tar.gz ]]; then
+ (cd $FILES; curl -OR $DOCKER_REGISTRY_IMAGE)
+fi
+if [[ ! -r $FILES/docker-registry.tar.gz ]]; then
+ die $LINENO "Docker registry image unavailable"
+fi
+docker import - $DOCKER_REGISTRY_IMAGE_NAME <$FILES/docker-registry.tar.gz
diff --git a/unstack.sh b/unstack.sh
index 84eee4f..38f795b 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -66,6 +66,14 @@
fi
fi
+# Shut down Nova hypervisor plugins after Nova
+NOVA_PLUGINS=$TOP_DIR/lib/nova_plugins
+if is_service_enabled nova && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+ # Load plugin
+ source $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER
+ stop_nova_hypervisor
+fi
+
# Swift runs daemons
if is_service_enabled s-proxy; then
stop_swift