Merge remote-tracking branch 'upstream/master' into 4-run.sh
diff --git a/README b/README.md
similarity index 94%
rename from README
rename to README.md
index 61119e9..82ef7fb 100644
--- a/README
+++ b/README.md
@@ -7,6 +7,8 @@
* To make it easier for developers to dive into openstack so that they can productively contribute without having to understand every part of the system at once
* To make it easy to prototype cross-project features
+Read more at http://devstack.org (built from the gh-pages branch)
+
Be sure to carefully read these scripts before you run them as they install software and may alter your networking configuration.
# To start a dev cloud on your local machine (installing on a dedicated vm is safer!):
@@ -32,7 +34,6 @@
* Add python-novaclient cli support
* syslog
-* allow rabbit connection to be specified via environment variables with sensible defaults
* Add volume support
* Add quantum support
diff --git a/exercise.sh b/exercise.sh
index d9d4c0a..dc8163f 100755
--- a/exercise.sh
+++ b/exercise.sh
@@ -52,10 +52,17 @@
# FIXME - why does this need to be specified?
export NOVA_REGION_NAME=RegionOne
+# set log level to DEBUG (helps debug issues)
+export NOVACLIENT_DEBUG=1
# Get a token for clients that don't support service catalog
# ==========================================================
-SERVICE_TOKEN=`curl -s -d "{\"auth\":{\"passwordCredentials\": {\"username\": \"$NOVA_PROJECT_ID\", \"password\": \"$NOVA_API_KEY\"}}}" -H "Content-type: application/json" http://$HOST:5000/v2.0/tokens | python -c "import sys; import json; tok = json.loads(sys.stdin.read()); print tok['access']['token']['id'];"`
+
+# manually create a token by querying keystone (sending JSON data). Keystone
+# returns a token and catalog of endpoints. We use python to parse the token
+# and save it.
+
+TOKEN=`curl -s -d "{\"auth\":{\"passwordCredentials\": {\"username\": \"$NOVA_USERNAME\", \"password\": \"$NOVA_API_KEY\"}}}" -H "Content-type: application/json" http://$HOST:5000/v2.0/tokens | python -c "import sys; import json; tok = json.loads(sys.stdin.read()); print tok['access']['token']['id'];"`
# Launching a server
# ==================
@@ -63,9 +70,6 @@
# List servers for tenant:
nova list
-# List of flavors:
-nova flavor-list
-
# Images
# ------
@@ -73,10 +77,46 @@
nova image-list
# But we recommend using glance directly
-glance -A $SERVICE_TOKEN index
+glance -A $TOKEN index
-# show details of the active servers::
-#
-# nova show 1234
-#
-nova list | grep ACTIVE | cut -d \| -f2 | xargs -n1 nova show
+# Let's grab the id of the first AMI image to launch
+IMAGE=`glance -A $TOKEN index | egrep ami | cut -d" " -f1`
+
+
+# Flavors
+# -------
+
+# List of flavors:
+nova flavor-list
+
+# and grab the first flavor in the list to launch
+FLAVOR=`nova flavor-list | head -n 4 | tail -n 1 | cut -d"|" -f2`
+
+NAME="firstpost"
+
+nova boot --flavor $FLAVOR --image $IMAGE $NAME
+
+# let's give it 10 seconds to launch
+sleep 10
+
+# check that the status is active
+nova show $NAME | grep status | grep -q ACTIVE
+
+# get the IP of the server
+IP=`nova show $NAME | grep "private network" | cut -d"|" -f3`
+
+# ping it once (timeout of a second)
+ping -c1 -w1 $IP || true
+
+# sometimes the first ping fails (10 seconds isn't enough time for the VM's
+# network to respond?), so let's wait 5 seconds and really test ping
+sleep 5
+
+ping -c1 -w1 $IP
+
+# shutdown the server
+nova delete $NAME
+
+# FIXME: validate shutdown within 5 seconds
+# (nova show $NAME returns 1 or status != ACTIVE)?
+
diff --git a/stack.sh b/stack.sh
index f6bf534..a7eacbf 100755
--- a/stack.sh
+++ b/stack.sh
@@ -20,9 +20,6 @@
# Sanity Check
# ============
-# Record the start time. This allows us to print how long this script takes to run.
-START_TIME=`python -c "import time; print time.time()"`
-
# Warn users who aren't on natty, but allow them to override check and attempt
# installation with ``FORCE=yes ./stack``
if ! grep -q natty /etc/lsb-release; then
@@ -43,6 +40,9 @@
exit 1
fi
+# Keep track of the current devstack directory.
+TOP_DIR=$(cd $(dirname "$0") && pwd)
+
# OpenStack is designed to be run as a regular user (Dashboard will fail to run
# as root, since apache refused to startup serve content from root user). If
# stack.sh is run as root, it automatically creates a stack user with
@@ -50,40 +50,38 @@
if [[ $EUID -eq 0 ]]; then
echo "You are running this script as root."
+ echo "In 10 seconds, we will create a user 'stack' and run as that user"
+ sleep 10
# since this script runs as a normal user, we need to give that user
# ability to run sudo
apt-get update
- apt-get install -qqy sudo
+ apt-get install -y sudo
- if ! getent passwd | grep -q stack; then
+ if ! getent passwd stack >/dev/null; then
echo "Creating a user called stack"
useradd -U -G sudo -s /bin/bash -m stack
fi
+
echo "Giving stack user passwordless sudo priviledges"
- echo "stack ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+ # natty uec images sudoers does not have a '#includedir'. add one.
+ grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
+ echo "#includedir /etc/sudoers.d" >> /etc/sudoers
+ ( umask 226 && echo "stack ALL=(ALL) NOPASSWD:ALL" \
+ > /etc/sudoers.d/50_stack_sh )
echo "Copying files to stack user"
- cp -r -f `pwd` /home/stack/
- THIS_DIR=$(basename $(dirname $(readlink -f $0)))
- chown -R stack /home/stack/$THIS_DIR
- echo "Running the script as stack in 3 seconds..."
- sleep 3
+ STACK_DIR="/home/stack/${PWD##*/}"
+ cp -r -f "$PWD" "$STACK_DIR"
+ chown -R stack "$STACK_DIR"
if [[ "$SHELL_AFTER_RUN" != "no" ]]; then
- exec su -c "cd /home/stack/$THIS_DIR/; bash stack.sh; bash" stack
+ exec su -c "set -e; cd $STACK_DIR; bash stack.sh; bash" stack
else
- exec su -c "cd /home/stack/$THIS_DIR/; bash stack.sh" stack
+ exec su -c "set -e; cd $STACK_DIR; bash stack.sh" stack
fi
- exit 0
+ exit 1
fi
-# So that errors don't compound we exit on any errors so you see only the
-# first error that occured.
-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
# ========
@@ -91,14 +89,14 @@
# This script is customizable through setting environment variables. If you
# want to override a setting you can either::
#
-# export MYSQL_PASS=anothersecret
+# export MYSQL_PASSWORD=anothersecret
# ./stack.sh
#
-# You can also pass options on a single line ``MYSQL_PASS=simple ./stack.sh``
+# You can also pass options on a single line ``MYSQL_PASSWORD=simple ./stack.sh``
#
# Additionally, you can put any local variables into a ``localrc`` file, like::
#
-# MYSQL_PASS=anothersecret
+# MYSQL_PASSWORD=anothersecret
# MYSQL_USER=hellaroot
#
# We try to have sensible defaults, so you should be able to run ``./stack.sh``
@@ -111,14 +109,12 @@
#
# If ``localrc`` exists, then ``stackrc`` will load those settings. This is
# useful for changing a branch or repostiory to test other versions. Also you
-# can store your other settings like **MYSQL_PASS** or **ADMIN_PASSWORD** instead
+# can store your other settings like **MYSQL_PASSWORD** or **ADMIN_PASSWORD** instead
# of letting devstack generate random ones for you.
source ./stackrc
# Destination path for installation ``DEST``
DEST=${DEST:-/opt/stack}
-sudo mkdir -p $DEST
-sudo chown `whoami` $DEST
# Set the destination directories for openstack projects
NOVA_DIR=$DEST/nova
@@ -146,6 +142,43 @@
HOST_IP=`LC_ALL=C /sbin/ifconfig | grep -m 1 'inet addr:'| cut -d: -f2 | awk '{print $1}'`
fi
+# Generic helper to configure passwords
+function read_password {
+ set +o xtrace
+ var=$1; msg=$2
+ pw=${!var}
+
+ localrc=$TOP_DIR/localrc
+
+ # If the password is not defined yet, proceed to prompt user for a password.
+ if [ ! $pw ]; then
+ # If there is no localrc file, create one
+ if [ ! -e $localrc ]; then
+ touch $localrc
+ fi
+
+ # Presumably if we got this far it can only be that our localrc is missing
+ # the required password. Prompt user for a password and write to localrc.
+ echo ''
+ echo '################################################################################'
+ echo $msg
+ echo '################################################################################'
+ echo "This value will be written to your localrc file so you don't have to enter it again."
+ echo "It is probably best to avoid spaces and weird characters."
+ echo "If you leave this blank, a random default value will be used."
+ echo "Enter a password now:"
+ read $var
+ pw=${!var}
+ if [ ! $pw ]; then
+ pw=`openssl rand -hex 10`
+ fi
+ eval "$var=$pw"
+ echo "$var=$pw" >> $localrc
+ fi
+ set -o xtrace
+}
+
+
# Nova Network Configuration
# --------------------------
@@ -194,32 +227,51 @@
# By default this script will install and configure MySQL. If you want to
# use an existing server, you can pass in the user/password/host parameters.
-# You will need to send the same ``MYSQL_PASS`` to every host if you are doing
+# You will need to send the same ``MYSQL_PASSWORD`` to every host if you are doing
# a multi-node devstack installation.
MYSQL_USER=${MYSQL_USER:-root}
-MYSQL_PASS=${MYSQL_PASS:-`openssl rand -hex 12`}
+read_password MYSQL_PASSWORD "ENTER A PASSWORD TO USE FOR MYSQL."
MYSQL_HOST=${MYSQL_HOST:-localhost}
# don't specify /db in this string, so we can use it for multiple services
-BASE_SQL_CONN=${BASE_SQL_CONN:-mysql://$MYSQL_USER:$MYSQL_PASS@$MYSQL_HOST}
+BASE_SQL_CONN=${BASE_SQL_CONN:-mysql://$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST}
# Rabbit connection info
RABBIT_HOST=${RABBIT_HOST:-localhost}
RABBIT_PASSWORD=${RABBIT_PASSWORD:-`openssl rand -hex 12`}
+read_password RABBIT_PASSWORD "ENTER A PASSWORD TO USE FOR RABBIT."
# Glance connection info. Note the port must be specified.
GLANCE_HOSTPORT=${GLANCE_HOSTPORT:-$HOST_IP:9292}
+
# Keystone
# --------
# Service Token - Openstack components need to have an admin token
# to validate user tokens.
-SERVICE_TOKEN=${SERVICE_TOKEN:-`openssl rand -hex 12`}
+read_password SERVICE_TOKEN "ENTER A SERVICE_TOKEN TO USE FOR THE SERVICE ADMIN TOKEN."
# Dash currently truncates usernames and passwords at 20 characters
-# so use 10 bytes
-ADMIN_PASSWORD=${ADMIN_PASSWORD:-`openssl rand -hex 10`}
+read_password ADMIN_PASSWORD "ENTER A PASSWORD TO USE FOR DASH AND KEYSTONE (20 CHARS OR LESS)."
+LOGFILE=${LOGFILE:-"$PWD/stack.sh.$$.log"}
+(
+# So that errors don't compound we exit on any errors so you see only the
+# first error that occured.
+trap failed ERR
+failed() {
+ local r=$?
+ set +o xtrace
+ [ -n "$LOGFILE" ] && echo "${0##*/} failed: full log in $LOGFILE"
+ exit $r
+}
+
+# Print the commands being run so that we can see the command that triggers
+# an error. It is also useful for following along as the install occurs.
+set -o xtrace
+
+sudo mkdir -p $DEST
+sudo chown `whoami` $DEST
# Install Packages
# ================
@@ -228,6 +280,7 @@
# install apt requirements
+sudo apt-get update
sudo apt-get install -qqy `cat $FILES/apts/* | cut -d\# -f1 | grep -Ev "mysql-server|rabbitmq-server"`
# install python requirements
@@ -301,15 +354,28 @@
# Seed configuration with mysql password so that apt-get install doesn't
# prompt us for a password upon install.
cat <<MYSQL_PRESEED | sudo debconf-set-selections
-mysql-server-5.1 mysql-server/root_password password $MYSQL_PASS
-mysql-server-5.1 mysql-server/root_password_again password $MYSQL_PASS
+mysql-server-5.1 mysql-server/root_password password $MYSQL_PASSWORD
+mysql-server-5.1 mysql-server/root_password_again password $MYSQL_PASSWORD
mysql-server-5.1 mysql-server/start_on_boot boolean true
MYSQL_PRESEED
+ # while ``.my.cnf`` is not needed for openstack to function, it is useful
+ # as it allows you to access the mysql databases via ``mysql nova`` instead
+ # of having to specify the username/password each time.
+ if [[ ! -e $HOME/.my.cnf ]]; then
+ cat <<EOF >$HOME/.my.cnf
+[client]
+user=$MYSQL_USER
+password=$MYSQL_PASSWORD
+host=$MYSQL_HOST
+EOF
+ chmod 0600 $HOME/.my.cnf
+ fi
+
# Install and start mysql-server
sudo apt-get -y -q install mysql-server
# Update the DB to give user ‘$MYSQL_USER’@’%’ full control of the all databases:
- sudo mysql -uroot -p$MYSQL_PASS -e "GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%' identified by '$MYSQL_PASS';"
+ sudo mysql -uroot -p$MYSQL_PASSWORD -e "GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%' identified by '$MYSQL_PASSWORD';"
# Edit /etc/mysql/my.cnf to change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0) and restart the mysql service:
sudo sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf
@@ -360,8 +426,8 @@
mkdir -p $GLANCE_IMAGE_DIR
# (re)create glance database
- mysql -u$MYSQL_USER -p$MYSQL_PASS -e 'DROP DATABASE IF EXISTS glance;'
- mysql -u$MYSQL_USER -p$MYSQL_PASS -e 'CREATE DATABASE glance;'
+ mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS glance;'
+ mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE glance;'
# Copy over our glance-registry.conf
GLANCE_CONF=$GLANCE_DIR/etc/glance-registry.conf
cp $FILES/glance-registry.conf $GLANCE_CONF
@@ -490,8 +556,8 @@
if [[ "$ENABLED_SERVICES" =~ "mysql" ]]; then
# (re)create nova database
- mysql -u$MYSQL_USER -p$MYSQL_PASS -e 'DROP DATABASE IF EXISTS nova;'
- mysql -u$MYSQL_USER -p$MYSQL_PASS -e 'CREATE DATABASE nova;'
+ mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS nova;'
+ mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE nova;'
# (re)create nova database
$NOVA_DIR/bin/nova-manage db sync
@@ -509,8 +575,8 @@
if [[ "$ENABLED_SERVICES" =~ "key" ]]; then
# (re)create keystone database
- mysql -u$MYSQL_USER -p$MYSQL_PASS -e 'DROP DATABASE IF EXISTS keystone;'
- mysql -u$MYSQL_USER -p$MYSQL_PASS -e 'CREATE DATABASE keystone;'
+ mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS keystone;'
+ mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE keystone;'
# FIXME (anthony) keystone should use keystone.conf.example
KEYSTONE_CONF=$KEYSTONE_DIR/etc/keystone.conf
@@ -584,9 +650,8 @@
# have to do a little more than that in our script. Since we add the group
# ``libvirtd`` to our user in this script, when nova-compute is run it is
# within the context of our original shell (so our groups won't be updated).
-# We can send the command nova-compute to the ``newgrp`` command to execute
-# in a specific context.
-screen_it n-cpu "cd $NOVA_DIR && echo $NOVA_DIR/bin/nova-compute | newgrp libvirtd"
+# Use 'sg' to execute nova-compute as a member of the libvirtd group.
+screen_it n-cpu "cd $NOVA_DIR && sg libvirtd $NOVA_DIR/bin/nova-compute"
screen_it n-net "cd $NOVA_DIR && $NOVA_DIR/bin/nova-network"
screen_it n-sch "cd $NOVA_DIR && $NOVA_DIR/bin/nova-scheduler"
screen_it n-vnc "cd $NOVNC_DIR && ./utils/nova-wsproxy.py 6080 --web . --flagfile=../nova/bin/nova.conf"
@@ -595,57 +660,53 @@
# Install Images
# ==============
-# Upload a couple images to glance. **TTY** is a simple small image that use the
-# lets you login to it with username/password of user/password. TTY is useful
-# for basic functionality. We all include an Ubuntu cloud build of **Natty**.
-# Natty uses cloud-init, supporting login via keypair and sending scripts as
-# userdata.
+# Upload an image to glance.
#
-# Read more about cloud-init at https://help.ubuntu.com/community/CloudInit
+# The default image is a small ***TTY*** testing image, which lets you login
+# the username/password of root/password.
+#
+# TTY also uses cloud-init, supporting login via keypair and sending scripts as
+# userdata. See https://help.ubuntu.com/community/CloudInit for more on cloud-init
+#
+# Override IMAGE_URLS if you would to launch a different image(s).
+# Specify IMAGE_URLS as a comma-separated list of uec urls. Some other options include:
+# natty: http://uec-images.ubuntu.com/natty/current/natty-server-cloudimg-amd64.tar.gz
+# oneiric: http://uec-images.ubuntu.com/oneiric/current/oneiric-server-cloudimg-amd64.tar.gz
if [[ "$ENABLED_SERVICES" =~ "g-reg" ]]; then
- # create a directory for the downloadedthe images tarballs.
+ # Create a directory for the downloaded image tarballs.
mkdir -p $FILES/images
- # Debug Image (TTY)
- # -----------------
+ for image_url in ${IMAGE_URLS//,/ }; do
+ # Downloads the image (uec ami+aki style), then extracts it.
+ IMAGE_FNAME=`echo "$image_url" | python -c "import sys; print sys.stdin.read().split('/')[-1]"`
+ IMAGE_NAME=`echo "$IMAGE_FNAME" | python -c "import sys; print sys.stdin.read().split('.tar.gz')[0].split('.tgz')[0]"`
+ if [ ! -f $FILES/$IMAGE_FNAME ]; then
+ wget -c $image_url -O $FILES/$IMAGE_FNAME
+ fi
- # Downloads the image (ami/aki/ari style), then extracts it. Upon extraction
- # we upload to glance with the glance cli tool. TTY is a stripped down
- # version of ubuntu.
- if [ ! -f $FILES/tty.tgz ]; then
- wget -c http://images.ansolabs.com/tty.tgz -O $FILES/tty.tgz
- fi
+ # Extract ami and aki files
+ tar -zxf $FILES/$IMAGE_FNAME -C $FILES/images
- # extract ami-tty/image, aki-tty/image & ari-tty/image
- tar -zxf $FILES/tty.tgz -C $FILES/images
-
- # Use glance client to add the kernel, ramdisk and finally the root
- # filesystem. We parse the results of the uploads to get glance IDs of the
- # ramdisk and kernel and use them for the root filesystem.
- RVAL=`glance add -A $SERVICE_TOKEN name="tty-kernel" is_public=true container_format=aki disk_format=aki < $FILES/images/aki-tty/image`
- KERNEL_ID=`echo $RVAL | cut -d":" -f2 | tr -d " "`
- RVAL=`glance add -A $SERVICE_TOKEN name="tty-ramdisk" is_public=true container_format=ari disk_format=ari < $FILES/images/ari-tty/image`
- RAMDISK_ID=`echo $RVAL | cut -d":" -f2 | tr -d " "`
- glance add -A $SERVICE_TOKEN name="tty" is_public=true container_format=ami disk_format=ami kernel_id=$KERNEL_ID ramdisk_id=$RAMDISK_ID < $FILES/images/ami-tty/image
-
- # Ubuntu 11.04 aka Natty
- # ----------------------
-
- # Downloaded from ubuntu enterprise cloud images. This
- # image doesn't use the ramdisk functionality
- if [ ! -f $FILES/natty.tgz ]; then
- wget -c http://uec-images.ubuntu.com/natty/current/natty-server-cloudimg-amd64.tar.gz -O $FILES/natty.tgz
- fi
-
- tar -zxf $FILES/natty.tgz -C $FILES/images
-
- RVAL=`glance add -A $SERVICE_TOKEN name="uec-natty-kernel" is_public=true container_format=aki disk_format=aki < $FILES/images/natty-server-cloudimg-amd64-vmlinuz-virtual`
- KERNEL_ID=`echo $RVAL | cut -d":" -f2 | tr -d " "`
- glance add -A $SERVICE_TOKEN name="uec-natty" is_public=true container_format=ami disk_format=ami kernel_id=$KERNEL_ID < $FILES/images/natty-server-cloudimg-amd64.img
-
+ # Use glance client to add the kernel the root filesystem.
+ # We parse the results of the first upload to get the glance ID of the
+ # kernel for use when uploading the root filesystem.
+ RVAL=`glance add -A $SERVICE_TOKEN name="$IMAGE_NAME-kernel" is_public=true container_format=aki disk_format=aki < $FILES/images/$IMAGE_NAME-vmlinuz*`
+ KERNEL_ID=`echo $RVAL | cut -d":" -f2 | tr -d " "`
+ glance add -A $SERVICE_TOKEN name="$IMAGE_NAME" is_public=true container_format=ami disk_format=ami kernel_id=$KERNEL_ID < $FILES/images/$IMAGE_NAME.img
+ done
fi
+# Fin
+# ===
+
+
+) 2>&1 | tee "${LOGFILE}"
+
+# Check that the left side of the above pipe succeeded
+for ret in "${PIPESTATUS[@]}"; do [ $ret -eq 0 ] || exit $ret; done
+
+(
# Using the cloud
# ===============
@@ -663,10 +724,7 @@
echo "the password: $ADMIN_PASSWORD"
fi
-# Fin
-# ===
+# indicate how long this took to run (bash maintained variable 'SECONDS')
+echo "stack.sh completed in $SECONDS seconds."
-# End our timer and give a timing summary
-END_TIME=`python -c "import time; print time.time()"`
-ELAPSED=`python -c "print $END_TIME - $START_TIME"`
-echo "stack.sh completed in $ELAPSED seconds."
+) | tee -a "$LOGFILE"
diff --git a/stackrc b/stackrc
index 15d73ce..e1b65c3 100644
--- a/stackrc
+++ b/stackrc
@@ -27,6 +27,9 @@
OPENSTACKX_REPO=https://github.com/cloudbuilders/openstackx.git
OPENSTACKX_BRANCH=diablo
+# Specify a comma-separated list of uec images to download and install into glance.
+IMAGE_URLS=http://smoser.brickies.net/ubuntu/ttylinux-uec/ttylinux-uec-amd64-11.2_2.6.35-15_1.tar.gz
+
# allow local overrides of env variables
if [ -f ./localrc ]; then
source ./localrc
diff --git a/build_lxc.sh b/tools/build_lxc.sh
similarity index 75%
rename from build_lxc.sh
rename to tools/build_lxc.sh
index 643da7e..42bd328 100755
--- a/build_lxc.sh
+++ b/tools/build_lxc.sh
@@ -6,9 +6,17 @@
exit 1
fi
-# Warn users who aren't on natty
-if ! grep -q natty /etc/lsb-release; then
- echo "WARNING: this script has only been tested on natty"
+# Keep track of ubuntu version
+UBUNTU_VERSION=`cat /etc/lsb-release | grep CODENAME | sed 's/.*=//g'`
+
+# Move to top devstack dir
+cd ..
+
+# Abort if localrc is not set
+if [ ! -e ./localrc ]; then
+ echo "You must have a localrc with ALL necessary passwords defined before proceeding."
+ echo "See stack.sh for required passwords."
+ exit 1
fi
# Source params
@@ -27,6 +35,7 @@
NAMESERVER=${NAMESERVER:-$CONTAINER_GATEWAY}
COPYENV=${COPYENV:-1}
DEST=${DEST:-/opt/stack}
+WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
# Param string to pass to stack.sh. Like "EC2_DMZ_HOST=192.168.1.1 MYSQL_USER=nova"
STACKSH_PARAMS=${STACKSH_PARAMS:-}
@@ -82,8 +91,21 @@
fi
}
+# Helper to create the container
+function create_lxc {
+ if [ "natty" = "$UBUNTU_VERSION" ]; then
+ lxc-create -n $CONTAINER -t natty -f $LXC_CONF
+ else
+ lxc-create -n $CONTAINER -t ubuntu -f $LXC_CONF
+ fi
+}
+
# Location of the base image directory
-CACHEDIR=/var/cache/lxc/natty/rootfs-amd64
+if [ "natty" = "$UBUNTU_VERSION" ]; then
+ CACHEDIR=/var/cache/lxc/natty/rootfs-amd64
+else
+ CACHEDIR=/var/cache/lxc/oneiric/rootfs-amd64
+fi
# Provide option to do totally clean install
if [ "$CLEAR_LXC_CACHE" = "1" ]; then
@@ -96,7 +118,7 @@
# lazy and doesn't do anything if a container already exists)
lxc-destroy -n $CONTAINER
# trigger the initial debootstrap
- lxc-create -n $CONTAINER -t natty -f $LXC_CONF
+ create_lxc
chroot $CACHEDIR apt-get update
chroot $CACHEDIR apt-get install -y --force-yes `cat files/apts/* | cut -d\# -f1 | egrep -v "(rabbitmq|libvirt-bin|mysql-server)"`
chroot $CACHEDIR pip install `cat files/pips/*`
@@ -133,7 +155,7 @@
fi
# Create the container
-lxc-create -n $CONTAINER -t natty -f $LXC_CONF
+create_lxc
# Specify where our container rootfs lives
ROOTFS=/var/lib/lxc/$CONTAINER/rootfs/
@@ -197,6 +219,10 @@
#!/usr/bin/env bash
# Make sure dns is set up
echo "nameserver $NAMESERVER" | sudo resolvconf -a eth0
+# Make there is a default route - needed for natty
+if ! route | grep -q default; then
+ sudo ip route add default via $CONTAINER_GATEWAY
+fi
sleep 1
# Kill any existing screens
@@ -208,7 +234,7 @@
if [ ! -d "$DEST/devstack" ]; then
git clone git://github.com/cloudbuilders/devstack.git $DEST/devstack
fi
-cd $DEST/devstack && $STACKSH_PARAMS ./stack.sh > /$DEST/run.sh.log
+cd $DEST/devstack && $STACKSH_PARAMS FORCE=yes ./stack.sh > /$DEST/run.sh.log
echo >> /$DEST/run.sh.log
echo >> /$DEST/run.sh.log
echo "All done! Time to start clicking." >> /$DEST/run.sh.log
@@ -218,11 +244,13 @@
chmod 755 $RUN_SH
# Make runner launch on boot
-RC_LOCAL=$ROOTFS/etc/rc.local
+RC_LOCAL=$ROOTFS/etc/init.d/local
cat > $RC_LOCAL <<EOF
#!/bin/sh -e
su -c "$DEST/run.sh" stack
EOF
+chmod +x $RC_LOCAL
+chroot $ROOTFS sudo update-rc.d local defaults 80
# Configure cgroup directory
if ! mount | grep -q cgroup; then
@@ -233,19 +261,39 @@
# Start our container
lxc-start -d -n $CONTAINER
-# Done creating the container, let's tail the log
-echo
-echo "============================================================="
-echo " -- YAY! --"
-echo "============================================================="
-echo
-echo "We're done creating the container, about to start tailing the"
-echo "stack.sh log. It will take a second or two to start."
-echo
-echo "Just CTRL-C at any time to stop tailing."
+if [ "$WAIT_TILL_LAUNCH" = "1" ]; then
+ # Done creating the container, let's tail the log
+ echo
+ echo "============================================================="
+ echo " -- YAY! --"
+ echo "============================================================="
+ echo
+ echo "We're done creating the container, about to start tailing the"
+ echo "stack.sh log. It will take a second or two to start."
+ echo
+ echo "Just CTRL-C at any time to stop tailing."
-while [ ! -e "$ROOTFS/$DEST/run.sh.log" ]; do
- sleep 1
-done
+ while [ ! -e "$ROOTFS/$DEST/run.sh.log" ]; do
+ sleep 1
+ done
-tail -F $ROOTFS/$DEST/run.sh.log
+ tail -F $ROOTFS/$DEST/run.sh.log &
+
+ TAIL_PID=$!
+
+ function kill_tail() {
+ exit 1
+ }
+
+ # Let Ctrl-c kill tail and exit
+ trap kill_tail SIGINT
+
+ echo "Waiting stack.sh to finish..."
+ while ! cat $ROOTFS/$DEST/run.sh.log | grep -q 'All done' ; do
+ sleep 5
+ done
+
+ kill $TAIL_PID
+ echo ""
+ echo "Finished - Zip-a-dee Doo-dah!"
+fi
diff --git a/build_lxc_multi.sh b/tools/build_lxc_multi.sh
similarity index 100%
rename from build_lxc_multi.sh
rename to tools/build_lxc_multi.sh
diff --git a/tools/build_pxe_boot.sh b/tools/build_pxe_boot.sh
index 84aa43b..0653664 100755
--- a/tools/build_pxe_boot.sh
+++ b/tools/build_pxe_boot.sh
@@ -4,15 +4,8 @@
# build_pxe_boot.sh [-k kernel-version] destdir
#
# Assumes syslinux is installed
-# Assumes devstack files are in `pwd`/pxe
# Only needs to run as root if the destdir permissions require it
-UBUNTU_MIRROR=http://archive.ubuntu.com/ubuntu/dists/natty/main/installer-amd64/current/images/netboot/ubuntu-installer/amd64
-
-MEMTEST_VER=4.10
-MEMTEST_BIN=memtest86+-${MEMTEST_VER}.bin
-MEMTEST_URL=http://www.memtest.org/download/${MEMTEST_VER}/
-
KVER=`uname -r`
if [ "$1" = "-k" ]; then
KVER=$2
@@ -30,8 +23,8 @@
cp -p /usr/lib/syslinux/$i $DEST_DIR
done
-DEFAULT=$DEST_DIR/pxelinux.cfg/default
-cat >$DEFAULT <<EOF
+CFG=$DEST_DIR/pxelinux.cfg/default
+cat >$CFG <<EOF
default menu.c32
prompt 0
timeout 0
@@ -59,7 +52,7 @@
sudo $PROGDIR/build_ramdisk.sh $PXEDIR/stack-initrd.gz
fi
cp -p $PXEDIR/stack-initrd.gz $DEST_DIR/ubuntu
-cat >>$DEFAULT <<EOF
+cat >>$CFG <<EOF
LABEL devstack
MENU LABEL ^devstack
@@ -69,48 +62,21 @@
EOF
# Get Ubuntu
-if [ -d $PXEDIR ]; then
+if [ -d $PXEDIR -a -r $PXEDIR/natty-base-initrd.gz ]; then
cp -p $PXEDIR/natty-base-initrd.gz $DEST_DIR/ubuntu
-fi
-cat >>$DEFAULT <<EOF
+ cat >>$CFG <<EOF
LABEL ubuntu
MENU LABEL ^Ubuntu Natty
KERNEL ubuntu/vmlinuz-$KVER
APPEND initrd=ubuntu/natty-base-initrd.gz ramdisk_size=419600 root=/dev/ram0
EOF
-
-# Get Memtest
-cd $DEST_DIR
-if [ ! -r $MEMTEST_BIN ]; then
- wget -N --quiet ${MEMTEST_URL}/${MEMTEST_BIN}.gz
- gunzip $MEMTEST_BIN
fi
-cat >>$DEFAULT <<EOF
-
-LABEL memtest
- MENU LABEL ^Memtest86+
- KERNEL $MEMTEST_BIN
-EOF
-
-# Get FreeDOS
-mkdir -p $DEST_DIR/freedos
-cd $DEST_DIR/freedos
-wget -N --quiet http://www.fdos.org/bootdisks/autogen/FDSTD.288.gz
-gunzip -f FDSTD.288.gz
-cat >>$DEFAULT <<EOF
-
-LABEL freedos
- MENU LABEL ^FreeDOS bootdisk
- KERNEL memdisk
- APPEND initrd=freedos/FDSTD.288
-EOF
# Local disk boot
-cat >>$DEFAULT <<EOF
+cat >>$CFG <<EOF
LABEL local
MENU LABEL ^Local disk
- MENU DEFAULT
LOCALBOOT 0
EOF
diff --git a/tools/build_usb_boot.sh b/tools/build_usb_boot.sh
new file mode 100755
index 0000000..ac49848
--- /dev/null
+++ b/tools/build_usb_boot.sh
@@ -0,0 +1,103 @@
+#!/bin/bash -e
+# build_usb_boot.sh - Create a syslinux boot environment
+#
+# build_usb_boot.sh [-k kernel-version] destdev
+#
+# Assumes syslinux is installed
+# Needs to run as root
+
+KVER=`uname -r`
+if [ "$1" = "-k" ]; then
+ KVER=$2
+ shift;shift
+fi
+
+DEST_DIR=${1:-/tmp/syslinux-boot}
+PXEDIR=${PXEDIR:-/var/cache/devstack/pxe}
+OPWD=`pwd`
+PROGDIR=`dirname $0`
+
+if [ -b $DEST_DIR ]; then
+ # We have a block device, install syslinux and mount it
+ DEST_DEV=$DEST_DIR
+ DEST_DIR=`mktemp -d mntXXXXXX`
+
+ # Install syslinux on the device
+ syslinux --install --directory syslinux $DEST_DEV
+
+ mount $DEST_DEV $DEST_DIR
+else
+ # We have a directory (for sanity checking output)
+ DEST_DEV=""
+ if [ ! -d $DEST_DIR/syslinux ]; then
+ mkdir -p $DEST_DIR/syslinux
+ fi
+fi
+
+# Get some more stuff from syslinux
+for i in memdisk menu.c32; do
+ cp -p /usr/lib/syslinux/$i $DEST_DIR/syslinux
+done
+
+CFG=$DEST_DIR/syslinux/syslinux.cfg
+cat >$CFG <<EOF
+default /syslinux/menu.c32
+prompt 0
+timeout 0
+
+MENU TITLE Boot Menu
+
+EOF
+
+# Setup devstack boot
+mkdir -p $DEST_DIR/ubuntu
+if [ ! -d $PXEDIR ]; then
+ mkdir -p $PXEDIR
+fi
+if [ ! -r $PXEDIR/vmlinuz-${KVER} ]; then
+ sudo chmod 644 /boot/vmlinuz-${KVER}
+ if [ ! -r /boot/vmlinuz-${KVER} ]; then
+ echo "No kernel found"
+ else
+ cp -p /boot/vmlinuz-${KVER} $PXEDIR
+ fi
+fi
+cp -p $PXEDIR/vmlinuz-${KVER} $DEST_DIR/ubuntu
+if [ ! -r $PXEDIR/stack-initrd.gz ]; then
+ cd $OPWD
+ sudo $PROGDIR/build_ramdisk.sh $PXEDIR/stack-initrd.gz
+fi
+cp -p $PXEDIR/stack-initrd.gz $DEST_DIR/ubuntu
+cat >>$CFG <<EOF
+
+LABEL devstack
+ MENU LABEL ^devstack
+ MENU DEFAULT
+ KERNEL /ubuntu/vmlinuz-$KVER
+ APPEND initrd=/ubuntu/stack-initrd.gz ramdisk_size=2109600 root=/dev/ram0
+EOF
+
+# Get Ubuntu
+if [ -d $PXEDIR -a -r $PXEDIR/natty-base-initrd.gz ]; then
+ cp -p $PXEDIR/natty-base-initrd.gz $DEST_DIR/ubuntu
+ cat >>$CFG <<EOF
+
+LABEL ubuntu
+ MENU LABEL ^Ubuntu Natty
+ KERNEL /ubuntu/vmlinuz-$KVER
+ APPEND initrd=/ubuntu/natty-base-initrd.gz ramdisk_size=419600 root=/dev/ram0
+EOF
+fi
+
+# Local disk boot
+cat >>$CFG <<EOF
+
+LABEL local
+ MENU LABEL ^Local disk
+ LOCALBOOT 0
+EOF
+
+if [ -n "$DEST_DEV" ]; then
+ umount $DEST_DIR
+ rmdir $DEST_DIR
+fi
diff --git a/lxc_network_hostonlyplusnat.sh b/tools/lxc_network_hostonlyplusnat.sh
similarity index 100%
rename from lxc_network_hostonlyplusnat.sh
rename to tools/lxc_network_hostonlyplusnat.sh