Browse code

Split the creation of $STACK_USER account out of stack.sh

Automatically creating a new user account is not always the right course
of action when stack.sh is running as root. Plus, the re-exec did not
work correctly in some cases.

* Create tools/create-stack-user.sh to set up a suitable user
for running DevStack
* Abort stack.sh and unstack.sh if running as root and suggest creating a
suitable user account.

Change-Id: I5d967c00c89f32e861449234ea8fe19261cd9ae3

Dean Troyer authored on 2013/10/05 02:35:24
Showing 4 changed files
... ...
@@ -34,7 +34,7 @@ You can also pick specific OpenStack project releases by setting the appropriate
34 34
 
35 35
 # Start A Dev Cloud
36 36
 
37
-Installing in a dedicated disposable vm is safer than installing on your dev machine!  To start a dev cloud:
37
+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):
38 38
 
39 39
     ./stack.sh
40 40
 
... ...
@@ -57,6 +57,12 @@ If the EC2 API is your cup-o-tea, you can create credentials and use euca2ools:
57 57
     # list instances using ec2 api
58 58
     euca-describe-instances
59 59
 
60
+# DevStack Execution Environment
61
+
62
+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...
63
+
64
+``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.
65
+
60 66
 # Customizing
61 67
 
62 68
 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.
... ...
@@ -172,67 +172,37 @@ fi
172 172
 # -----------
173 173
 
174 174
 # OpenStack is designed to be run as a non-root user; Horizon will fail to run
175
-# as **root** since Apache will not serve content from **root** user).  If
176
-# ``stack.sh`` is run as **root**, it automatically creates a **stack** user with
177
-# sudo privileges and runs as that user.
175
+# as **root** since Apache will not serve content from **root** user).
176
+# ``stack.sh`` must not be run as **root**.  It aborts and suggests one course of
177
+# action to create a suitable user account.
178 178
 
179 179
 if [[ $EUID -eq 0 ]]; then
180
-    ROOTSLEEP=${ROOTSLEEP:-10}
181 180
     echo "You are running this script as root."
182
-    echo "In $ROOTSLEEP seconds, we will create a user '$STACK_USER' and run as that user"
183
-    sleep $ROOTSLEEP
184
-
185
-    # Give the non-root user the ability to run as **root** via ``sudo``
186
-    is_package_installed sudo || install_package sudo
187
-    if ! getent group $STACK_USER >/dev/null; then
188
-        echo "Creating a group called $STACK_USER"
189
-        groupadd $STACK_USER
190
-    fi
191
-    if ! getent passwd $STACK_USER >/dev/null; then
192
-        echo "Creating a user called $STACK_USER"
193
-        useradd -g $STACK_USER -s /bin/bash -d $DEST -m $STACK_USER
194
-    fi
195
-
196
-    echo "Giving stack user passwordless sudo privileges"
197
-    # UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
198
-    grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
199
-        echo "#includedir /etc/sudoers.d" >> /etc/sudoers
200
-    ( umask 226 && echo "$STACK_USER ALL=(ALL) NOPASSWD:ALL" \
201
-        > /etc/sudoers.d/50_stack_sh )
202
-
203
-    STACK_DIR="$DEST/${TOP_DIR##*/}"
204
-    echo "Copying files to $STACK_DIR"
205
-    cp -r -f -T "$TOP_DIR" "$STACK_DIR"
206
-    safe_chown -R $STACK_USER "$STACK_DIR"
207
-    cd "$STACK_DIR"
208
-    if [[ "$SHELL_AFTER_RUN" != "no" ]]; then
209
-        exec sudo -u $STACK_USER  bash -l -c "set -e; bash stack.sh; bash"
210
-    else
211
-        exec sudo -u $STACK_USER bash -l -c "set -e; source stack.sh"
212
-    fi
181
+    echo "Cut it out."
182
+    echo "Really."
183
+    echo "If you need an account to run DevStack, do this (as root, heh) to create $STACK_USER:"
184
+    echo "$TOP_DIR/tools/create-stack-user.sh"
213 185
     exit 1
214
-else
215
-    # We're not **root**, make sure ``sudo`` is available
216
-    is_package_installed sudo || die "Sudo is required.  Re-run stack.sh as root ONE TIME ONLY to set up sudo."
217
-
218
-    # UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
219
-    sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
220
-        echo "#includedir /etc/sudoers.d" | sudo tee -a /etc/sudoers
221
-
222
-    # Set up devstack sudoers
223
-    TEMPFILE=`mktemp`
224
-    echo "$STACK_USER ALL=(root) NOPASSWD:ALL" >$TEMPFILE
225
-    # Some binaries might be under /sbin or /usr/sbin, so make sure sudo will
226
-    # see them by forcing PATH
227
-    echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
228
-    chmod 0440 $TEMPFILE
229
-    sudo chown root:root $TEMPFILE
230
-    sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
231
-
232
-    # Remove old file
233
-    sudo rm -f /etc/sudoers.d/stack_sh_nova
234 186
 fi
235 187
 
188
+# We're not **root**, make sure ``sudo`` is available
189
+is_package_installed sudo || install_package sudo
190
+
191
+# UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
192
+sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
193
+    echo "#includedir /etc/sudoers.d" | sudo tee -a /etc/sudoers
194
+
195
+# Set up devstack sudoers
196
+TEMPFILE=`mktemp`
197
+echo "$STACK_USER ALL=(root) NOPASSWD:ALL" >$TEMPFILE
198
+# Some binaries might be under /sbin or /usr/sbin, so make sure sudo will
199
+# see them by forcing PATH
200
+echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
201
+chmod 0440 $TEMPFILE
202
+sudo chown root:root $TEMPFILE
203
+sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
204
+
205
+
236 206
 # Create the destination directory and ensure it is writable by the user
237 207
 # and read/executable by everybody for daemons (e.g. apache run for horizon)
238 208
 sudo mkdir -p $DEST
239 209
new file mode 100644
... ...
@@ -0,0 +1,49 @@
0
+#!/usr/bin/env bash
1
+
2
+# **create-stack-user.sh**
3
+
4
+# Create a user account suitable for running DevStack
5
+# - create a group named $STACK_USER if it does not exist
6
+# - create a user named $STACK_USER if it does not exist
7
+#   - home is $DEST
8
+# - configure sudo for $STACK_USER
9
+
10
+# ``stack.sh`` was never intended to run as root.  It had a hack to do what is
11
+# now in this script and re-launch itself, but that hack was less than perfect
12
+# and it was time for this nonsense to stop.  Run this script as root to create
13
+# the user and configure sudo.
14
+
15
+
16
+# Keep track of the devstack directory
17
+TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
18
+
19
+# Import common functions
20
+source $TOP_DIR/functions
21
+
22
+# Determine what system we are running on.  This provides ``os_VENDOR``,
23
+# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
24
+# and ``DISTRO``
25
+GetDistro
26
+
27
+# Needed to get ``ENABLED_SERVICES``
28
+source $TOP_DIR/stackrc
29
+
30
+# Give the non-root user the ability to run as **root** via ``sudo``
31
+is_package_installed sudo || install_package sudo
32
+
33
+if ! getent group $STACK_USER >/dev/null; then
34
+    echo "Creating a group called $STACK_USER"
35
+    groupadd $STACK_USER
36
+fi
37
+
38
+if ! getent passwd $STACK_USER >/dev/null; then
39
+    echo "Creating a user called $STACK_USER"
40
+    useradd -g $STACK_USER -s /bin/bash -d $DEST -m $STACK_USER
41
+fi
42
+
43
+echo "Giving stack user passwordless sudo privileges"
44
+# UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
45
+grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
46
+    echo "#includedir /etc/sudoers.d" >> /etc/sudoers
47
+( umask 226 && echo "$STACK_USER ALL=(ALL) NOPASSWD:ALL" \
48
+    > /etc/sudoers.d/50_stack_sh )
... ...
@@ -24,6 +24,12 @@ source $TOP_DIR/stackrc
24 24
 # Destination path for service data
25 25
 DATA_DIR=${DATA_DIR:-${DEST}/data}
26 26
 
27
+if [[ $EUID -eq 0 ]]; then
28
+    echo "You are running this script as root."
29
+    echo "It might work but you will have a better day running it as $STACK_USER"
30
+    exit 1
31
+fi
32
+
27 33
 # Import apache functions
28 34
 source $TOP_DIR/lib/apache
29 35