Skip to content

Commit 2aa2a89

Browse files
author
Dean Troyer
committed
Add support for Docker as Nova hypervisor
* Add basic support for hypervisor plugins in lib/nova_plugins * Add lib/nova_plugins/hypervisor-docker to use Docker as a Nova hypervisor. * Add tools/install_docker.sh to install the Docker daemon and registry container, download base image and import * Configure Nova to use docker plugin * Add docker exercise and skip unsupported ones Nova blueprint: new-hypervisor-docker Change-Id: I9e7065b562dce2ce853def583ab1165886612227
1 parent 415360b commit 2aa2a89

14 files changed

Lines changed: 391 additions & 3 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ Read more at http://devstack.org (built from the gh-pages branch)
1212

1313
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.
1414

15-
# Devstack on Xenserver
15+
# DevStack on Xenserver
1616

1717
If you would like to use Xenserver as the hypervisor, please refer to the instructions in `./tools/xen/README.md`.
1818

19+
# DevStack on Docker
20+
21+
If you would like to use Docker as the hypervisor, please refer to the instructions in `./tools/docker/README.md`.
22+
1923
# Versions
2024

2125
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:

clean.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ cleanup_nova
6464
cleanup_neutron
6565
cleanup_swift
6666

67+
# Do the hypervisor cleanup until this can be moved back into lib/nova
68+
if [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
69+
cleanup_nova_hypervisor
70+
fi
71+
6772
# cinder doesn't always clean up the volume group as it might be used elsewhere...
6873
# clean it up if it is a loop device
6974
VG_DEV=$(sudo losetup -j $DATA_DIR/${VOLUME_GROUP}-backing-file | awk -F':' '/backing-file/ { print $1}')

exercises/boot_from_volume.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ source $TOP_DIR/exerciserc
4444
# the exercise is skipped
4545
is_service_enabled cinder || exit 55
4646

47+
# Also skip if the hypervisor is Docker
48+
[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
49+
4750
# Instance type to create
4851
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
4952

exercises/docker.sh

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#!/usr/bin/env bash
2+
3+
# **docker**
4+
5+
# Test Docker hypervisor
6+
7+
echo "*********************************************************************"
8+
echo "Begin DevStack Exercise: $0"
9+
echo "*********************************************************************"
10+
11+
# This script exits on an error so that errors don't compound and you see
12+
# only the first error that occurred.
13+
set -o errexit
14+
15+
# Print the commands being run so that we can see the command that triggers
16+
# an error. It is also useful for following allowing as the install occurs.
17+
set -o xtrace
18+
19+
20+
# Settings
21+
# ========
22+
23+
# Keep track of the current directory
24+
EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
25+
TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
26+
27+
# Import common functions
28+
source $TOP_DIR/functions
29+
30+
# Import configuration
31+
source $TOP_DIR/openrc
32+
33+
# Import exercise configuration
34+
source $TOP_DIR/exerciserc
35+
36+
# Skip if the hypervisor is not Docker
37+
[[ "$VIRT_DRIVER" == "docker" ]] || exit 55
38+
39+
# Import docker functions and declarations
40+
source $TOP_DIR/lib/nova_plugins/hypervisor-docker
41+
42+
# Image and flavor are ignored but the CLI requires them...
43+
44+
# Instance type to create
45+
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
46+
47+
# Boot this image, use first AMI image if unset
48+
DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-ami}
49+
50+
# Instance name
51+
VM_NAME=ex-docker
52+
53+
54+
# Launching a server
55+
# ==================
56+
57+
# Grab the id of the image to launch
58+
IMAGE=$(glance image-list | egrep " $DOCKER_IMAGE_NAME:latest " | get_field 1)
59+
die_if_not_set $LINENO IMAGE "Failure getting image $DOCKER_IMAGE_NAME"
60+
61+
# Select a flavor
62+
INSTANCE_TYPE=$(nova flavor-list | grep $DEFAULT_INSTANCE_TYPE | get_field 1)
63+
if [[ -z "$INSTANCE_TYPE" ]]; then
64+
# grab the first flavor in the list to launch if default doesn't exist
65+
INSTANCE_TYPE=$(nova flavor-list | head -n 4 | tail -n 1 | get_field 1)
66+
fi
67+
68+
# Clean-up from previous runs
69+
nova delete $VM_NAME || true
70+
if ! timeout $ACTIVE_TIMEOUT sh -c "while nova show $VM_NAME; do sleep 1; done"; then
71+
die $LINENO "server didn't terminate!"
72+
fi
73+
74+
# Boot instance
75+
# -------------
76+
77+
VM_UUID=$(nova boot --flavor $INSTANCE_TYPE --image $IMAGE $VM_NAME | grep ' id ' | get_field 2)
78+
die_if_not_set $LINENO VM_UUID "Failure launching $VM_NAME"
79+
80+
# Check that the status is active within ACTIVE_TIMEOUT seconds
81+
if ! timeout $ACTIVE_TIMEOUT sh -c "while ! nova show $VM_UUID | grep status | grep -q ACTIVE; do sleep 1; done"; then
82+
die $LINENO "server didn't become active!"
83+
fi
84+
85+
# Get the instance IP
86+
IP=$(nova show $VM_UUID | grep "$PRIVATE_NETWORK_NAME" | get_field 2)
87+
die_if_not_set $LINENO IP "Failure retrieving IP address"
88+
89+
# Private IPs can be pinged in single node deployments
90+
ping_check "$PRIVATE_NETWORK_NAME" $IP $BOOT_TIMEOUT
91+
92+
# Clean up
93+
# --------
94+
95+
# Delete instance
96+
nova delete $VM_UUID || die $LINENO "Failure deleting instance $VM_NAME"
97+
if ! timeout $TERMINATE_TIMEOUT sh -c "while nova list | grep -q $VM_UUID; do sleep 1; done"; then
98+
die $LINENO "Server $VM_NAME not deleted"
99+
fi
100+
101+
set +o xtrace
102+
echo "*********************************************************************"
103+
echo "SUCCESS: End DevStack Exercise: $0"
104+
echo "*********************************************************************"
105+

exercises/euca.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ fi
4141
# Import exercise configuration
4242
source $TOP_DIR/exerciserc
4343

44+
# Skip if the hypervisor is Docker
45+
[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
46+
4447
# Instance type to create
4548
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
4649

exercises/floating_ips.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ fi
3838
# Import exercise configuration
3939
source $TOP_DIR/exerciserc
4040

41+
# Skip if the hypervisor is Docker
42+
[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
43+
4144
# Instance type to create
4245
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
4346

exercises/sec_groups.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ source $TOP_DIR/openrc
3333
# Import exercise configuration
3434
source $TOP_DIR/exerciserc
3535

36+
# Skip if the hypervisor is Docker
37+
[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
38+
3639

3740
# Testing Security Groups
3841
# =======================

exercises/volumes.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ source $TOP_DIR/exerciserc
4242
# exercise is skipped.
4343
is_service_enabled cinder || exit 55
4444

45+
# Also skip if the hypervisor is Docker
46+
[[ "$VIRT_DRIVER" == "docker" ]] && exit 55
47+
4548
# Instance type to create
4649
DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
4750

lib/nova

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,13 @@ function cleanup_nova() {
169169
fi
170170

171171
sudo rm -rf $NOVA_STATE_PATH $NOVA_AUTH_CACHE_DIR
172+
173+
# NOTE(dtroyer): This really should be called from here but due to the way
174+
# nova abuses the _cleanup() function we're moving it
175+
# directly into cleanup.sh until this can be fixed.
176+
#if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
177+
# cleanup_nova_hypervisor
178+
#fi
172179
}
173180

174181
# configure_nova_rootwrap() - configure Nova's rootwrap
@@ -650,7 +657,9 @@ function install_novaclient() {
650657
# install_nova() - Collect source and prepare
651658
function install_nova() {
652659
if is_service_enabled n-cpu; then
653-
if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
660+
if [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
661+
install_nova_hypervisor
662+
elif [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
654663
if is_ubuntu; then
655664
install_package kvm
656665
install_package libvirt-bin
@@ -728,6 +737,9 @@ function start_nova() {
728737
screen_it n-cpu "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-compute --config-file $NOVA_CONF_BOTTOM"
729738
done
730739
else
740+
if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
741+
start_nova_hypervisor
742+
fi
731743
screen_it n-cpu "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-compute --config-file $NOVA_CONF_BOTTOM"
732744
fi
733745
screen_it n-crt "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-cert"
@@ -754,6 +766,9 @@ function stop_nova() {
754766
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
755767
screen -S $SCREEN_NAME -p $serv -X kill
756768
done
769+
if is_service_enabled n-cpu && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
770+
stop_nova_hypervisor
771+
fi
757772
}
758773

759774

lib/nova_plugins/hypervisor-docker

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# lib/nova_plugins/docker
2+
# Configure the Docker hypervisor
3+
4+
# Enable with:
5+
# VIRT_DRIVER=docker
6+
7+
# Dependencies:
8+
# ``functions`` file
9+
# ``nova`` and ``glance`` configurations
10+
11+
# install_nova_hypervisor - install any external requirements
12+
# configure_nova_hypervisor - make configuration changes, including those to other services
13+
# start_nova_hypervisor - start any external services
14+
# stop_nova_hypervisor - stop any external services
15+
# cleanup_nova_hypervisor - remove transient data and cache
16+
17+
# Save trace setting
18+
MY_XTRACE=$(set +o | grep xtrace)
19+
set +o xtrace
20+
21+
22+
# Defaults
23+
# --------
24+
25+
# Set up default directories
26+
DOCKER_DIR=$DEST/docker
27+
DOCKER_REPO=${DOCKER_REPO:-https://github.com/dotcloud/openstack-docker.git}
28+
DOCKER_BRANCH=${DOCKER_BRANCH:-master}
29+
30+
DOCKER_UNIX_SOCKET=/var/run/docker.sock
31+
DOCKER_PID_FILE=/var/run/docker.pid
32+
DOCKER_REGISTRY_PORT=${DOCKER_REGISTRY_PORT:-5042}
33+
34+
DOCKER_IMAGE=${DOCKER_IMAGE:-http://get.docker.io/images/openstack/docker-ut.tar.gz}
35+
DOCKER_IMAGE_NAME=docker-busybox
36+
DOCKER_REGISTRY_IMAGE=${DOCKER_REGISTRY_IMAGE:-http://get.docker.io/images/openstack/docker-registry.tar.gz}
37+
DOCKER_REGISTRY_IMAGE_NAME=docker-registry
38+
DOCKER_REPOSITORY_NAME=${SERVICE_HOST}:${DOCKER_REGISTRY_PORT}/${DOCKER_IMAGE_NAME}
39+
40+
DOCKER_PACKAGE_VERSION=${DOCKER_PACKAGE_VERSION:-0.6.1}
41+
DOCKER_APT_REPO=${DOCKER_APT_REPO:-https://get.docker.io/ubuntu}
42+
43+
44+
# Entry Points
45+
# ------------
46+
47+
# clean_nova_hypervisor - Clean up an installation
48+
function cleanup_nova_hypervisor() {
49+
stop_service docker
50+
51+
# Clean out work area
52+
sudo rm -rf /var/lib/docker
53+
}
54+
55+
# configure_nova_hypervisor - Set config files, create data dirs, etc
56+
function configure_nova_hypervisor() {
57+
git_clone $DOCKER_REPO $DOCKER_DIR $DOCKER_BRANCH
58+
59+
ln -snf ${DOCKER_DIR}/nova-driver $NOVA_DIR/nova/virt/docker
60+
61+
iniset $NOVA_CONF DEFAULT compute_driver docker.DockerDriver
62+
iniset $GLANCE_API_CONF DEFAULT container_formats ami,ari,aki,bare,ovf,docker
63+
64+
sudo cp -p ${DOCKER_DIR}/nova-driver/docker.filters $NOVA_CONF_DIR/rootwrap.d
65+
}
66+
67+
# install_nova_hypervisor() - Install external components
68+
function install_nova_hypervisor() {
69+
# So far this is Ubuntu only
70+
if ! is_ubuntu; then
71+
die $LINENO "Docker is only supported on Ubuntu at this time"
72+
fi
73+
74+
# Make sure Docker is installed
75+
if ! is_package_installed lxc-docker; then
76+
die $LINENO "Docker is not installed. Please run tools/docker/install_docker.sh"
77+
fi
78+
79+
local docker_pid
80+
read docker_pid <$DOCKER_PID_FILE
81+
if [[ -z $docker_pid ]] || ! ps -p $docker_pid | grep [d]ocker; then
82+
die $LINENO "Docker not running"
83+
fi
84+
}
85+
86+
# start_nova_hypervisor - Start any required external services
87+
function start_nova_hypervisor() {
88+
local docker_pid
89+
read docker_pid <$DOCKER_PID_FILE
90+
if [[ -z $docker_pid ]] || ! ps -p $docker_pid | grep [d]ocker; then
91+
die $LINENO "Docker not running, start the daemon"
92+
fi
93+
94+
# Start the Docker registry container
95+
docker run -d -p ${DOCKER_REGISTRY_PORT}:5000 \
96+
-e SETTINGS_FLAVOR=openstack -e OS_USERNAME=${OS_USERNAME} \
97+
-e OS_PASSWORD=${OS_PASSWORD} -e OS_TENANT_NAME=${OS_TENANT_NAME} \
98+
-e OS_GLANCE_URL="${SERVICE_PROTOCOL}://${GLANCE_HOSTPORT}" \
99+
-e OS_AUTH_URL=${OS_AUTH_URL} \
100+
$DOCKER_REGISTRY_IMAGE_NAME ./docker-registry/run.sh
101+
102+
echo "Waiting for docker registry to start..."
103+
DOCKER_REGISTRY=${SERVICE_HOST}:${DOCKER_REGISTRY_PORT}
104+
if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl -s $DOCKER_REGISTRY; do sleep 1; done"; then
105+
die $LINENO "docker-registry did not start"
106+
fi
107+
108+
# Tag image if not already tagged
109+
if ! docker images | grep $DOCKER_REPOSITORY_NAME; then
110+
docker tag $DOCKER_IMAGE_NAME $DOCKER_REPOSITORY_NAME
111+
fi
112+
113+
# Make sure we copied the image in Glance
114+
DOCKER_IMAGE=$(glance image-list | egrep " $DOCKER_IMAGE_NAME ")
115+
if ! is_set DOCKER_IMAGE ; then
116+
docker push $DOCKER_REPOSITORY_NAME
117+
fi
118+
}
119+
120+
# stop_nova_hypervisor - Stop any external services
121+
function stop_nova_hypervisor() {
122+
# Stop the docker registry container
123+
docker kill $(docker ps | grep docker-registry | cut -d' ' -f1)
124+
}
125+
126+
127+
# Restore xtrace
128+
$MY_XTRACE
129+
130+
# Local variables:
131+
# mode: shell-script
132+
# End:

0 commit comments

Comments
 (0)