Merge "Use --or-show for get_or_create_user/project/role function"
diff --git a/doc/source/changes.rst b/doc/source/changes.rst
index 7b75375..19fce0f 100644
--- a/doc/source/changes.rst
+++ b/doc/source/changes.rst
@@ -8,3 +8,5 @@
 These are the commits to DevStack for the last six months. For the
 complete list see `the DevStack project in
 Gerrit <https://review.openstack.org/#/q/status:merged+project:openstack-dev/devstack,n,z>`__.
+
+%GIT_LOG%
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 5157622..baebe97 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -92,7 +92,7 @@
     [[post-config|/$Q_PLUGIN_CONF_FILE]]
 
 Also note that the ``localrc`` section is sourced as a shell script
-fragment amd MUST conform to the shell requirements, specifically no
+fragment and MUST conform to the shell requirements, specifically no
 whitespace around ``=`` (equals).
 
 Minimal Configuration
@@ -131,7 +131,7 @@
 
 ``HOST_IP`` is normally detected on the first run of ``stack.sh`` but
 often is indeterminate on later runs due to the IP being moved from an
-Ethernet integace to a bridge on the host. Setting it here also makes it
+Ethernet interface to a bridge on the host. Setting it here also makes it
 available for ``openrc`` to set ``OS_AUTH_URL``. ``HOST_IP`` is not set
 by default.
 
@@ -208,7 +208,7 @@
        which is useful for watching log and debug output. However, in
        automated testing the interactive ``screen`` sessions may not be
        available after the fact; setting ``SCREEN_LOGDIR`` enables logging
-       of the ``screen`` sessions in the specified diretory. There will be
+       of the ``screen`` sessions in the specified directory. There will be
        one file per ``screen`` session named for the session name and a
        timestamp.
     |
diff --git a/doc/source/guides/neutron.rst b/doc/source/guides/neutron.rst
index 59b7a9d..dc2fc71 100644
--- a/doc/source/guides/neutron.rst
+++ b/doc/source/guides/neutron.rst
@@ -23,7 +23,7 @@
 
 eth1 is manually configured at boot to not have an IP address.
 Consult your operating system documentation for the appropriate
-technique. For Ubuntu, the contents of `/etc/networking/interfaces`
+technique. For Ubuntu, the contents of `/etc/network/interfaces`
 contains:
 
 ::
diff --git a/exercises/horizon.sh b/exercises/horizon.sh
index d62ad52..ad08221 100755
--- a/exercises/horizon.sh
+++ b/exercises/horizon.sh
@@ -36,7 +36,7 @@
 is_service_enabled horizon || exit 55
 
 # can we get the front page
-curl http://$SERVICE_HOST 2>/dev/null | grep -q '<h3>Log In</h3>' || die $LINENO "Horizon front page not functioning!"
+curl http://$SERVICE_HOST 2>/dev/null | grep -q '<h3.*>Log In</h3>' || die $LINENO "Horizon front page not functioning!"
 
 set +o xtrace
 echo "*********************************************************************"
diff --git a/lib/ceilometer b/lib/ceilometer
index cdef422..b43a4ed 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -1,13 +1,32 @@
 # lib/ceilometer
 # Install and start **Ceilometer** service
 
-# To enable a minimal set of Ceilometer services, add the following to localrc:
+# To enable a minimal set of Ceilometer services, add the following to the
+# localrc section of local.conf:
 #
 #   enable_service ceilometer-acompute ceilometer-acentral ceilometer-anotification ceilometer-collector ceilometer-api
 #
-# To ensure Ceilometer alarming services are enabled also, further add to the localrc:
+# To ensure Ceilometer alarming services are enabled also, further add to the
+# localrc section of local.conf:
 #
 #   enable_service ceilometer-alarm-notifier ceilometer-alarm-evaluator
+#
+# To ensure events are stored, add the following section to local.conf:
+#
+#   [[post-config|$CEILOMETER_CONF]]
+#   [notification]
+#   store_events=True
+#
+# Several variables set in the localrc section adjust common behaviors
+# of Ceilometer (see within for additional settings):
+#
+#   CEILOMETER_USE_MOD_WSGI:       When True, run the api under mod_wsgi.
+#   CEILOMETER_PIPELINE_INTERVAL:  The number of seconds between pipeline processing
+#                                  runs. Default 600.
+#   CEILOMETER_BACKEND:            The database backend (e.g. 'mysql', 'mongodb')
+#   CEILOMETER_COORDINATION_URL:   The URL for a group membership service provided
+#                                  by tooz.
+
 
 # Dependencies:
 #
diff --git a/lib/ceph b/lib/ceph
index 5214306..72631fd 100644
--- a/lib/ceph
+++ b/lib/ceph
@@ -72,7 +72,7 @@
 # ------------
 
 function get_ceph_version {
-    local ceph_version_str=$(sudo ceph daemon mon.$(hostname) version | cut -d '"' -f 4)
+    local ceph_version_str=$(sudo ceph daemon mon.$(hostname) version | cut -d '"' -f 4 | cut -f 1,2 -d '.')
     echo $ceph_version_str
 }
 
@@ -167,7 +167,7 @@
     # pools data and metadata were removed in the Giant release so depending on the version we apply different commands
     local ceph_version=$(get_ceph_version)
     # change pool replica size according to the CEPH_REPLICAS set by the user
-    if [[ ${ceph_version%.*} -eq 0 ]] && [[ ${ceph_version##*.} -lt 87 ]]; then
+    if [[ ${ceph_version%%.*} -eq 0 ]] && [[ ${ceph_version##*.} -lt 87 ]]; then
         sudo ceph -c ${CEPH_CONF_FILE} osd pool set rbd size ${CEPH_REPLICAS}
         sudo ceph -c ${CEPH_CONF_FILE} osd pool set data size ${CEPH_REPLICAS}
         sudo ceph -c ${CEPH_CONF_FILE} osd pool set metadata size ${CEPH_REPLICAS}
diff --git a/lib/ironic b/lib/ironic
index 28f8fe8..e79842c 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -60,7 +60,7 @@
 IRONIC_SSH_USERNAME=${IRONIC_SSH_USERNAME:-`whoami`}
 IRONIC_SSH_KEY_DIR=${IRONIC_SSH_KEY_DIR:-$IRONIC_DATA_DIR/ssh_keys}
 IRONIC_SSH_KEY_FILENAME=${IRONIC_SSH_KEY_FILENAME:-ironic_key}
-IRONIC_KEY_FILE=$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME
+IRONIC_KEY_FILE=${IRONIC_KEY_FILE:-$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME}
 IRONIC_SSH_VIRT_TYPE=${IRONIC_SSH_VIRT_TYPE:-virsh}
 IRONIC_TFTPBOOT_DIR=${IRONIC_TFTPBOOT_DIR:-$IRONIC_DATA_DIR/tftpboot}
 IRONIC_TFTPSERVER_IP=${IRONIC_TFTPSERVER_IP:-$HOST_IP}
@@ -460,7 +460,7 @@
     # intentional sleep to make sure the tag has been set to port
     sleep 10
 
-    local tapdev=$(sudo ip netns exec qdhcp-${ironic_net_id} ip link list | grep tap | cut -d':' -f2 | cut -b2-)
+    local tapdev=$(sudo ip netns exec qdhcp-${ironic_net_id} ip link list | grep " tap" | cut -d':' -f2 | cut -b2-)
     local tag_id=$(sudo ovs-vsctl show |grep ${tapdev} -A1 -m1 | grep tag | cut -d':' -f2 | cut -b2-)
 
     # make sure veth pair is not existing, otherwise delete its links
@@ -632,15 +632,16 @@
 }
 
 function configure_ironic_ssh_keypair {
-    # Generating ssh key pair for stack user
-    if [[ ! -d $IRONIC_SSH_KEY_DIR ]]; then
-        mkdir -p $IRONIC_SSH_KEY_DIR
-    fi
     if [[ ! -d $HOME/.ssh ]]; then
         mkdir -p $HOME/.ssh
         chmod 700 $HOME/.ssh
     fi
-    echo -e 'n\n' | ssh-keygen -q -t rsa -P '' -f $IRONIC_KEY_FILE
+    if [[ ! -e $IRONIC_KEY_FILE ]]; then
+        if [[ ! -d $(dirname $IRONIC_KEY_FILE) ]]; then
+            mkdir -p $(dirname $IRONIC_KEY_FILE)
+        fi
+        echo -e 'n\n' | ssh-keygen -q -t rsa -P '' -f $IRONIC_KEY_FILE
+    fi
     cat $IRONIC_KEY_FILE.pub | tee -a $IRONIC_AUTHORIZED_KEYS_FILE
 }
 
@@ -657,7 +658,7 @@
 
 function configure_ironic_auxiliary {
     configure_ironic_ssh_keypair
-    ironic_ssh_check $IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME 10
+    ironic_ssh_check $IRONIC_KEY_FILE $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME 10
 }
 
 function build_ipa_coreos_ramdisk {
@@ -740,6 +741,9 @@
 }
 
 function prepare_baremetal_basic_ops {
+    if ! is_ironic_hardware; then
+        configure_ironic_auxiliary
+    fi
     upload_baremetal_ironic_deploy
     if ! is_ironic_hardware; then
         create_bridge_and_vms
@@ -747,9 +751,6 @@
     enroll_nodes
     configure_tftpd
     configure_iptables
-    if ! is_ironic_hardware; then
-        configure_ironic_auxiliary
-    fi
 }
 
 function cleanup_baremetal_basic_ops {
diff --git a/lib/nova b/lib/nova
index 0e6c6af..1e55569 100644
--- a/lib/nova
+++ b/lib/nova
@@ -264,9 +264,6 @@
     configure_nova_rootwrap
 
     if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then
-        # Remove legacy paste config if present
-        rm -f $NOVA_DIR/bin/nova-api-paste.ini
-
         # Get the sample configuration file in place
         cp $NOVA_DIR/etc/nova/api-paste.ini $NOVA_CONF_DIR
 
diff --git a/lib/oslo b/lib/oslo
index d00580b..1fff1f5 100644
--- a/lib/oslo
+++ b/lib/oslo
@@ -21,14 +21,14 @@
 # Defaults
 # --------
 GITDIR["cliff"]=$DEST/cliff
-GITDIR["oslo.config"]=$DEST/oslo.config
 GITDIR["oslo.concurrency"]=$DEST/oslo.concurrency
+GITDIR["oslo.config"]=$DEST/oslo.config
 GITDIR["oslo.context"]=$DEST/oslo.context
 GITDIR["oslo.db"]=$DEST/oslo.db
 GITDIR["oslo.i18n"]=$DEST/oslo.i18n
 GITDIR["oslo.log"]=$DEST/oslo.log
-GITDIR["oslo.middleware"]=$DEST/oslo.middleware
 GITDIR["oslo.messaging"]=$DEST/oslo.messaging
+GITDIR["oslo.middleware"]=$DEST/oslo.middleware
 GITDIR["oslo.rootwrap"]=$DEST/oslo.rootwrap
 GITDIR["oslo.serialization"]=$DEST/oslo.serialization
 GITDIR["oslo.utils"]=$DEST/oslo.utils
@@ -54,16 +54,17 @@
 # install_oslo() - Collect source and prepare
 function install_oslo {
     _do_install_oslo_lib "cliff"
-    _do_install_oslo_lib "oslo.i18n"
-    _do_install_oslo_lib "oslo.utils"
-    _do_install_oslo_lib "oslo.serialization"
-    _do_install_oslo_lib "oslo.config"
     _do_install_oslo_lib "oslo.concurrency"
-    _do_install_oslo_lib "oslo.log"
-    _do_install_oslo_lib "oslo.middleware"
-    _do_install_oslo_lib "oslo.messaging"
-    _do_install_oslo_lib "oslo.rootwrap"
+    _do_install_oslo_lib "oslo.config"
+    _do_install_oslo_lib "oslo.context"
     _do_install_oslo_lib "oslo.db"
+    _do_install_oslo_lib "oslo.i18n"
+    _do_install_oslo_lib "oslo.log"
+    _do_install_oslo_lib "oslo.messaging"
+    _do_install_oslo_lib "oslo.middleware"
+    _do_install_oslo_lib "oslo.rootwrap"
+    _do_install_oslo_lib "oslo.serialization"
+    _do_install_oslo_lib "oslo.utils"
     _do_install_oslo_lib "oslo.vmware"
     _do_install_oslo_lib "pycadf"
     _do_install_oslo_lib "stevedore"
diff --git a/lib/tempest b/lib/tempest
index 46c9e26..da670ce 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -63,6 +63,7 @@
 
 
 BOTO_MATERIALS_PATH="$FILES/images/s3-materials/cirros-${CIRROS_VERSION}"
+BOTO_CONF=$TEMPEST_DIR/boto.cfg
 
 # Cinder/Volume variables
 TEMPEST_VOLUME_DRIVER=${TEMPEST_VOLUME_DRIVER:-default}
@@ -389,8 +390,8 @@
         iniset $TEMPEST_CONFIG volume vendor_name "$TEMPEST_VOLUME_VENDOR"
     fi
     if [ $TEMPEST_VOLUME_DRIVER != "default" -o \
-        $TEMPEST_STORAGE_PROTOCOL != $TEMPEST_DEFAULT_STORAGE_PROTOCOL ]; then
-        iniset $TEMPEST_CONFIG volume storage_protocol $TEMPEST_STORAGE_PROTOCOL
+        "$TEMPEST_STORAGE_PROTOCOL" != "$TEMPEST_DEFAULT_STORAGE_PROTOCOL" ]; then
+        iniset $TEMPEST_CONFIG volume storage_protocol "$TEMPEST_STORAGE_PROTOCOL"
     fi
 
     # Dashboard
@@ -424,6 +425,12 @@
         fi
     done
 
+    if is_ssl_enabled_service "keystone" || is_service_enabled tls-proxy; then
+        # Use the BOTO_CONFIG environment variable to point to this file
+        iniset $BOTO_CONF Boto ca_certificates_file $SSL_BUNDLE_FILE
+        sudo chown $STACK_USER $BOTO_CONF
+    fi
+
     # Restore IFS
     IFS=$ifs
 }
diff --git a/tools/build_docs.sh b/tools/build_docs.sh
index f52b179..929d1e0 100755
--- a/tools/build_docs.sh
+++ b/tools/build_docs.sh
@@ -1,35 +1,19 @@
 #!/usr/bin/env bash
 
-# **build_docs.sh** - Build the gh-pages docs for DevStack
+# **build_docs.sh** - Build the docs for DevStack
 #
 # - Install shocco if not found on PATH and INSTALL_SHOCCO is set
 # - Clone MASTER_REPO branch MASTER_BRANCH
 # - Re-creates ``doc/build/html`` directory from existing repo + new generated script docs
 
 # Usage:
-## build_docs.sh [-o <out-dir>] [-g] [master|<repo> [<branch>]]
-## <repo>           The DevStack repository to clone (default is DevStack github repo)
-##                  If a repo is not supplied use the current directory
-##                  (assumed to be a DevStack checkout) as the source.
-## <branch>         The DevStack branch to check out (default is master; ignored if
-##                  repo is not specified)
-## .                Use the current repo and branch (do not use with -p to
-##                  prevent stray files in the workspace being added tot he docs)
+## build_docs.sh [-o <out-dir>]
 ## -o <out-dir>     Write the static HTML output to <out-dir>
 ##                  (Note that <out-dir> will be deleted and re-created to ensure it is clean)
-## -g               Update the old gh-pages repo  (set PUSH=1 to actually push up to RCB)
 
 # Defaults
 # --------
 
-# Source repo/branch for DevStack
-MASTER_REPO=${MASTER_REPO:-git://git.openstack.org/openstack-dev/devstack}
-MASTER_BRANCH=${MASTER_BRANCH:-master}
-
-# http://devstack.org is a GitHub gh-pages site in the https://github.com/cloudbuilders/devtack.git repo
-GH_PAGES_REPO=git@github.com:cloudbuilders/devstack.git
-
-DOCS_SOURCE=doc/source
 HTML_BUILD=doc/build/html
 
 # Keep track of the devstack directory
@@ -60,10 +44,8 @@
 fi
 
 # Process command-line args
-while getopts go: c; do
+while getopts o: c; do
     case $c in
-        g)  GH_UPDATE=1
-            ;;
         o)  HTML_BUILD=$OPTARG
             ;;
     esac
@@ -71,55 +53,24 @@
 shift `expr $OPTIND - 1`
 
 
-if [[ -n "$1" ]]; then
-    master="master"
-    if [[ "${master/#$1}" != "master" ]]; then
-        # Partial match on "master"
-        REPO=$MASTER_REPO
-    else
-        REPO=$1
-    fi
-    REPO_BRANCH=${2:-$MASTER_BRANCH}
-fi
-
-# Check out a specific DevStack branch
-if [[ -n $REPO ]]; then
-    # Make a workspace
-    TMP_ROOT=$(mktemp -d work-docs-XXXX)
-    echo "Building docs in $TMP_ROOT"
-    cd $TMP_ROOT
-
-    # Get the master branch
-    git clone $REPO devstack
-    cd devstack
-    if [[ -n "$REPO_BRANCH" ]]; then
-        git checkout $REPO_BRANCH
-    fi
-fi
-
-# Assumption is we are now in the DevStack workspace to be processed
-
 # Processing
 # ----------
 
-# Clean up build dir
-rm -rf $HTML_BUILD
+# Ensure build dir exists
 mkdir -p $HTML_BUILD
 
 # Get fully qualified dirs
-FQ_DOCS_SOURCE=$(cd $DOCS_SOURCE && pwd)
 FQ_HTML_BUILD=$(cd $HTML_BUILD && pwd)
 
-# Get repo static
-cp -pr $FQ_DOCS_SOURCE/* $FQ_HTML_BUILD
-
 # Insert automated bits
 GLOG=$(mktemp gitlogXXXX)
+echo "<ul>" >$GLOG
 git log \
     --pretty=format:'            <li>%s - <em>Commit <a href="https://review.openstack.org/#q,%h,n,z">%h</a> %cd</em></li>' \
     --date=short \
-    --since '6 months ago' | grep -v Merge >$GLOG
-sed -e $"/%GIT_LOG%/r $GLOG" $FQ_DOCS_SOURCE/changes.html >$FQ_HTML_BUILD/changes.html
+    --since '6 months ago' | grep -v Merge >>$GLOG
+echo "</ul>" >>$GLOG
+sed -i~ -e $"/^.*%GIT_LOG%.*$/r $GLOG" -e $"/^.*%GIT_LOG%.*$/s/^.*%GIT_LOG%.*$//" $FQ_HTML_BUILD/changes.html
 rm -f $GLOG
 
 # Build list of scripts to process
@@ -138,28 +89,6 @@
 done
 echo "$FILES" >doc/files
 
-if [[ -n $GH_UPDATE ]]; then
-    GH_ROOT=$(mktemp -d work-gh-XXXX)
-    cd $GH_ROOT
-
-    # Pull the latest docs branch from devstack.org repo
-    git clone -b gh-pages $GH_PAGES_REPO gh-docs
-
-    # Get the generated files
-    cp -pr $FQ_HTML_BUILD/* gh-docs
-
-    # Collect the new generated pages
-    (cd gh-docs; find . -name \*.html -print0 | xargs -0 git add)
-
-    # Push our changes back up to the docs branch
-    if ! git diff-index HEAD --quiet; then
-        git commit -a -m "Update script docs"
-        if [[ -n $PUSH ]]; then
-            git push
-        fi
-    fi
-fi
-
 # Clean up or report the temp workspace
 if [[ -n REPO && -n $PUSH_REPO ]]; then
     echo rm -rf $TMP_ROOT
diff --git a/tools/upload_image.sh b/tools/upload_image.sh
index d81a5c8..5d23f31 100755
--- a/tools/upload_image.sh
+++ b/tools/upload_image.sh
@@ -37,6 +37,7 @@
 
 # Glance connection info.  Note the port must be specified.
 GLANCE_HOSTPORT=${GLANCE_HOSTPORT:-$GLANCE_HOST:9292}
+GLANCE_SERVICE_PROTOCOL=${GLANCE_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
 
 for IMAGE in "$*"; do
     upload_image $IMAGE $TOKEN
diff --git a/tox.ini b/tox.ini
index c8d3909..a958ae7 100644
--- a/tox.ini
+++ b/tox.ini
@@ -36,5 +36,5 @@
   TOP_DIR={toxinidir}
   INSTALL_SHOCCO=true
 commands = 
-	bash tools/build_docs.sh
 	python setup.py build_sphinx
+	bash tools/build_docs.sh