Merge "xenapi: enable block device access for stack user"
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/cinder b/files/apts/cinder
index 32cb3a0..f8e3b6d 100644
--- a/files/apts/cinder
+++ b/files/apts/cinder
@@ -3,3 +3,5 @@
qemu-utils
libpq-dev
python-dev
+open-iscsi
+open-iscsi-utils # Deprecated since quantal dist:lucid,oneiric,precise
diff --git a/files/keystone_data.sh b/files/keystone_data.sh
index 45f9c81..3f3137c 100755
--- a/files/keystone_data.sh
+++ b/files/keystone_data.sh
@@ -58,9 +58,9 @@
# Nova needs ResellerAdmin role to download images when accessing
# swift through the s3 api.
keystone user-role-add \
- --tenant_id $SERVICE_TENANT \
- --user_id $NOVA_USER \
- --role_id $RESELLER_ROLE
+ --tenant-id $SERVICE_TENANT \
+ --user-id $NOVA_USER \
+ --role-id $RESELLER_ROLE
fi
# Heat
@@ -69,9 +69,9 @@
--pass="$SERVICE_PASSWORD" \
--tenant_id $SERVICE_TENANT \
--email=heat@example.com)
- keystone user-role-add --tenant_id $SERVICE_TENANT \
- --user_id $HEAT_USER \
- --role_id $SERVICE_ROLE
+ keystone user-role-add --tenant-id $SERVICE_TENANT \
+ --user-id $HEAT_USER \
+ --role-id $SERVICE_ROLE
# heat_stack_user role is for users created by Heat
keystone role-create --name heat_stack_user
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
@@ -106,9 +106,9 @@
--tenant_id $SERVICE_TENANT \
--email=glance@example.com)
keystone user-role-add \
- --tenant_id $SERVICE_TENANT \
- --user_id $GLANCE_USER \
- --role_id $ADMIN_ROLE
+ --tenant-id $SERVICE_TENANT \
+ --user-id $GLANCE_USER \
+ --role-id $ADMIN_ROLE
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
GLANCE_SERVICE=$(get_id keystone service-create \
--name=glance \
@@ -129,13 +129,13 @@
--pass="$SERVICE_PASSWORD" \
--tenant_id $SERVICE_TENANT \
--email=ceilometer@example.com)
- keystone user-role-add --tenant_id $SERVICE_TENANT \
- --user_id $CEILOMETER_USER \
- --role_id $ADMIN_ROLE
+ keystone user-role-add --tenant-id $SERVICE_TENANT \
+ --user-id $CEILOMETER_USER \
+ --role-id $ADMIN_ROLE
# Ceilometer needs ResellerAdmin role to access swift account stats.
- keystone user-role-add --tenant_id $SERVICE_TENANT \
- --user_id $CEILOMETER_USER \
- --role_id $RESELLER_ROLE
+ keystone user-role-add --tenant-id $SERVICE_TENANT \
+ --user-id $CEILOMETER_USER \
+ --role-id $RESELLER_ROLE
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
CEILOMETER_SERVICE=$(get_id keystone service-create \
--name=ceilometer \
@@ -192,7 +192,7 @@
--pass="$ADMIN_PASSWORD" \
--email=alt_demo@example.com)
keystone user-role-add \
- --tenant_id $ALT_DEMO_TENANT \
- --user_id $ALT_DEMO_USER \
- --role_id $MEMBER_ROLE
+ --tenant-id $ALT_DEMO_TENANT \
+ --user-id $ALT_DEMO_USER \
+ --role-id $MEMBER_ROLE
fi
diff --git a/files/rpms-suse/cinder b/files/rpms-suse/cinder
index 49e2cb8..55078da 100644
--- a/files/rpms-suse/cinder
+++ b/files/rpms-suse/cinder
@@ -3,3 +3,4 @@
qemu-tools
python-devel
postgresql-devel
+open-iscsi
diff --git a/files/rpms/cinder b/files/rpms/cinder
index 699f2fc..c4edb68 100644
--- a/files/rpms/cinder
+++ b/files/rpms/cinder
@@ -3,3 +3,4 @@
qemu-img
python-devel
postgresql-devel
+iscsi-initiator-utils
diff --git a/functions b/functions
index f24cc89..df8166a 100644
--- a/functions
+++ b/functions
@@ -1454,7 +1454,6 @@
local check_command=""
MULTI_HOST=`trueorfalse False $MULTI_HOST`
if [[ "$MULTI_HOST" = "True" && "$from_net" = "$PRIVATE_NETWORK_NAME" ]]; then
- sleep $boot_timeout
return
fi
if [[ "$expected" = "True" ]]; then
@@ -1645,6 +1644,37 @@
}
+# ``policy_add policy_file policy_name policy_permissions``
+#
+# Add a policy to a policy.json file
+# Do nothing if the policy already exists
+
+function policy_add() {
+ local policy_file=$1
+ local policy_name=$2
+ local policy_perm=$3
+
+ if grep -q ${policy_name} ${policy_file}; then
+ echo "Policy ${policy_name} already exists in ${policy_file}"
+ return
+ fi
+
+ # Add a terminating comma to policy lines without one
+ # Remove the closing '}' and all lines following to the end-of-file
+ local tmpfile=$(mktemp)
+ uniq ${policy_file} | sed -e '
+ s/]$/],/
+ /^[}]/,$d
+ ' > ${tmpfile}
+
+ # Append policy and closing brace
+ echo " \"${policy_name}\": ${policy_perm}" >>${tmpfile}
+ echo "}" >>${tmpfile}
+
+ mv ${tmpfile} ${policy_file}
+}
+
+
# Restore xtrace
$XTRACE
diff --git a/lib/cinder b/lib/cinder
index 826b958..324db9d 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -226,6 +226,7 @@
iniset $CINDER_CONF DEFAULT volume_group $VOLUME_GROUP
iniset $CINDER_CONF DEFAULT volume_name_template ${VOLUME_NAME_PREFIX}%s
fi
+ iniset $CINDER_CONF DEFAULT my_ip "$CINDER_SERVICE_HOST"
iniset $CINDER_CONF DEFAULT iscsi_helper tgtadm
iniset $CINDER_CONF DEFAULT sql_connection `database_connection_url cinder`
iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
@@ -335,9 +336,9 @@
--email=cinder@example.com \
| grep " id " | get_field 2)
keystone user-role-add \
- --tenant_id $SERVICE_TENANT \
- --user_id $CINDER_USER \
- --role_id $ADMIN_ROLE
+ --tenant-id $SERVICE_TENANT \
+ --user-id $CINDER_USER \
+ --role-id $ADMIN_ROLE
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
CINDER_SERVICE=$(keystone service-create \
--name=cinder \
diff --git a/lib/heat b/lib/heat
index 5d6c6aa..67509bc 100644
--- a/lib/heat
+++ b/lib/heat
@@ -32,7 +32,9 @@
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
# ---------
@@ -42,6 +44,7 @@
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
@@ -52,6 +55,8 @@
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}
@@ -66,96 +71,55 @@
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
@@ -163,6 +127,12 @@
# 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/
+
}
# init_heat() - Initialize database
@@ -199,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/ironic b/lib/ironic
new file mode 100644
index 0000000..2ce5038
--- /dev/null
+++ b/lib/ironic
@@ -0,0 +1,222 @@
+# lib/ironic
+# Functions to control the configuration and operation of the **Ironic** service
+
+# Dependencies:
+# ``functions`` file
+# ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
+# ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined
+# ``SERVICE_HOST``
+# ``KEYSTONE_TOKEN_FORMAT`` must be defined
+
+# ``stack.sh`` calls the entry points in this order:
+#
+# install_ironic
+# configure_ironic
+# init_ironic
+# start_ironic
+# stop_ironic
+# cleanup_ironic
+
+# Save trace setting
+XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+IRONIC_DIR=$DEST/ironic
+IRONIC_AUTH_CACHE_DIR=${IRONIC_AUTH_CACHE_DIR:-/var/cache/ironic}
+IRONIC_CONF_DIR=${IRONIC_CONF_DIR:-/etc/ironic}
+IRONIC_CONF_FILE=$IRONIC_CONF_DIR/ironic.conf
+IRONIC_ROOTWRAP_CONF=$IRONIC_CONF_DIR/rootwrap.conf
+IRONIC_ROOTWRAP_FILTERS=$IRONIC_CONF_DIR/rootwrap.d
+IRONIC_POLICY_JSON=$IRONIC_CONF_DIR/policy.json
+
+# Support entry points installation of console scripts
+IRONIC_BIN_DIR=$(get_python_exec_prefix)
+
+# Ironic connection info. Note the port must be specified.
+IRONIC_SERVICE_PROTOCOL=http
+IRONIC_HOSTPORT=${IRONIC_HOSTPORT:-$SERVICE_HOST:6385}
+
+
+# Functions
+# ---------
+
+# cleanup_ironic() - Remove residual data files, anything left over from previous
+# runs that would need to clean up.
+function cleanup_ironic() {
+ sudo rm -rf $IRONIC_AUTH_CACHE_DIR
+}
+
+# configure_ironic() - Set config files, create data dirs, etc
+function configure_ironic() {
+ if [[ ! -d $IRONIC_CONF_DIR ]]; then
+ sudo mkdir -p $IRONIC_CONF_DIR
+ fi
+ sudo chown $STACK_USER $IRONIC_CONF_DIR
+
+ # Copy over ironic configuration file and configure common parameters.
+ cp $IRONIC_DIR/etc/ironic/ironic.conf.sample $IRONIC_CONF_FILE
+ iniset $IRONIC_CONF_FILE DEFAULT debug True
+ inicomment $IRONIC_CONF_FILE DEFAULT log_file
+ iniset $IRONIC_CONF_FILE DEFAULT sql_connection `database_connection_url ironic`
+ iniset $IRONIC_CONF_FILE DEFAULT use_syslog $SYSLOG
+
+ # Configure Ironic conductor, if it was enabled.
+ if is_service_enabled ir-cond; then
+ configure_ironic_conductor
+ fi
+
+ # Configure Ironic API, if it was enabled.
+ if is_service_enabled ir-api; then
+ configure_ironic_api
+ fi
+}
+
+# configure_ironic_api() - Is used by configure_ironic(). Performs
+# API specific configuration.
+function configure_ironic_api() {
+ iniset $IRONIC_CONF_FILE keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
+ iniset $IRONIC_CONF_FILE keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
+ iniset $IRONIC_CONF_FILE keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
+ iniset $IRONIC_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
+ iniset $IRONIC_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
+ iniset $IRONIC_CONF_FILE keystone_authtoken admin_user ironic
+ iniset $IRONIC_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
+ if is_service_enabled qpid; then
+ iniset $IRONIC_CONF_FILE DEFAULT notifier_strategy qpid
+ elif [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; then
+ iniset $IRONIC_CONF_FILE DEFAULT notifier_strategy rabbit
+ fi
+ iniset_rpc_backend ironic $IRONIC_CONF_FILE DEFAULT
+ iniset $IRONIC_CONF_FILE keystone_authtoken signing_dir $IRONIC_AUTH_CACHE_DIR/api
+
+ cp -p $IRONIC_DIR/etc/ironic/policy.json $IRONIC_POLICY_JSON
+}
+
+# configure_ironic_conductor() - Is used by configure_ironic().
+# Sets conductor specific settings.
+function configure_ironic_conductor() {
+ cp $IRONIC_DIR/etc/ironic/rootwrap.conf $IRONIC_ROOTWRAP_CONF
+ cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_ROOTWRAP_FILTERS
+
+ iniset $IRONIC_CONF DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
+}
+
+# create_ironic_cache_dir() - Part of the init_ironic() process
+function create_ironic_cache_dir() {
+ # Create cache dir
+ sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/api
+ sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/api
+ rm -f $IRONIC_AUTH_CACHE_DIR/api/*
+ sudo mkdir -p $IRONIC_AUTH_CACHE_DIR/registry
+ sudo chown $STACK_USER $IRONIC_AUTH_CACHE_DIR/registry
+ rm -f $IRONIC_AUTH_CACHE_DIR/registry/*
+}
+
+# create_ironic_accounts() - Set up common required ironic accounts
+
+# Tenant User Roles
+# ------------------------------------------------------------------
+# service ironic admin # if enabled
+create_ironic_accounts() {
+
+ SERVICE_TENANT=$(keystone tenant-list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
+ ADMIN_ROLE=$(keystone role-list | awk "/ admin / { print \$2 }")
+
+ # Ironic
+ if [[ "$ENABLED_SERVICES" =~ "ir-api" ]]; then
+ IRONIC_USER=$(keystone user-create \
+ --name=ironic \
+ --pass="$SERVICE_PASSWORD" \
+ --tenant_id $SERVICE_TENANT \
+ --email=ironic@example.com \
+ | grep " id " | get_field 2)
+ keystone user-role-add \
+ --tenant_id $SERVICE_TENANT \
+ --user_id $IRONIC_USER \
+ --role_id $ADMIN_ROLE
+ if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
+ IRONIC_SERVICE=$(keystone service-create \
+ --name=ironic \
+ --type=baremetal \
+ --description="Ironic baremetal provisioning service" \
+ | grep " id " | get_field 2)
+ keystone endpoint-create \
+ --region RegionOne \
+ --service_id $IRONIC_SERVICE \
+ --publicurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT/v1/" \
+ --adminurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT/v1/" \
+ --internalurl "$IRONIC_SERVICE_PROTOCOL://$IRONIC_HOSTPORT/v1/"
+ fi
+ fi
+}
+
+
+# init_ironic() - Initialize databases, etc.
+function init_ironic() {
+ # (Re)create ironic database
+ recreate_database ironic utf8
+
+ # Migrate ironic database
+ $IRONIC_BIN_DIR/ironic-dbsync
+
+ create_ironic_cache_dir
+
+ # Create keystone artifacts for Ironic.
+ create_ironic_accounts
+}
+
+# install_ironic() - Collect source and prepare
+function install_ironic() {
+ git_clone $IRONIC_REPO $IRONIC_DIR $IRONIC_BRANCH
+ setup_develop $IRONIC_DIR
+}
+
+# start_ironic() - Start running processes, including screen
+function start_ironic() {
+ # Start Ironic API server, if enabled.
+ if is_service_enabled ir-api; then
+ start_ironic_api
+ fi
+
+ # Start Ironic conductor, if enabled.
+ if is_service_enabled ir-cond; then
+ start_ironic_conductor
+ fi
+}
+
+# start_ironic_api() - Used by start_ironic().
+# Starts Ironic API server.
+function start_ironic_api() {
+ screen_it ir-api "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-api --config-file=$IRONIC_CONF_FILE"
+ echo "Waiting for ir-api ($IRONIC_HOSTPORT) to start..."
+ if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= wget -q -O- http://$IRONIC_HOSTPORT; do sleep 1; done"; then
+ die $LINENO "ir-api did not start"
+ fi
+}
+
+# start_ironic_conductor() - Used by start_ironic().
+# Starts Ironic conductor.
+function start_ironic_conductor() {
+ screen_it ir-cond "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-conductor --config-file=$IRONIC_CONF_FILE"
+ # TODO(romcheg): Find a way to check whether the conductor has started.
+}
+
+# stop_ironic() - Stop running processes
+function stop_ironic() {
+ # Kill the Ironic screen windows
+ screen -S $SCREEN_NAME -p ir-api -X kill
+ screen -S $SCREEN_NAME -p ir-cond -X kill
+}
+
+
+# Restore xtrace
+$XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/keystone b/lib/keystone
index 0a35dd5..535710f 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -217,9 +217,9 @@
--name admin \
| grep " id " | get_field 2)
keystone user-role-add \
- --user_id $ADMIN_USER \
- --role_id $ADMIN_ROLE \
- --tenant_id $ADMIN_TENANT
+ --user-id $ADMIN_USER \
+ --role-id $ADMIN_ROLE \
+ --tenant-id $ADMIN_TENANT
# service
SERVICE_TENANT=$(keystone tenant-create \
@@ -244,10 +244,10 @@
--pass "$ADMIN_PASSWORD" \
--email demo@example.com \
| grep " id " | get_field 2)
- keystone user-role-add --user_id $DEMO_USER --role_id $MEMBER_ROLE --tenant_id $DEMO_TENANT
- keystone user-role-add --user_id $ADMIN_USER --role_id $ADMIN_ROLE --tenant_id $DEMO_TENANT
- keystone user-role-add --user_id $DEMO_USER --role_id $ANOTHER_ROLE --tenant_id $DEMO_TENANT
- keystone user-role-add --user_id $DEMO_USER --role_id $MEMBER_ROLE --tenant_id $INVIS_TENANT
+ keystone user-role-add --user-id $DEMO_USER --role-id $MEMBER_ROLE --tenant-id $DEMO_TENANT
+ keystone user-role-add --user-id $ADMIN_USER --role-id $ADMIN_ROLE --tenant-id $DEMO_TENANT
+ keystone user-role-add --user-id $DEMO_USER --role-id $ANOTHER_ROLE --tenant-id $DEMO_TENANT
+ keystone user-role-add --user-id $DEMO_USER --role-id $MEMBER_ROLE --tenant-id $INVIS_TENANT
# Keystone
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/neutron b/lib/neutron
index c041cd4..dc3c622 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
@@ -294,9 +301,9 @@
--email=neutron@example.com \
| grep " id " | get_field 2)
keystone user-role-add \
- --tenant_id $SERVICE_TENANT \
- --user_id $NEUTRON_USER \
- --role_id $ADMIN_ROLE
+ --tenant-id $SERVICE_TENANT \
+ --user-id $NEUTRON_USER \
+ --role-id $ADMIN_ROLE
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
NEUTRON_SERVICE=$(keystone service-create \
--name=neutron \
@@ -419,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
@@ -508,6 +521,15 @@
done
fi
+ if [ "$VIRT_DRIVER" = 'fake' ]; then
+ # Disable arbitrary limits
+ iniset $NEUTRON_CONF quotas quota_network -1
+ iniset $NEUTRON_CONF quotas quota_subnet -1
+ iniset $NEUTRON_CONF quotas quota_port -1
+ iniset $NEUTRON_CONF quotas quota_security_group -1
+ iniset $NEUTRON_CONF quotas quota_security_group_rule -1
+ fi
+
_neutron_setup_rootwrap
}
@@ -563,6 +585,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
@@ -595,6 +621,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
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 a835386..19093ad 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
@@ -392,9 +399,9 @@
--email=nova@example.com \
| grep " id " | get_field 2)
keystone user-role-add \
- --tenant_id $SERVICE_TENANT \
- --user_id $NOVA_USER \
- --role_id $ADMIN_ROLE
+ --tenant-id $SERVICE_TENANT \
+ --user-id $NOVA_USER \
+ --role-id $ADMIN_ROLE
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
NOVA_SERVICE=$(keystone service-create \
--name=nova \
@@ -652,7 +659,9 @@
# 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
@@ -731,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"
@@ -757,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/swift b/lib/swift
index 8e64152..f72beaf 100644
--- a/lib/swift
+++ b/lib/swift
@@ -464,7 +464,7 @@
SWIFT_USER=$(keystone user-create --name=swift --pass="$SERVICE_PASSWORD" \
--tenant_id $SERVICE_TENANT --email=swift@example.com | grep " id " | get_field 2)
- keystone user-role-add --tenant_id $SERVICE_TENANT --user_id $SWIFT_USER --role_id $ADMIN_ROLE
+ keystone user-role-add --tenant-id $SERVICE_TENANT --user-id $SWIFT_USER --role-id $ADMIN_ROLE
if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
SWIFT_SERVICE=$(keystone service-create --name=swift --type="object-store" \
@@ -479,14 +479,14 @@
SWIFT_TENANT_TEST1=$(keystone tenant-create --name=swifttenanttest1 | grep " id " | get_field 2)
SWIFT_USER_TEST1=$(keystone user-create --name=swiftusertest1 --pass=testing --email=test@example.com | grep " id " | get_field 2)
- keystone user-role-add --user_id $SWIFT_USER_TEST1 --role_id $ADMIN_ROLE --tenant_id $SWIFT_TENANT_TEST1
+ keystone user-role-add --user-id $SWIFT_USER_TEST1 --role-id $ADMIN_ROLE --tenant-id $SWIFT_TENANT_TEST1
SWIFT_USER_TEST3=$(keystone user-create --name=swiftusertest3 --pass=testing3 --email=test3@example.com | grep " id " | get_field 2)
- keystone user-role-add --user_id $SWIFT_USER_TEST3 --role_id $ANOTHER_ROLE --tenant_id $SWIFT_TENANT_TEST1
+ keystone user-role-add --user-id $SWIFT_USER_TEST3 --role-id $ANOTHER_ROLE --tenant-id $SWIFT_TENANT_TEST1
SWIFT_TENANT_TEST2=$(keystone tenant-create --name=swifttenanttest2 | grep " id " | get_field 2)
SWIFT_USER_TEST2=$(keystone user-create --name=swiftusertest2 --pass=testing2 --email=test2@example.com | grep " id " | get_field 2)
- keystone user-role-add --user_id $SWIFT_USER_TEST2 --role_id $ADMIN_ROLE --tenant_id $SWIFT_TENANT_TEST2
+ keystone user-role-add --user-id $SWIFT_USER_TEST2 --role-id $ADMIN_ROLE --tenant-id $SWIFT_TENANT_TEST2
}
# init_swift() - Initialize rings
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 8f59328..89e4c24 100755
--- a/stack.sh
+++ b/stack.sh
@@ -318,6 +318,14 @@
source $TOP_DIR/lib/neutron
source $TOP_DIR/lib/baremetal
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
@@ -589,64 +597,6 @@
# Do the ugly hacks for borken packages and distros
$TOP_DIR/tools/fixup_stuff.sh
-
-# System-specific preconfigure
-# ============================
-
-if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
- # Disable selinux to avoid configuring to allow Apache access
- # to Horizon files or run nodejs (LP#1175444)
- if selinuxenabled; then
- sudo setenforce 0
- fi
-
- # The following workarounds break xenserver
- if [ "$VIRT_DRIVER" != 'xenserver' ]; then
- # An old version of ``python-crypto`` (2.0.1) may be installed on a
- # fresh system via Anaconda and the dependency chain
- # ``cas`` -> ``python-paramiko`` -> ``python-crypto``.
- # ``pip uninstall pycrypto`` will remove the packaged ``.egg-info``
- # file but leave most of the actual library files behind in
- # ``/usr/lib64/python2.6/Crypto``. Later ``pip install pycrypto``
- # will install over the packaged files resulting
- # in a useless mess of old, rpm-packaged files and pip-installed files.
- # Remove the package so that ``pip install python-crypto`` installs
- # cleanly.
- # Note: other RPM packages may require ``python-crypto`` as well.
- # For example, RHEL6 does not install ``python-paramiko packages``.
- uninstall_package python-crypto
-
- # A similar situation occurs with ``python-lxml``, which is required by
- # ``ipa-client``, an auditing package we don't care about. The
- # build-dependencies needed for ``pip install lxml`` (``gcc``,
- # ``libxml2-dev`` and ``libxslt-dev``) are present in
- # ``files/rpms/general``.
- uninstall_package python-lxml
- fi
-
- # If the ``dbus`` package was installed by DevStack dependencies the
- # uuid may not be generated because the service was never started (PR#598200),
- # causing Nova to stop later on complaining that ``/var/lib/dbus/machine-id``
- # does not exist.
- sudo service messagebus restart
-
- # ``setup.py`` contains a ``setup_requires`` package that is supposed
- # to be transient. However, RHEL6 distribute has a bug where
- # ``setup_requires`` registers entry points that are not cleaned
- # out properly after the setup-phase resulting in installation failures
- # (bz#924038). Pre-install the problem package so the ``setup_requires``
- # dependency is satisfied and it will not be installed transiently.
- # Note we do this before the track-depends below.
- pip_install hgtools
-
- # RHEL6's version of ``python-nose`` is incompatible with Tempest.
- # Install nose 1.1 (Tempest-compatible) from EPEL
- install_package python-nose1.1
- # Add a symlink for the new nosetests to allow tox for Tempest to
- # work unmolested.
- sudo ln -sf /usr/bin/nosetests1.1 /usr/local/bin/nosetests
-fi
-
install_rpc_backend
if is_service_enabled $DATABASE_BACKENDS; then
@@ -778,6 +728,11 @@
# don't be naive and add to existing line!
fi
+if is_service_enabled ir-api ir-cond; then
+ install_ironic
+ configure_ironic
+fi
+
if [[ $TRACK_DEPENDS = True ]]; then
$DEST/.venv/bin/pip freeze > $DEST/requires-post-pip
if ! diff -Nru $DEST/requires-pre-pip $DEST/requires-post-pip > $DEST/requires.diff; then
@@ -946,6 +901,15 @@
init_glance
fi
+# Ironic
+# ------
+
+if is_service_enabled ir-api ir-cond; then
+ echo_summary "Configuring Ironic"
+ init_ironic
+fi
+
+
# Neutron
# -------
@@ -1013,6 +977,10 @@
init_cinder
fi
+
+# Compute Service
+# ---------------
+
if is_service_enabled nova; then
echo_summary "Configuring Nova"
# Rebuild the config file from scratch
@@ -1027,10 +995,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"
@@ -1186,6 +1159,12 @@
start_glance
fi
+# Launch the Ironic services
+if is_service_enabled ir-api ir-cond; then
+ echo_summary "Starting Ironic"
+ start_ironic
+fi
+
# Create an access key and secret key for nova ec2 register image
if is_service_enabled key && is_service_enabled swift3 && is_service_enabled nova; then
NOVA_USER_ID=$(keystone user-list | grep ' nova ' | get_field 1)
diff --git a/stackrc b/stackrc
index 8b97536..f9a977c 100644
--- a/stackrc
+++ b/stackrc
@@ -96,6 +96,10 @@
HORIZON_REPO=${HORIZON_REPO:-${GIT_BASE}/openstack/horizon.git}
HORIZON_BRANCH=${HORIZON_BRANCH:-master}
+# baremetal provisionint service
+IRONIC_REPO=${IRONIC_REPO:-${GIT_BASE}/openstack/ironic.git}
+IRONIC_BRANCH=${IRONIC_BRANCH:-master}
+
# unified auth system (manages accounts/tokens)
KEYSTONE_REPO=${KEYSTONE_REPO:-${GIT_BASE}/openstack/keystone.git}
KEYSTONE_BRANCH=${KEYSTONE_BRANCH:-master}
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/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index 60d0f46..371b25f 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -9,10 +9,17 @@
# pip 1.4 doesn't fix it (1.3 did)
# - httplib2 0.8 permissions are 600 in the package and
# pip 1.4 doesn't fix it (1.3 did)
+# - RHEL6:
+# - set selinux not enforcing
+# - (re)start messagebus daemon
+# - remove distro packages python-crypto and python-lxml
+# - pre-install hgtools to work around a bug in RHEL6 distribute
+# - install nose 1.1 from EPEL
+
# Keep track of the current directory
TOOLS_DIR=$(cd $(dirname "$0") && pwd)
-TOP_DIR=`cd $TOOLS_DIR/..; pwd`
+TOP_DIR=$(cd $TOOLS_DIR/..; pwd)
# Change dir to top of devstack
cd $TOP_DIR
@@ -22,6 +29,10 @@
FILES=$TOP_DIR/files
+
+# Python Packages
+# ---------------
+
# Pre-install affected packages so we can fix the permissions
sudo pip install prettytable
sudo pip install httplib2
@@ -41,3 +52,65 @@
fi
done
+
+
+# RHEL6
+# -----
+
+if [[ $DISTRO =~ (rhel6) ]]; then
+
+ # Disable selinux to avoid configuring to allow Apache access
+ # to Horizon files or run nodejs (LP#1175444)
+ # FIXME(dtroyer): see if this can be skipped without node or if Horizon is not enabled
+ if selinuxenabled; then
+ sudo setenforce 0
+ fi
+
+ # If the ``dbus`` package was installed by DevStack dependencies the
+ # uuid may not be generated because the service was never started (PR#598200),
+ # causing Nova to stop later on complaining that ``/var/lib/dbus/machine-id``
+ # does not exist.
+ sudo service messagebus restart
+
+ # The following workarounds break xenserver
+ if [ "$VIRT_DRIVER" != 'xenserver' ]; then
+ # An old version of ``python-crypto`` (2.0.1) may be installed on a
+ # fresh system via Anaconda and the dependency chain
+ # ``cas`` -> ``python-paramiko`` -> ``python-crypto``.
+ # ``pip uninstall pycrypto`` will remove the packaged ``.egg-info``
+ # file but leave most of the actual library files behind in
+ # ``/usr/lib64/python2.6/Crypto``. Later ``pip install pycrypto``
+ # will install over the packaged files resulting
+ # in a useless mess of old, rpm-packaged files and pip-installed files.
+ # Remove the package so that ``pip install python-crypto`` installs
+ # cleanly.
+ # Note: other RPM packages may require ``python-crypto`` as well.
+ # For example, RHEL6 does not install ``python-paramiko packages``.
+ uninstall_package python-crypto
+
+ # A similar situation occurs with ``python-lxml``, which is required by
+ # ``ipa-client``, an auditing package we don't care about. The
+ # build-dependencies needed for ``pip install lxml`` (``gcc``,
+ # ``libxml2-dev`` and ``libxslt-dev``) are present in
+ # ``files/rpms/general``.
+ uninstall_package python-lxml
+ fi
+
+ # ``setup.py`` contains a ``setup_requires`` package that is supposed
+ # to be transient. However, RHEL6 distribute has a bug where
+ # ``setup_requires`` registers entry points that are not cleaned
+ # out properly after the setup-phase resulting in installation failures
+ # (bz#924038). Pre-install the problem package so the ``setup_requires``
+ # dependency is satisfied and it will not be installed transiently.
+ # Note we do this before the track-depends in ``stack.sh``.
+ pip_install hgtools
+
+
+ # RHEL6's version of ``python-nose`` is incompatible with Tempest.
+ # Install nose 1.1 (Tempest-compatible) from EPEL
+ install_package python-nose1.1
+ # Add a symlink for the new nosetests to allow tox for Tempest to
+ # work unmolested.
+ sudo ln -sf /usr/bin/nosetests1.1 /usr/local/bin/nosetests
+
+fi
diff --git a/tools/xen/README.md b/tools/xen/README.md
index af54d72..06192ed 100644
--- a/tools/xen/README.md
+++ b/tools/xen/README.md
@@ -1,48 +1,54 @@
-# Getting Started With XenServer 5.6 and Devstack
-The purpose of the code in this directory it to help developers bootstrap
-a XenServer 5.6 (or greater) + Openstack development environment. This file gives
-some pointers on how to get started.
+# Getting Started With XenServer and Devstack
-Xenserver is a Type 1 hypervisor, so it needs to be installed on bare metal.
-The Openstack services are configured to run within a "privileged" virtual
-machine on the Xenserver host (called OS domU). The VM uses the XAPI toolstack
-to communicate with the host.
+The purpose of the code in this directory it to help developers bootstrap a
+XenServer 6.2 (older versions may also work) + Openstack development
+environment. This file gives some pointers on how to get started.
+
+Xenserver is a Type 1 hypervisor, so it is best installed on bare metal. The
+Openstack services are configured to run within a virtual machine (called OS
+domU) on the XenServer host. The VM uses the XAPI toolstack to communicate with
+the host over a network connection (see `MGT_BRIDGE_OR_NET_NAME`).
The provided localrc helps to build a basic environment.
-The requirements are:
+
+## Introduction
+
+### Requirements
+
- An internet-enabled network with a DHCP server on it
- XenServer box plugged in to the same network
This network will be used as the OpenStack management network. The VM Network
and the Public Network will not be connected to any physical interfaces, only
new virtual networks will be created by the `install_os_domU.sh` script.
-Steps to follow:
+### Steps to follow
+
- Install XenServer
- Download Devstack to XenServer
- Customise `localrc`
- Start `install_os_domU.sh` script
+### Brief explanation
+
The `install_os_domU.sh` script will:
- Setup XenAPI plugins
- Create the named networks, if they don't exist
- - Preseed-Netinstall an Ubuntu Virtual Machine, with 1 network interface:
- - eth0 - Connected to `UBUNTU_INST_BRIDGE_OR_NET_NAME`, defaults to
- `MGT_BRIDGE_OR_NET_NAME`
+ - Preseed-Netinstall an Ubuntu Virtual Machine (NOTE: you can save and reuse
+ it, see [Reuse the Ubuntu VM](#reuse-the-ubuntu-vm)), with 1 network
+ interface:
+ - `eth0` - Connected to `UBUNTU_INST_BRIDGE_OR_NET_NAME`, defaults to
+ `MGT_BRIDGE_OR_NET_NAME`
- After the Ubuntu install process finished, the network configuration is
modified to:
- - eth0 - Management interface, connected to `MGT_BRIDGE_OR_NET_NAME`
- - eth1 - VM interface, connected to `VM_BRIDGE_OR_NET_NAME`
- - eth2 - Public interface, connected to `PUB_BRIDGE_OR_NET_NAME`
- - (eth3) - Optional network interface if neutron is used, to enforce xapi to
- create the underlying bridge.
+ - `eth0` - Management interface, connected to `MGT_BRIDGE_OR_NET_NAME`. Xapi
+ must be accessible through this network.
+ - `eth1` - VM interface, connected to `VM_BRIDGE_OR_NET_NAME`
+ - `eth2` - Public interface, connected to `PUB_BRIDGE_OR_NET_NAME`
- Start devstack inside the created OpenStack VM
## Step 1: Install Xenserver
-Install XenServer 5.6+ on a clean box. You can get XenServer by signing
-up for an account on citrix.com, and then visiting:
-https://www.citrix.com/English/ss/downloads/details.asp?downloadId=2311504&productId=683148
-
-For details on installation, see: http://wiki.openstack.org/XenServer/Install
+Install XenServer on a clean box. You can download the latest XenServer for
+free from: http://www.xenserver.org/
The XenServer IP configuration depends on your local network setup. If you are
using dhcp, make a reservation for XenServer, so its IP address won't change
@@ -85,17 +91,20 @@
XENAPI_CONNECTION_URL="http://address_of_your_xenserver"
VNCSERVER_PROXYCLIENT_ADDRESS=address_of_your_xenserver
- # Do not download the usual images
- IMAGE_URLS=""
- # Explicitly set virt driver here
+ # Download a vhd and a uec image
+ IMAGE_URLS="\
+ https://github.com/downloads/citrix-openstack/warehouse/cirros-0.3.0-x86_64-disk.vhd.tgz,\
+ http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz"
+
+ # Explicitly set virt driver
VIRT_DRIVER=xenserver
- # Explicitly enable multi-host
+
+ # Explicitly enable multi-host for nova-network HA
MULTI_HOST=1
+
# Give extra time for boot
ACTIVE_TIMEOUT=45
- # NOTE: the value of FLAT_NETWORK_BRIDGE will automatically be determined
- # by install_os_domU.sh script.
EOF
## Step 4: Run `./install_os_domU.sh` from the `tools/xen` directory
@@ -107,12 +116,60 @@
installed and tail the run.sh.log file. You will need to wait until it run.sh
has finished executing.
-## Step 5: Do cloudy stuff!
-* Play with horizon
-* Play with the CLI
-* Log bugs to devstack and core projects, and submit fixes!
+# Appendix
-## Step 6: Run from snapshot
-If you want to quicky re-run devstack from a clean state,
-using the same settings you used in your previous run,
-you can revert the DomU to the snapshot called `before_first_boot`
+This section contains useful information for running devstack in CI
+environments / using ubuntu network mirrors.
+
+## Use a specific Ubuntu mirror for installation
+
+To speed up the Ubuntu installation, you can use a specific mirror. To specify
+a mirror explicitly, include the following settings in your `localrc` file:
+
+ UBUNTU_INST_HTTP_HOSTNAME="archive.ubuntu.com"
+ UBUNTU_INST_HTTP_DIRECTORY="/ubuntu"
+
+These variables set the `mirror/http/hostname` and `mirror/http/directory`
+settings in the ubuntu preseed file. The minimal ubuntu VM will use the
+specified parameters.
+
+## Use an http proxy to speed up Ubuntu installation
+
+To further speed up the Ubuntu VM and package installation, an internal http
+proxy could be used. `squid-deb-proxy` has prooven to be stable. To use an http
+proxy, specify:
+
+ UBUNTU_INST_HTTP_PROXY="http://ubuntu-proxy.somedomain.com:8000"
+
+in your `localrc` file.
+
+## Reuse the Ubuntu VM
+
+Performing a minimal ubuntu installation could take a lot of time, depending on
+your mirror/network speed. If you run `install_os_domU.sh` script on a clean
+hypervisor, you can speed up the installation, by re-using the ubuntu vm from
+a previous installation.
+
+### Export the Ubuntu VM to an XVA
+
+Given you have an nfs export `TEMPLATE_NFS_DIR`:
+
+ TEMPLATE_FILENAME=devstack-jeos.xva
+ TEMPLATE_NAME=jeos_template_for_devstack
+ mountdir=$(mktemp -d)
+ mount -t nfs "$TEMPLATE_NFS_DIR" "$mountdir"
+ VM="$(xe template-list name-label="$TEMPLATE_NAME" --minimal)"
+ xe template-export template-uuid=$VM filename="$mountdir/$TEMPLATE_FILENAME"
+ umount "$mountdir"
+ rm -rf "$mountdir"
+
+### Import the Ubuntu VM
+
+Given you have an nfs export `TEMPLATE_NFS_DIR` where you exported the Ubuntu
+VM as `TEMPLATE_FILENAME`:
+
+ mountdir=$(mktemp -d)
+ mount -t nfs "$TEMPLATE_NFS_DIR" "$mountdir"
+ xe vm-import filename="$mountdir/$TEMPLATE_FILENAME"
+ umount "$mountdir"
+ rm -rf "$mountdir"
diff --git a/tools/xen/functions b/tools/xen/functions
index 7616a5f..a5c4b70 100644
--- a/tools/xen/functions
+++ b/tools/xen/functions
@@ -268,3 +268,22 @@
xe network-attach uuid=$net host-uuid=$host
}
+
+function set_vm_memory() {
+ local vm_name_label
+ local memory
+
+ vm_name_label="$1"
+ memory="$2"
+
+ local vm
+
+ vm=$(_vm_uuid "$vm_name_label")
+
+ xe vm-memory-limits-set \
+ static-min=${memory}MiB \
+ static-max=${memory}MiB \
+ dynamic-min=${memory}MiB \
+ dynamic-max=${memory}MiB \
+ uuid=$vm
+}
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index 997644d..b49504d 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -181,7 +181,7 @@
mgmt_ip=$(echo $XENAPI_CONNECTION_URL | tr -d -c '1234567890.')
domid=$(xe vm-list name-label="$GUEST_NAME" params=dom-id minimal=true)
port=$(xenstore-read /local/domain/$domid/console/vnc-port)
- echo "vncviewer -via $mgmt_ip localhost:${port:2}"
+ echo "vncviewer -via root@$mgmt_ip localhost:${port:2}"
while true
do
state=$(xe_min vm-list name-label="$GUEST_NAME" power-state=halted)
@@ -228,8 +228,11 @@
$THIS_DIR/scripts/install-os-vpx.sh \
-t "$UBUNTU_INST_TEMPLATE_NAME" \
-n "$UBUNTU_INST_BRIDGE_OR_NET_NAME" \
- -l "$GUEST_NAME" \
- -r "$OSDOMU_MEM_MB"
+ -l "$GUEST_NAME"
+
+ set_vm_memory "$GUEST_NAME" "$OSDOMU_MEM_MB"
+
+ xe vm-start vm="$GUEST_NAME"
# wait for install to finish
wait_for_VM_to_halt
@@ -255,6 +258,9 @@
# Install XenServer tools, and other such things
$THIS_DIR/prepare_guest_template.sh "$GUEST_NAME"
+# Set virtual machine parameters
+set_vm_memory "$GUEST_NAME" "$OSDOMU_MEM_MB"
+
# start the VM to run the prepare steps
xe vm-start vm="$GUEST_NAME"
diff --git a/tools/xen/scripts/install-os-vpx.sh b/tools/xen/scripts/install-os-vpx.sh
index 8ee8b67..c94a593 100755
--- a/tools/xen/scripts/install-os-vpx.sh
+++ b/tools/xen/scripts/install-os-vpx.sh
@@ -20,8 +20,6 @@
set -eux
BRIDGE=
-RAM=
-BALLOONING=
NAME_LABEL=
TEMPLATE_NAME=
@@ -29,7 +27,7 @@
{
cat << EOF
- Usage: $0 -t TEMPLATE_NW_INSTALL -l NAME_LABEL [-n BRIDGE] [-r RAM] [-b]
+ Usage: $0 -t TEMPLATE_NW_INSTALL -l NAME_LABEL [-n BRIDGE]
Install a VM from a template
@@ -37,9 +35,6 @@
-h Shows this message.
-t template VM template to use
- -b Enable memory ballooning. When set min_RAM=RAM/2 max_RAM=RAM.
- -r MiB Specifies RAM used by the VPX, in MiB.
- By default it will take the value from the XVA.
-l name Specifies the name label for the VM.
-n bridge The bridge/network to use for eth0. Defaults to xenbr0
EOF
@@ -53,12 +48,6 @@
h) usage
exit 1
;;
- b)
- BALLOONING=1
- ;;
- r)
- RAM=$OPTARG
- ;;
n)
BRIDGE=$OPTARG
;;
@@ -119,19 +108,6 @@
}
-set_memory()
-{
- local v="$1"
- if [ "$RAM" != "" ]
- then
- echo "Setting RAM to $RAM MiB."
- [ "$BALLOONING" == 1 ] && RAM_MIN=$(($RAM / 2)) || RAM_MIN=$RAM
- xe vm-memory-limits-set static-min=16MiB static-max=${RAM}MiB \
- dynamic-min=${RAM_MIN}MiB dynamic-max=${RAM}MiB \
- uuid="$v"
- fi
-}
-
# Make the VM auto-start on server boot.
set_auto_start()
@@ -161,5 +137,3 @@
create_vif "$vm_uuid"
xe vm-param-set other-config:os-vpx=true uuid="$vm_uuid"
xe vm-param-set actions-after-reboot=Destroy uuid="$vm_uuid"
-set_memory "$vm_uuid"
-xe vm-start uuid=$vm_uuid
diff --git a/tools/xen/xenrc b/tools/xen/xenrc
index 03b30ac..f698be1 100644
--- a/tools/xen/xenrc
+++ b/tools/xen/xenrc
@@ -13,7 +13,7 @@
# Size of image
VDI_MB=${VDI_MB:-5000}
-OSDOMU_MEM_MB=1024
+OSDOMU_MEM_MB=2048
OSDOMU_VDI_GB=8
# Network mapping. Specify bridge names or network names. Network names may
diff --git a/unstack.sh b/unstack.sh
index 2268b90..38f795b 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -33,6 +33,7 @@
source $TOP_DIR/lib/horizon
source $TOP_DIR/lib/swift
source $TOP_DIR/lib/neutron
+source $TOP_DIR/lib/ironic
# Determine what system we are running on. This provides ``os_VENDOR``,
# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
@@ -65,12 +66,26 @@
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
cleanup_swift
fi
+# Ironic runs daemons
+if is_service_enabled ir-api ir-cond; then
+ stop_ironic
+ cleanup_ironic
+fi
+
# Apache has the WSGI processes
if is_service_enabled horizon; then
stop_horizon