stack.sh
ba23cc73
 #!/usr/bin/env bash
 
c6c1d439
 # ``stack.sh`` is an opinionated OpenStack developer installation.  It
4a43b7bd
 # installs and configures various combinations of **Ceilometer**, **Cinder**,
 # **Glance**, **Heat**, **Horizon**, **Keystone**, **Nova**, **Quantum**
 # and **Swift**
ba23cc73
 
9b353671
 # This script allows you to specify configuration options of what git
5372f433
 # repositories to use, enabled services, network configuration and various
 # passwords.  If you are crafty you can run the script on multiple nodes using
 # shared settings for common resources (mysql, rabbitmq) and build a multi-node
 # developer install.
782b9917
 
4a43b7bd
 # To keep this script simple we assume you are running on a recent **Ubuntu**
 # (11.10 Oneiric or 12.04 Precise) or **Fedora** (F16 or F17) machine.  It
 # should work in a VM or physical server.  Additionally we put the list of
 # ``apt`` and ``rpm`` dependencies and other configuration files in this repo.
24859060
 
0e7e897b
 # Learn more and get the most recent version at http://devstack.org
6edd17f7
 
4a43b7bd
 
c6c1d439
 # Keep track of the devstack directory
51fb22ef
 TOP_DIR=$(cd $(dirname "$0") && pwd)
 
6563a3ce
 # Import common functions
c6c1d439
 source $TOP_DIR/functions
 
 # Determine what system we are running on.  This provides ``os_VENDOR``,
 # ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
a9e0a488
 # and ``DISTRO``
 GetDistro
6edd17f7
 
6015c82a
 
9122e7b1
 # Settings
 # ========
 
df0972c1
 # ``stack.sh`` is customizable through setting environment variables.  If you
 # want to override a setting you can set and export it::
9122e7b1
 #
 #     export MYSQL_PASSWORD=anothersecret
 #     ./stack.sh
 #
 # You can also pass options on a single line ``MYSQL_PASSWORD=simple ./stack.sh``
 #
df0972c1
 # Additionally, you can put any local variables into a ``localrc`` file::
9122e7b1
 #
 #     MYSQL_PASSWORD=anothersecret
 #     MYSQL_USER=hellaroot
 #
 # We try to have sensible defaults, so you should be able to run ``./stack.sh``
4a43b7bd
 # in most cases.  ``localrc`` is not distributed with DevStack and will never
 # be overwritten by a DevStack update.
9122e7b1
 #
df0972c1
 # DevStack distributes ``stackrc`` which contains locations for the OpenStack
 # repositories and branches to configure.  ``stackrc`` sources ``localrc`` to
4a43b7bd
 # allow you to safely override those settings.
 
bbafb1b5
 if [[ ! -r $TOP_DIR/stackrc ]]; then
     echo "ERROR: missing $TOP_DIR/stackrc - did you grab more than just stack.sh?"
     exit 1
 fi
 source $TOP_DIR/stackrc
df0972c1
 
4a43b7bd
 
 # Proxy Settings
 # --------------
 
 # HTTP and HTTPS proxy servers are supported via the usual environment variables [1]
 # ``http_proxy``, ``https_proxy`` and ``no_proxy``. They can be set in
 # ``localrc`` if necessary or on the command line::
 #
 # [1] http://www.w3.org/Daemon/User/Proxies/ProxyClients.html
c727aa89
 #
7abe4f24
 #     http_proxy=http://proxy.example.com:3128/ no_proxy=repo.example.net ./stack.sh
4a43b7bd
 
bbafb1b5
 if [[ -n "$http_proxy" ]]; then
     export http_proxy=$http_proxy
 fi
 if [[ -n "$https_proxy" ]]; then
     export https_proxy=$https_proxy
c6c1d439
 fi
7abe4f24
 if [[ -n "$no_proxy" ]]; then
     export no_proxy=$no_proxy
 fi
9122e7b1
 
 # Destination path for installation ``DEST``
 DEST=${DEST:-/opt/stack}
 
c6c1d439
 
 # Sanity Check
 # ============
 
f04178fd
 # Remove services which were negated in ENABLED_SERVICES
 # using the "-" prefix (e.g., "-n-vol") instead of
 # calling disable_service().
 disable_negated_services
c4cd4140
 
c6c1d439
 # Warn users who aren't on an explicitly supported distro, but allow them to
 # override check and attempt installation with ``FORCE=yes ./stack``
4a1f5a72
 if [[ ! ${DISTRO} =~ (oneiric|precise|quantal|f16|f17) ]]; then
     echo "WARNING: this script has not been tested on $DISTRO"
c6c1d439
     if [[ "$FORCE" != "yes" ]]; then
         echo "If you wish to run this script anyway run with FORCE=yes"
         exit 1
     fi
 fi
 
4a43b7bd
 # Disallow qpid on oneiric
4a221459
 if [ "${DISTRO}" = "oneiric" ] && is_service_enabled qpid ; then
     # Qpid was introduced in precise
     echo "You must use Ubuntu Precise or newer for Qpid support."
     exit 1
 fi
 
67787e6b
 # ``stack.sh`` keeps function libraries here
 # Make sure ``$TOP_DIR/lib`` directory is present
 if [ ! -d $TOP_DIR/lib ]; then
4a43b7bd
     echo "ERROR: missing devstack/lib"
67787e6b
     exit 1
 fi
 
4a43b7bd
 # ``stack.sh`` keeps the list of ``apt`` and ``rpm`` dependencies and config
 # templates and other useful files in the ``files`` subdirectory
c6c1d439
 FILES=$TOP_DIR/files
 if [ ! -d $FILES ]; then
4a43b7bd
     echo "ERROR: missing devstack/files"
c6c1d439
     exit 1
 fi
 
15733351
 SCREEN_NAME=${SCREEN_NAME:-stack}
c6c1d439
 # Check to see if we are already running DevStack
15733351
 if type -p screen >/dev/null && screen -ls | egrep -q "[0-9].$SCREEN_NAME"; then
55458455
     echo "You are already running a stack.sh session."
     echo "To rejoin this session type 'screen -x stack'."
4a43b7bd
     echo "To destroy this session, type './unstack.sh'."
55458455
     exit 1
 fi
0a16145a
 
3bae7c2c
 # Make sure we only have one rpc backend enabled.
 rpc_backend_cnt=0
 for svc in qpid zeromq rabbit; do
     is_service_enabled $svc &&
         ((rpc_backend_cnt++))
 done
 if [ "$rpc_backend_cnt" -gt 1 ]; then
     echo "ERROR: only one rpc backend may be enabled,"
     echo "       set only one of 'rabbit', 'qpid', 'zeromq'"
     echo "       via ENABLED_SERVICES."
 elif [ "$rpc_backend_cnt" == 0 ]; then
     echo "ERROR: at least one rpc backend must be enabled,"
     echo "       set one of 'rabbit', 'qpid', 'zeromq'"
     echo "       via ENABLED_SERVICES."
 fi
 unset rpc_backend_cnt
 
67787e6b
 # Make sure we only have one volume service enabled.
 if is_service_enabled cinder && is_service_enabled n-vol; then
     echo "ERROR: n-vol and cinder must not be enabled at the same time"
     exit 1
 fi
 
7903b795
 # Set up logging level
 VERBOSE=$(trueorfalse True $VERBOSE)
 
4a43b7bd
 
 # root Access
 # -----------
 
 # 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
df0972c1
 # ``stack.sh`` is run as **root**, it automatically creates a **stack** user with
c9e3fff7
 # sudo privileges and runs as that user.
cbe98d56
 
d4622953
 if [[ $EUID -eq 0 ]]; then
92e81992
     ROOTSLEEP=${ROOTSLEEP:-10}
0031df01
     echo "You are running this script as root."
92e81992
     echo "In $ROOTSLEEP seconds, we will create a user 'stack' and run as that user"
     sleep $ROOTSLEEP
782b9917
 
4a43b7bd
     # Give the non-root user the ability to run as **root** via ``sudo``
71ebc6ff
     is_package_installed sudo || install_package sudo
e29b94e2
     if ! getent group stack >/dev/null; then
         echo "Creating a group called stack"
         groupadd stack
     fi
0d2145a0
     if ! getent passwd stack >/dev/null; then
0031df01
         echo "Creating a user called stack"
e29b94e2
         useradd -g stack -s /bin/bash -d $DEST -m stack
c9e3fff7
     fi
0d2145a0
 
e5d92380
     echo "Giving stack user passwordless sudo privileges"
4a43b7bd
     # UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
4bec581e
     grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
         echo "#includedir /etc/sudoers.d" >> /etc/sudoers
55c9d3f1
     ( umask 226 && echo "stack ALL=(ALL) NOPASSWD:ALL" \
         > /etc/sudoers.d/50_stack_sh )
782b9917
 
c9e3fff7
     echo "Copying files to stack user"
9122e7b1
     STACK_DIR="$DEST/${PWD##*/}"
0c3db253
     cp -r -f -T "$PWD" "$STACK_DIR"
5f4ae107
     chown -R stack "$STACK_DIR"
74c084cd
     if [[ "$SHELL_AFTER_RUN" != "no" ]]; then
102e440e
         exec su -c "set -e; cd $STACK_DIR; bash stack.sh; bash" stack
74c084cd
     else
102e440e
         exec su -c "set -e; cd $STACK_DIR; bash stack.sh" stack
74c084cd
     fi
f9da5081
     exit 1
509992fe
 else
4a43b7bd
     # We're not **root**, make sure ``sudo`` is available
71ebc6ff
     is_package_installed sudo || die "Sudo is required.  Re-run stack.sh as root ONE TIME ONLY to set up sudo."
e0d677c7
 
4a43b7bd
     # UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
84a399b4
     sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
         echo "#includedir /etc/sudoers.d" | sudo tee -a /etc/sudoers
e0d677c7
 
     # Set up devstack sudoers
0a16145a
     TEMPFILE=`mktemp`
e0d677c7
     echo "`whoami` ALL=(root) NOPASSWD:ALL" >$TEMPFILE
f2a25b77
     # Some binaries might be under /sbin or /usr/sbin, so make sure sudo will
     # see them by forcing PATH
     echo "Defaults:`whoami` secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
0a16145a
     chmod 0440 $TEMPFILE
     sudo chown root:root $TEMPFILE
e0d677c7
     sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
 
     # Remove old file
     sudo rm -f /etc/sudoers.d/stack_sh_nova
d4622953
 fi
 
1d62181f
 # Ensure /usr/sbin and /sbin are available on PATH
 S_PATH="/sbin /usr/sbin"
 for i in $S_PATH
 do
     echo ":$PATH:" | egrep ":$i:" > /dev/null || (PATH=$PATH:$i; echo $PATH)
 done
 
e26232bc
 # Create the destination directory and ensure it is writable by the user
 sudo mkdir -p $DEST
 if [ ! -w $DEST ]; then
     sudo chown `whoami` $DEST
 fi
 
4a43b7bd
 # Set ``OFFLINE`` to ``True`` to configure ``stack.sh`` to run cleanly without
 # Internet access. ``stack.sh`` must have been previously run with Internet
 # access to install prerequisites and fetch repositories.
25dab66b
 OFFLINE=`trueorfalse False $OFFLINE`
 
4a43b7bd
 # Set ``ERROR_ON_CLONE`` to ``True`` to configure ``stack.sh`` to exit if
 # the destination git repository does not exist during the ``git_clone``
 # operation.
94cb9600
 ERROR_ON_CLONE=`trueorfalse False $ERROR_ON_CLONE`
 
67787e6b
 # Destination path for service data
 DATA_DIR=${DATA_DIR:-${DEST}/data}
 sudo mkdir -p $DATA_DIR
 sudo chown `whoami` $DATA_DIR
 
 
d81a0274
 # Common Configuration
 # ====================
 
 # Set fixed and floating range here so we can make sure not to use addresses
 # from either range when attempting to guess the IP to use for the host.
 # Note that setting FIXED_RANGE may be necessary when running DevStack
 # in an OpenStack cloud that uses either of these address ranges internally.
 FLOATING_RANGE=${FLOATING_RANGE:-172.24.4.224/28}
 FIXED_RANGE=${FIXED_RANGE:-10.0.0.0/24}
 FIXED_NETWORK_SIZE=${FIXED_NETWORK_SIZE:-256}
 NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
 
 # Find the interface used for the default route
 HOST_IP_IFACE=${HOST_IP_IFACE:-$(ip route | sed -n '/^default/{ s/.*dev \(\w\+\)\s\+.*/\1/; p; }')}
 # Search for an IP unless an explicit is set by ``HOST_IP`` environment variable
 if [ -z "$HOST_IP" -o "$HOST_IP" == "dhcp" ]; then
     HOST_IP=""
     HOST_IPS=`LC_ALL=C ip -f inet addr show ${HOST_IP_IFACE} | awk '/inet/ {split($2,parts,"/");  print parts[1]}'`
     for IP in $HOST_IPS; do
         # Attempt to filter out IP addresses that are part of the fixed and
         # floating range. Note that this method only works if the ``netaddr``
         # python library is installed. If it is not installed, an error
         # will be printed and the first IP from the interface will be used.
         # If that is not correct set ``HOST_IP`` in ``localrc`` to the correct
         # address.
         if ! (address_in_net $IP $FIXED_RANGE || address_in_net $IP $FLOATING_RANGE); then
             HOST_IP=$IP
             break;
         fi
     done
     if [ "$HOST_IP" == "" ]; then
         echo "Could not determine host ip address."
         echo "Either localrc specified dhcp on ${HOST_IP_IFACE} or defaulted"
         exit 1
     fi
 fi
 
 # Allow the use of an alternate hostname (such as localhost/127.0.0.1) for service endpoints.
 SERVICE_HOST=${SERVICE_HOST:-$HOST_IP}
 
 # Configure services to use syslog instead of writing to individual log files
 SYSLOG=`trueorfalse False $SYSLOG`
 SYSLOG_HOST=${SYSLOG_HOST:-$HOST_IP}
 SYSLOG_PORT=${SYSLOG_PORT:-516}
 
 # Use color for logging output (only available if syslog is not used)
 LOG_COLOR=`trueorfalse True $LOG_COLOR`
 
 # Service startup timeout
 SERVICE_TIMEOUT=${SERVICE_TIMEOUT:-60}
 
 
4a43b7bd
 # Configure Projects
 # ==================
67787e6b
 
 # Get project function libraries
d81a0274
 source $TOP_DIR/lib/keystone
73f6f25b
 source $TOP_DIR/lib/glance
bf67c19c
 source $TOP_DIR/lib/nova
67787e6b
 source $TOP_DIR/lib/cinder
5bf7d5cc
 source $TOP_DIR/lib/n-vol
93361643
 source $TOP_DIR/lib/ceilometer
bfdad75e
 source $TOP_DIR/lib/heat
d6767d0d
 source $TOP_DIR/lib/quantum
67787e6b
 
4a43b7bd
 # Set the destination directories for OpenStack projects
ca85b799
 HORIZON_DIR=$DEST/horizon
77a4e3a0
 OPENSTACKCLIENT_DIR=$DEST/python-openstackclient
ba23cc73
 NOVNC_DIR=$DEST/noVNC
28fa4e8d
 SWIFT_DIR=$DEST/swift
42b1aa9c
 SWIFT3_DIR=$DEST/swift3
fda9df87
 SWIFTCLIENT_DIR=$DEST/python-swiftclient
6c753fc1
 QUANTUM_DIR=$DEST/neutron
 QUANTUM_CLIENT_DIR=$DEST/python-neutronclient
1bfa3d53
 
 # Default Quantum Plugin
 Q_PLUGIN=${Q_PLUGIN:-openvswitch}
f1f3a8fb
 # Default Quantum Port
 Q_PORT=${Q_PORT:-9696}
 # Default Quantum Host
 Q_HOST=${Q_HOST:-localhost}
9313dfac
 # Which Quantum API nova should use
 # Default admin username
 Q_ADMIN_USERNAME=${Q_ADMIN_USERNAME:-quantum}
 # Default auth strategy
 Q_AUTH_STRATEGY=${Q_AUTH_STRATEGY:-keystone}
ea23e686
 # Use namespace or not
 Q_USE_NAMESPACE=${Q_USE_NAMESPACE:-True}
cbeeccbb
 Q_USE_ROOTWRAP=${Q_USE_ROOTWRAP=:-True}
d6767d0d
 # Meta data IP
c8dc1f36
 Q_META_DATA_IP=${Q_META_DATA_IP:-$HOST_IP}
a841644e
 
4a43b7bd
 # Name of the LVM volume group to use/create for iscsi volumes
67787e6b
 VOLUME_GROUP=${VOLUME_GROUP:-stack-volumes}
2229a6e3
 VOLUME_NAME_PREFIX=${VOLUME_NAME_PREFIX:-volume-}
55458455
 INSTANCE_NAME_PREFIX=${INSTANCE_NAME_PREFIX:-instance-}
d02b7b7b
 
7a549f40
 # Generic helper to configure passwords
 function read_password {
7903b795
     XTRACE=$(set +o | grep xtrace)
7a549f40
     set +o xtrace
     var=$1; msg=$2
     pw=${!var}
 
b4db2254
     localrc=$TOP_DIR/localrc
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
 
9b353671
         # Presumably if we got this far it can only be that our localrc is missing
7a549f40
         # the required password.  Prompt user for a password and write to localrc.
b4db2254
         echo ''
         echo '################################################################################'
         echo $msg
         echo '################################################################################'
4e6a2b71
         echo "This value will be written to your localrc file so you don't have to enter it "
         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
             pw=`openssl rand -hex 10`
7a549f40
         fi
b4db2254
         eval "$var=$pw"
         echo "$var=$pw" >> $localrc
7a549f40
     fi
7903b795
     $XTRACE
7a549f40
 }
 
13dc5ccd
 
782b9917
 # Nova Network Configuration
 # --------------------------
 
df0972c1
 # FIXME: more documentation about why these are important options.  Also
 # we should make sure we use the same variable names as the option names.
5372f433
 
8e2cffdf
 if [ "$VIRT_DRIVER" = 'xenserver' ]; then
     PUBLIC_INTERFACE_DEFAULT=eth3
4a43b7bd
     # Allow ``build_domU.sh`` to specify the flat network bridge via kernel args
0af143b3
     FLAT_NETWORK_BRIDGE_DEFAULT=$(grep -o 'flat_network_bridge=[[:alnum:]]*' /proc/cmdline | cut -d= -f 2 | sort -u)
8e2cffdf
     GUEST_INTERFACE_DEFAULT=eth1
 else
     PUBLIC_INTERFACE_DEFAULT=br100
     FLAT_NETWORK_BRIDGE_DEFAULT=br100
     GUEST_INTERFACE_DEFAULT=eth0
 fi
 
 PUBLIC_INTERFACE=${PUBLIC_INTERFACE:-$PUBLIC_INTERFACE_DEFAULT}
a72f7ad3
 NET_MAN=${NET_MAN:-FlatDHCPManager}
1097c7ca
 EC2_DMZ_HOST=${EC2_DMZ_HOST:-$SERVICE_HOST}
8e2cffdf
 FLAT_NETWORK_BRIDGE=${FLAT_NETWORK_BRIDGE:-$FLAT_NETWORK_BRIDGE_DEFAULT}
 VLAN_INTERFACE=${VLAN_INTERFACE:-$GUEST_INTERFACE_DEFAULT}
cbe98d56
 
696ad331
 # Test floating pool and range are used for testing.  They are defined
 # here until the admin APIs can replace nova-manage
 TEST_FLOATING_POOL=${TEST_FLOATING_POOL:-test}
 TEST_FLOATING_RANGE=${TEST_FLOATING_RANGE:-192.168.253.0/29}
 
4a43b7bd
 # ``MULTI_HOST`` is a mode where each compute node runs its own network node.  This
cbe98d56
 # allows network operations and routing for a VM to occur on the server that is
 # running the VM - removing a SPOF and bandwidth bottleneck.
7d13f309
 MULTI_HOST=`trueorfalse False $MULTI_HOST`
30f68e96
 
4a43b7bd
 # If you are using the FlatDHCP network mode on multiple hosts, set the
 # ``FLAT_INTERFACE`` variable but make sure that the interface doesn't already
 # have an IP or you risk breaking things.
5372f433
 #
9b353671
 # **DHCP Warning**:  If your flat interface device uses DHCP, there will be a
 # hiccup while the network is moved from the flat interface to the flat network
 # bridge.  This will happen when you launch your first instance.  Upon launch
4a43b7bd
 # you will lose all connectivity to the node, and the VM launch will probably
5372f433
 # fail.
9b353671
 #
 # If you are running on a single node and don't need to access the VMs from
3a19d18e
 # devices other than that node, you can set FLAT_INTERFACE=
 # This will stop nova from bridging any interfaces into FLAT_NETWORK_BRIDGE.
 FLAT_INTERFACE=${FLAT_INTERFACE-$GUEST_INTERFACE_DEFAULT}
ba23cc73
 
cbe98d56
 ## FIXME(ja): should/can we check that FLAT_INTERFACE is sane?
 
1bfa3d53
 # Using Quantum networking:
 #
6e77163b
 # Make sure that quantum is enabled in ENABLED_SERVICES.  If you want
 # to run Quantum on this host, make sure that q-svc is also in
1bfa3d53
 # ENABLED_SERVICES.
 #
6e77163b
 # If you're planning to use the Quantum openvswitch plugin, set
 # Q_PLUGIN to "openvswitch" and make sure the q-agt service is enabled
 # in ENABLED_SERVICES.  If you're planning to use the Quantum
 # linuxbridge plugin, set Q_PLUGIN to "linuxbridge" and make sure the
 # q-agt service is enabled in ENABLED_SERVICES.
 #
 # See "Quantum Network Configuration" below for additional variables
 # that must be set in localrc for connectivity across hosts with
 # Quantum.
 #
1bfa3d53
 # With Quantum networking the NET_MAN variable is ignored.
 
4a43b7bd
 
4a221459
 # MySQL & (RabbitMQ or Qpid)
 # --------------------------
782b9917
 
ca85b799
 # We configure Nova, Horizon, Glance and Keystone to use MySQL as their
782b9917
 # database server.  While they share a single server, each has their own
 # database and tables.
 
9b353671
 # By default this script will install and configure MySQL.  If you want to
782b9917
 # use an existing server, you can pass in the user/password/host parameters.
7a549f40
 # You will need to send the same ``MYSQL_PASSWORD`` to every host if you are doing
df0972c1
 # a multi-node DevStack installation.
a50a3461
 MYSQL_HOST=${MYSQL_HOST:-localhost}
320412b2
 MYSQL_USER=${MYSQL_USER:-root}
7a549f40
 read_password MYSQL_PASSWORD "ENTER A PASSWORD TO USE FOR MYSQL."
782b9917
 
4a43b7bd
 # NOTE: Don't specify ``/db`` in this string so we can use it for multiple services
7a549f40
 BASE_SQL_CONN=${BASE_SQL_CONN:-mysql://$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST}
a841644e
 
 # Rabbit connection info
4a221459
 if is_service_enabled rabbit; then
     RABBIT_HOST=${RABBIT_HOST:-localhost}
     read_password RABBIT_PASSWORD "ENTER A PASSWORD TO USE FOR RABBIT."
 fi
ba23cc73
 
4a43b7bd
 
7d28a0e1
 # Swift
28fa4e8d
 # -----
7d28a0e1
 
3d9c5d5e
 # TODO: add logging to different location.
b93478f6
 
4a43b7bd
 # Set ``SWIFT_DATA_DIR`` to the location of swift drives and objects.
 # Default is the common DevStack data directory.
8b2a15c8
 SWIFT_DATA_DIR=${SWIFT_DATA_DIR:-${DATA_DIR}/swift}
28fa4e8d
 
4a43b7bd
 # Set ``SWIFT_CONFIG_DIR`` to the location of the configuration files.
 # Default is ``/etc/swift``.
1e51c115
 SWIFT_CONFIG_DIR=${SWIFT_CONFIG_DIR:-/etc/swift}
28fa4e8d
 
7d28a0e1
 # DevStack will create a loop-back disk formatted as XFS to store the
4a43b7bd
 # swift data. Set ``SWIFT_LOOPBACK_DISK_SIZE`` to the disk size in bytes.
 # Default is 1 gigabyte.
28fa4e8d
 SWIFT_LOOPBACK_DISK_SIZE=${SWIFT_LOOPBACK_DISK_SIZE:-1000000}
7a549f40
 
3d9c5d5e
 # The ring uses a configurable number of bits from a path’s MD5 hash as
 # a partition index that designates a device. The number of bits kept
 # from the hash is known as the partition power, and 2 to the partition
 # power indicates the partition count. Partitioning the full MD5 hash
 # ring allows other parts of the cluster to work in batches of items at
 # once which ends up either more efficient or at least less complex than
 # working with each item separately or the entire cluster all at once.
 # By default we define 9 for the partition count (which mean 512).
a2118984
 SWIFT_PARTITION_POWER_SIZE=${SWIFT_PARTITION_POWER_SIZE:-9}
 
4a43b7bd
 # Set ``SWIFT_REPLICAS`` to configure how many replicas are to be
a95efab1
 # configured for your Swift cluster.  By default the three replicas would need a
 # bit of IO and Memory on a VM you may want to lower that to 1 if you want to do
 # only some quick testing.
 SWIFT_REPLICAS=${SWIFT_REPLICAS:-3}
 
a6651e94
 if is_service_enabled swift; then
6ae9ea59
     # If we are using swift3, we can default the s3 port to swift instead
77b0e1d8
     # of nova-objectstore
6ae9ea59
     if is_service_enabled swift3;then
         S3_SERVICE_PORT=${S3_SERVICE_PORT:-8080}
     fi
77b0e1d8
     # We only ask for Swift Hash if we have enabled swift service.
b2857e4d
     # SWIFT_HASH is a random unique string for a swift cluster that
     # can never change.
     read_password SWIFT_HASH "ENTER A RANDOM SWIFT HASH."
 fi
5f039326
 
77b0e1d8
 # Set default port for nova-objectstore
 S3_SERVICE_PORT=${S3_SERVICE_PORT:-3333}
df0972c1
 
7d28a0e1
 
782b9917
 # Keystone
 # --------
 
4a43b7bd
 # The ``SERVICE_TOKEN`` is used to bootstrap the Keystone database.  It is
 # just a string and is not a 'real' Keystone token.
7a549f40
 read_password SERVICE_TOKEN "ENTER A SERVICE_TOKEN TO USE FOR THE SERVICE ADMIN TOKEN."
b3288381
 # Services authenticate to Identity with servicename/SERVICE_PASSWORD
 read_password SERVICE_PASSWORD "ENTER A SERVICE_PASSWORD TO USE FOR THE SERVICE AUTHENTICATION."
ca85b799
 # 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)."
b96871e4
 
b3288381
 # Set the tenant for service accounts in Keystone
 SERVICE_TENANT_NAME=${SERVICE_TENANT_NAME:-service}
 
6577b468
 
df0972c1
 
9bb84f0a
 # Horizon
 # -------
 
 # Allow overriding the default Apache user and group, default both to
 # current user.
 APACHE_USER=${APACHE_USER:-$USER}
 APACHE_GROUP=${APACHE_GROUP:-$APACHE_USER}
 
df0972c1
 
471de7a3
 # Log files
 # ---------
 
7879a3ce
 # 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
 }
 
7903b795
 # Echo text to the log file, summary log file and stdout
 # echo_summary "something to say"
 function echo_summary() {
7879a3ce
     if [[ -t 3 && "$VERBOSE" != "True" ]]; then
         kill >/dev/null 2>&1 $LAST_SPINNER_PID
         if [ ! -z "$LAST_SPINNER_PID" ]; then
             printf "\b\b\bdone\n" >&3
         fi
         echo -n $@ >&6
         spinner &
         LAST_SPINNER_PID=$!
     else
         echo $@ >&6
     fi
7903b795
 }
 
 # Echo text only to stdout, no log files
 # echo_nolog "something not for the logs"
 function echo_nolog() {
     echo $@ >&3
 }
 
4a43b7bd
 # 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
d966ed23
 if [[ -n "$LOGFILE" || -n "$SCREEN_LOGDIR" ]]; then
     LOGDAYS=${LOGDAYS:-7}
     TIMESTAMP_FORMAT=${TIMESTAMP_FORMAT:-"%F-%H%M%S"}
     CURRENT_LOG_TIME=$(date "+$TIMESTAMP_FORMAT")
 fi
 
471de7a3
 if [[ -n "$LOGFILE" ]]; then
4a43b7bd
     # First clean up old log files.  Use the user-specified ``LOGFILE``
471de7a3
     # as the template to search for, appending '.*' to match the date
     # we added on earlier runs.
     LOGDIR=$(dirname "$LOGFILE")
     LOGNAME=$(basename "$LOGFILE")
fff6fec4
     mkdir -p $LOGDIR
471de7a3
     find $LOGDIR -maxdepth 1 -name $LOGNAME.\* -mtime +$LOGDAYS -exec rm {} \;
d966ed23
     LOGFILE=$LOGFILE.${CURRENT_LOG_TIME}
7903b795
     SUMFILE=$LOGFILE.${CURRENT_LOG_TIME}.summary
 
     # Redirect output according to config
     # Copy stdout to fd 3
     exec 3>&1
     if [[ "$VERBOSE" == "True" ]]; then
         # Redirect stdout/stderr to tee to write the log file
         exec 1> >( tee "${LOGFILE}" ) 2>&1
         # Set up a second fd for output
         exec 6> >( tee "${SUMFILE}" )
     else
         # Set fd 1 and 2 to primary logfile
         exec 1> "${LOGFILE}" 2>&1
         # Set fd 6 to summary logfile and stdout
         exec 6> >( tee "${SUMFILE}" /dev/fd/3 )
     fi
 
     echo_summary "stack.sh log $LOGFILE"
471de7a3
     # Specified logfile name always links to the most recent log
     ln -sf $LOGFILE $LOGDIR/$LOGNAME
7903b795
     ln -sf $SUMFILE $LOGDIR/$LOGNAME.summary
 else
     # Set up output redirection without log files
     # Copy stdout to fd 3
     exec 3>&1
efdf3ffc
     if [[ "$VERBOSE" != "True" ]]; then
7903b795
         # Throw away stdout and stderr
         exec 1>/dev/null 2>&1
     fi
     # Always send summary fd to original stdout
     exec 6>&3
471de7a3
 fi
 
d966ed23
 # Set up logging of screen windows
4a43b7bd
 # Set ``SCREEN_LOGDIR`` to turn on logging of screen windows to the
 # directory specified in ``SCREEN_LOGDIR``, we will log to the the file
 # ``screen-$SERVICE_NAME-$TIMESTAMP.log`` in that dir and have a link
 # ``screen-$SERVICE_NAME.log`` to the latest log file.
 # Logs are kept for as long specified in ``LOGDAYS``.
d966ed23
 if [[ -n "$SCREEN_LOGDIR" ]]; then
 
     # We make sure the directory is created.
     if [[ -d "$SCREEN_LOGDIR" ]]; then
         # We cleanup the old logs
         find $SCREEN_LOGDIR -maxdepth 1 -name screen-\*.log -mtime +$LOGDAYS -exec rm {} \;
     else
         mkdir -p $SCREEN_LOGDIR
     fi
 fi
 
4a43b7bd
 
 # Set Up Script Execution
 # -----------------------
 
7879a3ce
 # Kill background processes on exit
 trap clean EXIT
 clean() {
     local r=$?
     kill >/dev/null 2>&1 $(jobs -p)
     exit $r
 }
 
 
4a43b7bd
 # Exit on any errors so that errors don't compound
f9da5081
 trap failed ERR
 failed() {
     local r=$?
7879a3ce
     kill >/dev/null 2>&1 $(jobs -p)
f9da5081
     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
 
df0972c1
 
30f68e96
 # Install Packages
d74257d0
 # ================
7d28a0e1
 
4a43b7bd
 # OpenStack uses a fair number of other projects.
30f68e96
 
7d28a0e1
 # Install package requirements
7903b795
 echo_summary "Installing package prerequisites"
5218d451
 if [[ "$os_PACKAGE" = "deb" ]]; then
     install_package $(get_packages $FILES/apts)
 else
     install_package $(get_packages $FILES/rpms)
 fi
75a37653
 
47f02060
 if [[ $SYSLOG != "False" ]]; then
     install_package rsyslog-relp
 fi
 
 if is_service_enabled rabbit; then
     # Install rabbitmq-server
     # the temp file is necessary due to LP: #878600
     tfile=$(mktemp)
     install_package rabbitmq-server > "$tfile" 2>&1
     cat "$tfile"
     rm -f "$tfile"
 elif is_service_enabled qpid; then
     if [[ "$os_PACKAGE" = "rpm" ]]; then
20df2a83
         install_package qpid-cpp-server-daemon
47f02060
     else
         install_package qpidd
     fi
3bae7c2c
 elif is_service_enabled zeromq; then
     if [[ "$os_PACKAGE" = "rpm" ]]; then
         install_package zeromq python-zmq
     else
         install_package libzmq1 python-zmq
     fi
47f02060
 fi
 
 if is_service_enabled mysql; then
 
     if [[ "$os_PACKAGE" = "deb" ]]; then
         # 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_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
     fi
 
4a43b7bd
     # while ``.my.cnf`` is not needed for OpenStack to function, it is useful
47f02060
     # 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 mysql-server
     install_package mysql-server
 fi
 
 if is_service_enabled horizon; then
     if [[ "$os_PACKAGE" = "deb" ]]; then
         # Install apache2, which is NOPRIME'd
         install_package apache2 libapache2-mod-wsgi
     else
         sudo rm -f /etc/httpd/conf.d/000-*
         install_package httpd mod_wsgi
     fi
 fi
 
 if is_service_enabled q-agt; then
     if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
         # Install deps
         # FIXME add to files/apts/quantum, but don't install if not needed!
         if [[ "$os_PACKAGE" = "deb" ]]; then
             kernel_version=`cat /proc/version | cut -d " " -f3`
             install_package make fakeroot dkms openvswitch-switch openvswitch-datapath-dkms linux-headers-$kernel_version
         else
             ### FIXME(dtroyer): Find RPMs for OpenVSwitch
             echo "OpenVSwitch packages need to be located"
b782a2c0
             # Fedora does not started OVS by default
             restart_service openvswitch
47f02060
         fi
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
        install_package bridge-utils
     fi
 fi
 
 if is_service_enabled swift; then
     # Install memcached for swift.
     install_package memcached
 fi
 
 TRACK_DEPENDS=${TRACK_DEPENDS:-False}
 
 # Install python packages into a virtualenv so that we can track them
 if [[ $TRACK_DEPENDS = True ]] ; then
7903b795
     echo_summary "Installing Python packages into a virtualenv $DEST/.venv"
47f02060
     install_package python-virtualenv
 
     rm -rf $DEST/.venv
     virtualenv --system-site-packages $DEST/.venv
     source $DEST/.venv/bin/activate
     $DEST/.venv/bin/pip freeze > $DEST/requires-pre-pip
 fi
 
7d28a0e1
 # Install python requirements
7903b795
 echo_summary "Installing Python prerequisites"
d0b21e2d
 pip_install $(get_packages $FILES/pips | sort -u)
75a37653
 
4a43b7bd
 
 # Check Out Source
 # ----------------
 
7903b795
 echo_summary "Installing OpenStack project source"
 
e5efa312
 # Install clients libraries
d81a0274
 install_keystoneclient
73f6f25b
 install_glanceclient
e5efa312
 install_cinderclient
bf67c19c
 install_novaclient
e5efa312
 if is_service_enabled swift glance; then
     # storage service client and and Library
     git_clone $SWIFTCLIENT_REPO $SWIFTCLIENT_DIR $SWIFTCLIENT_BRANCH
     setup_develop $SWIFTCLIENT_DIR
 fi
 if is_service_enabled quantum nova; then
     git_clone $QUANTUM_CLIENT_REPO $QUANTUM_CLIENT_DIR $QUANTUM_CLIENT_BRANCH
     setup_develop $QUANTUM_CLIENT_DIR
 fi
7d28a0e1
 
 # Check out the client libs that are used most
77a4e3a0
 git_clone $OPENSTACKCLIENT_REPO $OPENSTACKCLIENT_DIR $OPENSTACKCLIENT_BRANCH
e5efa312
 setup_develop $OPENSTACKCLIENT_DIR
38df1228
 
 # glance, swift middleware and nova api needs keystone middleware
a6651e94
 if is_service_enabled key g-api n-api swift; then
38df1228
     # unified auth system (manages accounts/tokens)
d81a0274
     install_keystone
38df1228
 fi
a6651e94
 if is_service_enabled swift; then
e7ce24fc
     # storage service
     git_clone $SWIFT_REPO $SWIFT_DIR $SWIFT_BRANCH
6ae9ea59
     if is_service_enabled swift3; then
         # swift3 middleware to provide S3 emulation to Swift
         git_clone $SWIFT3_REPO $SWIFT3_DIR $SWIFT3_BRANCH
     fi
e7ce24fc
 fi
a6651e94
 if is_service_enabled g-api n-api; then
e7ce24fc
     # image catalog service
73f6f25b
     install_glance
e7ce24fc
 fi
bf67c19c
 if is_service_enabled nova; then
     # compute service
     install_nova
 fi
a6651e94
 if is_service_enabled n-novnc; then
e7ce24fc
     # a websockets/html5 or flash powered VNC console for vm instances
     git_clone $NOVNC_REPO $NOVNC_DIR $NOVNC_BRANCH
 fi
a6651e94
 if is_service_enabled horizon; then
e7ce24fc
     # django powered web control panel for openstack
     git_clone $HORIZON_REPO $HORIZON_DIR $HORIZON_BRANCH $HORIZON_TAG
 fi
5440ac0e
 if is_service_enabled quantum; then
e7ce24fc
     # quantum
     git_clone $QUANTUM_REPO $QUANTUM_DIR $QUANTUM_BRANCH
1e98bdc5
 fi
bfdad75e
 if is_service_enabled heat; then
     install_heat
 fi
67787e6b
 if is_service_enabled cinder; then
     install_cinder
 fi
93361643
 if is_service_enabled ceilometer; then
     install_ceilometer
 fi
64a90660
 
4a43b7bd
 
30f68e96
 # Initialization
d74257d0
 # ==============
30f68e96
 
7903b795
 echo_summary "Configuring OpenStack projects"
 
7d28a0e1
 # Set up our checkouts so they are installed into python path
d74257d0
 # allowing ``import nova`` or ``import glance.client``
a6651e94
 if is_service_enabled key g-api n-api swift; then
d81a0274
     configure_keystone
e7ce24fc
 fi
a6651e94
 if is_service_enabled swift; then
bbafb1b5
     setup_develop $SWIFT_DIR
3b73df76
 fi
 if is_service_enabled swift3; then
bbafb1b5
     setup_develop $SWIFT3_DIR
e7ce24fc
 fi
a6651e94
 if is_service_enabled g-api n-api; then
73f6f25b
     configure_glance
a34961b0
 
e5efa312
     # Do this again _after_ glance is installed to overwrite
     # the old binary shipped in glance
     setup_develop $GLANCECLIENT_DIR
 fi
a34961b0
 
bf67c19c
 if is_service_enabled nova; then
     configure_nova
 fi
a6651e94
 if is_service_enabled horizon; then
bbafb1b5
     setup_develop $HORIZON_DIR
1e98bdc5
 fi
0007f3a6
 if is_service_enabled quantum; then
bbafb1b5
     setup_develop $QUANTUM_DIR
5440ac0e
 fi
bfdad75e
 if is_service_enabled heat; then
     configure_heat
 fi
67787e6b
 if is_service_enabled cinder; then
     configure_cinder
 fi
75a37653
 
47f02060
 if [[ $TRACK_DEPENDS = True ]] ; then
     $DEST/.venv/bin/pip freeze > $DEST/requires-post-pip
     if ! diff -Nru $DEST/requires-pre-pip $DEST/requires-post-pip > $DEST/requires.diff ; then
         cat $DEST/requires.diff
     fi
     echo "Ran stack.sh in depend tracking mode, bailing out now"
     exit 0
 fi
df0972c1
 
4a43b7bd
 
ff603ef5
 # Syslog
df0972c1
 # ------
ff603ef5
 
 if [[ $SYSLOG != "False" ]]; then
     if [[ "$SYSLOG_HOST" = "$HOST_IP" ]]; then
         # Configure the master host to receive
         cat <<EOF >/tmp/90-stack-m.conf
 \$ModLoad imrelp
 \$InputRELPServerRun $SYSLOG_PORT
 EOF
         sudo mv /tmp/90-stack-m.conf /etc/rsyslog.d
     else
         # Set rsyslog to send to remote host
         cat <<EOF >/tmp/90-stack-s.conf
 *.*		:omrelp:$SYSLOG_HOST:$SYSLOG_PORT
 EOF
         sudo mv /tmp/90-stack-s.conf /etc/rsyslog.d
     fi
7903b795
     echo_summary "Starting rsyslog"
13dc5ccd
     restart_service rsyslog
ff603ef5
 fi
 
df0972c1
 
e5d92380
 # Finalize queue installation
 # ----------------------------
cbe98d56
 
a6651e94
 if is_service_enabled rabbit; then
47f02060
     # Start rabbitmq-server
7903b795
     echo_summary "Starting RabbitMQ"
5218d451
     if [[ "$os_PACKAGE" = "rpm" ]]; then
         # RPM doesn't start the service
         restart_service rabbitmq-server
     fi
53ed387d
     # change the rabbit password since the default is "guest"
     sudo rabbitmqctl change_password guest $RABBIT_PASSWORD
4a221459
 elif is_service_enabled qpid; then
7903b795
     echo_summary "Starting qpid"
47f02060
     restart_service qpidd
a09ae2ff
 fi
ba23cc73
 
df0972c1
 
24859060
 # Mysql
df0972c1
 # -----
cbe98d56
 
47f02060
 if is_service_enabled mysql; then
7903b795
     echo_summary "Configuring and starting MySQL"
d5d5b680
 
7e3c3f8f
     if [[ "$os_PACKAGE" = "deb" ]]; then
         MY_CONF=/etc/mysql/my.cnf
         MYSQL=mysql
     else
         MY_CONF=/etc/my.cnf
         MYSQL=mysqld
     fi
 
4a43b7bd
     # Start mysql-server
5218d451
     if [[ "$os_PACKAGE" = "rpm" ]]; then
         # RPM doesn't start the service
7e3c3f8f
         start_service $MYSQL
5218d451
         # Set the root password - only works the first time
         sudo mysqladmin -u root password $MYSQL_PASSWORD || true
     fi
24859060
     # Update the DB to give user ‘$MYSQL_USER’@’%’ full control of the all databases:
92e81992
     sudo mysql -uroot -p$MYSQL_PASSWORD -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%' identified by '$MYSQL_PASSWORD';"
24859060
 
7e3c3f8f
     # Now update ``my.cnf`` for some local needs and restart the mysql service
588f4069
 
     # Change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0)
     sudo sed -i '/^bind-address/s/127.0.0.1/0.0.0.0/g' $MY_CONF
 
     # Set default db type to InnoDB
4556b5d2
     if sudo grep -q "default-storage-engine" $MY_CONF; then
588f4069
         # Change it
         sudo bash -c "source $TOP_DIR/functions; iniset $MY_CONF mysqld default-storage-engine InnoDB"
     else
         # Add it
         sudo sed -i -e "/^\[mysqld\]/ a \
 default-storage-engine = InnoDB" $MY_CONF
     fi
 
5218d451
     restart_service $MYSQL
24859060
 fi
 
0a7a41eb
 if [ -z "$SCREEN_HARDSTATUS" ]; then
     SCREEN_HARDSTATUS='%{= .} %-Lw%{= .}%> %n%f %t*%{= .}%+Lw%< %-=%{g}(%{d}%H/%l%{g})'
 fi
 
7d28a0e1
 # Create a new named screen to run processes in
15733351
 screen -d -m -S $SCREEN_NAME -t shell -s /bin/bash
60df29a2
 sleep 1
e5d92380
 # Set a reasonable status bar
15733351
 screen -r $SCREEN_NAME -X hardstatus alwayslastline "$SCREEN_HARDSTATUS"
24859060
 
7d28a0e1
 
d81a0274
 # Keystone
 # --------
 
 if is_service_enabled key; then
7903b795
     echo_summary "Starting Keystone"
d81a0274
     configure_keystone
     init_keystone
     start_keystone
     echo "Waiting for keystone to start..."
     if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= curl -s $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$KEYSTONE_API_PORT/v2.0/ >/dev/null; do sleep 1; done"; then
       echo "keystone did not start"
       exit 1
     fi
 
     # ``keystone_data.sh`` creates services, admin and demo users, and roles.
     SERVICE_ENDPOINT=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v2.0
 
     ADMIN_PASSWORD=$ADMIN_PASSWORD SERVICE_TENANT_NAME=$SERVICE_TENANT_NAME SERVICE_PASSWORD=$SERVICE_PASSWORD \
     SERVICE_TOKEN=$SERVICE_TOKEN SERVICE_ENDPOINT=$SERVICE_ENDPOINT SERVICE_HOST=$SERVICE_HOST \
     S3_SERVICE_PORT=$S3_SERVICE_PORT KEYSTONE_CATALOG_BACKEND=$KEYSTONE_CATALOG_BACKEND \
e2790210
     DEVSTACK_DIR=$TOP_DIR ENABLED_SERVICES=$ENABLED_SERVICES HEAT_API_CFN_PORT=$HEAT_API_CFN_PORT \
d81a0274
         bash -x $FILES/keystone_data.sh
 
     # Set up auth creds now that keystone is bootstrapped
     export OS_AUTH_URL=$SERVICE_ENDPOINT
     export OS_TENANT_NAME=admin
     export OS_USERNAME=admin
     export OS_PASSWORD=$ADMIN_PASSWORD
 fi
 
 
ca85b799
 # Horizon
df0972c1
 # -------
cbe98d56
 
7d28a0e1
 # Set up the django horizon application to serve via apache/wsgi
75a37653
 
a6651e94
 if is_service_enabled horizon; then
7903b795
     echo_summary "Configuring and starting Horizon"
24859060
 
a575d500
     # Remove stale session database.
f1a11adf
     rm -f $HORIZON_DIR/openstack_dashboard/local/dashboard_openstack.sqlite3
40a37006
 
ca85b799
     # ``local_settings.py`` is used to override horizon default settings.
f1a11adf
     local_settings=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
9c7c9083
     cp $FILES/horizon_settings.py $local_settings
 
ca85b799
     # Initialize the horizon database (it stores sessions and notices shown to
51fb22ef
     # users).  The user system is external (keystone).
f1a11adf
     cd $HORIZON_DIR
8156062d
     python manage.py syncdb --noinput
5218d451
     cd $TOP_DIR
70dc5e05
 
7d28a0e1
     # Create an empty directory that apache uses as docroot
ca85b799
     sudo mkdir -p $HORIZON_DIR/.blackhole
70dc5e05
 
5218d451
     if [[ "$os_PACKAGE" = "deb" ]]; then
         APACHE_NAME=apache2
         APACHE_CONF=sites-available/horizon
         # Clean up the old config name
         sudo rm -f /etc/apache2/sites-enabled/000-default
         # Be a good citizen and use the distro tools here
         sudo touch /etc/$APACHE_NAME/$APACHE_CONF
         sudo a2ensite horizon
     else
         # Install httpd, which is NOPRIME'd
         APACHE_NAME=httpd
         APACHE_CONF=conf.d/horizon.conf
         sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
     fi
4a43b7bd
 
     # Configure apache to run horizon
5218d451
     sudo sh -c "sed -e \"
9bb84f0a
         s,%USER%,$APACHE_USER,g;
         s,%GROUP%,$APACHE_GROUP,g;
         s,%HORIZON_DIR%,$HORIZON_DIR,g;
5218d451
         s,%APACHE_NAME%,$APACHE_NAME,g;
         s,%DEST%,$DEST,g;
     \" $FILES/apache-horizon.template >/etc/$APACHE_NAME/$APACHE_CONF"
4a43b7bd
 
5218d451
     restart_service $APACHE_NAME
70dc5e05
 fi
1c1d1505
 
18d350da
 
d74257d0
 # Glance
 # ------
 
a6651e94
 if is_service_enabled g-reg; then
7903b795
     echo_summary "Configuring Glance"
 
73f6f25b
     init_glance
9bab2597
 
ee76d26f
     # Store the images in swift if enabled.
     if is_service_enabled swift; then
         iniset $GLANCE_API_CONF DEFAULT default_store swift
         iniset $GLANCE_API_CONF DEFAULT swift_store_auth_address $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/
         iniset $GLANCE_API_CONF DEFAULT swift_store_user $SERVICE_TENANT_NAME:glance
         iniset $GLANCE_API_CONF DEFAULT swift_store_key $SERVICE_PASSWORD
         iniset $GLANCE_API_CONF DEFAULT swift_store_create_container_on_put True
     fi
70dc5e05
 fi
75a37653
 
7d28a0e1
 
 # Quantum
60df29a2
 # -------
7d28a0e1
 
4dc53aa7
 if is_service_enabled quantum; then
7903b795
     echo_summary "Configuring Quantum"
6e77163b
     #
     # Quantum Network Configuration
     #
     # The following variables control the Quantum openvswitch and
     # linuxbridge plugins' allocation of tenant networks and
     # availability of provider networks. If these are not configured
     # in localrc, tenant networks will be local to the host (with no
     # remote connectivity), and no physical resources will be
     # available for the allocation of provider networks.
 
     # To use GRE tunnels for tenant networks, set to True in
     # localrc. GRE tunnels are only supported by the openvswitch
     # plugin, and currently only on Ubuntu.
     ENABLE_TENANT_TUNNELS=${ENABLE_TENANT_TUNNELS:-False}
 
     # If using GRE tunnels for tenant networks, specify the range of
     # tunnel IDs from which tenant networks are allocated. Can be
     # overriden in localrc in necesssary.
     TENANT_TUNNEL_RANGES=${TENANT_TUNNEL_RANGE:-1:1000}
 
     # To use VLANs for tenant networks, set to True in localrc. VLANs
     # are supported by the openvswitch and linuxbridge plugins, each
     # requiring additional configuration described below.
     ENABLE_TENANT_VLANS=${ENABLE_TENANT_VLANS:-False}
 
     # If using VLANs for tenant networks, set in localrc to specify
     # the range of VLAN VIDs from which tenant networks are
     # allocated. An external network switch must be configured to
     # trunk these VLANs between hosts for multi-host connectivity.
     #
     # Example: TENANT_VLAN_RANGE=1000:1999
     TENANT_VLAN_RANGE=${TENANT_VLAN_RANGE:-}
 
     # If using VLANs for tenant networks, or if using flat or VLAN
     # provider networks, set in localrc to the name of the physical
     # network, and also configure OVS_PHYSICAL_BRIDGE for the
     # openvswitch agent or LB_PHYSICAL_INTERFACE for the linuxbridge
     # agent, as described below.
     #
     # Example: PHYSICAL_NETWORK=default
     PHYSICAL_NETWORK=${PHYSICAL_NETWORK:-}
 
     # With the openvswitch plugin, if using VLANs for tenant networks,
     # or if using flat or VLAN provider networks, set in localrc to
     # the name of the OVS bridge to use for the physical network. The
     # bridge will be created if it does not already exist, but a
     # physical interface must be manually added to the bridge as a
     # port for external connectivity.
     #
     # Example: OVS_PHYSICAL_BRIDGE=br-eth1
     OVS_PHYSICAL_BRIDGE=${OVS_PHYSICAL_BRIDGE:-}
 
     # With the linuxbridge plugin, if using VLANs for tenant networks,
     # or if using flat or VLAN provider networks, set in localrc to
     # the name of the network interface to use for the physical
     # network.
     #
     # Example: LB_PHYSICAL_INTERFACE=eth1
     LB_PHYSICAL_INTERFACE=${LB_PHYSICAL_INTERFACE:-}
 
fddd8f8f
     # With the openvswitch plugin, set to True in localrc to enable
     # provider GRE tunnels when ENABLE_TENANT_TUNNELS is False.
     #
     # Example: OVS_ENABLE_TUNNELING=True
     OVS_ENABLE_TUNNELING=${OVS_ENABLE_TUNNELING:-$ENABLE_TENANT_TUNNELS}
 
4a43b7bd
     # Put config files in ``/etc/quantum`` for everyone to find
0007f3a6
     if [[ ! -d /etc/quantum ]]; then
         sudo mkdir -p /etc/quantum
     fi
     sudo chown `whoami` /etc/quantum
 
     if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
         Q_PLUGIN_CONF_PATH=etc/quantum/plugins/openvswitch
         Q_PLUGIN_CONF_FILENAME=ovs_quantum_plugin.ini
         Q_DB_NAME="ovs_quantum"
37dda8d7
         Q_PLUGIN_CLASS="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
0007f3a6
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
         Q_PLUGIN_CONF_PATH=etc/quantum/plugins/linuxbridge
         Q_PLUGIN_CONF_FILENAME=linuxbridge_conf.ini
         Q_DB_NAME="quantum_linux_bridge"
37dda8d7
         Q_PLUGIN_CLASS="quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2"
0007f3a6
     else
         echo "Unknown Quantum plugin '$Q_PLUGIN'.. exiting"
         exit 1
     fi
 
4a43b7bd
     # If needed, move config file from ``$QUANTUM_DIR/etc/quantum`` to ``/etc/quantum``
0007f3a6
     mkdir -p /$Q_PLUGIN_CONF_PATH
     Q_PLUGIN_CONF_FILE=$Q_PLUGIN_CONF_PATH/$Q_PLUGIN_CONF_FILENAME
8301f147
     cp $QUANTUM_DIR/$Q_PLUGIN_CONF_FILE /$Q_PLUGIN_CONF_FILE
 
d6767d0d
     iniset /$Q_PLUGIN_CONF_FILE DATABASE sql_connection mysql:\/\/$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST\/$Q_DB_NAME?charset=utf8
0007f3a6
 
396a014b
     Q_CONF_FILE=/etc/quantum/quantum.conf
     cp $QUANTUM_DIR/etc/quantum.conf $Q_CONF_FILE
b782a2c0
     Q_RR_CONF_FILE=/etc/quantum/rootwrap.conf
cbeeccbb
     if [[ "$Q_USE_ROOTWRAP" == "False" ]]; then
         Q_RR_COMMAND="sudo"
     else
         Q_RR_COMMAND="sudo $QUANTUM_DIR/bin/quantum-rootwrap $Q_RR_CONF_FILE"
     fi
b782a2c0
     cp -p $QUANTUM_DIR/etc/rootwrap.conf $Q_RR_CONF_FILE
 
     # Copy over the config and filter bits
     Q_CONF_ROOTWRAP_D=/etc/quantum/rootwrap.d
     mkdir -p $Q_CONF_ROOTWRAP_D
     cp -pr $QUANTUM_DIR/etc/quantum/rootwrap.d/* $Q_CONF_ROOTWRAP_D/
4dc53aa7
 fi
0007f3a6
 
 # Quantum service (for controller node)
4dc53aa7
 if is_service_enabled q-svc; then
5f4b6de2
     Q_API_PASTE_FILE=/etc/quantum/api-paste.ini
4402d6e9
     Q_POLICY_FILE=/etc/quantum/policy.json
4dc53aa7
 
1a4166ca
     cp $QUANTUM_DIR/etc/api-paste.ini $Q_API_PASTE_FILE
     cp $QUANTUM_DIR/etc/policy.json $Q_POLICY_FILE
4402d6e9
 
0007f3a6
     if is_service_enabled mysql; then
             mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "DROP DATABASE IF EXISTS $Q_DB_NAME;"
             mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "CREATE DATABASE IF NOT EXISTS $Q_DB_NAME CHARACTER SET utf8;"
4dc53aa7
         else
             echo "mysql must be enabled in order to use the $Q_PLUGIN Quantum plugin."
             exit 1
8a5c93f6
     fi
0007f3a6
 
4402d6e9
     # Update either configuration file with plugin
1a4166ca
     iniset $Q_CONF_FILE DEFAULT core_plugin $Q_PLUGIN_CLASS
 
     iniset $Q_CONF_FILE DEFAULT auth_strategy $Q_AUTH_STRATEGY
d6767d0d
     quantum_setup_keystone $Q_API_PASTE_FILE filter:authtoken
6e77163b
 
     # Configure plugin
     if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
         if [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
             iniset /$Q_PLUGIN_CONF_FILE OVS tenant_network_type gre
             iniset /$Q_PLUGIN_CONF_FILE OVS tunnel_id_ranges $TENANT_TUNNEL_RANGES
         elif [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
             iniset /$Q_PLUGIN_CONF_FILE OVS tenant_network_type vlan
         else
             echo "WARNING - The openvswitch plugin is using local tenant networks, with no connectivity between hosts."
         fi
 
         # Override OVS_VLAN_RANGES and OVS_BRIDGE_MAPPINGS in localrc
         # for more complex physical network configurations.
         if [[ "$OVS_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
             OVS_VLAN_RANGES=$PHYSICAL_NETWORK
             if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
                 OVS_VLAN_RANGES=$OVS_VLAN_RANGES:$TENANT_VLAN_RANGE
             fi
         fi
         if [[ "$OVS_VLAN_RANGES" != "" ]]; then
             iniset /$Q_PLUGIN_CONF_FILE OVS network_vlan_ranges $OVS_VLAN_RANGES
         fi
fddd8f8f
 
         # Enable tunnel networks if selected
         if [[ $OVS_ENABLE_TUNNELING = "True" ]]; then
             iniset /$Q_PLUGIN_CONF_FILE OVS enable_tunneling True
         fi
6e77163b
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
         if [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
             iniset /$Q_PLUGIN_CONF_FILE VLANS tenant_network_type vlan
         else
             echo "WARNING - The linuxbridge plugin is using local tenant networks, with no connectivity between hosts."
         fi
 
         # Override LB_VLAN_RANGES and LB_INTERFACE_MAPPINGS in localrc
         # for more complex physical network configurations.
         if [[ "$LB_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
             LB_VLAN_RANGES=$PHYSICAL_NETWORK
             if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
                 LB_VLAN_RANGES=$LB_VLAN_RANGES:$TENANT_VLAN_RANGE
             fi
         fi
         if [[ "$LB_VLAN_RANGES" != "" ]]; then
             iniset /$Q_PLUGIN_CONF_FILE VLANS network_vlan_ranges $LB_VLAN_RANGES
         fi
     fi
60df29a2
 fi
 
 # Quantum agent (for compute nodes)
 if is_service_enabled q-agt; then
6e77163b
     # Configure agent for plugin
60df29a2
     if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
6e77163b
         # Setup integration bridge
60df29a2
         OVS_BRIDGE=${OVS_BRIDGE:-br-int}
d6767d0d
         quantum_setup_ovs_bridge $OVS_BRIDGE
6e77163b
 
         # Setup agent for tunneling
fddd8f8f
         if [[ "$OVS_ENABLE_TUNNELING" = "True" ]]; then
6e77163b
             # Verify tunnels are supported
             # REVISIT - also check kernel module support for GRE and patch ports
             OVS_VERSION=`ovs-vsctl --version | head -n 1 | awk '{print $4;}'`
             if [ $OVS_VERSION \< "1.4" ] && ! is_service_enabled q-svc ; then
                 echo "You are running OVS version $OVS_VERSION."
                 echo "OVS 1.4+ is required for tunneling between multiple hosts."
                 exit 1
             fi
fddd8f8f
             iniset /$Q_PLUGIN_CONF_FILE OVS enable_tunneling True
b26a27ae
             iniset /$Q_PLUGIN_CONF_FILE OVS local_ip $HOST_IP
         fi
6e77163b
 
         # Setup physical network bridge mappings.  Override
         # OVS_VLAN_RANGES and OVS_BRIDGE_MAPPINGS in localrc for more
         # complex physical network configurations.
         if [[ "$OVS_BRIDGE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
             OVS_BRIDGE_MAPPINGS=$PHYSICAL_NETWORK:$OVS_PHYSICAL_BRIDGE
 
b26a27ae
             # Configure bridge manually with physical interface as port for multi-node
6e77163b
             sudo ovs-vsctl --no-wait -- --may-exist add-br $OVS_PHYSICAL_BRIDGE
         fi
         if [[ "$OVS_BRIDGE_MAPPINGS" != "" ]]; then
             iniset /$Q_PLUGIN_CONF_FILE OVS bridge_mappings $OVS_BRIDGE_MAPPINGS
b26a27ae
         fi
cea6c512
         AGENT_BINARY="$QUANTUM_DIR/bin/quantum-openvswitch-agent"
4dc53aa7
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
6e77163b
         # Setup physical network interface mappings.  Override
         # LB_VLAN_RANGES and LB_INTERFACE_MAPPINGS in localrc for more
         # complex physical network configurations.
         if [[ "$LB_INTERFACE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$LB_PHYSICAL_INTERFACE" != "" ]]; then
             LB_INTERFACE_MAPPINGS=$PHYSICAL_NETWORK:$LB_PHYSICAL_INTERFACE
         fi
         if [[ "$LB_INTERFACE_MAPPINGS" != "" ]]; then
             iniset /$Q_PLUGIN_CONF_FILE LINUX_BRIDGE physical_interface_mappings $LB_INTERFACE_MAPPINGS
         fi
cea6c512
         AGENT_BINARY="$QUANTUM_DIR/bin/quantum-linuxbridge-agent"
60df29a2
     fi
cbeeccbb
     # Update config w/rootwrap
     iniset /$Q_PLUGIN_CONF_FILE AGENT root_helper "$Q_RR_COMMAND"
60df29a2
 fi
 
bff593d9
 # Quantum DHCP
 if is_service_enabled q-dhcp; then
     AGENT_DHCP_BINARY="$QUANTUM_DIR/bin/quantum-dhcp-agent"
 
     Q_DHCP_CONF_FILE=/etc/quantum/dhcp_agent.ini
 
396a014b
     cp $QUANTUM_DIR/etc/dhcp_agent.ini $Q_DHCP_CONF_FILE
bff593d9
 
     # Set verbose
     iniset $Q_DHCP_CONF_FILE DEFAULT verbose True
     # Set debug
     iniset $Q_DHCP_CONF_FILE DEFAULT debug True
ea23e686
     iniset $Q_DHCP_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
bff593d9
 
d6767d0d
     quantum_setup_keystone $Q_DHCP_CONF_FILE DEFAULT set_auth_url
bff593d9
 
b782a2c0
     # Update config w/rootwrap
cbeeccbb
     iniset $Q_DHCP_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND"
b782a2c0
 
bff593d9
     if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
         iniset $Q_DHCP_CONF_FILE DEFAULT interface_driver quantum.agent.linux.interface.OVSInterfaceDriver
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
         iniset $Q_DHCP_CONF_FILE DEFAULT interface_driver quantum.agent.linux.interface.BridgeInterfaceDriver
     fi
 fi
 
d6767d0d
 # Quantum L3
 if is_service_enabled q-l3; then
     AGENT_L3_BINARY="$QUANTUM_DIR/bin/quantum-l3-agent"
     PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
     Q_L3_CONF_FILE=/etc/quantum/l3_agent.ini
 
     cp $QUANTUM_DIR/etc/l3_agent.ini $Q_L3_CONF_FILE
 
     # Set verbose
     iniset $Q_L3_CONF_FILE DEFAULT verbose True
     # Set debug
     iniset $Q_L3_CONF_FILE DEFAULT debug True
 
     iniset $Q_L3_CONF_FILE DEFAULT metadata_ip $Q_META_DATA_IP
     iniset $Q_L3_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
 
cbeeccbb
     iniset $Q_L3_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND"
 
d6767d0d
     quantum_setup_keystone $Q_L3_CONF_FILE DEFAULT set_auth_url
     if [[ "$Q_PLUGIN" == "openvswitch" ]]; then
         iniset $Q_L3_CONF_FILE DEFAULT interface_driver quantum.agent.linux.interface.OVSInterfaceDriver
cea6c512
         iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge $PUBLIC_BRIDGE
d6767d0d
         # Set up external bridge
         # Create it if it does not exist
         sudo ovs-vsctl --no-wait -- --may-exist add-br $PUBLIC_BRIDGE
         # remove internal ports
         for PORT in `sudo ovs-vsctl --no-wait list-ports $PUBLIC_BRIDGE`; do
             TYPE=$(sudo ovs-vsctl get interface $PORT type)
             if [[ "$TYPE" == "internal" ]]; then
                 echo `sudo ip link delete $PORT` > /dev/null
                 sudo ovs-vsctl --no-wait del-port $bridge $PORT
             fi
         done
         # ensure no IP is configured on the public bridge
         sudo ip addr flush dev $PUBLIC_BRIDGE
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
         iniset $Q_L3_CONF_FILE DEFAULT interface_driver quantum.agent.linux.interface.BridgeInterfaceDriver
cea6c512
         iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge ''
d6767d0d
     fi
 fi
 
396a014b
 # Quantum RPC support - must be updated prior to starting any of the services
 if is_service_enabled quantum; then
     iniset $Q_CONF_FILE DEFAULT control_exchange quantum
     if is_service_enabled qpid ; then
         iniset $Q_CONF_FILE DEFAULT rpc_backend quantum.openstack.common.rpc.impl_qpid
3bae7c2c
     elif is_service_enabled zeromq; then
         iniset $Q_CONF_FILE DEFAULT rpc_backend quantum.openstack.common.rpc.impl_zmq
396a014b
     elif [ -n "$RABBIT_HOST" ] &&  [ -n "$RABBIT_PASSWORD" ]; then
         iniset $Q_CONF_FILE DEFAULT rabbit_host $RABBIT_HOST
         iniset $Q_CONF_FILE DEFAULT rabbit_password $RABBIT_PASSWORD
     fi
 fi
 
d74257d0
 # Nova
 # ----
bd13b708
 
bf67c19c
 if is_service_enabled nova; then
     echo_summary "Configuring Nova"
     configure_nova
70dc5e05
 fi
 
6f85ab35
 if is_service_enabled n-net q-dhcp; then
55458455
     # Delete traces of nova networks from prior runs
09fde81c
     sudo killall dnsmasq || true
55458455
     clean_iptables
50ac7921
     rm -rf $NOVA_STATE_PATH/networks
     mkdir -p $NOVA_STATE_PATH/networks
0b31e867
 
     # Force IP forwarding on, just on case
     sudo sysctl -w net.ipv4.ip_forward=1
70dc5e05
 fi
 
7d28a0e1
 
28fa4e8d
 # Storage Service
7d28a0e1
 # ---------------
 
a6651e94
 if is_service_enabled swift; then
7903b795
     echo_summary "Configuring Swift"
77b0e1d8
 
4a43b7bd
     # Make sure to kill all swift processes first
2a5f681b
     swift-init all stop || true
f87fd042
 
4a43b7bd
     # First do a bit of setup by creating the directories and
3d9c5d5e
     # changing the permissions so we can run it as our user.
 
067163df
     USER_GROUP=$(id -g)
1e51c115
     sudo mkdir -p ${SWIFT_DATA_DIR}/drives
     sudo chown -R $USER:${USER_GROUP} ${SWIFT_DATA_DIR}
5f039326
 
4a43b7bd
     # Create a loopback disk and format it to XFS.
00edc95c
     if [[ -e ${SWIFT_DATA_DIR}/drives/images/swift.img ]]; then
         if egrep -q ${SWIFT_DATA_DIR}/drives/sdb1 /proc/mounts; then
             sudo umount ${SWIFT_DATA_DIR}/drives/sdb1
         fi
     else
1e51c115
         mkdir -p  ${SWIFT_DATA_DIR}/drives/images
         sudo touch  ${SWIFT_DATA_DIR}/drives/images/swift.img
         sudo chown $USER: ${SWIFT_DATA_DIR}/drives/images/swift.img
5f039326
 
1e51c115
         dd if=/dev/zero of=${SWIFT_DATA_DIR}/drives/images/swift.img \
b93478f6
             bs=1024 count=0 seek=${SWIFT_LOOPBACK_DISK_SIZE}
28fa4e8d
     fi
4a43b7bd
 
00edc95c
     # Make a fresh XFS filesystem
     mkfs.xfs -f -i size=1024  ${SWIFT_DATA_DIR}/drives/images/swift.img
28fa4e8d
 
4a43b7bd
     # Mount the disk with mount options to make it as efficient as possible
1e51c115
     mkdir -p ${SWIFT_DATA_DIR}/drives/sdb1
     if ! egrep -q ${SWIFT_DATA_DIR}/drives/sdb1 /proc/mounts; then
b93478f6
         sudo mount -t xfs -o loop,noatime,nodiratime,nobarrier,logbufs=8  \
1e51c115
             ${SWIFT_DATA_DIR}/drives/images/swift.img ${SWIFT_DATA_DIR}/drives/sdb1
a03f0056
     fi
28fa4e8d
 
4a43b7bd
     # Create a link to the above mount
a95efab1
     for x in $(seq ${SWIFT_REPLICAS}); do
1e51c115
         sudo ln -sf ${SWIFT_DATA_DIR}/drives/sdb1/$x ${SWIFT_DATA_DIR}/$x; done
5f039326
 
4a43b7bd
     # Create all of the directories needed to emulate a few different servers
a95efab1
     for x in $(seq ${SWIFT_REPLICAS}); do
1e51c115
             drive=${SWIFT_DATA_DIR}/drives/sdb1/${x}
             node=${SWIFT_DATA_DIR}/${x}/node
a95efab1
             node_device=${node}/sdb1
             [[ -d $node ]] && continue
             [[ -d $drive ]] && continue
             sudo install -o ${USER} -g $USER_GROUP -d $drive
             sudo install -o ${USER} -g $USER_GROUP -d $node_device
             sudo chown -R $USER: ${node}
e1d2bcb1
     done
 
1e51c115
    sudo mkdir -p ${SWIFT_CONFIG_DIR}/{object,container,account}-server /var/run/swift
    sudo chown -R $USER: ${SWIFT_CONFIG_DIR} /var/run/swift
28fa4e8d
 
1e51c115
     if [[ "$SWIFT_CONFIG_DIR" != "/etc/swift" ]]; then
e5d92380
         # Some swift tools are hard-coded to use ``/etc/swift`` and are apparently not going to be fixed.
1e51c115
         # Create a symlink if the config dir is moved
         sudo ln -sf ${SWIFT_CONFIG_DIR} /etc/swift
     fi
5f039326
 
e5d92380
     # Swift use rsync to synchronize between all the different
1e51c115
     # partitions (which make more sense when you have a multi-node
     # setup) we configure it with our version of rsync.
     sed -e "
         s/%GROUP%/${USER_GROUP}/;
         s/%USER%/$USER/;
         s,%SWIFT_DATA_DIR%,$SWIFT_DATA_DIR,;
     " $FILES/swift/rsyncd.conf | sudo tee /etc/rsyncd.conf
5218d451
     if [[ "$os_PACKAGE" = "deb" ]]; then
         sudo sed -i '/^RSYNC_ENABLE=false/ { s/false/true/ }' /etc/default/rsync
     else
         sudo sed -i '/disable *= *yes/ { s/yes/no/ }' /etc/xinetd.d/rsync
     fi
45c51137
 
6ae9ea59
     if is_service_enabled swift3;then
         swift_auth_server="s3token "
     fi
4e823ff4
 
c7214e83
     # By default Swift will be installed with the tempauth middleware
     # which has some default username and password if you have
     # configured keystone it will checkout the directory.
     if is_service_enabled key; then
84394b9f
         swift_auth_server+="authtoken keystoneauth"
c7214e83
     else
         swift_auth_server=tempauth
     fi
 
     SWIFT_CONFIG_PROXY_SERVER=${SWIFT_CONFIG_DIR}/proxy-server.conf
     cp ${SWIFT_DIR}/etc/proxy-server.conf-sample ${SWIFT_CONFIG_PROXY_SERVER}
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT user
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT user ${USER}
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT swift_dir
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT swift_dir ${SWIFT_CONFIG_DIR}
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT workers
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT workers 1
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT log_level
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT log_level DEBUG
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT:-8080}
 
6ae9ea59
     # Only enable Swift3 if we have it enabled in ENABLED_SERVICES
     is_service_enabled swift3 && swift3=swift3 || swift3=""
 
     iniset ${SWIFT_CONFIG_PROXY_SERVER} pipeline:main pipeline "catch_errors healthcheck cache ratelimit ${swift3} ${swift_auth_server} proxy-logging proxy-server"
c7214e83
 
     iniset ${SWIFT_CONFIG_PROXY_SERVER} app:proxy-server account_autocreate true
 
84394b9f
     # Configure Keystone
     sed -i '/^# \[filter:authtoken\]/,/^# \[filter:keystoneauth\]$/ s/^#[ \t]*//' ${SWIFT_CONFIG_PROXY_SERVER}
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_host $KEYSTONE_AUTH_HOST
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_port $KEYSTONE_AUTH_PORT
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_tenant_name $SERVICE_TENANT_NAME
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_user swift
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_password $SERVICE_PASSWORD
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} filter:keystoneauth use
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} filter:keystoneauth operator_roles
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:keystoneauth operator_roles "Member, admin"
 
6ae9ea59
     if is_service_enabled swift3;then
         cat <<EOF>>${SWIFT_CONFIG_PROXY_SERVER}
 # NOTE(chmou): s3token middleware is not updated yet to use only
 # username and password.
 [filter:s3token]
 paste.filter_factory = keystone.middleware.s3_token:filter_factory
 auth_port = ${KEYSTONE_AUTH_PORT}
 auth_host = ${KEYSTONE_AUTH_HOST}
 auth_protocol = ${KEYSTONE_AUTH_PROTOCOL}
 auth_token = ${SERVICE_TOKEN}
 admin_token = ${SERVICE_TOKEN}
c7214e83
 
 [filter:swift3]
f8be4288
 use = egg:swift3#swift3
c7214e83
 EOF
6ae9ea59
     fi
c7214e83
 
     cp ${SWIFT_DIR}/etc/swift.conf-sample ${SWIFT_CONFIG_DIR}/swift.conf
     iniset ${SWIFT_CONFIG_DIR}/swift.conf swift-hash swift_hash_path_suffix ${SWIFT_HASH}
1e51c115
 
4a43b7bd
     # This function generates an object/account/proxy configuration
     # emulating 4 nodes on different ports
1e51c115
     function generate_swift_configuration() {
         local server_type=$1
         local bind_port=$2
         local log_facility=$3
         local node_number
c7214e83
         local swift_node_config
1e51c115
 
         for node_number in $(seq ${SWIFT_REPLICAS}); do
             node_path=${SWIFT_DATA_DIR}/${node_number}
c7214e83
             swift_node_config=${SWIFT_CONFIG_DIR}/${server_type}-server/${node_number}.conf
 
             cp ${SWIFT_DIR}/etc/${server_type}-server.conf-sample ${swift_node_config}
 
             iniuncomment ${swift_node_config} DEFAULT user
             iniset ${swift_node_config} DEFAULT user ${USER}
 
             iniuncomment ${swift_node_config} DEFAULT bind_port
             iniset ${swift_node_config} DEFAULT bind_port ${bind_port}
 
             iniuncomment ${swift_node_config} DEFAULT swift_dir
             iniset ${swift_node_config} DEFAULT swift_dir ${SWIFT_CONFIG_DIR}
 
             iniuncomment ${swift_node_config} DEFAULT devices
             iniset ${swift_node_config} DEFAULT devices ${node_path}
 
             iniuncomment ${swift_node_config} DEFAULT log_facility
             iniset ${swift_node_config} DEFAULT log_facility LOG_LOCAL${log_facility}
 
             iniuncomment ${swift_node_config} DEFAULT mount_check
             iniset ${swift_node_config} DEFAULT mount_check false
 
             iniuncomment ${swift_node_config} ${server_type}-replicator vm_test_mode
             iniset ${swift_node_config} ${server_type}-replicator vm_test_mode yes
 
1e51c115
             bind_port=$(( ${bind_port} + 10 ))
             log_facility=$(( ${log_facility} + 1 ))
         done
     }
     generate_swift_configuration object 6010 2
     generate_swift_configuration container 6011 2
     generate_swift_configuration account 6012 2
a03f0056
 
4a43b7bd
     # Specific configuration for swift for rsyslog. See
     # ``/etc/rsyslog.d/10-swift.conf`` for more info.
c7214e83
     swift_log_dir=${SWIFT_DATA_DIR}/logs
     rm -rf ${swift_log_dir}
     mkdir -p ${swift_log_dir}/hourly
     sudo chown -R $USER:adm ${swift_log_dir}
     sed "s,%SWIFT_LOGDIR%,${swift_log_dir}," $FILES/swift/rsyslog.conf | sudo \
         tee /etc/rsyslog.d/10-swift.conf
     restart_service rsyslog
 
     # This is where we create three different rings for swift with
     # different object servers binding on different ports.
     pushd ${SWIFT_CONFIG_DIR} >/dev/null && {
 
         rm -f *.builder *.ring.gz backups/*.builder backups/*.ring.gz
 
         port_number=6010
         swift-ring-builder object.builder create ${SWIFT_PARTITION_POWER_SIZE} ${SWIFT_REPLICAS} 1
         for x in $(seq ${SWIFT_REPLICAS}); do
             swift-ring-builder object.builder add z${x}-127.0.0.1:${port_number}/sdb1 1
             port_number=$[port_number + 10]
         done
         swift-ring-builder object.builder rebalance
 
         port_number=6011
         swift-ring-builder container.builder create ${SWIFT_PARTITION_POWER_SIZE} ${SWIFT_REPLICAS} 1
         for x in $(seq ${SWIFT_REPLICAS}); do
             swift-ring-builder container.builder add z${x}-127.0.0.1:${port_number}/sdb1 1
             port_number=$[port_number + 10]
         done
         swift-ring-builder container.builder rebalance
 
         port_number=6012
         swift-ring-builder account.builder create ${SWIFT_PARTITION_POWER_SIZE} ${SWIFT_REPLICAS} 1
         for x in $(seq ${SWIFT_REPLICAS}); do
             swift-ring-builder account.builder add z${x}-127.0.0.1:${port_number}/sdb1 1
             port_number=$[port_number + 10]
         done
         swift-ring-builder account.builder rebalance
769eb1cf
 
c7214e83
     } && popd >/dev/null
a95efab1
 
4a43b7bd
    # Start rsync
5218d451
     if [[ "$os_PACKAGE" = "deb" ]]; then
         sudo /etc/init.d/rsync restart || :
     else
         sudo systemctl start xinetd.service
     fi
5f039326
 
b1f6c183
    # First spawn all the swift services then kill the
185c66e4
    # proxy service so we can run it in foreground in screen.
b1f6c183
    # ``swift-init ... {stop|restart}`` exits with '1' if no servers are running,
    # ignore it just in case
    swift-init all restart || true
    swift-init proxy stop || true
5f039326
 
a95efab1
    unset s swift_hash swift_auth_server
28fa4e8d
 fi
 
df0972c1
 
acff87a2
 # Volume Service
 # --------------
 
67787e6b
 if is_service_enabled cinder; then
7903b795
     echo_summary "Configuring Cinder"
67787e6b
     init_cinder
 elif is_service_enabled n-vol; then
7903b795
     echo_summary "Configuring Nova volumes"
5bf7d5cc
     init_nvol
acff87a2
 fi
 
bf67c19c
 if is_service_enabled nova; then
     echo_summary "Configuring Nova"
     init_nova
 fi
d1879c5c
 
bf67c19c
 # Additional Nova configuration that is dependent on other services
a6651e94
 if is_service_enabled quantum; then
37dda8d7
     add_nova_opt "network_api_class=nova.network.quantumv2.api.API"
     add_nova_opt "quantum_admin_username=$Q_ADMIN_USERNAME"
     add_nova_opt "quantum_admin_password=$SERVICE_PASSWORD"
     add_nova_opt "quantum_admin_auth_url=$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v2.0"
     add_nova_opt "quantum_auth_strategy=$Q_AUTH_STRATEGY"
     add_nova_opt "quantum_admin_tenant_name=$SERVICE_TENANT_NAME"
     add_nova_opt "quantum_url=http://$Q_HOST:$Q_PORT"
0007f3a6
 
     if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
cea6c512
         NOVA_VIF_DRIVER="nova.virt.libvirt.vif.LibvirtHybridOVSBridgeDriver"
0007f3a6
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
         NOVA_VIF_DRIVER="nova.virt.libvirt.vif.QuantumLinuxBridgeVIFDriver"
1bfa3d53
     fi
0007f3a6
     add_nova_opt "libvirt_vif_driver=$NOVA_VIF_DRIVER"
     add_nova_opt "linuxnet_interface_driver=$LINUXNET_VIF_DRIVER"
1bfa3d53
 else
ced65179
     add_nova_opt "network_manager=nova.network.manager.$NET_MAN"
cea6c512
     add_nova_opt "public_interface=$PUBLIC_INTERFACE"
     add_nova_opt "vlan_interface=$VLAN_INTERFACE"
     add_nova_opt "flat_network_bridge=$FLAT_NETWORK_BRIDGE"
     if [ -n "$FLAT_INTERFACE" ]; then
         add_nova_opt "flat_interface=$FLAT_INTERFACE"
     fi
1bfa3d53
 fi
2fcb6661
 # All nova-compute workers need to know the vnc configuration options
 # These settings don't hurt anything if n-xvnc and n-novnc are disabled
a6651e94
 if is_service_enabled n-cpu; then
ce116914
     NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://$SERVICE_HOST:6080/vnc_auto.html"}
ced65179
     add_nova_opt "novncproxy_base_url=$NOVNCPROXY_URL"
ce116914
     XVPVNCPROXY_URL=${XVPVNCPROXY_URL:-"http://$SERVICE_HOST:6081/console"}
ced65179
     add_nova_opt "xvpvncproxy_base_url=$XVPVNCPROXY_URL"
ce116914
 fi
 if [ "$VIRT_DRIVER" = 'xenserver' ]; then
     VNCSERVER_PROXYCLIENT_ADDRESS=${VNCSERVER_PROXYCLIENT_ADDRESS=169.254.0.1}
 else
     VNCSERVER_PROXYCLIENT_ADDRESS=${VNCSERVER_PROXYCLIENT_ADDRESS=127.0.0.1}
 fi
50fc5c64
 # Address on which instance vncservers will listen on compute hosts.
 # For multi-host, this should be the management ip of the compute host.
 VNCSERVER_LISTEN=${VNCSERVER_LISTEN=127.0.0.1}
ced65179
 add_nova_opt "vncserver_listen=$VNCSERVER_LISTEN"
 add_nova_opt "vncserver_proxyclient_address=$VNCSERVER_PROXYCLIENT_ADDRESS"
 add_nova_opt "ec2_dmz_host=$EC2_DMZ_HOST"
3bae7c2c
 if is_service_enabled zeromq; then
     add_nova_opt "rpc_backend=nova.openstack.common.rpc.impl_zmq"
 elif is_service_enabled qpid; then
22ddb27e
     add_nova_opt "rpc_backend=nova.rpc.impl_qpid"
 elif [ -n "$RABBIT_HOST" ] &&  [ -n "$RABBIT_PASSWORD" ]; then
4a221459
     add_nova_opt "rabbit_host=$RABBIT_HOST"
     add_nova_opt "rabbit_password=$RABBIT_PASSWORD"
 fi
ced65179
 add_nova_opt "glance_api_servers=$GLANCE_HOSTPORT"
df0972c1
 
b62b4ca2
 # XenServer
 # ---------
 
 if [ "$VIRT_DRIVER" = 'xenserver' ]; then
7903b795
     echo_summary "Using XenServer virtualization driver"
b62b4ca2
     read_password XENAPI_PASSWORD "ENTER A PASSWORD TO USE FOR XEN."
e0e91d2c
     add_nova_opt "compute_driver=xenapi.XenAPIDriver"
92e85601
     XENAPI_CONNECTION_URL=${XENAPI_CONNECTION_URL:-"http://169.254.0.1"}
030fb236
     XENAPI_USER=${XENAPI_USER:-"root"}
ced65179
     add_nova_opt "xenapi_connection_url=$XENAPI_CONNECTION_URL"
030fb236
     add_nova_opt "xenapi_connection_username=$XENAPI_USER"
ced65179
     add_nova_opt "xenapi_connection_password=$XENAPI_PASSWORD"
     add_nova_opt "flat_injected=False"
ce116914
     # Need to avoid crash due to new firewall support
     XEN_FIREWALL_DRIVER=${XEN_FIREWALL_DRIVER:-"nova.virt.firewall.IptablesFirewallDriver"}
ced65179
     add_nova_opt "firewall_driver=$XEN_FIREWALL_DRIVER"
c0c6f006
 elif [ "$VIRT_DRIVER" = 'openvz' ]; then
7903b795
     echo_summary "Using OpenVZ virtualization driver"
c0c6f006
     # TODO(deva): OpenVZ driver does not yet work if compute_driver is set here.
     #             Replace connection_type when this is fixed.
     #             add_nova_opt "compute_driver=openvz.connection.OpenVzConnection"
     add_nova_opt "connection_type=openvz"
     LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.libvirt.firewall.IptablesFirewallDriver"}
     add_nova_opt "firewall_driver=$LIBVIRT_FIREWALL_DRIVER"
b62b4ca2
 else
7903b795
     echo_summary "Using libvirt virtualization driver"
e0e91d2c
     add_nova_opt "compute_driver=libvirt.LibvirtDriver"
34f6249f
     LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.libvirt.firewall.IptablesFirewallDriver"}
ced65179
     add_nova_opt "firewall_driver=$LIBVIRT_FIREWALL_DRIVER"
b62b4ca2
 fi
 
df0972c1
 
bfdad75e
 # Heat
4a43b7bd
 # ----
 
bfdad75e
 if is_service_enabled heat; then
7903b795
     echo_summary "Configuring Heat"
bfdad75e
     init_heat
 fi
a074800c
 
4a43b7bd
 
d74257d0
 # Launch Services
 # ===============
30f68e96
 
dfcd2003
 # Only run the services specified in ``ENABLED_SERVICES``
 
73f6f25b
 # Launch the Glance services
 if is_service_enabled g-api g-reg; then
7903b795
     echo_summary "Starting Glance"
73f6f25b
     start_glance
d000b22d
 fi
 
d81a0274
 # Create an access key and secret key for nova ec2 register image
 if is_service_enabled key && is_service_enabled swift3 && is_service_enabled nova; then
     NOVA_USER_ID=$(keystone user-list | grep ' nova ' | get_field 1)
     NOVA_TENANT_ID=$(keystone tenant-list | grep " $SERVICE_TENANT_NAME " | get_field 1)
     CREDS=$(keystone ec2-credentials-create --user_id $NOVA_USER_ID --tenant_id $NOVA_TENANT_ID)
     ACCESS_KEY=$(echo "$CREDS" | awk '/ access / { print $4 }')
     SECRET_KEY=$(echo "$CREDS" | awk '/ secret / { print $4 }')
     add_nova_opt "s3_access_key=$ACCESS_KEY"
     add_nova_opt "s3_secret_key=$SECRET_KEY"
     add_nova_opt "s3_affix_tenant=True"
d000b22d
 fi
 
3bae7c2c
 screen_it zeromq "cd $NOVA_DIR && $NOVA_DIR/bin/nova-rpc-zmq-receiver"
 
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"
9fbeeddc
     screen_it n-api "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-api"
92e81992
     echo "Waiting for nova-api to start..."
c727aa89
     if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= wget -q -O- http://127.0.0.1:8774; do sleep 1; done"; then
92e81992
       echo "nova-api did not start"
       exit 1
     fi
d000b22d
 fi
1bfa3d53
 
37dda8d7
 if is_service_enabled q-svc; then
7903b795
     echo_summary "Starting Quantum"
d6767d0d
     # Start the Quantum service
     screen_it q-svc "cd $QUANTUM_DIR && python $QUANTUM_DIR/bin/quantum-server --config-file $Q_CONF_FILE --config-file /$Q_PLUGIN_CONF_FILE"
     echo "Waiting for Quantum to start..."
     if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= wget -q -O- http://127.0.0.1:9696; do sleep 1; done"; then
       echo "Quantum did not start"
       exit 1
     fi
 
     # Configure Quantum elements
     # Configure internal network & subnet
 
37dda8d7
     TENANT_ID=$(keystone tenant-list | grep " demo " | get_field 1)
 
     # Create a small network
     # Since quantum command is executed in admin context at this point,
4a43b7bd
     # ``--tenant_id`` needs to be specified.
5ffac6b1
     NET_ID=$(quantum net-create --tenant_id $TENANT_ID "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2)
d6767d0d
     SUBNET_ID=$(quantum subnet-create --tenant_id $TENANT_ID --ip_version 4 --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2)
     if is_service_enabled q-l3; then
         # Create a router, and add the private subnet as one of its interfaces
         ROUTER_ID=$(quantum router-create --tenant_id $TENANT_ID router1 | grep ' id ' | get_field 2)
         quantum router-interface-add $ROUTER_ID $SUBNET_ID
         # Create an external network, and a subnet. Configure the external network as router gw
5ffac6b1
         EXT_NET_ID=$(quantum net-create "$PUBLIC_NETWORK_NAME" -- --router:external=True | grep ' id ' | get_field 2)
d6767d0d
         EXT_GW_IP=$(quantum subnet-create --ip_version 4 $EXT_NET_ID $FLOATING_RANGE -- --enable_dhcp=False | grep 'gateway_ip' | get_field 2)
         quantum router-gateway-set $ROUTER_ID $EXT_NET_ID
c8dc1f36
         if [[ "$Q_PLUGIN" = "openvswitch" ]] && [[ "$Q_USE_NAMESPACE" = "True" ]]; then
d6767d0d
             CIDR_LEN=${FLOATING_RANGE#*/}
             sudo ip addr add $EXT_GW_IP/$CIDR_LEN dev $PUBLIC_BRIDGE
             sudo ip link set $PUBLIC_BRIDGE up
c8dc1f36
             ROUTER_GW_IP=`quantum port-list -c fixed_ips -c device_owner | grep router_gateway | awk -F '"' '{ print $8; }'`
             sudo route add -net $FIXED_RANGE gw $ROUTER_GW_IP
d6767d0d
         fi
         if [[ "$Q_USE_NAMESPACE" == "False" ]]; then
             # Explicitly set router id in l3 agent configuration
             iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID
         fi
    fi
 
f758f4cc
 elif is_service_enabled mysql && is_service_enabled n-net; then
37dda8d7
     # Create a small network
5ffac6b1
     $NOVA_BIN_DIR/nova-manage network create "$PRIVATE_NETWORK_NAME" $FIXED_RANGE 1 $FIXED_NETWORK_SIZE $NETWORK_CREATE_ARGS
37dda8d7
 
     # Create some floating ips
5ffac6b1
     $NOVA_BIN_DIR/nova-manage floating create $FLOATING_RANGE --pool=$PUBLIC_NETWORK_NAME
37dda8d7
 
     # Create a second pool
9fbeeddc
     $NOVA_BIN_DIR/nova-manage floating create --ip_range=$TEST_FLOATING_RANGE --pool=$TEST_FLOATING_POOL
1bfa3d53
 fi
 
6e77163b
 # Start up the quantum agents if enabled
b782a2c0
 screen_it q-agt "python $AGENT_BINARY --config-file $Q_CONF_FILE --config-file /$Q_PLUGIN_CONF_FILE"
 screen_it q-dhcp "python $AGENT_DHCP_BINARY --config-file $Q_CONF_FILE --config-file=$Q_DHCP_CONF_FILE"
 screen_it q-l3 "python $AGENT_L3_BINARY --config-file $Q_CONF_FILE --config-file=$Q_L3_CONF_FILE"
6e77163b
 
bf67c19c
 if is_service_enabled nova; then
     echo_summary "Starting Nova"
     start_nova
 fi
5bf7d5cc
 if is_service_enabled n-vol; then
7903b795
     echo_summary "Starting Nova volumes"
5bf7d5cc
     start_nvol
 fi
67787e6b
 if is_service_enabled cinder; then
7903b795
     echo_summary "Starting Cinder"
67787e6b
     start_cinder
 fi
93361643
 if is_service_enabled ceilometer; then
c5259b4a
     echo_summary "Configuring Ceilometer"
93361643
     configure_ceilometer
c5259b4a
     echo_summary "Starting Ceilometer"
93361643
     start_ceilometer
 fi
5218d451
 screen_it horizon "cd $HORIZON_DIR && sudo tail -f /var/log/$APACHE_NAME/horizon_error.log"
1e51c115
 screen_it swift "cd $SWIFT_DIR && $SWIFT_DIR/bin/swift-proxy-server ${SWIFT_CONFIG_DIR}/proxy-server.conf -v"
75a37653
 
6ae9ea59
 # Starting the nova-objectstore only if swift3 service is not enabled.
e347b990
 # Swift will act as s3 objectstore.
6ae9ea59
 is_service_enabled swift3 || \
9fbeeddc
     screen_it n-obj "cd $NOVA_DIR && $NOVA_BIN_DIR/nova-objectstore"
df0972c1
 
bfdad75e
 # launch heat engine, api and metadata
 if is_service_enabled heat; then
7903b795
     echo_summary "Starting Heat"
bfdad75e
     start_heat
 fi
7d28a0e1
 
4a43b7bd
 
d74257d0
 # Install Images
 # ==============
e49b8bd6
 
0ab1d46e
 # Upload an image to glance.
5372f433
 #
4a43b7bd
 # The default image is cirros, a small testing image which lets you login as **root**
ca0e3d02
 # cirros also uses ``cloud-init``, supporting login via keypair and sending scripts as
0ab1d46e
 # userdata.  See https://help.ubuntu.com/community/CloudInit for more on cloud-init
 #
4a43b7bd
 # Override ``IMAGE_URLS`` with a comma-separated list of UEC images.
aab7eae0
 #  * **oneiric**: http://uec-images.ubuntu.com/oneiric/current/oneiric-server-cloudimg-amd64.tar.gz
ca0e3d02
 #  * **precise**: http://uec-images.ubuntu.com/precise/current/precise-server-cloudimg-amd64.tar.gz
08e8b745
 
a6651e94
 if is_service_enabled g-reg; then
7903b795
     echo_summary "Uploading images"
5cc2129c
     TOKEN=$(keystone  token-get | grep ' id ' | get_field 2)
747ee33e
 
b62b4ca2
     # Option to upload legacy ami-tty, which works with xenserver
314da5a4
     if [[ -n "$UPLOAD_LEGACY_TTY" ]]; then
         IMAGE_URLS="${IMAGE_URLS:+${IMAGE_URLS},}http://images.ansolabs.com/tty.tgz"
b62b4ca2
     fi
 
120f4860
     for image_url in ${IMAGE_URLS//,/ }; do
ca0e3d02
         upload_image $image_url $TOKEN
120f4860
     done
70dc5e05
 fi
24859060
 
df0972c1
 
f5633ddb
 # 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
 
 
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
 
df0972c1
 
24859060
 # Using the cloud
4a43b7bd
 # ---------------
24859060
 
e19d8847
 echo ""
 echo ""
 echo ""
 
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
df0972c1
     echo "Horizon is now available at http://$SERVICE_HOST/"
24859060
 fi
 
df0972c1
 # If Keystone is present you can point ``nova`` cli to this server
a6651e94
 if is_service_enabled key; then
df0972c1
     echo "Keystone is serving at $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$KEYSTONE_API_PORT/v2.0/"
     echo "Examples on using novaclient command line is in exercise.sh"
     echo "The default users are: admin and demo"
     echo "The password: $ADMIN_PASSWORD"
24859060
 fi
523c405f
 
4a43b7bd
 # Echo ``HOST_IP`` - useful for ``build_uec.sh``, which uses dhcp to give the instance an address
1097c7ca
 echo "This is your host ip: $HOST_IP"
 
df0972c1
 # Warn that ``EXTRA_FLAGS`` needs to be converted to ``EXTRA_OPTS``
ced65179
 if [[ -n "$EXTRA_FLAGS" ]]; then
7903b795
     echo_summary "WARNING: EXTRA_FLAGS is defined and may need to be converted to EXTRA_OPTS"
ced65179
 fi
 
4a43b7bd
 # Indicate how long this took to run (bash maintained variable ``SECONDS``)
7903b795
 echo_summary "stack.sh completed in $SECONDS seconds."