Merge "Split functions"
diff --git a/driver_certs/cinder_driver_cert.sh b/driver_certs/cinder_driver_cert.sh
index edcc6d4..8380dee 100755
--- a/driver_certs/cinder_driver_cert.sh
+++ b/driver_certs/cinder_driver_cert.sh
@@ -89,9 +89,8 @@
 sleep 5
 
 # run tempest api/volume/test_*
-log_message "Run the actual tempest volume tests (./tools/pretty_tox.sh api.volume_*)...", True
-exec 2> >(tee -a $TEMPFILE)
-`./tools/pretty_tox.sh api.volume`
+log_message "Run the actual tempest volume tests (./tools/pretty_tox.sh api.volume)...", True
+./tools/pretty_tox.sh api.volume 2>&1 | tee -a $TEMPFILE
 if [[ $? = 0 ]]; then
     log_message "CONGRATULATIONS!!!  Device driver PASSED!", True
     log_message "Submit output: ($TEMPFILE)"
diff --git a/lib/cinder b/lib/cinder
index 3ec0fd4..d5e78bb 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -27,6 +27,12 @@
 
 # set up default driver
 CINDER_DRIVER=${CINDER_DRIVER:-default}
+CINDER_PLUGINS=$TOP_DIR/lib/cinder_plugins
+
+# grab plugin config if specified via cinder_driver
+if [[ -r $CINDER_PLUGINS/$CINDER_DRIVER ]]; then
+    source $CINDER_PLUGINS/$CINDER_DRIVER
+fi
 
 # set up default directories
 CINDER_DIR=$DEST/cinder
@@ -178,43 +184,28 @@
 function configure_cinder_rootwrap() {
     # Set the paths of certain binaries
     CINDER_ROOTWRAP=$(get_rootwrap_location cinder)
-    if [[ ! -x $CINDER_ROOTWRAP ]]; then
-        CINDER_ROOTWRAP=$(get_rootwrap_location oslo)
-        if [[ ! -x $CINDER_ROOTWRAP ]]; then
-            die $LINENO "No suitable rootwrap found."
-        fi
-    fi
 
-    # If Cinder ships the new rootwrap filters files, deploy them
-    # (owned by root) and add a parameter to $CINDER_ROOTWRAP
-    ROOTWRAP_CINDER_SUDOER_CMD="$CINDER_ROOTWRAP"
-    if [[ -d $CINDER_DIR/etc/cinder/rootwrap.d ]]; then
-        # Wipe any existing rootwrap.d files first
-        if [[ -d $CINDER_CONF_DIR/rootwrap.d ]]; then
-            sudo rm -rf $CINDER_CONF_DIR/rootwrap.d
-        fi
-        # Deploy filters to /etc/cinder/rootwrap.d
-        sudo mkdir -m 755 $CINDER_CONF_DIR/rootwrap.d
-        sudo cp $CINDER_DIR/etc/cinder/rootwrap.d/*.filters $CINDER_CONF_DIR/rootwrap.d
-        sudo chown -R root:root $CINDER_CONF_DIR/rootwrap.d
-        sudo chmod 644 $CINDER_CONF_DIR/rootwrap.d/*
-        # Set up rootwrap.conf, pointing to /etc/cinder/rootwrap.d
-        if [[ -f $CINDER_DIR/etc/cinder/rootwrap.conf ]]; then
-            sudo cp $CINDER_DIR/etc/cinder/rootwrap.conf $CINDER_CONF_DIR/
-        else
-            # rootwrap.conf is no longer shipped in Cinder itself
-            echo "filters_path=" | sudo tee $CINDER_CONF_DIR/rootwrap.conf > /dev/null
-        fi
-        sudo sed -e "s:^filters_path=.*$:filters_path=$CINDER_CONF_DIR/rootwrap.d:" -i $CINDER_CONF_DIR/rootwrap.conf
-        sudo chown root:root $CINDER_CONF_DIR/rootwrap.conf
-        sudo chmod 0644 $CINDER_CONF_DIR/rootwrap.conf
-        # Specify rootwrap.conf as first parameter to rootwrap
-        CINDER_ROOTWRAP="$CINDER_ROOTWRAP $CINDER_CONF_DIR/rootwrap.conf"
-        ROOTWRAP_CINDER_SUDOER_CMD="$CINDER_ROOTWRAP *"
+    # Deploy new rootwrap filters files (owned by root).
+    # Wipe any existing rootwrap.d files first
+    if [[ -d $CINDER_CONF_DIR/rootwrap.d ]]; then
+        sudo rm -rf $CINDER_CONF_DIR/rootwrap.d
     fi
+    # Deploy filters to /etc/cinder/rootwrap.d
+    sudo mkdir -m 755 $CINDER_CONF_DIR/rootwrap.d
+    sudo cp $CINDER_DIR/etc/cinder/rootwrap.d/*.filters $CINDER_CONF_DIR/rootwrap.d
+    sudo chown -R root:root $CINDER_CONF_DIR/rootwrap.d
+    sudo chmod 644 $CINDER_CONF_DIR/rootwrap.d/*
+    # Set up rootwrap.conf, pointing to /etc/cinder/rootwrap.d
+    sudo cp $CINDER_DIR/etc/cinder/rootwrap.conf $CINDER_CONF_DIR/
+    sudo sed -e "s:^filters_path=.*$:filters_path=$CINDER_CONF_DIR/rootwrap.d:" -i $CINDER_CONF_DIR/rootwrap.conf
+    sudo chown root:root $CINDER_CONF_DIR/rootwrap.conf
+    sudo chmod 0644 $CINDER_CONF_DIR/rootwrap.conf
+    # Specify rootwrap.conf as first parameter to rootwrap
+    ROOTWRAP_CSUDOER_CMD="$CINDER_ROOTWRAP $CINDER_CONF_DIR/rootwrap.conf *"
 
+    # Set up the rootwrap sudoers for cinder
     TEMPFILE=`mktemp`
-    echo "$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_CINDER_SUDOER_CMD" >$TEMPFILE
+    echo "$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_CSUDOER_CMD" >$TEMPFILE
     chmod 0440 $TEMPFILE
     sudo chown root:root $TEMPFILE
     sudo mv $TEMPFILE /etc/sudoers.d/cinder-rootwrap
@@ -308,42 +299,8 @@
         setup_colorized_logging $CINDER_CONF DEFAULT "project_id" "user_id"
     fi
 
-    if [ "$CINDER_DRIVER" == "XenAPINFS" ]; then
-        (
-            set -u
-            iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.xenapi.sm.XenAPINFSDriver"
-            iniset $CINDER_CONF DEFAULT xenapi_connection_url "$CINDER_XENAPI_CONNECTION_URL"
-            iniset $CINDER_CONF DEFAULT xenapi_connection_username "$CINDER_XENAPI_CONNECTION_USERNAME"
-            iniset $CINDER_CONF DEFAULT xenapi_connection_password "$CINDER_XENAPI_CONNECTION_PASSWORD"
-            iniset $CINDER_CONF DEFAULT xenapi_nfs_server "$CINDER_XENAPI_NFS_SERVER"
-            iniset $CINDER_CONF DEFAULT xenapi_nfs_serverpath "$CINDER_XENAPI_NFS_SERVERPATH"
-        )
-    elif [ "$CINDER_DRIVER" == "nfs" ]; then
-        iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.nfs.NfsDriver"
-        iniset $CINDER_CONF DEFAULT nfs_shares_config "$CINDER_CONF_DIR/nfs_shares.conf"
-        echo "$CINDER_NFS_SERVERPATH" | sudo tee "$CINDER_CONF_DIR/nfs_shares.conf"
-        sudo chmod 666 $CINDER_CONF_DIR/nfs_shares.conf
-    elif [ "$CINDER_DRIVER" == "sheepdog" ]; then
-        iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.sheepdog.SheepdogDriver"
-    elif [ "$CINDER_DRIVER" == "glusterfs" ]; then
-        # To use glusterfs, set the following in localrc:
-        # CINDER_DRIVER=glusterfs
-        # CINDER_GLUSTERFS_SHARES="127.0.0.1:/vol1;127.0.0.1:/vol2"
-        # Shares are <host>:<volume> and separated by semicolons.
-
-        iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.glusterfs.GlusterfsDriver"
-        iniset $CINDER_CONF DEFAULT glusterfs_shares_config "$CINDER_CONF_DIR/glusterfs_shares"
-        touch $CINDER_CONF_DIR/glusterfs_shares
-        if [ ! -z "$CINDER_GLUSTERFS_SHARES" ]; then
-            CINDER_GLUSTERFS_SHARES=$(echo $CINDER_GLUSTERFS_SHARES | tr ";" "\n")
-            echo "$CINDER_GLUSTERFS_SHARES" > $CINDER_CONF_DIR/glusterfs_shares
-        fi
-    elif [ "$CINDER_DRIVER" == "vsphere" ]; then
-        echo_summary "Using VMware vCenter driver"
-        iniset $CINDER_CONF DEFAULT vmware_host_ip "$VMWAREAPI_IP"
-        iniset $CINDER_CONF DEFAULT vmware_host_username "$VMWAREAPI_USER"
-        iniset $CINDER_CONF DEFAULT vmware_host_password "$VMWAREAPI_PASSWORD"
-        iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver"
+    if [[ -r $CINDER_PLUGINS/$CINDER_DRIVER ]]; then
+        configure_cinder_driver
     fi
 
     if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
diff --git a/lib/cinder_plugins/XenAPINFS b/lib/cinder_plugins/XenAPINFS
new file mode 100644
index 0000000..72e1c13
--- /dev/null
+++ b/lib/cinder_plugins/XenAPINFS
@@ -0,0 +1,44 @@
+# lib/cinder_plugins/XenAPINFS
+# Configure the XenAPINFS driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=XenAPINFS
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.xenapi.sm.XenAPINFSDriver"
+    iniset $CINDER_CONF DEFAULT xenapi_connection_url "$CINDER_XENAPI_CONNECTION_URL"
+    iniset $CINDER_CONF DEFAULT xenapi_connection_username "$CINDER_XENAPI_CONNECTION_USERNAME"
+    iniset $CINDER_CONF DEFAULT xenapi_connection_password "$CINDER_XENAPI_CONNECTION_PASSWORD"
+    iniset $CINDER_CONF DEFAULT xenapi_nfs_server "$CINDER_XENAPI_NFS_SERVER"
+    iniset $CINDER_CONF DEFAULT xenapi_nfs_serverpath "$CINDER_XENAPI_NFS_SERVERPATH"
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/glusterfs b/lib/cinder_plugins/glusterfs
new file mode 100644
index 0000000..a0c5ae8
--- /dev/null
+++ b/lib/cinder_plugins/glusterfs
@@ -0,0 +1,50 @@
+# lib/cinder_plugins/glusterfs
+# Configure the glusterfs driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=glusterfs
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    # To use glusterfs, set the following in localrc:
+    # CINDER_DRIVER=glusterfs
+    # CINDER_GLUSTERFS_SHARES="127.0.0.1:/vol1;127.0.0.1:/vol2"
+    # Shares are <host>:<volume> and separated by semicolons.
+
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.glusterfs.GlusterfsDriver"
+    iniset $CINDER_CONF DEFAULT glusterfs_shares_config "$CINDER_CONF_DIR/glusterfs_shares"
+    touch $CINDER_CONF_DIR/glusterfs_shares
+    if [ ! -z "$CINDER_GLUSTERFS_SHARES" ]; then
+        CINDER_GLUSTERFS_SHARES=$(echo $CINDER_GLUSTERFS_SHARES | tr ";" "\n")
+        echo "$CINDER_GLUSTERFS_SHARES" > $CINDER_CONF_DIR/glusterfs_shares
+    fi
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/nfs b/lib/cinder_plugins/nfs
new file mode 100644
index 0000000..ea2c9ce
--- /dev/null
+++ b/lib/cinder_plugins/nfs
@@ -0,0 +1,42 @@
+# lib/cinder_plugins/nfs
+# Configure the nfs driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=nfs
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.nfs.NfsDriver"
+    iniset $CINDER_CONF DEFAULT nfs_shares_config "$CINDER_CONF_DIR/nfs_shares.conf"
+    echo "$CINDER_NFS_SERVERPATH" | sudo tee "$CINDER_CONF_DIR/nfs_shares.conf"
+    sudo chmod 660 $CINDER_CONF_DIR/nfs_shares.conf
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/sheepdog b/lib/cinder_plugins/sheepdog
new file mode 100644
index 0000000..4435932
--- /dev/null
+++ b/lib/cinder_plugins/sheepdog
@@ -0,0 +1,39 @@
+# lib/cinder_plugins/sheepdog
+# Configure the sheepdog driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=sheepdog
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.sheepdog.SheepdogDriver"
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/solidfire b/lib/cinder_plugins/solidfire
new file mode 100644
index 0000000..47c113e
--- /dev/null
+++ b/lib/cinder_plugins/solidfire
@@ -0,0 +1,48 @@
+# lib/cinder_plugins/solidfire
+# Configure the solidfire driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=solidfire
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    # To use solidfire, set the following in localrc:
+    # CINDER_DRIVER=solidfire
+    # SAN_IP=<mvip>
+    # SAN_LOGIN=<cluster-admin-account>
+    # SAN_PASSWORD=<cluster-admin-password>
+
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.solidfire.SolidFireDriver"
+    iniset $CINDER_CONF DEFAULT san_ip $SAN_IP
+    iniset $CINDER_CONF DEFAULT san_login $SAN_LOGIN
+    iniset $CINDER_CONF DEFAULT san_password $SAN_PASSWORD
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/vsphere b/lib/cinder_plugins/vsphere
new file mode 100644
index 0000000..c8cab6a
--- /dev/null
+++ b/lib/cinder_plugins/vsphere
@@ -0,0 +1,42 @@
+# lib/cinder_plugins/vsphere
+# Configure the vsphere driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=vsphere
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    iniset $CINDER_CONF DEFAULT vmware_host_ip "$VMWAREAPI_IP"
+    iniset $CINDER_CONF DEFAULT vmware_host_username "$VMWAREAPI_USER"
+    iniset $CINDER_CONF DEFAULT vmware_host_password "$VMWAREAPI_PASSWORD"
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver"
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/ironic b/lib/ironic
index 0b9df57..3c0e3cb 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -112,11 +112,6 @@
     iniset $IRONIC_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
     iniset $IRONIC_CONF_FILE keystone_authtoken admin_user ironic
     iniset $IRONIC_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
-    if is_service_enabled qpid; then
-        iniset $IRONIC_CONF_FILE DEFAULT notifier_strategy qpid
-    elif [ -n "$RABBIT_HOST" ] &&  [ -n "$RABBIT_PASSWORD" ]; then
-        iniset $IRONIC_CONF_FILE DEFAULT notifier_strategy rabbit
-    fi
     iniset_rpc_backend ironic $IRONIC_CONF_FILE DEFAULT
     iniset $IRONIC_CONF_FILE keystone_authtoken signing_dir $IRONIC_AUTH_CACHE_DIR/api
 
diff --git a/lib/marconi b/lib/marconi
index 1eaebbd..7c8fd14 100644
--- a/lib/marconi
+++ b/lib/marconi
@@ -58,6 +58,13 @@
 # Functions
 # ---------
 
+# Test if any Marconi services are enabled
+# is_marconi_enabled
+function is_marconi_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"marconi-" ]] && return 0
+    return 1
+}
+
 # cleanup_marconi() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_marconi() {
@@ -82,10 +89,6 @@
     iniset $MARCONI_CONF DEFAULT verbose True
     iniset $MARCONI_CONF 'drivers:transport:wsgi' bind '0.0.0.0'
 
-    # Install the policy file for the API server
-    cp $MARCONI_DIR/etc/marconi/policy.json $MARCONI_CONF_DIR
-    iniset $MARCONI_CONF DEFAULT policy_file $MARCONI_CONF_DIR/policy.json
-
     iniset $MARCONI_CONF keystone_authtoken auth_protocol http
     iniset $MARCONI_CONF keystone_authtoken admin_user marconi
     iniset $MARCONI_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
@@ -102,9 +105,16 @@
 function configure_mongodb() {
     # Set nssize to 2GB. This increases the number of namespaces supported
     # # per database.
-    sudo sed -i '/--nssize/!s/OPTIONS=\"/OPTIONS=\"--nssize 2047 /' /etc/sysconfig/mongod
-
-    restart_service mongod
+    if is_ubuntu; then
+        sudo sed -i -e "
+            s|[^ \t]*#[ \t]*\(nssize[ \t]*=.*\$\)|\1|
+            s|^\(nssize[ \t]*=[ \t]*\).*\$|\1 2047|
+        " /etc/mongodb.conf
+        restart_service mongodb
+    elif is_fedora; then
+        sudo sed -i '/--nssize/!s/OPTIONS=\"/OPTIONS=\"--nssize 2047 /' /etc/sysconfig/mongod
+        restart_service mongod
+    fi
 }
 
 # init_marconi() - Initialize etc.
@@ -147,10 +157,12 @@
     MARCONI_USER=$(get_id keystone user-create --name=marconi \
                                                 --pass="$SERVICE_PASSWORD" \
                                                 --tenant-id $SERVICE_TENANT \
-                                                --email=marconi@example.com)
+                                                --email=marconi@example.com \
+                                                | grep " id " | get_field 2)
     keystone user-role-add --tenant-id $SERVICE_TENANT \
                             --user-id $MARCONI_USER \
                             --role-id $ADMIN_ROLE
+
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
         MARCONI_SERVICE=$(keystone service-create \
             --name=marconi \
diff --git a/lib/nova_plugins/hypervisor-docker b/lib/nova_plugins/hypervisor-docker
index bb934b8..cdd9317 100644
--- a/lib/nova_plugins/hypervisor-docker
+++ b/lib/nova_plugins/hypervisor-docker
@@ -31,8 +31,8 @@
 DOCKER_PID_FILE=/var/run/docker.pid
 DOCKER_REGISTRY_PORT=${DOCKER_REGISTRY_PORT:-5042}
 
-DOCKER_IMAGE=${DOCKER_IMAGE:-busybox:latest}
-DOCKER_IMAGE_NAME=busybox
+DOCKER_IMAGE=${DOCKER_IMAGE:-cirros:latest}
+DOCKER_IMAGE_NAME=cirros
 DOCKER_REGISTRY_IMAGE=${DOCKER_REGISTRY_IMAGE:-registry:latest}
 DOCKER_REGISTRY_IMAGE_NAME=registry
 DOCKER_REPOSITORY_NAME=${SERVICE_HOST}:${DOCKER_REGISTRY_PORT}/${DOCKER_IMAGE_NAME}
diff --git a/lib/nova_plugins/hypervisor-xenserver b/lib/nova_plugins/hypervisor-xenserver
index f47994f..9843261 100644
--- a/lib/nova_plugins/hypervisor-xenserver
+++ b/lib/nova_plugins/hypervisor-xenserver
@@ -56,6 +56,34 @@
     # Need to avoid crash due to new firewall support
     XEN_FIREWALL_DRIVER=${XEN_FIREWALL_DRIVER:-"nova.virt.firewall.IptablesFirewallDriver"}
     iniset $NOVA_CONF DEFAULT firewall_driver "$XEN_FIREWALL_DRIVER"
+
+    local dom0_ip
+    dom0_ip=$(echo "$XENAPI_CONNECTION_URL" | cut -d "/" -f 3-)
+
+    local ssh_dom0
+    ssh_dom0="sudo -u $DOMZERO_USER ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@$dom0_ip"
+
+    # install nova plugins to dom0
+    tar -czf - -C $NOVA_DIR/plugins/xenserver/xenapi/etc/xapi.d/plugins/ ./ |
+        $ssh_dom0 'tar -xzf - -C /etc/xapi.d/plugins/ && chmod a+x /etc/xapi.d/plugins/*'
+
+    # install console logrotate script
+    tar -czf - -C $NOVA_DIR/tools/xenserver/ rotate_xen_guest_logs.sh |
+        $ssh_dom0 'tar -xzf - -C /root/ && chmod +x /root/rotate_xen_guest_logs.sh && mkdir -p /var/log/xen/guest'
+
+    # Create a cron job that will rotate guest logs
+    $ssh_dom0 crontab - << CRONTAB
+* * * * * /root/rotate_xen_guest_logs.sh
+CRONTAB
+
+    # Create directories for kernels and images
+    {
+        echo "set -eux"
+        cat $TOP_DIR/tools/xen/functions
+        echo "create_directory_for_images"
+        echo "create_directory_for_kernels"
+    } | $ssh_dom0
+
 }
 
 # install_nova_hypervisor() - Install external components
diff --git a/lib/swift b/lib/swift
index 0febb00..be25c81 100644
--- a/lib/swift
+++ b/lib/swift
@@ -520,6 +520,11 @@
 # swifttenanttest2   swiftusertest2     admin
 
 function create_swift_accounts() {
+    # Defines specific passwords used by tools/create_userrc.sh
+    SWIFTUSERTEST1_PASSWORD=testing
+    SWIFTUSERTEST2_PASSWORD=testing2
+    SWIFTUSERTEST3_PASSWORD=testing3
+
     KEYSTONE_CATALOG_BACKEND=${KEYSTONE_CATALOG_BACKEND:-sql}
 
     SERVICE_TENANT=$(keystone tenant-list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
@@ -542,17 +547,17 @@
 
     SWIFT_TENANT_TEST1=$(keystone tenant-create --name=swifttenanttest1 | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_TENANT_TEST1 "Failure creating SWIFT_TENANT_TEST1"
-    SWIFT_USER_TEST1=$(keystone user-create --name=swiftusertest1 --pass=testing --email=test@example.com | grep " id " | get_field 2)
+    SWIFT_USER_TEST1=$(keystone user-create --name=swiftusertest1 --pass=$SWIFTUSERTEST1_PASSWORD --email=test@example.com | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_USER_TEST1 "Failure creating SWIFT_USER_TEST1"
     keystone user-role-add --user-id $SWIFT_USER_TEST1 --role-id $ADMIN_ROLE --tenant-id $SWIFT_TENANT_TEST1
 
-    SWIFT_USER_TEST3=$(keystone user-create --name=swiftusertest3 --pass=testing3 --email=test3@example.com | grep " id " | get_field 2)
+    SWIFT_USER_TEST3=$(keystone user-create --name=swiftusertest3 --pass=$SWIFTUSERTEST3_PASSWORD --email=test3@example.com | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_USER_TEST3 "Failure creating SWIFT_USER_TEST3"
     keystone user-role-add --user-id $SWIFT_USER_TEST3 --role-id $ANOTHER_ROLE --tenant-id $SWIFT_TENANT_TEST1
 
     SWIFT_TENANT_TEST2=$(keystone tenant-create --name=swifttenanttest2 | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_TENANT_TEST2 "Failure creating SWIFT_TENANT_TEST2"
-    SWIFT_USER_TEST2=$(keystone user-create --name=swiftusertest2 --pass=testing2 --email=test2@example.com | grep " id " | get_field 2)
+    SWIFT_USER_TEST2=$(keystone user-create --name=swiftusertest2 --pass=$SWIFTUSERTEST2_PASSWORD --email=test2@example.com | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_USER_TEST2 "Failure creating SWIFT_USER_TEST2"
     keystone user-role-add --user-id $SWIFT_USER_TEST2 --role-id $ADMIN_ROLE --tenant-id $SWIFT_TENANT_TEST2
 }
diff --git a/lib/tempest b/lib/tempest
index 76da170..c8eebfc 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -348,9 +348,6 @@
         fi
     done
 
-    echo "Created tempest configuration file:"
-    cat $TEMPEST_CONFIG
-
     # Restore IFS
     IFS=$ifs
     #Restore errexit
diff --git a/stack.sh b/stack.sh
index e45707b..c153132 100755
--- a/stack.sh
+++ b/stack.sh
@@ -1102,6 +1102,47 @@
     start_glance
 fi
 
+# Install Images
+# ==============
+
+# Upload an image to glance.
+#
+# The default image is cirros, a small testing image which lets you login as **root**
+# cirros has a ``cloud-init`` analog supporting login via keypair and sending
+# scripts as userdata.
+# See https://help.ubuntu.com/community/CloudInit for more on cloud-init
+#
+# Override ``IMAGE_URLS`` with a comma-separated list of UEC images.
+#  * **precise**: http://uec-images.ubuntu.com/precise/current/precise-server-cloudimg-amd64.tar.gz
+
+if is_service_enabled g-reg; then
+    TOKEN=$(keystone token-get | grep ' id ' | get_field 2)
+    die_if_not_set $LINENO TOKEN "Keystone fail to get token"
+
+    if is_baremetal; then
+        echo_summary "Creating and uploading baremetal images"
+
+        # build and upload separate deploy kernel & ramdisk
+        upload_baremetal_deploy $TOKEN
+
+        # upload images, separating out the kernel & ramdisk for PXE boot
+        for image_url in ${IMAGE_URLS//,/ }; do
+            upload_baremetal_image $image_url $TOKEN
+        done
+    else
+        echo_summary "Uploading images"
+
+        # Option to upload legacy ami-tty, which works with xenserver
+        if [[ -n "$UPLOAD_LEGACY_TTY" ]]; then
+            IMAGE_URLS="${IMAGE_URLS:+${IMAGE_URLS},}https://github.com/downloads/citrix-openstack/warehouse/tty.tgz"
+        fi
+
+        for image_url in ${IMAGE_URLS//,/ }; do
+            upload_image $image_url $TOKEN
+        done
+    fi
+fi
+
 # 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)
@@ -1181,7 +1222,7 @@
 
 # Configure and launch heat engine, api and metadata
 if is_service_enabled heat; then
-    # Initialize heat, including replacing nova flavors
+    # Initialize heat
     echo_summary "Configuring Heat"
     init_heat
     echo_summary "Starting Heat"
@@ -1207,47 +1248,6 @@
 fi
 
 
-# Install Images
-# ==============
-
-# Upload an image to glance.
-#
-# The default image is cirros, a small testing image which lets you login as **root**
-# cirros has a ``cloud-init`` analog supporting login via keypair and sending
-# scripts as userdata.
-# See https://help.ubuntu.com/community/CloudInit for more on cloud-init
-#
-# Override ``IMAGE_URLS`` with a comma-separated list of UEC images.
-#  * **precise**: http://uec-images.ubuntu.com/precise/current/precise-server-cloudimg-amd64.tar.gz
-
-if is_service_enabled g-reg; then
-    TOKEN=$(keystone token-get | grep ' id ' | get_field 2)
-    die_if_not_set $LINENO TOKEN "Keystone fail to get token"
-
-    if is_baremetal; then
-        echo_summary "Creating and uploading baremetal images"
-
-        # build and upload separate deploy kernel & ramdisk
-        upload_baremetal_deploy $TOKEN
-
-        # upload images, separating out the kernel & ramdisk for PXE boot
-        for image_url in ${IMAGE_URLS//,/ }; do
-            upload_baremetal_image $image_url $TOKEN
-        done
-    else
-        echo_summary "Uploading images"
-
-        # Option to upload legacy ami-tty, which works with xenserver
-        if [[ -n "$UPLOAD_LEGACY_TTY" ]]; then
-            IMAGE_URLS="${IMAGE_URLS:+${IMAGE_URLS},}https://github.com/downloads/citrix-openstack/warehouse/tty.tgz"
-        fi
-
-        for image_url in ${IMAGE_URLS//,/ }; do
-            upload_image $image_url $TOKEN
-        done
-    fi
-fi
-
 # If we are running nova with baremetal driver, there are a few
 # last-mile configuration bits to attend to, which must happen
 # after n-api and n-sch have started.
@@ -1350,11 +1350,6 @@
     echo "Horizon is now available at http://$SERVICE_HOST/"
 fi
 
-# Warn that the default flavors have been changed by Heat
-if is_service_enabled heat; then
-    echo "Heat has replaced the default flavors. View by running: nova flavor-list"
-fi
-
 # If Keystone is present you can point ``nova`` cli to this server
 if is_service_enabled key; then
     echo "Keystone is serving at $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/"
diff --git a/stackrc b/stackrc
index 9166a17..e362cd1 100644
--- a/stackrc
+++ b/stackrc
@@ -245,6 +245,10 @@
     xenserver)
         # Xen config common to nova and neutron
         XENAPI_USER=${XENAPI_USER:-"root"}
+        # This user will be used for dom0 - domU communication
+        #   should be able to log in to dom0 without a password
+        #   will be used to install the plugins
+        DOMZERO_USER=${DOMZERO_USER:-"domzero"}
         ;;
     *)
         ;;
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index e2d855c..d9c93cc 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -253,6 +253,14 @@
             if [ $MODE = one -a "$user_name" != "$USER_NAME" ]; then
                 continue;
             fi
+
+            # Checks for a specific password defined for an user.
+            # Example for an username johndoe:
+            #                     JOHNDOE_PASSWORD=1234
+            eval SPECIFIC_UPASSWORD="\$${USER_NAME^^}_PASSWORD"
+            if [ -n "$SPECIFIC_UPASSWORD" ]; then
+                USER_PASS=$SPECIFIC_UPASSWORD
+            fi
             add_entry "$user_id" "$user_name" "$tenant_id" "$tenant_name" "$USER_PASS"
         done
     done
diff --git a/tools/docker/install_docker.sh b/tools/docker/install_docker.sh
index 4fa2386..27c8c82 100755
--- a/tools/docker/install_docker.sh
+++ b/tools/docker/install_docker.sh
@@ -30,15 +30,19 @@
 # Install Docker Service
 # ======================
 
-# Stop the auto-repo updates and do it when required here
-NO_UPDATE_REPOS=True
+if is_fedora; then
+    install_package docker-io socat
+else
+    # Stop the auto-repo updates and do it when required here
+    NO_UPDATE_REPOS=True
 
-# Set up home repo
-curl https://get.docker.io/gpg | sudo apt-key add -
-install_package python-software-properties && \
-    sudo sh -c "echo deb $DOCKER_APT_REPO docker main > /etc/apt/sources.list.d/docker.list"
-apt_get update
-install_package --force-yes lxc-docker socat
+    # Set up home repo
+    curl https://get.docker.io/gpg | sudo apt-key add -
+    install_package python-software-properties && \
+        sudo sh -c "echo deb $DOCKER_APT_REPO docker main > /etc/apt/sources.list.d/docker.list"
+    apt_get update
+    install_package --force-yes lxc-docker socat
+fi
 
 # Start the daemon - restart just in case the package ever auto-starts...
 restart_service docker
@@ -60,5 +64,5 @@
 docker tag $DOCKER_IMAGE $DOCKER_IMAGE_NAME
 
 # Get docker-registry image
-docker pull $REGISTRY_IMAGE
-docker tag $REGISTRY_IMAGE $REGISTRY_IMAGE_NAME
+docker pull $DOCKER_REGISTRY_IMAGE
+docker tag $DOCKER_REGISTRY_IMAGE $DOCKER_REGISTRY_IMAGE_NAME
diff --git a/tools/xen/functions b/tools/xen/functions
index 97c56bc..ab0be84 100644
--- a/tools/xen/functions
+++ b/tools/xen/functions
@@ -336,3 +336,11 @@
     xe vm-param-set uuid=$vm VCPUs-max=$cpu_count
     xe vm-param-set uuid=$vm VCPUs-at-startup=$cpu_count
 }
+
+function get_domid() {
+    local vm_name_label
+
+    vm_name_label="$1"
+
+    xe vm-list name-label="$vm_name_label" params=dom-id minimal=true
+}
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index d0d81a2..7b59bae 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -67,21 +67,6 @@
 
 # Install plugins
 
-## Nova plugins
-NOVA_ZIPBALL_URL=${NOVA_ZIPBALL_URL:-$(zip_snapshot_location $NOVA_REPO $NOVA_BRANCH)}
-EXTRACTED_NOVA=$(extract_remote_zipball "$NOVA_ZIPBALL_URL")
-install_xapi_plugins_from "$EXTRACTED_NOVA"
-
-LOGROT_SCRIPT=$(find "$EXTRACTED_NOVA" -name "rotate_xen_guest_logs.sh" -print)
-if [ -n "$LOGROT_SCRIPT" ]; then
-    mkdir -p "/var/log/xen/guest"
-    cp "$LOGROT_SCRIPT" /root/consolelogrotate
-    chmod +x /root/consolelogrotate
-    echo "* * * * * /root/consolelogrotate" | crontab
-fi
-
-rm -rf "$EXTRACTED_NOVA"
-
 ## Install the netwrap xapi plugin to support agent control of dom0 networking
 if [[ "$ENABLED_SERVICES" =~ "q-agt" && "$Q_PLUGIN" = "openvswitch" ]]; then
     NEUTRON_ZIPBALL_URL=${NEUTRON_ZIPBALL_URL:-$(zip_snapshot_location $NEUTRON_REPO $NEUTRON_BRANCH)}
@@ -90,9 +75,6 @@
     rm -rf "$EXTRACTED_NEUTRON"
 fi
 
-create_directory_for_kernels
-create_directory_for_images
-
 #
 # Configure Networking
 #
@@ -188,7 +170,7 @@
     set +x
     echo "Waiting for the VM to halt.  Progress in-VM can be checked with vncviewer:"
     mgmt_ip=$(echo $XENAPI_CONNECTION_URL | tr -d -c '1234567890.')
-    domid=$(xe vm-list name-label="$GUEST_NAME" params=dom-id minimal=true)
+    domid=$(get_domid "$GUEST_NAME")
     port=$(xenstore-read /local/domain/$domid/console/vnc-port)
     echo "vncviewer -via root@$mgmt_ip localhost:${port:2}"
     while true; do
@@ -359,6 +341,37 @@
     fi
 fi
 
+# Create an ssh-keypair, and set it up for dom0 user
+rm -f /root/dom0key /root/dom0key.pub
+ssh-keygen -f /root/dom0key -P "" -C "dom0"
+DOMID=$(get_domid "$GUEST_NAME")
+
+xenstore-write /local/domain/$DOMID/authorized_keys/$DOMZERO_USER "$(cat /root/dom0key.pub)"
+xenstore-chmod -u /local/domain/$DOMID/authorized_keys/$DOMZERO_USER r$DOMID
+
+function run_on_appliance() {
+    ssh \
+        -i /root/dom0key \
+        -o UserKnownHostsFile=/dev/null \
+        -o StrictHostKeyChecking=no \
+        -o BatchMode=yes \
+        "$DOMZERO_USER@$OS_VM_MANAGEMENT_ADDRESS" "$@"
+}
+
+# Wait until we can log in to the appliance
+while ! run_on_appliance true; do
+    sleep 1
+done
+
+# Remove authenticated_keys updater cronjob
+echo "" | run_on_appliance crontab -
+
+# Generate a passwordless ssh key for domzero user
+echo "ssh-keygen -f /home/$DOMZERO_USER/.ssh/id_rsa -C $DOMZERO_USER@appliance -N \"\" -q" | run_on_appliance
+
+# Authenticate that user to dom0
+run_on_appliance cat /home/$DOMZERO_USER/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
+
 # If we have copied our ssh credentials, use ssh to monitor while the installation runs
 WAIT_TILL_LAUNCH=${WAIT_TILL_LAUNCH:-1}
 COPYENV=${COPYENV:-1}
diff --git a/tools/xen/prepare_guest.sh b/tools/xen/prepare_guest.sh
index 05ac86c..0946126 100755
--- a/tools/xen/prepare_guest.sh
+++ b/tools/xen/prepare_guest.sh
@@ -18,6 +18,57 @@
 GUEST_PASSWORD="$1"
 XS_TOOLS_PATH="$2"
 STACK_USER="$3"
+DOMZERO_USER="$4"
+
+
+function setup_domzero_user() {
+    local username
+
+    username="$1"
+
+    local key_updater_script
+    local sudoers_file
+    key_updater_script="/home/$username/update_authorized_keys.sh"
+    sudoers_file="/etc/sudoers.d/allow_$username"
+
+    # Create user
+    adduser --disabled-password --quiet "$username" --gecos "$username"
+
+    # Give passwordless sudo
+    cat > $sudoers_file << EOF
+    $username ALL = NOPASSWD: ALL
+EOF
+    chmod 0440 $sudoers_file
+
+    # A script to populate this user's authenticated_keys from xenstore
+    cat > $key_updater_script << EOF
+#!/bin/bash
+set -eux
+
+DOMID=\$(sudo xenstore-read domid)
+sudo xenstore-exists /local/domain/\$DOMID/authorized_keys/$username
+sudo xenstore-read /local/domain/\$DOMID/authorized_keys/$username > /home/$username/xenstore_value
+cat /home/$username/xenstore_value > /home/$username/.ssh/authorized_keys
+EOF
+
+    # Give the key updater to the user
+    chown $username:$username $key_updater_script
+    chmod 0700 $key_updater_script
+
+    # Setup the .ssh folder
+    mkdir -p /home/$username/.ssh
+    chown $username:$username /home/$username/.ssh
+    chmod 0700 /home/$username/.ssh
+    touch /home/$username/.ssh/authorized_keys
+    chown $username:$username /home/$username/.ssh/authorized_keys
+    chmod 0600 /home/$username/.ssh/authorized_keys
+
+    # Setup the key updater as a cron job
+    crontab -u $username - << EOF
+* * * * * $key_updater_script
+EOF
+
+}
 
 # Install basics
 apt-get update
@@ -48,6 +99,8 @@
 echo $STACK_USER:$GUEST_PASSWORD | chpasswd
 echo "$STACK_USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
 
+setup_domzero_user "$DOMZERO_USER"
+
 # Add an udev rule, so that new block devices could be written by stack user
 cat > /etc/udev/rules.d/50-openstack-blockdev.rules << EOF
 KERNEL=="xvd[b-z]", GROUP="$STACK_USER", MODE="0660"
diff --git a/tools/xen/prepare_guest_template.sh b/tools/xen/prepare_guest_template.sh
index 4fa70d3..eaab2fe 100755
--- a/tools/xen/prepare_guest_template.sh
+++ b/tools/xen/prepare_guest_template.sh
@@ -86,7 +86,7 @@
 cat <<EOF >$STAGING_DIR/etc/rc.local
 #!/bin/sh -e
 bash /opt/stack/prepare_guest.sh \\
-    "$GUEST_PASSWORD" "$XS_TOOLS_PATH" "$STACK_USER" \\
+    "$GUEST_PASSWORD" "$XS_TOOLS_PATH" "$STACK_USER" "$DOMZERO_USER" \\
     > /opt/stack/prepare_guest.log 2>&1
 EOF