From c4e47ab8586069dea52b86fa939ad8a8deeacc2e Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 7 Oct 2011 13:29:29 +0000 Subject: [PATCH 01/11] simplify script duration output Bash contains a variable 'SECONDS' that indicates how long the current shell has been alive. It seems sane to just use that to indicate to the user how long the script took. --- stack.sh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/stack.sh b/stack.sh index f6bf534..fbc75b5 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 @@ -666,7 +663,5 @@ fi # Fin # === -# 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." +# indicate how long this took to run (bash maintained variable 'SECONDS') +echo "stack.sh completed in $SECONDS seconds." From 7c481189bdeda3c79029b1b47d8edd1bf8bd50fa Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 7 Oct 2011 13:50:21 +0000 Subject: [PATCH 02/11] log output of stack.sh to logfile in current dir use the variable LOGFILE to log stack.sh output for debugging --- stack.sh | 103 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 42 deletions(-) diff --git a/stack.sh b/stack.sh index fbc75b5..2e823ea 100755 --- a/stack.sh +++ b/stack.sh @@ -40,6 +40,52 @@ if [ ! -d $FILES ]; then exit 1 fi +# Settings +# ======== + +# This script is customizable through setting environment variables. If you +# want to override a setting you can either:: +# +# export MYSQL_PASS=anothersecret +# ./stack.sh +# +# You can also pass options on a single line ``MYSQL_PASS=simple ./stack.sh`` +# +# Additionally, you can put any local variables into a ``localrc`` file, like:: +# +# MYSQL_PASS=anothersecret +# MYSQL_USER=hellaroot +# +# We try to have sensible defaults, so you should be able to run ``./stack.sh`` +# in most cases. +# +# We our settings from ``stackrc``. This file is distributed with devstack and +# contains locations for what repositories to use. If you want to use other +# repositories and branches, you can add your own settings with another file +# called ``localrc`` +# +# 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 +# of letting devstack generate random ones for you. +source ./stackrc + +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 + # 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 @@ -51,7 +97,7 @@ if [[ $EUID -eq 0 ]]; then # 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 echo "Creating a user called stack" @@ -67,51 +113,13 @@ if [[ $EUID -eq 0 ]]; then echo "Running the script as stack in 3 seconds..." sleep 3 if [[ "$SHELL_AFTER_RUN" != "no" ]]; then - exec su -c "cd /home/stack/$THIS_DIR/; bash stack.sh; bash" stack + exec su -c "cd /home/stack/$THIS_DIR/; bash stack.sh; bash" stack else - exec su -c "cd /home/stack/$THIS_DIR/; bash stack.sh" stack + exec su -c "cd /home/stack/$THIS_DIR/; bash stack.sh" stack fi exit 0 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 -# ======== - -# This script is customizable through setting environment variables. If you -# want to override a setting you can either:: -# -# export MYSQL_PASS=anothersecret -# ./stack.sh -# -# You can also pass options on a single line ``MYSQL_PASS=simple ./stack.sh`` -# -# Additionally, you can put any local variables into a ``localrc`` file, like:: -# -# MYSQL_PASS=anothersecret -# MYSQL_USER=hellaroot -# -# We try to have sensible defaults, so you should be able to run ``./stack.sh`` -# in most cases. -# -# We our settings from ``stackrc``. This file is distributed with devstack and -# contains locations for what repositories to use. If you want to use other -# repositories and branches, you can add your own settings with another file -# called ``localrc`` -# -# 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 -# of letting devstack generate random ones for you. -source ./stackrc - # Destination path for installation ``DEST`` DEST=${DEST:-/opt/stack} sudo mkdir -p $DEST @@ -663,5 +671,16 @@ fi # Fin # === + +) 2>&1 | tee "${LOGFILE}" + +# because of the way pipes work, the left side of the pipe may +# have failed, but 'tee' will succeed. We need to check that. +for ret in "${PIPESTATUS[@]}"; do + [ $ret -eq 0 ] || exit $ret +done + # indicate how long this took to run (bash maintained variable 'SECONDS') -echo "stack.sh completed in $SECONDS seconds." +echo "stack.sh completed in $SECONDS seconds." | tee -a "${LOGFILE}" + +exit 0 From 0d2145a0f37da869fcc4754e41b1b8e0618679ea Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 7 Oct 2011 15:18:10 +0000 Subject: [PATCH 03/11] some improvements to 'create stack user' path * Increase the timeout from 3 to 10, so user has a bigger chance to kill the script if being run interactively before a 'stack' user is created. * explicitly ask 'getent' for the stack user rather than getting all users and grepping (which would match an "openstack" user, or a user named "bob.stack") * use $PWD rather than `pwd` * create file in sudoers.d rather than modifying /etc/sudoers. --- stack.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/stack.sh b/stack.sh index 2e823ea..9881ede 100755 --- a/stack.sh +++ b/stack.sh @@ -93,29 +93,31 @@ set -o xtrace 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 -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 + ( 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 -ec "cd $STACK_DIR; bash stack.sh; bash" stack else - exec su -c "cd /home/stack/$THIS_DIR/; bash stack.sh" stack + exec su -ec "cd $STACK_DIR; bash stack.sh" stack fi exit 0 fi From d67a18bb0716b6dca1cfcfced39c65ac3b41a6e3 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 7 Oct 2011 14:44:38 +0000 Subject: [PATCH 04/11] make sure apt-get update is run Previously, the only path that would only ensure that 'apt-get update' was run was when the stack user was created. Archives can be out of date, apt-get should be run. --- stack.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/stack.sh b/stack.sh index 9881ede..045bcc9 100755 --- a/stack.sh +++ b/stack.sh @@ -235,6 +235,7 @@ ADMIN_PASSWORD=${ADMIN_PASSWORD:-`openssl rand -hex 10`} # 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 From b94f4bf35b9c2acd469f839515a96f9c30a45331 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 7 Oct 2011 14:51:07 +0000 Subject: [PATCH 05/11] move 'how to use cloud' info outside of xtrace make the successful run output end with more clear messages. By moving them outside of the "do it all" path, the xtrace output will not mix with echo statements. --- stack.sh | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/stack.sh b/stack.sh index 045bcc9..5f13671 100755 --- a/stack.sh +++ b/stack.sh @@ -654,6 +654,16 @@ if [[ "$ENABLED_SERVICES" =~ "g-reg" ]]; then 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 # =============== @@ -671,19 +681,7 @@ if [[ "$ENABLED_SERVICES" =~ "key" ]]; then echo "the password: $ADMIN_PASSWORD" fi -# Fin -# === - - -) 2>&1 | tee "${LOGFILE}" - -# because of the way pipes work, the left side of the pipe may -# have failed, but 'tee' will succeed. We need to check that. -for ret in "${PIPESTATUS[@]}"; do - [ $ret -eq 0 ] || exit $ret -done - # indicate how long this took to run (bash maintained variable 'SECONDS') -echo "stack.sh completed in $SECONDS seconds." | tee -a "${LOGFILE}" +echo "stack.sh completed in $SECONDS seconds." -exit 0 +) | tee -a "$LOGFILE" From 8ab1ade42ed3b4d4bda00c3dc5a6110c05c201e4 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 7 Oct 2011 21:03:16 -0400 Subject: [PATCH 06/11] instead of 'newgrp' and a pipe, use 'sg' sg and newgrp basically do the same thing, but sg takes a command to execute rather than just executing sh. This just seems cleaner. --- stack.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stack.sh b/stack.sh index 5f13671..516c920 100755 --- a/stack.sh +++ b/stack.sh @@ -592,9 +592,8 @@ fi # 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" From f9da5081222d2c353e577cb83c538912bca26972 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 7 Oct 2011 21:28:00 -0400 Subject: [PATCH 07/11] move setting variables and run-as-stack-user code Change the over all flow so that the default settings are filled in in the outside shell (not inside the '()' and 'tee'). This way, those variables pass through to the subshell, but they're also available in the parent shell at the end for outputting status. Also, exit failure rather than success if 'exec' to run as stack user failed. --- stack.sh | 99 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/stack.sh b/stack.sh index 516c920..a4cbc2e 100755 --- a/stack.sh +++ b/stack.sh @@ -40,52 +40,6 @@ if [ ! -d $FILES ]; then exit 1 fi -# Settings -# ======== - -# This script is customizable through setting environment variables. If you -# want to override a setting you can either:: -# -# export MYSQL_PASS=anothersecret -# ./stack.sh -# -# You can also pass options on a single line ``MYSQL_PASS=simple ./stack.sh`` -# -# Additionally, you can put any local variables into a ``localrc`` file, like:: -# -# MYSQL_PASS=anothersecret -# MYSQL_USER=hellaroot -# -# We try to have sensible defaults, so you should be able to run ``./stack.sh`` -# in most cases. -# -# We our settings from ``stackrc``. This file is distributed with devstack and -# contains locations for what repositories to use. If you want to use other -# repositories and branches, you can add your own settings with another file -# called ``localrc`` -# -# 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 -# of letting devstack generate random ones for you. -source ./stackrc - -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 - # 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 @@ -119,13 +73,42 @@ if [[ $EUID -eq 0 ]]; then else exec su -ec "cd $STACK_DIR; bash stack.sh" stack fi - exit 0 + exit 1 fi + +# Settings +# ======== + +# This script is customizable through setting environment variables. If you +# want to override a setting you can either:: +# +# export MYSQL_PASS=anothersecret +# ./stack.sh +# +# You can also pass options on a single line ``MYSQL_PASS=simple ./stack.sh`` +# +# Additionally, you can put any local variables into a ``localrc`` file, like:: +# +# MYSQL_PASS=anothersecret +# MYSQL_USER=hellaroot +# +# We try to have sensible defaults, so you should be able to run ``./stack.sh`` +# in most cases. +# +# We our settings from ``stackrc``. This file is distributed with devstack and +# contains locations for what repositories to use. If you want to use other +# repositories and branches, you can add your own settings with another file +# called ``localrc`` +# +# 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 +# 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 @@ -227,6 +210,24 @@ SERVICE_TOKEN=${SERVICE_TOKEN:-`openssl rand -hex 12`} # so use 10 bytes ADMIN_PASSWORD=${ADMIN_PASSWORD:-`openssl rand -hex 10`} +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 # ================ From 102e440e2b4908051e314f7d88730270bc89f1fd Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 12 Oct 2011 20:00:34 -0400 Subject: [PATCH 08/11] fix bad usage of 'su'. instead use 'set -e'. I had had tried to use -e argument to su, thinking that it would go through to sh, but it does not. instead, just use 'set -e' --- stack.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stack.sh b/stack.sh index a4cbc2e..2d76875 100755 --- a/stack.sh +++ b/stack.sh @@ -69,9 +69,9 @@ if [[ $EUID -eq 0 ]]; then cp -r -f "$PWD" "$STACK_DIR" chown -R stack "$STACK_DIR" if [[ "$SHELL_AFTER_RUN" != "no" ]]; then - exec su -ec "cd $STACK_DIR; bash stack.sh; bash" stack + exec su -c "set -e; cd $STACK_DIR; bash stack.sh; bash" stack else - exec su -ec "cd $STACK_DIR; bash stack.sh" stack + exec su -c "set -e; cd $STACK_DIR; bash stack.sh" stack fi exit 1 fi From df47967da46462e5f0b444a48d9019988449f94b Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 12 Oct 2011 20:15:50 -0400 Subject: [PATCH 09/11] fix STACK_DIR variable --- stack.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stack.sh b/stack.sh index 2d76875..7ef13a5 100755 --- a/stack.sh +++ b/stack.sh @@ -65,7 +65,7 @@ if [[ $EUID -eq 0 ]]; then >> /etc/sudoers.d/50_stack_sh ) echo "Copying files to stack user" - STACK_DIR="/home/stack/${PWD%/*}" + STACK_DIR="/home/stack/${PWD##*/}" cp -r -f "$PWD" "$STACK_DIR" chown -R stack "$STACK_DIR" if [[ "$SHELL_AFTER_RUN" != "no" ]]; then From 55c9d3f13dac9e4073d941cdbe55532f3f3f5279 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 12 Oct 2011 20:19:46 -0400 Subject: [PATCH 10/11] fix writing of 50_stack_sh in sudoers --- stack.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stack.sh b/stack.sh index 7ef13a5..b43f3cc 100755 --- a/stack.sh +++ b/stack.sh @@ -61,8 +61,8 @@ if [[ $EUID -eq 0 ]]; then fi echo "Giving stack user passwordless sudo priviledges" - ( umask 226 && echo "stack ALL=(ALL) NOPASSWD: ALL" \ - >> /etc/sudoers.d/50_stack_sh ) + ( umask 226 && echo "stack ALL=(ALL) NOPASSWD:ALL" \ + > /etc/sudoers.d/50_stack_sh ) echo "Copying files to stack user" STACK_DIR="/home/stack/${PWD##*/}" From 4bec581e4e5a15c204f1042f9ecd4701c33ac4ca Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 12 Oct 2011 20:32:16 -0400 Subject: [PATCH 11/11] add includedir entry to sudoers if its not there --- stack.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stack.sh b/stack.sh index b43f3cc..38560e6 100755 --- a/stack.sh +++ b/stack.sh @@ -61,6 +61,9 @@ if [[ $EUID -eq 0 ]]; then fi echo "Giving stack user passwordless sudo priviledges" + # 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 )