Merge "Move install responsibilities to domU"
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/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/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