diff --git a/README.md b/README.md index 99e983887e..6dc9ecd1e3 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ You can also pick specific OpenStack project releases by setting the appropriate # Start A Dev Cloud -Installing in a dedicated disposable vm is safer than installing on your dev machine! To start a dev cloud: +Installing in a dedicated disposable vm is safer than installing on your dev machine! Plus you can pick one of the supported Linux distros for your VM. To start a dev cloud run the following NOT AS ROOT (see below for more): ./stack.sh @@ -57,6 +57,12 @@ If the EC2 API is your cup-o-tea, you can create credentials and use euca2ools: # list instances using ec2 api euca-describe-instances +# DevStack Execution Environment + +DevStack runs rampant over the system it runs on, installing things and uninstalling other things. Running this on a system you care about is a recipe for disappointment, or worse. Alas, we're all in the virtualization business here, so run it in a VM. And take advantage of the snapshot capabilities of your hypervisor of choice to reduce testing cycle times. You might even save enough time to write one more feature before the next feature freeze... + +``stack.sh`` needs to have root access for a lot of tasks, but it also needs to have not-root permissions for most of its work and for all of the OpenStack services. So ``stack.sh`` specifically does not run if you are root. This is a recent change (Oct 2013) from the previous behaviour of automatically creating a ``stack`` user. Automatically creating a user account is not always the right response to running as root, so that bit is now an explicit step using ``tools/create-stack-user.sh``. Run that (as root!) if you do not want to just use your normal login here, which works perfectly fine. + # Customizing You can override environment variables used in `stack.sh` by creating file name `localrc`. It is likely that you will need to do this to tweak your networking configuration should you need to access your cloud from a different host. diff --git a/stack.sh b/stack.sh index b39cd73bb9..86fe82a584 100755 --- a/stack.sh +++ b/stack.sh @@ -172,67 +172,37 @@ fi # ----------- # OpenStack is designed to be run as a non-root user; Horizon will fail to run -# as **root** since Apache will not serve content from **root** user). If -# ``stack.sh`` is run as **root**, it automatically creates a **stack** user with -# sudo privileges and runs as that user. +# as **root** since Apache will not serve content from **root** user). +# ``stack.sh`` must not be run as **root**. It aborts and suggests one course of +# action to create a suitable user account. if [[ $EUID -eq 0 ]]; then - ROOTSLEEP=${ROOTSLEEP:-10} echo "You are running this script as root." - echo "In $ROOTSLEEP seconds, we will create a user '$STACK_USER' and run as that user" - sleep $ROOTSLEEP - - # Give the non-root user the ability to run as **root** via ``sudo`` - is_package_installed sudo || install_package sudo - if ! getent group $STACK_USER >/dev/null; then - echo "Creating a group called $STACK_USER" - groupadd $STACK_USER - fi - if ! getent passwd $STACK_USER >/dev/null; then - echo "Creating a user called $STACK_USER" - useradd -g $STACK_USER -s /bin/bash -d $DEST -m $STACK_USER - fi - - echo "Giving stack user passwordless sudo privileges" - # UEC images ``/etc/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_USER ALL=(ALL) NOPASSWD:ALL" \ - > /etc/sudoers.d/50_stack_sh ) - - STACK_DIR="$DEST/${TOP_DIR##*/}" - echo "Copying files to $STACK_DIR" - cp -r -f -T "$TOP_DIR" "$STACK_DIR" - safe_chown -R $STACK_USER "$STACK_DIR" - cd "$STACK_DIR" - if [[ "$SHELL_AFTER_RUN" != "no" ]]; then - exec sudo -u $STACK_USER bash -l -c "set -e; bash stack.sh; bash" - else - exec sudo -u $STACK_USER bash -l -c "set -e; source stack.sh" - fi + echo "Cut it out." + echo "Really." + echo "If you need an account to run DevStack, do this (as root, heh) to create $STACK_USER:" + echo "$TOP_DIR/tools/create-stack-user.sh" exit 1 -else - # We're not **root**, make sure ``sudo`` is available - is_package_installed sudo || die "Sudo is required. Re-run stack.sh as root ONE TIME ONLY to set up sudo." - - # UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one - sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers || - echo "#includedir /etc/sudoers.d" | sudo tee -a /etc/sudoers - - # Set up devstack sudoers - TEMPFILE=`mktemp` - echo "$STACK_USER ALL=(root) NOPASSWD:ALL" >$TEMPFILE - # Some binaries might be under /sbin or /usr/sbin, so make sure sudo will - # see them by forcing PATH - echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE - chmod 0440 $TEMPFILE - sudo chown root:root $TEMPFILE - sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh - - # Remove old file - sudo rm -f /etc/sudoers.d/stack_sh_nova fi +# We're not **root**, make sure ``sudo`` is available +is_package_installed sudo || install_package sudo + +# UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one +sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers || + echo "#includedir /etc/sudoers.d" | sudo tee -a /etc/sudoers + +# Set up devstack sudoers +TEMPFILE=`mktemp` +echo "$STACK_USER ALL=(root) NOPASSWD:ALL" >$TEMPFILE +# Some binaries might be under /sbin or /usr/sbin, so make sure sudo will +# see them by forcing PATH +echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE +chmod 0440 $TEMPFILE +sudo chown root:root $TEMPFILE +sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh + + # Create the destination directory and ensure it is writable by the user # and read/executable by everybody for daemons (e.g. apache run for horizon) sudo mkdir -p $DEST diff --git a/tools/create-stack-user.sh b/tools/create-stack-user.sh new file mode 100644 index 0000000000..2251d1e67c --- /dev/null +++ b/tools/create-stack-user.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# **create-stack-user.sh** + +# Create a user account suitable for running DevStack +# - create a group named $STACK_USER if it does not exist +# - create a user named $STACK_USER if it does not exist +# - home is $DEST +# - configure sudo for $STACK_USER + +# ``stack.sh`` was never intended to run as root. It had a hack to do what is +# now in this script and re-launch itself, but that hack was less than perfect +# and it was time for this nonsense to stop. Run this script as root to create +# the user and configure sudo. + + +# Keep track of the devstack directory +TOP_DIR=$(cd $(dirname "$0")/.. && pwd) + +# Import common functions +source $TOP_DIR/functions + +# Determine what system we are running on. This provides ``os_VENDOR``, +# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME`` +# and ``DISTRO`` +GetDistro + +# Needed to get ``ENABLED_SERVICES`` +source $TOP_DIR/stackrc + +# Give the non-root user the ability to run as **root** via ``sudo`` +is_package_installed sudo || install_package sudo + +if ! getent group $STACK_USER >/dev/null; then + echo "Creating a group called $STACK_USER" + groupadd $STACK_USER +fi + +if ! getent passwd $STACK_USER >/dev/null; then + echo "Creating a user called $STACK_USER" + useradd -g $STACK_USER -s /bin/bash -d $DEST -m $STACK_USER +fi + +echo "Giving stack user passwordless sudo privileges" +# UEC images ``/etc/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_USER ALL=(ALL) NOPASSWD:ALL" \ + > /etc/sudoers.d/50_stack_sh ) diff --git a/unstack.sh b/unstack.sh index 05d9fb7c83..c944ccc0fb 100755 --- a/unstack.sh +++ b/unstack.sh @@ -24,6 +24,12 @@ source $TOP_DIR/stackrc # Destination path for service data DATA_DIR=${DATA_DIR:-${DEST}/data} +if [[ $EUID -eq 0 ]]; then + echo "You are running this script as root." + echo "It might work but you will have a better day running it as $STACK_USER" + exit 1 +fi + # Import apache functions source $TOP_DIR/lib/apache