stack.sh
ba23cc73
 #!/usr/bin/env bash
 
c6c1d439
 # ``stack.sh`` is an opinionated OpenStack developer installation.  It
e9a4750f
 # installs and configures various combinations of **Cinder**, **Glance**,
3336b4be
 # **Horizon**, **Keystone**, **Nova**, **Neutron**, and **Swift**
ba23cc73
 
27f29440
 # This script's options can be changed by setting appropriate environment
 # variables.  You can configure things like which git repositories to use,
 # services to enable, OS images to use, etc.  Default values are located in the
 # ``stackrc`` file. If you are crafty you can run the script on multiple nodes
 # using shared settings for common resources (eg., mysql or rabbitmq) and build
 # a multi-node developer install.
782b9917
 
4a43b7bd
 # To keep this script simple we assume you are running on a recent **Ubuntu**
2e667786
 # (Bionic or newer), **Fedora** (F24 or newer), or **CentOS/RHEL**
5bee0cd4
 # (7 or newer) machine. (It may work on other platforms but support for those
 # platforms is left to those who added them to DevStack.) It should work in
dc97cb71
 # a VM or physical server. Additionally, we maintain a list of ``deb`` and
5bee0cd4
 # ``rpm`` dependencies and other configuration files in this repo.
24859060
 
0e7e897b
 # Learn more and get the most recent version at http://devstack.org
6edd17f7
 
f0247ed2
 # 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
 
4e971118
 # Make sure custom grep options don't get in the way
 unset GREP_OPTIONS
 
d095e976
 # NOTE(sdague): why do we explicitly set locale when running stack.sh?
 #
 # Devstack is written in bash, and many functions used throughout
32608da2
 # devstack process text coming off a command (like the ip command)
d095e976
 # and do transforms using grep, sed, cut, awk on the strings that are
f0636bac
 # returned. Many of these programs are internationalized, which is
d095e976
 # great for end users, but means that the strings that devstack
 # functions depend upon might not be there in other locales. We thus
 # need to pin the world to an english basis during the runs.
 #
 # Previously we used the C locale for this, every system has it, and
 # it gives us a stable sort order. It does however mean that we
 # effectively drop unicode support.... boo!  :(
 #
 # With python3 being more unicode aware by default, that's not the
 # right option. While there is a C.utf8 locale, some distros are
 # shipping it as C.UTF8 for extra confusingness. And it's support
 # isn't super clear across distros. This is made more challenging when
 # trying to support both out of the box distros, and the gate which
 # uses diskimage builder to build disk images in a different way than
 # the distros do.
 #
 # So... en_US.utf8 it is. That's existed for a very long time. It is a
 # compromise position, but it is the least worse idea at the time of
 # this comment.
 #
 # We also have to unset other variables that might impact LC_ALL
 # taking effect.
9162608d
 unset LANG
 unset LANGUAGE
d095e976
 LC_ALL=en_US.utf8
9162608d
 export LC_ALL
 
1348ac99
 # Clear all OpenStack related envvars
 unset `env | grep -E '^OS_' | cut -d = -f 1`
 
27f29440
 # Make sure umask is sane
 umask 022
 
7df9d1be
 # Not all distros have sbin in PATH for regular users.
 PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin
 
dc97cb71
 # Keep track of the DevStack directory
51fb22ef
 TOP_DIR=$(cd $(dirname "$0") && pwd)
 
53753293
 # Check for uninitialized variables, a big cause of bugs
 NOUNSET=${NOUNSET:-}
 if [[ -n "$NOUNSET" ]]; then
     set -o nounset
 fi
 
4af2afcd
 # Set start of devstack timestamp
 DEVSTACK_START_TIME=$(date +%s)
dc97cb71
 
 # Configuration
 # =============
 
d3bf9bdb
 # Sanity Checks
 # -------------
 
 # Clean up last environment var cache
 if [[ -r $TOP_DIR/.stackenv ]]; then
     rm $TOP_DIR/.stackenv
 fi
 
dc97cb71
 # ``stack.sh`` keeps the list of ``deb`` and ``rpm`` dependencies, config
d3bf9bdb
 # templates and other useful files in the ``files`` subdirectory
 FILES=$TOP_DIR/files
 if [ ! -d $FILES ]; then
     die $LINENO "missing devstack/files"
 fi
 
 # ``stack.sh`` keeps function libraries here
dc97cb71
 # Make sure ``$TOP_DIR/inc`` directory is present
 if [ ! -d $TOP_DIR/inc ]; then
     die $LINENO "missing devstack/inc"
 fi
 
 # ``stack.sh`` keeps project libraries here
d3bf9bdb
 # Make sure ``$TOP_DIR/lib`` directory is present
 if [ ! -d $TOP_DIR/lib ]; then
     die $LINENO "missing devstack/lib"
 fi
 
dc97cb71
 # Check if run in POSIX shell
 if [[ "${POSIXLY_CORRECT}" == "y" ]]; then
1afc28bf
     set +o xtrace
dc97cb71
     echo "You are running POSIX compatibility mode, DevStack requires bash 4.2 or newer."
     exit 1
 fi
 
d3bf9bdb
 # 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).
 # ``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
1afc28bf
     set +o xtrace
     echo "DevStack should be run as a user with sudo permissions, "
     echo "not root."
     echo "A \"stack\" user configured correctly can be created with:"
     echo " $TOP_DIR/tools/create-stack-user.sh"
d3bf9bdb
     exit 1
 fi
 
90dd262c
 # OpenStack is designed to run at a system level, with system level
 # installation of python packages. It does not support running under a
 # virtual env, and will fail in really odd ways if you do this. Make
 # this explicit as it has come up on the mailing list.
 if [[ -n "$VIRTUAL_ENV" ]]; then
1afc28bf
     set +o xtrace
90dd262c
     echo "You appear to be running under a python virtualenv."
c1750401
     echo "DevStack does not support this, as we may break the"
90dd262c
     echo "virtualenv you are currently in by modifying "
     echo "external system-level components the virtualenv relies on."
c1750401
     echo "We recommend you use a separate virtual-machine if "
90dd262c
     echo "you are worried about DevStack taking over your system."
     exit 1
 fi
 
56037e9a
 # Provide a safety switch for devstack. If you do a lot of devstack,
 # on a lot of different environments, you sometimes run it on the
 # wrong box. This makes there be a way to prevent that.
 if [[ -e $HOME/.no-devstack ]]; then
1afc28bf
     set +o xtrace
56037e9a
     echo "You've marked this host as a no-devstack host, to save yourself from"
     echo "running devstack accidentally. If this is in error, please remove the"
     echo "~/.no-devstack file"
     exit 1
 fi
d9de1199
 
d3bf9bdb
 # Prepare the environment
 # -----------------------
 
53753293
 # Initialize variables:
 LAST_SPINNER_PID=""
 
6563a3ce
 # Import common functions
c6c1d439
 source $TOP_DIR/functions
 
8c2ce6ea
 # Import 'public' stack.sh functions
 source $TOP_DIR/lib/stack
 
c6c1d439
 # Determine what system we are running on.  This provides ``os_VENDOR``,
7710e7fc
 # ``os_RELEASE``, ``os_PACKAGE``, ``os_CODENAME``
a9e0a488
 # and ``DISTRO``
 GetDistro
6edd17f7
 
dc97cb71
 
48352ee7
 # Global Settings
0e8dcedf
 # ---------------
9122e7b1
 
893e6636
 # Check for a ``localrc`` section embedded in ``local.conf`` and extract if
 # ``localrc`` does not already exist
 
 # Phase: local
 rm -f $TOP_DIR/.localrc.auto
cc6af3fc
 extract_localrc_section $TOP_DIR/local.conf $TOP_DIR/localrc $TOP_DIR/.localrc.auto
893e6636
 
1a6d4492
 # ``stack.sh`` is customizable by setting environment variables.  Override a
7f80649e
 # default setting via export:
9122e7b1
 #
428af5a2
 #     export DATABASE_PASSWORD=anothersecret
9122e7b1
 #     ./stack.sh
 #
7f80649e
 # or by setting the variable on the command line:
9122e7b1
 #
1a6d4492
 #     DATABASE_PASSWORD=simple ./stack.sh
 #
7f80649e
 # Persistent variables can be placed in a ``local.conf`` file:
9122e7b1
 #
dc97cb71
 #     [[local|localrc]]
428af5a2
 #     DATABASE_PASSWORD=anothersecret
 #     DATABASE_USER=hellaroot
9122e7b1
 #
 # We try to have sensible defaults, so you should be able to run ``./stack.sh``
dc97cb71
 # in most cases.  ``local.conf`` is not distributed with DevStack and will never
4a43b7bd
 # be overwritten by a DevStack update.
9122e7b1
 #
df0972c1
 # DevStack distributes ``stackrc`` which contains locations for the OpenStack
cc6b4435
 # repositories, branches to configure, and other configuration defaults.
dc97cb71
 # ``stackrc`` sources the ``localrc`` section of ``local.conf`` to allow you to
 # safely override those settings.
4a43b7bd
 
bbafb1b5
 if [[ ! -r $TOP_DIR/stackrc ]]; then
14fd979a
     die $LINENO "missing $TOP_DIR/stackrc - did you grab more than just stack.sh?"
bbafb1b5
 fi
 source $TOP_DIR/stackrc
df0972c1
 
07cbc449
 # write /etc/devstack-version
2c0faca0
 write_devstack_version
 
c973e6c9
 # Warn users who aren't on an explicitly supported distro, but allow them to
 # override check and attempt installation with ``FORCE=yes ./stack``
cd57449c
 if [[ ! ${DISTRO} =~ (bionic|focal|f30|f31|opensuse-15.0|opensuse-15.1|opensuse-tumbleweed|rhel8) ]]; then
c973e6c9
     echo "WARNING: this script has not been tested on $DISTRO"
     if [[ "$FORCE" != "yes" ]]; then
         die $LINENO "If you wish to run this script anyway run with FORCE=yes"
     fi
 fi
 
48352ee7
 # Local Settings
4a43b7bd
 # --------------
 
48352ee7
 # Make sure the proxy config is visible to sub-processes
 export_proxy_variables
9122e7b1
 
dc97cb71
 # Remove services which were negated in ``ENABLED_SERVICES``
6fd28117
 # using the "-" prefix (e.g., "-rabbit") instead of
f04178fd
 # calling disable_service().
 disable_negated_services
c4cd4140
 
a79617c1
 
d3bf9bdb
 # Configure sudo
 # --------------
531aeb79
 
dc97cb71
 # We're not as **root** so make sure ``sudo`` is available
5e2d0e0b
 is_package_installed sudo || is_package_installed sudo-ldap || install_package sudo
531aeb79
 
 # 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
 
b0160d0f
 # Conditionally setup detailed logging for sudo
 if [[ -n "$LOG_SUDO" ]]; then
     TEMPFILE=`mktemp`
     echo "Defaults log_output" > $TEMPFILE
     chmod 0440 $TEMPFILE
     sudo chown root:root $TEMPFILE
     sudo mv $TEMPFILE /etc/sudoers.d/00_logging
 fi
 
dc97cb71
 # Set up DevStack sudoers
531aeb79
 TEMPFILE=`mktemp`
 echo "$STACK_USER ALL=(root) NOPASSWD:ALL" >$TEMPFILE
dc97cb71
 # Some binaries might be under ``/sbin`` or ``/usr/sbin``, so make sure sudo will
 # see them by forcing ``PATH``
531aeb79
 echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
ea2fcb55
 echo "Defaults:$STACK_USER !requiretty" >> $TEMPFILE
531aeb79
 chmod 0440 $TEMPFILE
 sudo chown root:root $TEMPFILE
 sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
4a43b7bd
 
0e8dcedf
 
 # Configure Distro Repositories
 # -----------------------------
1a6d4492
 
dc97cb71
 # For Debian/Ubuntu make apt attempt to retry network ops on it's own
e83f7785
 if is_ubuntu; then
9246d96e
     echo 'APT::Acquire::Retries "20";' | sudo tee /etc/apt/apt.conf.d/80retry  >/dev/null
e83f7785
 fi
 
1a6d4492
 # Some distros need to add repos beyond the defaults provided by the vendor
 # to pick up required packages.
 
dc04b5aa
 function _install_epel {
36705b52
     # epel-release is in extras repo which is enabled by default
     install_package epel-release
 
     # RDO repos are not tested with epel and may have incompatibilities so
     # let's limit the packages fetched from epel to the ones not in RDO repos.
67fd81a4
     sudo dnf config-manager --save --setopt=includepkgs=debootstrap,dpkg epel
dc04b5aa
 }
3e37326a
 
dc04b5aa
 function _install_rdo {
36705b52
     # NOTE(ianw) 2020-04-30 : when we have future branches, we
     # probably want to install the relevant branch RDO release as
     # well.  But for now it's all master.
     sudo dnf -y install https://rdoproject.org/repos/rdo-release.el8.rpm
     sudo dnf -y update
95a9ff05
 }
 
0e8dcedf
 
 # Configure Target Directories
 # ----------------------------
 
 # Destination path for installation ``DEST``
 DEST=${DEST:-/opt/stack}
23f69d83
 
e26232bc
 # Create the destination directory and ensure it is writable by the user
376b6316
 # and read/executable by everybody for daemons (e.g. apache run for horizon)
352d58a7
 # If directory exists do not modify the permissions.
 if [[ ! -d $DEST ]]; then
     sudo mkdir -p $DEST
     safe_chown -R $STACK_USER $DEST
     safe_chmod 0755 $DEST
 fi
e26232bc
 
09a3e715
 # Destination path for devstack logs
 if [[ -n ${LOGDIR:-} ]]; then
     mkdir -p $LOGDIR
 fi
 
0e8dcedf
 # Destination path for service data
 DATA_DIR=${DATA_DIR:-${DEST}/data}
352d58a7
 if [[ ! -d $DATA_DIR ]]; then
     sudo mkdir -p $DATA_DIR
     safe_chown -R $STACK_USER $DATA_DIR
     safe_chmod 0755 $DATA_DIR
 fi
0e8dcedf
 
 # Configure proper hostname
3ee52c81
 # Certain services such as rabbitmq require that the local hostname resolves
 # correctly.  Make sure it exists in /etc/hosts so that is always true.
 LOCAL_HOSTNAME=`hostname -s`
854cb676
 if ! fgrep -qwe "$LOCAL_HOSTNAME" /etc/hosts; then
3ee52c81
     sudo sed -i "s/\(^127.0.0.1.*\)/\1 $LOCAL_HOSTNAME/" /etc/hosts
 fi
 
09a3e715
 # If you have all the repos installed above already setup (e.g. a CI
 # situation where they are on your image) you may choose to skip this
 # to speed things up
 SKIP_EPEL_INSTALL=$(trueorfalse False SKIP_EPEL_INSTALL)
 
36705b52
 if [[ $DISTRO == "rhel8" ]]; then
dc04b5aa
     # If we have /etc/ci/mirror_info.sh assume we're on a OpenStack CI
     # node, where EPEL is installed (but disabled) and already
     # pointing at our internal mirror
     if [[ -f /etc/ci/mirror_info.sh ]]; then
         SKIP_EPEL_INSTALL=True
36705b52
         sudo dnf config-manager --set-enabled epel
bc4b8eb5
     fi
bda194ad
 
36705b52
     # PowerTools repo provides libyaml-devel required by devstack itself and
     # EPEL packages assume that the PowerTools repository is enable.
     sudo dnf config-manager --set-enabled PowerTools
 
dc04b5aa
     if [[ ${SKIP_EPEL_INSTALL} != True ]]; then
         _install_epel
     fi
     # Along with EPEL, CentOS (and a-likes) require some packages only
     # available in RDO repositories (e.g. OVS, or later versions of
     # kvm) to run.
     _install_rdo
36705b52
 
     # NOTE(cgoncalves): workaround RHBZ#1154272
     # dnf fails for non-privileged users when expired_repos.json doesn't exist.
     # RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1154272
     # Patch: https://github.com/rpm-software-management/dnf/pull/1448
     echo "[]" | sudo tee /var/cache/dnf/expired_repos.json
09a3e715
 fi
 
adcf40d5
 # Ensure python is installed
 # --------------------------
21a10d34
 install_python
adcf40d5
 
531aeb79
 
ffd17680
 # Configure Logging
 # -----------------
 
 # Set up logging level
53753293
 VERBOSE=$(trueorfalse True VERBOSE)
83ecb97f
 VERBOSE_NO_TIMESTAMP=$(trueorfalse False VERBOSE)
ffd17680
 
 # Draw a spinner so the user knows something is happening
 function spinner {
     local delay=0.75
     local spinstr='/-\|'
     printf "..." >&3
     while [ true ]; do
         local temp=${spinstr#?}
         printf "[%c]" "$spinstr" >&3
         local spinstr=$temp${spinstr%"$temp"}
         sleep $delay
         printf "\b\b\b" >&3
     done
 }
 
 function kill_spinner {
     if [ ! -z "$LAST_SPINNER_PID" ]; then
         kill >/dev/null 2>&1 $LAST_SPINNER_PID
         printf "\b\b\bdone\n" >&3
     fi
 }
 
 # Echo text to the log file, summary log file and stdout
 # echo_summary "something to say"
 function echo_summary {
     if [[ -t 3 && "$VERBOSE" != "True" ]]; then
         kill_spinner
         echo -n -e $@ >&6
         spinner &
         LAST_SPINNER_PID=$!
     else
         echo -e $@ >&6
     fi
 }
 
 # Echo text only to stdout, no log files
 # echo_nolog "something not for the logs"
 function echo_nolog {
     echo $@ >&3
 }
 
 # Set up logging for ``stack.sh``
 # Set ``LOGFILE`` to turn on logging
 # Append '.xxxxxxxx' to the given name to maintain history
 # where 'xxxxxxxx' is a representation of the date the file was created
 TIMESTAMP_FORMAT=${TIMESTAMP_FORMAT:-"%F-%H%M%S"}
dde41d07
 LOGDAYS=${LOGDAYS:-7}
 CURRENT_LOG_TIME=$(date "+$TIMESTAMP_FORMAT")
ffd17680
 
 if [[ -n "$LOGFILE" ]]; then
ad5cc986
     # Clean up old log files.  Append '.*' to the user-specified
     # ``LOGFILE`` to match the date in the search template.
fc9cc965
     LOGFILE_DIR="${LOGFILE%/*}"           # dirname
     LOGFILE_NAME="${LOGFILE##*/}"         # basename
     mkdir -p $LOGFILE_DIR
     find $LOGFILE_DIR -maxdepth 1 -name $LOGFILE_NAME.\* -mtime +$LOGDAYS -exec rm {} \;
ffd17680
     LOGFILE=$LOGFILE.${CURRENT_LOG_TIME}
ad5cc986
     SUMFILE=$LOGFILE.summary.${CURRENT_LOG_TIME}
ffd17680
 
     # Redirect output according to config
 
     # Set fd 3 to a copy of stdout. So we can set fd 1 without losing
     # stdout later.
     exec 3>&1
     if [[ "$VERBOSE" == "True" ]]; then
83ecb97f
         _of_args="-v"
         if [[ "$VERBOSE_NO_TIMESTAMP" == "True" ]]; then
             _of_args="$_of_args --no-timestamp"
         fi
ffd17680
         # Set fd 1 and 2 to write the log file
21a10d34
         exec 1> >( $PYTHON $TOP_DIR/tools/outfilter.py $_of_args -o "${LOGFILE}" ) 2>&1
ffd17680
         # Set fd 6 to summary log file
21a10d34
         exec 6> >( $PYTHON $TOP_DIR/tools/outfilter.py -o "${SUMFILE}" )
ffd17680
     else
         # Set fd 1 and 2 to primary logfile
21a10d34
         exec 1> >( $PYTHON $TOP_DIR/tools/outfilter.py -o "${LOGFILE}" ) 2>&1
ffd17680
         # Set fd 6 to summary logfile and stdout
21a10d34
         exec 6> >( $PYTHON $TOP_DIR/tools/outfilter.py -v -o "${SUMFILE}" >&3 )
ffd17680
     fi
 
     echo_summary "stack.sh log $LOGFILE"
     # Specified logfile name always links to the most recent log
fc9cc965
     ln -sf $LOGFILE $LOGFILE_DIR/$LOGFILE_NAME
     ln -sf $SUMFILE $LOGFILE_DIR/$LOGFILE_NAME.summary
ffd17680
 else
     # Set up output redirection without log files
     # Set fd 3 to a copy of stdout. So we can set fd 1 without losing
     # stdout later.
     exec 3>&1
     if [[ "$VERBOSE" != "True" ]]; then
         # Throw away stdout and stderr
         exec 1>/dev/null 2>&1
     fi
     # Always send summary fd to original stdout
21a10d34
     exec 6> >( $PYTHON $TOP_DIR/tools/outfilter.py -v >&3 )
ffd17680
 fi
 
9e11e098
 # Basic test for ``$DEST`` path permissions (fatal on error unless skipped)
 check_path_perm_sanity ${DEST}
ffd17680
 
 # Configure Error Traps
 # ---------------------
 
 # Kill background processes on exit
 trap exit_trap EXIT
 function exit_trap {
     local r=$?
     jobs=$(jobs -p)
     # Only do the kill when we're logging through a process substitution,
     # which currently is only to verbose logfile
     if [[ -n $jobs && -n "$LOGFILE" && "$VERBOSE" == "True" ]]; then
         echo "exit_trap: cleaning up child processes"
         kill 2>&1 $jobs
     fi
 
85cf2933
     #Remove timing data file
     if [ -f "$OSCWRAP_TIMER_FILE" ] ; then
         rm "$OSCWRAP_TIMER_FILE"
     fi
 
ffd17680
     # Kill the last spinner process
     kill_spinner
 
     if [[ $r -ne 0 ]]; then
         echo "Error on exit"
03ae3c48
         # If we error before we've installed os-testr, this will fail.
cbd5f4e0
         if type -p generate-subunit > /dev/null; then
             generate-subunit $DEVSTACK_START_TIME $SECONDS 'fail' >> ${SUBUNIT_OUTPUT}
         fi
ffd17680
         if [[ -z $LOGDIR ]]; then
21a10d34
             ${PYTHON} $TOP_DIR/tools/worlddump.py
ffd17680
         else
21a10d34
             ${PYTHON} $TOP_DIR/tools/worlddump.py -d $LOGDIR
ffd17680
         fi
4af2afcd
     else
03ae3c48
         # If we error before we've installed os-testr, this will fail.
cbd5f4e0
         if type -p generate-subunit > /dev/null; then
             generate-subunit $DEVSTACK_START_TIME $SECONDS >> ${SUBUNIT_OUTPUT}
         fi
ffd17680
     fi
 
     exit $r
 }
 
 # Exit on any errors so that errors don't compound
 trap err_trap ERR
 function err_trap {
     local r=$?
     set +o xtrace
     if [[ -n "$LOGFILE" ]]; then
         echo "${0##*/} failed: full log in $LOGFILE"
     else
         echo "${0##*/} failed"
     fi
     exit $r
 }
 
 # Begin trapping error exit codes
 set -o errexit
 
dc97cb71
 # Print the kernel version
 uname -a
 
bd24a8d0
 # Reset the bundle of CA certificates
 SSL_BUNDLE_FILE="$DATA_DIR/ca-bundle.pem"
 rm -f $SSL_BUNDLE_FILE
 
0e8dcedf
 # Import common services (database, message queue) configuration
 source $TOP_DIR/lib/database
 source $TOP_DIR/lib/rpc_backend
 
4a43b7bd
 # Configure Projects
 # ==================
67787e6b
 
7b9341e1
 # Clone all external plugins
 fetch_plugins
 
2af6915e
 # Plugin Phase 0: override_defaults - allow plugins to override
6e275e17
 # defaults before other services are run
 run_phase override_defaults
 
dc97cb71
 # Import Apache functions
d98a5d0a
 source $TOP_DIR/lib/apache
0049c0c4
 
 # Import TLS functions
c83a7e12
 source $TOP_DIR/lib/tls
0049c0c4
 
 # Source project function libraries
0392a10a
 source $TOP_DIR/lib/infra
3ed99c0b
 source $TOP_DIR/lib/libraries
d470867f
 source $TOP_DIR/lib/lvm
b562e6a7
 source $TOP_DIR/lib/horizon
d81a0274
 source $TOP_DIR/lib/keystone
73f6f25b
 source $TOP_DIR/lib/glance
bf67c19c
 source $TOP_DIR/lib/nova
4d601756
 source $TOP_DIR/lib/placement
67787e6b
 source $TOP_DIR/lib/cinder
ece6a332
 source $TOP_DIR/lib/swift
2a242519
 source $TOP_DIR/lib/neutron
f127e2f3
 source $TOP_DIR/lib/ldap
e0b08d04
 source $TOP_DIR/lib/dstat
2bbc9bbb
 source $TOP_DIR/lib/tcpdump
546656fc
 source $TOP_DIR/lib/etcd3
67787e6b
 
cdf3d766
 # Extras Source
 # --------------
 
 # Phase: source
2c65e71a
 run_phase source
cdf3d766
 
c6d47014
 
b7490da9
 # Interactive Configuration
 # -------------------------
 
 # Do all interactive config up front before the logging spew begins
213c4168
 
7a549f40
 # Generic helper to configure passwords
 function read_password {
523f4880
     local xtrace
     xtrace=$(set +o | grep xtrace)
7a549f40
     set +o xtrace
     var=$1; msg=$2
     pw=${!var}
 
9e032c2d
     if [[ -f $RC_DIR/localrc ]]; then
         localrc=$TOP_DIR/localrc
     else
975f4209
         localrc=$TOP_DIR/.localrc.password
9e032c2d
     fi
6015c82a
 
7a549f40
     # 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
b4db2254
         if [ ! -e $localrc ]; then
             touch $localrc
7a549f40
         fi
 
975f4209
         # 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.
 
b4db2254
         echo ''
         echo '################################################################################'
         echo $msg
         echo '################################################################################'
975f4209
         echo "This value will be written to ${localrc} file so you don't have to enter it "
4e6a2b71
         echo "again.  Use only alphanumeric characters."
b4db2254
         echo "If you leave this blank, a random default value will be used."
4e6a2b71
         pw=" "
         while true; do
             echo "Enter a password now:"
             read -e $var
             pw=${!var}
             [[ "$pw" = "`echo $pw | tr -cd [:alnum:]`" ]] && break
             echo "Invalid chars in password.  Try again:"
         done
b4db2254
         if [ ! $pw ]; then
f71b500b
             pw=$(generate_hex_string 10)
7a549f40
         fi
b4db2254
         eval "$var=$pw"
         echo "$var=$pw" >> $localrc
7a549f40
     fi
523f4880
 
     # restore previous xtrace value
     $xtrace
7a549f40
 }
 
13dc5ccd
 
b9182d65
 # Database Configuration
dc97cb71
 # ----------------------
b9182d65
 
b14665f0
 # To select between database backends, add the following to ``local.conf``:
428af5a2
 #
afc29fe5
 #    disable_service mysql
b14665f0
 #    enable_service postgresql
 #
 # The available database backends are listed in ``DATABASE_BACKENDS`` after
 # ``lib/database`` is sourced. ``mysql`` is the default.
 
29771c1c
 if initialize_database_backends; then
     echo "Using $DATABASE_TYPE database backend"
     # Last chance for the database password. This must be handled here
     # because read_password is not a library function.
     read_password DATABASE_PASSWORD "ENTER A PASSWORD TO USE FOR THE DATABASE."
 else
     echo "No database enabled"
 fi
782b9917
 
b9182d65
 
b7490da9
 # Queue Configuration
dc97cb71
 # -------------------
a841644e
 
 # Rabbit connection info
dc97cb71
 # In multi node DevStack, second node needs ``RABBIT_USERID``, but rabbit
f6287c2a
 # isn't enabled.
4a221459
 if is_service_enabled rabbit; then
     read_password RABBIT_PASSWORD "ENTER A PASSWORD TO USE FOR RABBIT."
 fi
ba23cc73
 
7d28a0e1
 
782b9917
 # Keystone
dc97cb71
 # --------
782b9917
 
5ce44cd6
 if is_service_enabled keystone; then
b7490da9
     # Services authenticate to Identity with servicename/``SERVICE_PASSWORD``
     read_password SERVICE_PASSWORD "ENTER A SERVICE_PASSWORD TO USE FOR THE SERVICE AUTHENTICATION."
     # Horizon currently truncates usernames and passwords at 20 characters
     read_password ADMIN_PASSWORD "ENTER A PASSWORD TO USE FOR HORIZON AND KEYSTONE (20 CHARS OR LESS)."
 
     # Keystone can now optionally install OpenLDAP by enabling the ``ldap``
dc97cb71
     # service in ``local.conf`` (e.g. ``enable_service ldap``).
b7490da9
     # To clean out the Keystone contents in OpenLDAP set ``KEYSTONE_CLEAR_LDAP``
dc97cb71
     # to ``yes`` (e.g. ``KEYSTONE_CLEAR_LDAP=yes``) in ``local.conf``.  To enable the
b7490da9
     # Keystone Identity Driver (``keystone.identity.backends.ldap.Identity``)
     # set ``KEYSTONE_IDENTITY_BACKEND`` to ``ldap`` (e.g.
dc97cb71
     # ``KEYSTONE_IDENTITY_BACKEND=ldap``) in ``local.conf``.
b7490da9
 
dc97cb71
     # Only request LDAP password if the service is enabled
b7490da9
     if is_service_enabled ldap; then
         read_password LDAP_PASSWORD "ENTER A PASSWORD TO USE FOR LDAP"
     fi
 fi
f127e2f3
 
 
29771c1c
 # Nova
 # -----
 
 if is_service_enabled nova && [[ "$VIRT_DRIVER" == 'xenserver' ]]; then
     # Look for the backend password here because read_password
     # is not a library function.
     read_password XENAPI_PASSWORD "ENTER A PASSWORD TO USE FOR XEN."
 fi
 
 
b7490da9
 # Swift
dc97cb71
 # -----
b96871e4
 
b7490da9
 if is_service_enabled s-proxy; then
     # We only ask for Swift Hash if we have enabled swift service.
     # ``SWIFT_HASH`` is a random unique string for a swift cluster that
     # can never change.
     read_password SWIFT_HASH "ENTER A RANDOM SWIFT HASH."
abbb0e9a
 
     if [[ -z "$SWIFT_TEMPURL_KEY" ]] && [[ "$SWIFT_ENABLE_TEMPURLS" == "True" ]]; then
         read_password SWIFT_TEMPURL_KEY "ENTER A KEY FOR SWIFT TEMPURLS."
     fi
b7490da9
 fi
b3288381
 
6816234d
 # Save configuration values
 save_stackenv $LINENO
 
6577b468
 
30f68e96
 # Install Packages
d74257d0
 # ================
7d28a0e1
 
4a43b7bd
 # OpenStack uses a fair number of other projects.
30f68e96
 
2d91fe8a
 # Bring down global requirements before any use of pip_install. This is
 # necessary to ensure that the constraints file is in place before we
 # attempt to apply any constraints to pip installs.
 git_clone $REQUIREMENTS_REPO $REQUIREMENTS_DIR $REQUIREMENTS_BRANCH
 
7d28a0e1
 # Install package requirements
48352ee7
 # Source it so the entire environment is available
7903b795
 echo_summary "Installing package prerequisites"
48352ee7
 source $TOP_DIR/tools/install_prereqs.sh
47f02060
 
dc97cb71
 # Configure an appropriate Python environment
8b5d3cf3
 if [[ "$OFFLINE" != "True" ]]; then
53753293
     PYPI_ALTERNATIVE_URL=${PYPI_ALTERNATIVE_URL:-""} $TOP_DIR/tools/install_pip.sh
8b5d3cf3
 fi
1a6d4492
 
d3121f64
 # Do the ugly hacks for broken packages and distros
04a35113
 source $TOP_DIR/tools/fixup_stuff.sh
4d835e33
 fixup_all
9acc12a3
 
6eb2c599
 # Install subunit for the subunit output stream
 pip_install -U os-testr
 
6808a346
 pip_install_gr systemd-python
 # the default rate limit of 1000 messages / 30 seconds is not
 # sufficient given how verbose our logging is.
 iniset -sudo /etc/systemd/journald.conf "Journal" "RateLimitBurst" "0"
 sudo systemctl restart systemd-journald
5c3a63e6
 
b1d8e8e2
 # Virtual Environment
 # -------------------
 
0a9d03d5
 # Install required infra support libraries
 install_infra
 
58243f62
 # Install bindep
 $VIRTUALENV_CMD $DEST/bindep-venv
 # TODO(ianw) : optionally install from zuul checkout?
 $DEST/bindep-venv/bin/pip install bindep
fa9aadfd
 export BINDEP_CMD=${DEST}/bindep-venv/bin/bindep
 
 # Install packages as defined in plugin bindep.txt files
 pkgs="$( _get_plugin_bindep_packages )"
 if [[ -n "${pkgs}" ]]; then
     install_package ${pkgs}
 fi
58243f62
 
5c3a63e6
 # Extras Pre-install
 # ------------------
 # Phase: pre-install
2c65e71a
 run_phase stack pre-install
5c3a63e6
 
1f55d389
 # NOTE(danms): Set global limits before installing anything
 set_systemd_override DefaultLimitNOFILE ${ULIMIT_NOFILE}
 
62d1d698
 install_rpc_backend
b1d8519b
 restart_rpc_backend
62d1d698
 
 if is_service_enabled $DATABASE_BACKENDS; then
     install_database
7dd890d6
 fi
 if [ -n "$DATABASE_TYPE" ]; then
5686dbc4
     install_database_python
62d1d698
 fi
 
 if is_service_enabled neutron; then
     install_neutron_agent_packages
 fi
 
62b56601
 if is_service_enabled etcd3; then
     install_etcd3
 fi
 
cc072fd3
 # Setup TLS certs
 # ---------------
 
 # Do this early, before any webservers are set up to ensure
 # we don't run into problems with missing certs when apache
 # is restarted.
 if is_service_enabled tls-proxy; then
     configure_CA
     init_CA
     init_cert
 fi
 
19e4d972
 # Dstat
 # -----
 
 # Install dstat services prerequisites
 install_dstat
 
 
fe51a900
 # Check Out and Install Source
 # ----------------------------
4a43b7bd
 
7903b795
 echo_summary "Installing OpenStack project source"
 
3ed99c0b
 # Install additional libraries
 install_libs
1b6b5318
 
604e598e
 # Install uwsgi
 install_apache_uwsgi
 
dc97cb71
 # Install client libraries
21a9077d
 install_keystoneauth
d81a0274
 install_keystoneclient
73f6f25b
 install_glanceclient
253a1a35
 install_cinderclient
bf67c19c
 install_novaclient
75195b58
 if is_service_enabled swift glance horizon; then
fe51a900
     install_swiftclient
 fi
75195b58
 if is_service_enabled neutron nova horizon; then
b05c8769
     install_neutronclient
fe51a900
 fi
 
58936fdb
 # Install middleware
 install_keystonemiddleware
 
5ce44cd6
 if is_service_enabled keystone; then
0abde393
     if [ "$KEYSTONE_AUTH_HOST" == "$SERVICE_HOST" ]; then
8c2ce6ea
         stack_install_service keystone
0abde393
         configure_keystone
     fi
38df1228
 fi
ece6a332
 
8b416ae8
 if is_service_enabled swift; then
b6197e6a
     if is_service_enabled ceilometer; then
         install_ceilometermiddleware
     fi
8c2ce6ea
     stack_install_service swift
fe51a900
     configure_swift
 
070e4ee6
     # s3api middleware to provide S3 emulation to Swift
     if is_service_enabled s3api; then
dc97cb71
         # Replace the nova-objectstore port by the swift port
9d2647a9
         S3_SERVICE_PORT=8080
6ae9ea59
     fi
e7ce24fc
 fi
ece6a332
 
a6651e94
 if is_service_enabled g-api n-api; then
dc97cb71
     # Image catalog service
8c2ce6ea
     stack_install_service glance
fe51a900
     configure_glance
e7ce24fc
 fi
fe51a900
 
 if is_service_enabled cinder; then
dc97cb71
     # Block volume service
8c2ce6ea
     stack_install_service cinder
fe51a900
     configure_cinder
 fi
 
b05c8769
 if is_service_enabled neutron; then
dc97cb71
     # Network service
8c2ce6ea
     stack_install_service neutron
fe51a900
 fi
 
bf67c19c
 if is_service_enabled nova; then
dc97cb71
     # Compute service
8c2ce6ea
     stack_install_service nova
fe51a900
     configure_nova
bf67c19c
 fi
fe51a900
 
4d601756
 if is_service_enabled placement; then
     # placement api
     stack_install_service placement
     configure_placement
 fi
 
51a225c5
 # create a placement-client fake service to know we need to configure
 # placement connectivity. We configure the placement service for nova
 # if placement-api or placement-client is active, and n-cpu on the
 # same box.
 if is_service_enabled placement placement-client; then
f58b3735
     if is_service_enabled n-cpu || is_service_enabled n-sch; then
51a225c5
         configure_placement_nova_compute
     fi
 fi
 
a6651e94
 if is_service_enabled horizon; then
b562e6a7
     # dashboard
8c2ce6ea
     stack_install_service horizon
e7ce24fc
 fi
fe51a900
 
f3b2f4c8
 if is_service_enabled tls-proxy; then
c30b8def
     fix_system_ca_bundle_path
67787e6b
 fi
75a37653
 
cdf3d766
 # Extras Install
 # --------------
 
 # Phase: install
2c65e71a
 run_phase stack install
cdf3d766
 
dc97cb71
 # Install the OpenStack client, needed for most setup commands
1ffa3321
 if use_library_from_git "python-openstackclient"; then
     git_clone_by_name "python-openstackclient"
     setup_dev_lib "python-openstackclient"
 else
60996b1b
     pip_install_gr python-openstackclient
1ffa3321
 fi
 
85cf2933
 # Installs alias for osc so that we can collect timing for all
 # osc commands. Alias dies with stack.sh.
 install_oscwrap
 
ff603ef5
 # Syslog
df0972c1
 # ------
ff603ef5
 
 if [[ $SYSLOG != "False" ]]; then
     if [[ "$SYSLOG_HOST" = "$HOST_IP" ]]; then
         # Configure the master host to receive
6bab8321
         cat <<EOF | sudo tee /etc/rsyslog.d/90-stack-m.conf >/dev/null
ff603ef5
 \$ModLoad imrelp
 \$InputRELPServerRun $SYSLOG_PORT
 EOF
     else
         # Set rsyslog to send to remote host
6bab8321
         cat <<EOF | sudo tee /etc/rsyslog.d/90-stack-s.conf >/dev/null
ff603ef5
 *.*		:omrelp:$SYSLOG_HOST:$SYSLOG_PORT
 EOF
     fi
e4859f0b
 
     RSYSLOGCONF="/etc/rsyslog.conf"
     if [ -f $RSYSLOGCONF ]; then
         sudo cp -b $RSYSLOGCONF $RSYSLOGCONF.bak
         if [[ $(grep '$SystemLogRateLimitBurst' $RSYSLOGCONF)  ]]; then
             sudo sed -i 's/$SystemLogRateLimitBurst\ .*/$SystemLogRateLimitBurst\ 0/' $RSYSLOGCONF
         else
             sudo sed -i '$ i $SystemLogRateLimitBurst\ 0' $RSYSLOGCONF
         fi
         if [[ $(grep '$SystemLogRateLimitInterval' $RSYSLOGCONF)  ]]; then
             sudo sed -i 's/$SystemLogRateLimitInterval\ .*/$SystemLogRateLimitInterval\ 0/' $RSYSLOGCONF
         else
             sudo sed -i '$ i $SystemLogRateLimitInterval\ 0' $RSYSLOGCONF
         fi
     fi
 
7903b795
     echo_summary "Starting rsyslog"
13dc5ccd
     restart_service rsyslog
ff603ef5
 fi
 
df0972c1
 
fe7b56cd
 # Export Certificate Authority Bundle
 # -----------------------------------
bd24a8d0
 
 # If certificates were used and written to the SSL bundle file then these
 # should be exported so clients can validate their connections.
 
 if [ -f $SSL_BUNDLE_FILE ]; then
     export OS_CACERT=$SSL_BUNDLE_FILE
 fi
 
 
428af5a2
 # Configure database
 # ------------------
b9182d65
 
428af5a2
 if is_service_enabled $DATABASE_BACKENDS; then
     configure_database
24859060
 fi
 
6816234d
 # Save configuration values
 save_stackenv $LINENO
 
f85e0ba3
 # Kernel Samepage Merging (KSM)
 # -----------------------------
 
 # Processes that mark their memory as mergeable can share identical memory
 # pages if KSM is enabled. This is particularly useful for nova + libvirt
 # backends but any other setup that marks its memory as mergeable can take
 # advantage. The drawback is there is higher cpu load; however, we tend to
 # be memory bound not cpu bound so enable KSM by default but allow people
 # to opt out if the CPU time is more important to them.
 
e8db8674
 if [[ $ENABLE_KSM == "True" ]] ; then
f85e0ba3
     if [[ -f /sys/kernel/mm/ksm/run ]] ; then
         sudo sh -c "echo 1 > /sys/kernel/mm/ksm/run"
     fi
 fi
 
dc97cb71
 
 # Start Services
 # ==============
 
78096b50
 # Dstat
dc97cb71
 # -----
1a6d4492
 
f1eb0475
 # A better kind of sysstat, with the top process per time slice
e0b08d04
 start_dstat
921f2dab
 
2bbc9bbb
 # Run a background tcpdump for debugging
 # Note: must set TCPDUMP_ARGS with the enabled service
 if is_service_enabled tcpdump; then
     start_tcpdump
 fi
 
546656fc
 # Etcd
 # -----
 
 # etcd is a distributed key value store that provides a reliable way to store data across a cluster of machines
94b9fae4
 if is_service_enabled etcd3; then
     start_etcd3
 fi
893e6636
 
d81a0274
 # Keystone
 # --------
 
a5d965a3
 # Rather than just export these, we write them out to a
 # intermediate userrc file that can also be used to debug if
 # something goes wrong between here and running
 # tools/create_userrc.sh (this script relies on services other
 # than keystone being available, so we can't call it right now)
 cat > $TOP_DIR/userrc_early <<EOF
7adf15df
 # Use this for debugging issues before files in accrc are created
 
 # Set up password auth credentials now that Keystone is bootstrapped
923be5f7
 export OS_IDENTITY_API_VERSION=3
32c00890
 export OS_AUTH_URL=$KEYSTONE_SERVICE_URI
7adf15df
 export OS_USERNAME=admin
 export OS_USER_DOMAIN_ID=default
 export OS_PASSWORD=$ADMIN_PASSWORD
 export OS_PROJECT_NAME=admin
 export OS_PROJECT_DOMAIN_ID=default
6f1781f9
 export OS_REGION_NAME=$KEYSTONE_REGION_NAME
7adf15df
 
 EOF
 
a5d965a3
 if is_service_enabled tls-proxy; then
     echo "export OS_CACERT=$INT_CA_DIR/ca-chain.pem" >> $TOP_DIR/userrc_early
     start_tls_proxy http-services '*' 443 $SERVICE_HOST 80
 fi
 
 source $TOP_DIR/userrc_early
 
 if is_service_enabled keystone; then
     echo_summary "Starting Keystone"
be00e95d
 
a5d965a3
     if [ "$KEYSTONE_AUTH_HOST" == "$SERVICE_HOST" ]; then
         init_keystone
         start_keystone
         bootstrap_keystone
     fi
7adf15df
 
923be5f7
     create_keystone_accounts
93a41560
     if is_service_enabled nova; then
         create_nova_accounts
     fi
     if is_service_enabled glance; then
         create_glance_accounts
     fi
     if is_service_enabled cinder; then
         create_cinder_accounts
     fi
     if is_service_enabled neutron; then
         create_neutron_accounts
     fi
923be5f7
     if is_service_enabled swift; then
         create_swift_accounts
     fi
 
d81a0274
 fi
 
7224eecb
 # Write a clouds.yaml file
 write_clouds_yaml
16a2d64f
 
ca85b799
 # Horizon
df0972c1
 # -------
cbe98d56
 
a6651e94
 if is_service_enabled horizon; then
43f62c08
     echo_summary "Configuring Horizon"
     configure_horizon
70dc5e05
 fi
1c1d1505
 
18d350da
 
d74257d0
 # Glance
 # ------
 
09e860fc
 # NOTE(yoctozepto): limited to node hosting the database which is the controller
 if is_service_enabled $DATABASE_BACKENDS && is_service_enabled glance; then
7903b795
     echo_summary "Configuring Glance"
73f6f25b
     init_glance
70dc5e05
 fi
75a37653
 
8c032d16
 
b05c8769
 # Neutron
60df29a2
 # -------
7d28a0e1
 
b05c8769
 if is_service_enabled neutron; then
     echo_summary "Configuring Neutron"
b9182d65
 
b05c8769
     configure_neutron
297a50ac
 
dc97cb71
     # Run init_neutron only on the node hosting the Neutron API server
2a242519
     if is_service_enabled $DATABASE_BACKENDS && is_service_enabled neutron; then
dd64988f
         init_neutron
     fi
60df29a2
 fi
 
4b8cba77
 
d74257d0
 # Nova
 # ----
bd13b708
 
4b8cba77
 if is_service_enabled q-dhcp; then
55458455
     # Delete traces of nova networks from prior runs
d71d6e71
     # Do not kill any dnsmasq instance spawned by NetworkManager
     netman_pid=$(pidof NetworkManager || true)
     if [ -z "$netman_pid" ]; then
         sudo killall dnsmasq || true
     else
         sudo ps h -o pid,ppid -C dnsmasq | grep -v $netman_pid | awk '{print $1}' | sudo xargs kill || true
     fi
 
55458455
     clean_iptables
7a7fb49b
 
1a6d4492
     # Force IP forwarding on, just in case
0b31e867
     sudo sysctl -w net.ipv4.ip_forward=1
70dc5e05
 fi
 
7d28a0e1
 
28fa4e8d
 # Storage Service
7d28a0e1
 # ---------------
 
8b416ae8
 if is_service_enabled swift; then
7903b795
     echo_summary "Configuring Swift"
ece6a332
     init_swift
28fa4e8d
 fi
 
df0972c1
 
acff87a2
 # Volume Service
 # --------------
 
67787e6b
 if is_service_enabled cinder; then
7903b795
     echo_summary "Configuring Cinder"
67787e6b
     init_cinder
acff87a2
 fi
 
e8bad5cd
 # Placement Service
 # ---------------
 
 if is_service_enabled placement; then
     echo_summary "Configuring placement"
     init_placement
 fi
2aa2a89c
 
 # Compute Service
 # ---------------
 
bf67c19c
 if is_service_enabled nova; then
     echo_summary "Configuring Nova"
     init_nova
0007f3a6
 
86a79694
     # Additional Nova configuration that is dependent on other services
4b8cba77
     # TODO(stephenfin): Is it possible for neutron to *not* be enabled now? If
     # not, remove the if here
b05c8769
     if is_service_enabled neutron; then
2a242519
         configure_neutron_nova
1bfa3d53
     fi
b62b4ca2
 fi
 
dc97cb71
 
cdf3d766
 # Extras Configuration
 # ====================
 
 # Phase: post-config
2c65e71a
 run_phase stack post-config
cdf3d766
 
 
893e6636
 # Local Configuration
 # ===================
 
dc97cb71
 # Apply configuration from ``local.conf`` if it exists for layer 2 services
893e6636
 # Phase: post-config
 merge_config_group $TOP_DIR/local.conf post-config
 
 
d74257d0
 # Launch Services
 # ===============
30f68e96
 
dfcd2003
 # Only run the services specified in ``ENABLED_SERVICES``
 
ece6a332
 # Launch Swift Services
8b416ae8
 if is_service_enabled swift; then
ece6a332
     echo_summary "Starting Swift"
     start_swift
 fi
 
73f6f25b
 # Launch the Glance services
e4fa7213
 if is_service_enabled glance; then
7903b795
     echo_summary "Starting Glance"
73f6f25b
     start_glance
d000b22d
 fi
 
dc97cb71
 
0b9776d2
 # Install Images
 # ==============
 
dc97cb71
 # Upload an image to Glance.
0b9776d2
 #
dc97cb71
 # The default image is CirrOS, a small testing image which lets you login as **root**
 # CirrOS has a ``cloud-init`` analog supporting login via keypair and sending
0b9776d2
 # scripts as userdata.
dc97cb71
 # See https://help.ubuntu.com/community/CloudInit for more on ``cloud-init``
0b9776d2
 
09e860fc
 # NOTE(yoctozepto): limited to node hosting the database which is the controller
 if is_service_enabled $DATABASE_BACKENDS && is_service_enabled glance; then
2f8e08b5
     echo_summary "Uploading images"
0b9776d2
 
2f8e08b5
     for image_url in ${IMAGE_URLS//,/ }; do
5aeea6ae
         upload_image $image_url
2f8e08b5
     done
0b9776d2
 fi
 
da6de10f
 # NOTE(lyarwood): By default use a single hardcoded fixed_key across devstack
 # deployments.  This ensures the keys match across nova and cinder across all
 # hosts.
 FIXED_KEY=${FIXED_KEY:-bae3516cc1c0eb18b05440eba8012a4a880a2ee04d584a9c1579445e675b12defdc716ec}
def4c141
 if is_service_enabled nova; then
da6de10f
     iniset $NOVA_CONF key_manager fixed_key "$FIXED_KEY"
     iniset $NOVA_CPU_CONF key_manager fixed_key "$FIXED_KEY"
 fi
 
 if is_service_enabled cinder; then
     iniset $CINDER_CONF key_manager fixed_key "$FIXED_KEY"
def4c141
 fi
 
7d28a0e1
 # Launch the nova-api and wait for it to answer before continuing
a6651e94
 if is_service_enabled n-api; then
7903b795
     echo_summary "Starting Nova API"
3a3a2bac
     start_nova_api
d000b22d
 fi
1bfa3d53
 
2a242519
 if is_service_enabled neutron-api; then
     echo_summary "Starting Neutron"
     start_neutron_api
 elif is_service_enabled q-svc; then
b05c8769
     echo_summary "Starting Neutron"
a1875b1f
     configure_neutron_after_post_config
b05c8769
     start_neutron_service_and_check
1bfa3d53
 fi
 
7a74c2ab
 # Start placement before any of the service that are likely to want
 # to use it to manage resource providers.
 if is_service_enabled placement; then
     echo_summary "Starting Placement"
     start_placement
 fi
 
b05c8769
 if is_service_enabled neutron; then
2a242519
     start_neutron
66afb47c
 fi
6fbb28d0
 # Once neutron agents are started setup initial network elements
07edde1c
 if is_service_enabled q-svc && [[ "$NEUTRON_CREATE_INITIAL_NETWORKS" == "True" ]]; then
     echo_summary "Creating initial neutron network elements"
f8755bd4
     # Here's where plugins can wire up their own networks instead
     # of the code in lib/neutron_plugins/services/l3
     if type -p neutron_plugin_create_initial_networks > /dev/null; then
         neutron_plugin_create_initial_networks
     else
         create_neutron_initial_network
     fi
 
07edde1c
 fi
2a242519
 
bf67c19c
 if is_service_enabled nova; then
     echo_summary "Starting Nova"
     start_nova
4b205db4
     create_flavors
bf67c19c
 fi
67787e6b
 if is_service_enabled cinder; then
7903b795
     echo_summary "Starting Cinder"
67787e6b
     start_cinder
09718335
     create_volume_types
67787e6b
 fi
b562e6a7
 
7d28a0e1
 
43f62c08
 if is_service_enabled horizon; then
     echo_summary "Starting Horizon"
     init_horizon
     start_horizon
 fi
 
bd24a8d0
 
50901429
 # Create account rc files
 # =======================
 
 # Creates source able script files for easier user switching.
 # This step also creates certificates for tenants and users,
 # which is helpful in image bundle steps.
 
 if is_service_enabled nova && is_service_enabled keystone; then
     USERRC_PARAMS="-PA --target-dir $TOP_DIR/accrc"
 
     if [ -f $SSL_BUNDLE_FILE ]; then
         USERRC_PARAMS="$USERRC_PARAMS --os-cacert $SSL_BUNDLE_FILE"
     fi
 
     $TOP_DIR/tools/create_userrc.sh $USERRC_PARAMS
 fi
 
 
 # Save some values we generated for later use
 save_stackenv
 
 
dc97cb71
 # Wrapup configuration
 # ====================
 
 # local.conf extra
 # ----------------
893e6636
 
dc97cb71
 # Apply configuration from ``local.conf`` if it exists for layer 2 services
893e6636
 # Phase: extra
 merge_config_group $TOP_DIR/local.conf extra
 
 
768295e9
 # Run extras
dc97cb71
 # ----------
768295e9
 
cdf3d766
 # Phase: extra
2c65e71a
 run_phase stack extra
768295e9
 
feb28837
 
dc97cb71
 # local.conf post-extra
 # ---------------------
 
 # Apply late configuration from ``local.conf`` if it exists for layer 2 services
feb28837
 # Phase: post-extra
 merge_config_group $TOP_DIR/local.conf post-extra
 
768295e9
 
c71973eb
 # Sanity checks
 # =============
 
c2fe916f
 # Check that computes are all ready
 #
 # TODO(sdague): there should be some generic phase here.
 if is_service_enabled n-cpu; then
     is_nova_ready
 fi
 
a9414249
 # Check the status of running services
 service_check
f5633ddb
 
71119b47
 # Configure nova cellsv2
 # ----------------------
 
 # Do this late because it requires compute hosts to have started
f166081d
 if is_service_enabled n-api; then
6d66e647
     if is_service_enabled n-cpu; then
f15224c7
         $TOP_DIR/tools/discover_hosts.sh
6d66e647
     else
         # Some CI systems like Hyper-V build the control plane on
         # Linux, and join in non Linux Computes after setup. This
         # allows them to delay the processing until after their whole
         # environment is up.
         echo_summary "SKIPPING Cell setup because n-cpu is not enabled. You will have to do this manually before you have a working environment."
     fi
9e3b3bf5
     # Run the nova-status upgrade check command which can also be used
     # to verify the base install. Note that this is good enough in a
     # single node deployment, but in a multi-node setup it won't verify
     # any subnodes - that would have to be driven from whatever tooling
     # is deploying the subnodes, e.g. the zuul v3 devstack-multinode job.
     $NOVA_BIN_DIR/nova-status --config-file $NOVA_CONF upgrade check
71119b47
 fi
 
7880904d
 # Run local script
 # ----------------
 
 # Run ``local.sh`` if it exists to perform user-managed tasks
 if [[ -x $TOP_DIR/local.sh ]]; then
     echo "Running user script $TOP_DIR/local.sh"
     $TOP_DIR/local.sh
 fi
 
bbe771a8
 # Bash completion
 # ===============
 
 # Prepare bash completion for OSC
474f535a
 # Note we use "command" to avoid the timing wrapper
 # which isn't relevant here and floods logs
 command openstack complete \
     | sudo tee /etc/bash_completion.d/osc.bash_completion > /dev/null
bbe771a8
 
4bf861c7
 # If cinder is configured, set global_filter for PV devices
 if is_service_enabled cinder; then
     if is_ubuntu; then
         echo_summary "Configuring lvm.conf global device filter"
         set_lvm_filter
     else
         echo_summary "Skip setting lvm filters for non Ubuntu systems"
     fi
 fi
bbe771a8
 
655c22c7
 # Run test-config
 # ---------------
 
 # Phase: test-config
 run_phase stack test-config
 
8bf8c8f3
 # Apply late configuration from ``local.conf`` if it exists for layer 2 services
 # Phase: test-config
 merge_config_group $TOP_DIR/local.conf test-config
dc97cb71
 
b94f4bf3
 # Fin
 # ===
 
471de7a3
 set +o xtrace
b94f4bf3
 
7903b795
 if [[ -n "$LOGFILE" ]]; then
     exec 1>&3
     # Force all output to stdout and logs now
baa8b42a
     exec 1> >( tee -a "${LOGFILE}" ) 2>&1
7903b795
 else
     # Force all output to stdout now
     exec 1>&3
 fi
 
95c33d53
 # Dump out the time totals
 time_totals
df0972c1
 
24859060
 # Using the cloud
dc97cb71
 # ===============
24859060
 
e19d8847
 echo ""
 echo ""
 echo ""
180f5eb6
 echo "This is your host IP address: $HOST_IP"
 if [ "$HOST_IPV6" != "" ]; then
     echo "This is your host IPv6 address: $HOST_IPV6"
 fi
e19d8847
 
df0972c1
 # If you installed Horizon on this server you should be able
40a37006
 # to access the site using your browser.
a6651e94
 if is_service_enabled horizon; then
7b105c57
     echo "Horizon is now available at http://$SERVICE_HOST$HORIZON_APACHE_ROOT"
24859060
 fi
 
df0972c1
 # If Keystone is present you can point ``nova`` cli to this server
5ce44cd6
 if is_service_enabled keystone; then
dc97cb71
     echo "Keystone is serving at $KEYSTONE_SERVICE_URI/"
df0972c1
     echo "The default users are: admin and demo"
     echo "The password: $ADMIN_PASSWORD"
24859060
 fi
523c405f
 
afc29fe5
 # Warn that a deprecated feature was used
 if [[ -n "$DEPRECATED_TEXT" ]]; then
2c0faca0
     echo
     echo -e "WARNING: $DEPRECATED_TEXT"
     echo
ced65179
 fi
 
6808a346
 echo
 echo "Services are running under systemd unit files."
 echo "For more information see: "
 echo "https://docs.openstack.org/devstack/latest/systemd.html"
 echo
8b8441f3
 
07cbc449
 # Useful info on current state
 cat /etc/devstack-version
2c0faca0
 echo
 
4a43b7bd
 # Indicate how long this took to run (bash maintained variable ``SECONDS``)
7903b795
 echo_summary "stack.sh completed in $SECONDS seconds."
8068455a
 
2c0faca0
 
8068455a
 # Restore/close logging file descriptors
 exec 1>&3
 exec 2>&3
 exec 3>&-
 exec 6>&-