Merge "Add rhel7 as supported distro"
diff --git a/files/apts/keystone b/files/apts/keystone
index 57fde80..b7218b7 100644
--- a/files/apts/keystone
+++ b/files/apts/keystone
@@ -11,3 +11,4 @@
 python-routes
 libldap2-dev
 libsasl2-dev
+libkrb5-dev
diff --git a/files/apts/opendaylight b/files/apts/opendaylight
deleted file mode 100644
index ec3cc9d..0000000
--- a/files/apts/opendaylight
+++ /dev/null
@@ -1,2 +0,0 @@
-openvswitch-datapath-dkms # NOPRIME
-openvswitch-switch # NOPRIME
diff --git a/files/apts/openvswitch b/files/apts/openvswitch
new file mode 100644
index 0000000..4c0af4a
--- /dev/null
+++ b/files/apts/openvswitch
@@ -0,0 +1,3 @@
+fakeroot
+make
+openvswitch-switch
diff --git a/files/rpms-suse/opendaylight b/files/rpms-suse/opendaylight
deleted file mode 100644
index f7fafff..0000000
--- a/files/rpms-suse/opendaylight
+++ /dev/null
@@ -1,3 +0,0 @@
-openvswitch # NOPRIME
-openvswitch-switch # NOPRIME
-
diff --git a/files/rpms-suse/openvswitch b/files/rpms-suse/openvswitch
new file mode 100644
index 0000000..edfb4d2
--- /dev/null
+++ b/files/rpms-suse/openvswitch
@@ -0,0 +1,3 @@
+openvswitch
+openvswitch-switch
+
diff --git a/files/rpms/opendaylight b/files/rpms/opendaylight
deleted file mode 100644
index 98aaaf4..0000000
--- a/files/rpms/opendaylight
+++ /dev/null
@@ -1 +0,0 @@
-openvswitch # NOPRIME
diff --git a/files/rpms/openvswitch b/files/rpms/openvswitch
new file mode 100644
index 0000000..64796f7
--- /dev/null
+++ b/files/rpms/openvswitch
@@ -0,0 +1 @@
+openvswitch
diff --git a/functions-common b/functions-common
index 613a86c..0bf354f 100644
--- a/functions-common
+++ b/functions-common
@@ -1058,44 +1058,100 @@
     echo $!
 }
 
+function _start_in_screen {
+    local service=$1
+    local cmd=$2
+    local screen_name=${SCREEN_NAME:-stack}
+    local status_dir=${SERVICE_DIR:-${DEST}/status}
+    local service_dir="$status_dir/$screen_name"
+    local pid="$service_dir/$service.pid"
+    local failure="$service_dir/$service.failure"
+
+    if [[ -n ${SCREEN_LOGDIR} ]]; then
+        local logfile=${SCREEN_LOGDIR}/screen-${service}.${CURRENT_LOG_TIME}.log
+        local shortlog=${SCREEN_LOGDIR}/screen-${service}.log
+        # this whole dance is done because of slow nodes
+        screen -S $screen_name -p $service -X logfile ${logfile}
+        screen -S $screen_name -p $service -X log on
+        ln -sf ${logfile} ${shortlog}
+    fi
+
+    NL=`echo -ne '\015'`
+    # This fun command does the following:
+    # - the passed server command is backgrounded
+    # - the pid of the background process is saved in the usual place
+    # - the server process is brought back to the foreground
+    # - if the server process exits prematurely the fg command errors
+    #   and a message is written to stdout and the service failure file
+    # The pid saved can be used in screen_stop() as a process group
+    # id to kill off all child processes
+    echo "Running: $cmd & echo \$! >$pid; fg || echo \"$service failed to start\" | tee \"$failure\"$NL"
+    screen -S $screen_name -p $service -X stuff "$cmd & echo \$! >$pid; fg || echo \"$service failed to start\" | tee \"$failure\"$NL"
+}
+
+
+function _is_running_in_screen {
+    local service=$1
+    local screen_name=${SCREEN_NAME:-stack}
+    local status_dir=${SERVICE_DIR:-${DEST}/status}
+    local service_dir="$status_dir/$screen_name"
+    local pid="$service_dir/$service.pid"
+    local failure="$service_dir/$service.failure"
+    if [[ ! -e "$pid" && ! -e "$failure" ]]; then
+        # if we don't have a pid or a failure for why, the command may not
+        # have stuffed in there
+        echo "Warning: neither $pid nor $failure exist, $service didn't seem to start"
+        return 1
+    fi
+    if [[ -n ${SCREEN_LOGDIR} ]]; then
+        # if we should be logging, but we don't have a log file, something is wrong
+        local logfile=${SCREEN_LOGDIR}/screen-${service}.${CURRENT_LOG_TIME}.log
+        if [[ ! -e "$logfile" ]]; then
+            echo "Warning: expected logfile $logfile not found, something wrong with starting $service"
+            return 1
+        fi
+    fi
+    return 0
+}
+
 # Helper to launch a service in a named screen
 # screen_it service "command-line"
 function screen_it {
-    SCREEN_NAME=${SCREEN_NAME:-stack}
-    SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
-    USE_SCREEN=$(trueorfalse True $USE_SCREEN)
+    local service=$1
+    local cmd=$2
+    local screen_name=${SCREEN_NAME:-stack}
+    local status_dir=${SERVICE_DIR:-${DEST}/status}
+    local service_dir="$status_dir/$screen_name"
+    local use_screen=$(trueorfalse True $USE_SCREEN)
+    local pid="$service_dir/$service.pid"
 
     if is_service_enabled $1; then
         # Append the service to the screen rc file
-        screen_rc "$1" "$2"
+        screen_rc "$service" "$cmd"
 
-        if [[ "$USE_SCREEN" = "True" ]]; then
-            screen -S $SCREEN_NAME -X screen -t $1
+        if [[ "$use_screen" = "True" ]]; then
+            screen -S $screen_name -X screen -t $service
 
-            if [[ -n ${SCREEN_LOGDIR} ]]; then
-                screen -S $SCREEN_NAME -p $1 -X logfile ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log
-                screen -S $SCREEN_NAME -p $1 -X log on
-                ln -sf ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log ${SCREEN_LOGDIR}/screen-${1}.log
-            fi
-
-            # sleep to allow bash to be ready to be send the command - we are
-            # creating a new window in screen and then sends characters, so if
-            # bash isn't running by the time we send the command, nothing happens
-            sleep 3
-
-            NL=`echo -ne '\015'`
-            # This fun command does the following:
-            # - the passed server command is backgrounded
-            # - the pid of the background process is saved in the usual place
-            # - the server process is brought back to the foreground
-            # - if the server process exits prematurely the fg command errors
-            #   and a message is written to stdout and the service failure file
-            # The pid saved can be used in screen_stop() as a process group
-            # id to kill off all child processes
-            screen -S $SCREEN_NAME -p $1 -X stuff "$2 & echo \$! >$SERVICE_DIR/$SCREEN_NAME/$1.pid; fg || echo \"$1 failed to start\" | tee \"$SERVICE_DIR/$SCREEN_NAME/$1.failure\"$NL"
+            # this retry loop brought to you by slow compute nodes, screen raciness,
+            # and frustration in upgrading.
+            local screen_tries=0
+            while [ "$screen_tries" -lt 10 ]; do
+                _start_in_screen "$service" "$cmd"
+                if _is_running_in_screen $service; then
+                    screen_tries=10
+                else
+                    screen_tries=$[screen_tries + 1]
+                    echo "Failed to start service after $screen_tries attempt(s), retrying"
+                    if [[ "$screen_tries" -eq 10 ]]; then
+                        echo "Too many retries, giving up"
+                        exit 1
+                    fi
+                    sleep 1
+                fi
+            done
         else
             # Spawn directly without screen
-            run_process "$1" "$2" >$SERVICE_DIR/$SCREEN_NAME/$1.pid
+            run_process "$service" "$cmd" >$pid
         fi
     fi
 }
diff --git a/lib/keystone b/lib/keystone
index 5fcd018..41ed4c1 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -41,6 +41,10 @@
 
 KEYSTONECLIENT_DIR=$DEST/python-keystoneclient
 
+# Set up additional extensions, such as oauth1, federation
+# Example of KEYSTONE_EXTENSIONS=oauth1,federation
+KEYSTONE_EXTENSIONS=${KEYSTONE_EXTENSIONS:-}
+
 # Select the backend for Keystone's service catalog
 KEYSTONE_CATALOG_BACKEND=${KEYSTONE_CATALOG_BACKEND:-sql}
 KEYSTONE_CATALOG=$KEYSTONE_CONF_DIR/default_catalog.templates
@@ -153,6 +157,8 @@
         KEYSTONE_PASTE_INI="$KEYSTONE_CONF"
     fi
 
+    configure_keystone_extensions
+
     # Rewrite stock ``keystone.conf``
 
     if is_service_enabled ldap; then
@@ -273,6 +279,25 @@
     fi
 }
 
+function configure_keystone_extensions {
+    # Add keystone extension into keystone v3 application pipeline
+    local extension_value
+    local api_v3
+    local extension
+    local api_v3_extension
+    for extension_value in ${KEYSTONE_EXTENSIONS//,/ }; do
+        if [[ -z "${extension_value}" ]]; then
+            continue
+        fi
+        api_v3=$(iniget $KEYSTONE_PASTE_INI pipeline:api_v3 pipeline)
+        extension=$(echo $api_v3 | sed -ne "/${extension_value}/ p;" )
+        if [[ -z $extension ]]; then
+            api_v3_extension=$(echo $api_v3 | sed -ne "s/service_v3/${extension_value}_extension service_v3/p;" )
+            iniset $KEYSTONE_PASTE_INI pipeline:api_v3 pipeline "$api_v3_extension"
+        fi
+    done
+}
+
 # create_keystone_accounts() - Sets up common required keystone accounts
 
 # Tenant               User       Roles
@@ -386,6 +411,14 @@
     # Initialize keystone database
     $KEYSTONE_DIR/bin/keystone-manage db_sync
 
+    local extension_value
+    for extension_value in ${KEYSTONE_EXTENSIONS//,/ }; do
+        if [[ -z "${extension_value}" ]]; then
+            continue
+        fi
+        $KEYSTONE_DIR/bin/keystone-manage db_sync --extension "${extension_value}"
+    done
+
     if [[ "$KEYSTONE_TOKEN_FORMAT" != "uuid" ]]; then
         # Set up certificates
         rm -rf $KEYSTONE_CONF_DIR/ssl
@@ -446,7 +479,10 @@
     fi
 
     echo "Waiting for keystone to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -k -s $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
+    # Check that the keystone service is running. Even if the tls tunnel
+    # should be enabled, make sure the internal port is checked using
+    # unencryted traffic at this point.
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -k -s http://$KEYSTONE_SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
         die $LINENO "keystone did not start"
     fi
 
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
index e13cbb1..26c5489 100644
--- a/lib/neutron_plugins/ovs_base
+++ b/lib/neutron_plugins/ovs_base
@@ -32,26 +32,24 @@
     done
 }
 
+function _neutron_ovs_base_install_ubuntu_dkms {
+    # install Dynamic Kernel Module Support packages if needed
+    local kernel_version=$(uname -r)
+    local kernel_major_minor=`echo $kernel_version | cut -d. -f1-2`
+    # From kernel 3.13 on, openvswitch-datapath-dkms is not needed
+    if [ `vercmp_numbers "$kernel_major_minor" "3.13"` -lt "0" ]; then
+        install_package "dkms openvswitch-datapath-dkms linux-headers-$kernel_version"
+    fi
+}
+
 function _neutron_ovs_base_install_agent_packages {
-    local kernel_version
     # Install deps
-    # FIXME add to ``files/apts/neutron``, but don't install if not needed!
+    install_package $(get_packages "openvswitch")
     if is_ubuntu; then
-        kernel_version=`cat /proc/version | cut -d " " -f3`
-        ovs_packages="make fakeroot dkms openvswitch-switch"
-        # From kernel 3.13 on, openvswitch-datapath-dkms is not needed
-        kernel_major_minor=`echo $kernel_version | cut -d. -f1-2`
-        if [ `vercmp_numbers "$kernel_major_minor" "3.13"` -lt "0" ]; then
-            ovs_packages="$ovs_packages openvswitch-datapath-dkms"
-        fi
-        ovs_packages="$ovs_packages linux-headers-$kernel_version"
-        install_package $ovs_packages
+        _neutron_ovs_base_install_ubuntu_dkms
     elif is_fedora; then
-        install_package openvswitch
-        # Ensure that the service is started
         restart_service openvswitch
     elif is_suse; then
-        install_package openvswitch-switch
         restart_service openvswitch-switch
     fi
 }
diff --git a/lib/opendaylight b/lib/opendaylight
index 0ac7f2b..33b3f0a 100644
--- a/lib/opendaylight
+++ b/lib/opendaylight
@@ -122,22 +122,10 @@
     unzip -u $ODL_PKG
 }
 
-# install_opendaylight-compute - Make sure OVS is install
+# install_opendaylight-compute - Make sure OVS is installed
 function install_opendaylight-compute {
-    local kernel_version
-    # Install deps
-    # FIXME add to ``files/apts/neutron``, but don't install if not needed!
-    if is_ubuntu; then
-        kernel_version=`cat /proc/version | cut -d " " -f3`
-        install_package make fakeroot dkms openvswitch-switch openvswitch-datapath-dkms linux-headers-$kernel_version
-    elif is_fedora; then
-        install_package openvswitch
-        # Ensure that the service is started
-        restart_service openvswitch
-    elif is_suse; then
-        install_package openvswitch-switch
-        restart_service openvswitch-switch
-    fi
+    # packages are the same as for Neutron OVS agent
+    _neutron_ovs_base_install_agent_packages
 }
 
 # start_opendaylight() - Start running processes, including screen
diff --git a/stack.sh b/stack.sh
index 823f558..ab6dcf3 100755
--- a/stack.sh
+++ b/stack.sh
@@ -211,6 +211,11 @@
 # Additional repos
 # ----------------
 
+# For debian/ubuntu make apt attempt to retry network ops on it's own
+if is_ubuntu; then
+    echo 'APT::Acquire::Retries "20";' | sudo tee /etc/apt/apt.conf.d/80retry
+fi
+
 # Some distros need to add repos beyond the defaults provided by the vendor
 # to pick up required packages.
 
@@ -234,7 +239,7 @@
     fi
     # RHEL requires EPEL for many Open Stack dependencies
     if [[ $DISTRO =~ (rhel7) ]]; then
-        EPEL_RPM=${RHEL7_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/beta/7/x86_64/epel-release-7-0.1.noarch.rpm"}
+        EPEL_RPM=${RHEL7_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/beta/7/x86_64/epel-release-7-0.2.noarch.rpm"}
     else
         EPEL_RPM=${RHEL6_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm"}
     fi
diff --git a/stackrc b/stackrc
index a517fbb..840f3ac 100644
--- a/stackrc
+++ b/stackrc
@@ -366,7 +366,7 @@
 PRECACHE_IMAGES=$(trueorfalse False $PRECACHE_IMAGES)
 if [[ "$PRECACHE_IMAGES" == "True" ]]; then
     # staging in update for nodepool
-    IMAGE_URLS+=",https://dl.fedoraproject.org/pub/fedora/linux/updates/20/Images/x86_64/Fedora-x86_64-20-20140407-sda.qcow2"
+    IMAGE_URLS+=",http://dl.fedoraproject.org/pub/alt/openstack/20/x86_64/Fedora-x86_64-20-20140618-sda.qcow2"
 fi
 
 # 10Gb default volume backing file size
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index a4b3e06..44e8dc1 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -383,13 +383,12 @@
         sleep 10
     done
     echo -n "devstack is running"
-    while ssh_no_check -q stack@$OS_VM_MANAGEMENT_ADDRESS "service devstack status | grep -q running"; do
-        sleep 10
-        echo -n "."
-    done
-    echo "done!"
     set -x
 
+    # Watch devstack's output
+    pid=`ssh_no_check -q stack@$OS_VM_MANAGEMENT_ADDRESS pgrep run.sh`
+    ssh_no_check -q stack@$OS_VM_MANAGEMENT_ADDRESS "tail --pid $pid -n +1 -f /tmp/devstack/log/stack.log"
+
     # Fail if devstack did not succeed
     ssh_no_check -q stack@$OS_VM_MANAGEMENT_ADDRESS 'test -e /var/run/devstack.succeeded'
 
diff --git a/tools/xen/prepare_guest_template.sh b/tools/xen/prepare_guest_template.sh
index eaab2fe..e6a7e02 100755
--- a/tools/xen/prepare_guest_template.sh
+++ b/tools/xen/prepare_guest_template.sh
@@ -70,7 +70,7 @@
 else
     echo "WARNING: no XenServer tools found, falling back to 5.6 tools"
     TOOLS_URL="https://github.com/downloads/citrix-openstack/warehouse/xe-guest-utilities_5.6.100-651_amd64.deb"
-    wget $TOOLS_URL -O $XS_TOOLS_FILE_NAME
+    curl --no-sessionid -L -o "$XS_TOOLS_FILE_NAME" $TOOLS_URL
     cp $XS_TOOLS_FILE_NAME "${STAGING_DIR}${XS_TOOLS_PATH}"
     rm -rf $XS_TOOLS_FILE_NAME
 fi