diff --git a/lib/nova_plugins/hypervisor-xenserver b/lib/nova_plugins/hypervisor-xenserver index f47994f187..9843261065 100644 --- a/lib/nova_plugins/hypervisor-xenserver +++ b/lib/nova_plugins/hypervisor-xenserver @@ -56,6 +56,34 @@ function configure_nova_hypervisor() { # 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 9166a171e1..e362cd1f1d 100644 --- a/stackrc +++ b/stackrc @@ -245,6 +245,10 @@ case "$VIRT_DRIVER" in 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 97c56bc1af..ab0be84bd2 100644 --- a/tools/xen/functions +++ b/tools/xen/functions @@ -336,3 +336,11 @@ function max_vcpus() { 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 d0d81a2d7e..7b59bae6b8 100755 --- a/tools/xen/install_os_domU.sh +++ b/tools/xen/install_os_domU.sh @@ -67,21 +67,6 @@ fi # 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 @@ if [[ "$ENABLED_SERVICES" =~ "q-agt" && "$Q_PLUGIN" = "openvswitch" ]]; then rm -rf "$EXTRACTED_NEUTRON" fi -create_directory_for_kernels -create_directory_for_images - # # Configure Networking # @@ -188,7 +170,7 @@ function wait_for_VM_to_halt() { 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 @@ else 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 05ac86cf99..094612624b 100755 --- a/tools/xen/prepare_guest.sh +++ b/tools/xen/prepare_guest.sh @@ -18,6 +18,57 @@ set -o xtrace 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 @@ useradd $STACK_USER -s /bin/bash -d /opt/stack -G libvirtd 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 4fa70d377d..eaab2feabe 100755 --- a/tools/xen/prepare_guest_template.sh +++ b/tools/xen/prepare_guest_template.sh @@ -86,7 +86,7 @@ cp $STAGING_DIR/etc/rc.local $STAGING_DIR/etc/rc.local.preparebackup cat <$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