349 lines
9.5 KiB
Bash
Executable File
349 lines
9.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# This script is run by install_on_xen_host.sh
|
|
#
|
|
# It modifies the ubuntu image created by install_on_xen_host.sh
|
|
# and previously moodified by prepare_guest_template.sh
|
|
#
|
|
# This script is responsible for:
|
|
# - creates a DomU VM
|
|
# - creating run.sh, to run the code on DomU boot
|
|
#
|
|
# by install_on_xen_host.sh
|
|
|
|
# Exit on errors
|
|
set -o errexit
|
|
# Echo commands
|
|
set -o xtrace
|
|
|
|
# This directory
|
|
THIS_DIR=$(cd $(dirname "$0") && pwd)
|
|
TOP_DIR="$THIS_DIR/../"
|
|
SCRIPT_DIR="$TOP_DIR/scripts"
|
|
COMM_DIR="$TOP_DIR/common"
|
|
CONF_DIR="$TOP_DIR/conf"
|
|
|
|
# Include onexit commands
|
|
. $SCRIPT_DIR/on_exit.sh
|
|
|
|
# xapi functions
|
|
. $COMM_DIR/functions
|
|
|
|
# Source params
|
|
source $CONF_DIR/xenrc
|
|
|
|
# Defaults for optional arguments
|
|
DEVSTACK_SRC=${DEVSTACK_SRC:-"https://github.com/openstack-dev/devstack"}
|
|
LOGDIR="/opt/stack/devstack_logs"
|
|
|
|
# Number of options passed to this script
|
|
REMAINING_OPTIONS="$#"
|
|
# Get optional parameters
|
|
set +e
|
|
while getopts ":d:l:" flag; do
|
|
REMAINING_OPTIONS=$(expr "$REMAINING_OPTIONS" - 1)
|
|
case "$flag" in
|
|
d)
|
|
DEVSTACK_SRC="$DEVSTACK_SRC"
|
|
REMAINING_OPTIONS=$(expr "$REMAINING_OPTIONS" - 1)
|
|
;;
|
|
l)
|
|
LOGDIR="$LOGDIR"
|
|
REMAINING_OPTIONS=$(expr "$REMAINING_OPTIONS" - 1)
|
|
;;
|
|
\?)
|
|
print_usage_and_die "Invalid option -$OPTARG"
|
|
;;
|
|
esac
|
|
done
|
|
set -e
|
|
|
|
# Make sure that all options processed
|
|
if [ "0" != "$REMAINING_OPTIONS" ]; then
|
|
print_usage_and_die "ERROR: some arguments were not recognised!"
|
|
fi
|
|
|
|
#
|
|
# Prepare VM for DevStack
|
|
#
|
|
|
|
#
|
|
# Configure Networking
|
|
#
|
|
|
|
MGT_NETWORK=`xe pif-list management=true params=network-uuid minimal=true`
|
|
MGT_BRIDGE_OR_NET_NAME=`xe network-list uuid=$MGT_NETWORK params=bridge minimal=true`
|
|
|
|
setup_network "$VM_BRIDGE_OR_NET_NAME"
|
|
setup_network "$MGT_BRIDGE_OR_NET_NAME"
|
|
setup_network "$PUB_BRIDGE_OR_NET_NAME"
|
|
|
|
if parameter_is_specified "FLAT_NETWORK_BRIDGE"; then
|
|
if [ "$(bridge_for "$VM_BRIDGE_OR_NET_NAME")" != "$(bridge_for "$FLAT_NETWORK_BRIDGE")" ]; then
|
|
cat >&2 << EOF
|
|
ERROR: FLAT_NETWORK_BRIDGE is specified in localrc file, and either no network
|
|
found on XenServer by searching for networks by that value as name-label or
|
|
bridge name or the network found does not match the network specified by
|
|
VM_BRIDGE_OR_NET_NAME. Please check your localrc file.
|
|
EOF
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if ! xenapi_is_listening_on "$MGT_BRIDGE_OR_NET_NAME"; then
|
|
cat >&2 << EOF
|
|
ERROR: XenAPI does not have an assigned IP address on the management network.
|
|
please review your XenServer network configuration / localrc file.
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
HOST_IP=$(xenapi_ip_on "$MGT_BRIDGE_OR_NET_NAME")
|
|
|
|
# Also, enable ip forwarding in rc.local, since the above trick isn't working
|
|
if ! grep -q "echo 1 >/proc/sys/net/ipv4/ip_forward" /etc/rc.local; then
|
|
echo "echo 1 >/proc/sys/net/ipv4/ip_forward" >> /etc/rc.local
|
|
fi
|
|
# Enable ip forwarding at runtime as well
|
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
|
|
|
HOST_IP=$(xenapi_ip_on "$MGT_BRIDGE_OR_NET_NAME")
|
|
|
|
#install the previous ubuntu VM
|
|
|
|
vm_exist=$(xe vm-list name-label="$DEV_STACK_DOMU_NAME" --minimal)
|
|
if [ "$vm_exist" != "" ]
|
|
then
|
|
echo "Uninstall the previous VM"
|
|
xe vm-uninstall vm="$DEV_STACK_DOMU_NAME" force=true
|
|
fi
|
|
|
|
echo "Install a new ubuntu VM according to previous template"
|
|
|
|
vm_uuid=$(xe vm-install template="$TNAME" new-name-label="$DEV_STACK_DOMU_NAME")
|
|
|
|
xe vm-param-set other-config:os-vpx=true uuid="$vm_uuid"
|
|
|
|
# Install XenServer tools, and other such things
|
|
$SCRIPT_DIR/prepare_guest_template.sh "$DEV_STACK_DOMU_NAME"
|
|
|
|
# Set virtual machine parameters
|
|
set_vm_memory "$DEV_STACK_DOMU_NAME" "$VM_MEM_MB"
|
|
|
|
# Max out VCPU count for better performance
|
|
max_vcpus "$DEV_STACK_DOMU_NAME"
|
|
|
|
# Wipe out all network cards
|
|
destroy_all_vifs_of "$DEV_STACK_DOMU_NAME"
|
|
|
|
# Add only one interface to prepare the guest template
|
|
add_interface "$DEV_STACK_DOMU_NAME" "$MGT_BRIDGE_OR_NET_NAME" "0"
|
|
|
|
# start the VM to run the prepare steps
|
|
xe vm-start vm="$DEV_STACK_DOMU_NAME"
|
|
|
|
# Wait for prep script to finish and shutdown system
|
|
wait_for_VM_to_halt "$DEV_STACK_DOMU_NAME"
|
|
|
|
## Setup network cards
|
|
# Wipe out all
|
|
destroy_all_vifs_of "$DEV_STACK_DOMU_NAME"
|
|
# Tenant network
|
|
add_interface "$DEV_STACK_DOMU_NAME" "$VM_BRIDGE_OR_NET_NAME" "$VM_DEV_NR"
|
|
# Management network
|
|
add_interface "$DEV_STACK_DOMU_NAME" "$MGT_BRIDGE_OR_NET_NAME" "$MGT_DEV_NR"
|
|
# Public network
|
|
add_interface "$DEV_STACK_DOMU_NAME" "$PUB_BRIDGE_OR_NET_NAME" "$PUB_DEV_NR"
|
|
|
|
#
|
|
# persistant the VM's interfaces
|
|
#
|
|
$SCRIPT_DIR/persist_domU_interfaces.sh "$DEV_STACK_DOMU_NAME"
|
|
|
|
|
|
FLAT_NETWORK_BRIDGE="${FLAT_NETWORK_BRIDGE:-$(bridge_for "$VM_BRIDGE_OR_NET_NAME")}"
|
|
append_kernel_cmdline "$DEV_STACK_DOMU_NAME" "flat_network_bridge=${FLAT_NETWORK_BRIDGE}"
|
|
|
|
# Add a separate xvdb, if it was requested
|
|
if [[ "0" != "$XEN_XVDB_SIZE_GB" ]]; then
|
|
vm=$(xe vm-list name-label="$DEV_STACK_DOMU_NAME" --minimal)
|
|
|
|
# Add a new disk
|
|
localsr=$(get_local_sr)
|
|
extra_vdi=$(xe vdi-create \
|
|
name-label=xvdb-added-by-devstack \
|
|
virtual-size="${XEN_XVDB_SIZE_GB}GiB" \
|
|
sr-uuid=$localsr type=user)
|
|
xe vbd-create vm-uuid=$vm vdi-uuid=$extra_vdi device=1
|
|
fi
|
|
|
|
#
|
|
# Run DevStack VM
|
|
#
|
|
xe vm-start vm="$DEV_STACK_DOMU_NAME"
|
|
|
|
# Get hold of the Management IP of OpenStack VM
|
|
OS_VM_MANAGEMENT_ADDRESS=$MGT_IP
|
|
if [ $OS_VM_MANAGEMENT_ADDRESS == "dhcp" ]; then
|
|
OS_VM_MANAGEMENT_ADDRESS=$(find_ip_by_name $DEV_STACK_DOMU_NAME $MGT_DEV_NR)
|
|
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 "$DEV_STACK_DOMU_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
|
|
|
|
set +x
|
|
echo "################################################################################"
|
|
echo ""
|
|
echo "VM configuration done!"
|
|
echo "################################################################################"
|
|
|
|
|
|
xe vm-shutdown vm="$DEV_STACK_DOMU_NAME"
|
|
wait_for_VM_to_halt "$DEV_STACK_DOMU_NAME"
|
|
#
|
|
# Mount the VDI
|
|
#
|
|
echo "check vdi mapping"
|
|
STAGING_DIR=$($SCRIPT_DIR/manage-vdi open $DEV_STACK_DOMU_NAME 0 1 | grep -o "/tmp/tmp.[[:alnum:]]*")
|
|
add_on_exit "$SCRIPT_DIR/manage-vdi close $DEV_STACK_DOMU_NAME 0 1"
|
|
# Make sure we have a stage
|
|
if [ ! -d $STAGING_DIR/etc ]; then
|
|
echo "ERROR:ct properly set up!"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$STAGING_DIR/opt/stack" ]; then
|
|
echo "ERROR: scet"
|
|
exit -1
|
|
fi
|
|
|
|
rm -f $STAGING_DIR/opt/stack/local.conf
|
|
XENSERVER_IP=$(xe host-list params=address minimal=true)
|
|
|
|
# Create an systemd task for devstack
|
|
cat >$STAGING_DIR/etc/systemd/system/devstack.service << EOF
|
|
[Unit]
|
|
Description=Install OpenStack by DevStack
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
RemainAfterExit=yes
|
|
ExecStartPre=/bin/rm -f /opt/stack/runsh.succeeded
|
|
ExecStart=/bin/su -c "/opt/stack/run.sh" stack
|
|
StandardOutput=tty
|
|
StandardError=tty
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
EOF
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "fatal error, install service failed."
|
|
exit 1
|
|
fi
|
|
|
|
# enable this service
|
|
rm -f $STAGING_DIR/etc/systemd/system/multi-user.target.wants/devstack.service
|
|
ln -s /etc/systemd/system/devstack.service $STAGING_DIR/etc/systemd/system/multi-user.target.wants/devstack.service
|
|
|
|
# Gracefully cp only if source file/dir exists
|
|
function cp_it {
|
|
if [ -e $1 ] || [ -d $1 ]; then
|
|
cp -pRL $1 $2
|
|
fi
|
|
}
|
|
|
|
# Copy over your ssh keys and env if desired
|
|
cp_it ~/.ssh $STAGING_DIR/opt/stack/.ssh
|
|
cp_it ~/.ssh/id_rsa.pub $STAGING_DIR/opt/stack/.ssh/authorized_keys
|
|
cp_it ~/.gitconfig $STAGING_DIR/opt/stack/.gitconfig
|
|
cp_it ~/.vimrc $STAGING_DIR/opt/stack/.vimrc
|
|
cp_it ~/.bashrc $STAGING_DIR/opt/stack/.bashrc
|
|
|
|
|
|
# Configure run.sh
|
|
DOMU_STACK_DIR=/opt/stack
|
|
DOMU_DEV_STACK_DIR=$DOMU_STACK_DIR/devstack
|
|
cat <<EOF >$STAGING_DIR/opt/stack/run.sh
|
|
#!/bin/bash
|
|
set -eux
|
|
(
|
|
flock -n 9 || exit 1
|
|
|
|
sudo chown -R stack $DOMU_STACK_DIR
|
|
|
|
cd $DOMU_STACK_DIR
|
|
|
|
[ -e /opt/stack/runsh.succeeded ] && rm /opt/stack/runsh.succeeded
|
|
echo \$\$ >> /opt/stack/run_sh.pid
|
|
|
|
if [ ! -d $DOMU_DEV_STACK_DIR ]; then
|
|
git clone $DEVSTACK_SRC $DOMU_DEV_STACK_DIR
|
|
fi
|
|
|
|
cp $DOMU_STACK_DIR/local.conf $DOMU_DEV_STACK_DIR/
|
|
|
|
cd $DOMU_DEV_STACK_DIR
|
|
./unstack.sh || true
|
|
./stack.sh
|
|
|
|
# Got to the end - success
|
|
touch /opt/stack/runsh.succeeded
|
|
|
|
# Update /etc/issue
|
|
(
|
|
echo "OpenStack VM - Installed by DevStack"
|
|
IPADDR=$(ip -4 address show eth0 | sed -n 's/.*inet \([0-9\.]\+\).*/\1/p')
|
|
echo " Management IP: $IPADDR"
|
|
echo -n " Devstack run: "
|
|
if [ -e /opt/stack/runsh.succeeded ]; then
|
|
echo "SUCCEEDED"
|
|
else
|
|
echo "FAILED"
|
|
fi
|
|
echo ""
|
|
) > /opt/stack/issue
|
|
sudo cp /opt/stack/issue /etc/issue
|
|
|
|
rm /opt/stack/run_sh.pid
|
|
) 9> /opt/stack/.runsh_lock
|
|
EOF
|
|
|
|
chmod 755 $STAGING_DIR/opt/stack/run.sh
|
|
if [ ! -f $TOP_DIR/local.conf ]; then
|
|
echo "ERROR: You should prepare a local.conf and put it under $TOP_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
cp_it $TOP_DIR/local.conf $STAGING_DIR/opt/stack/local.conf
|
|
cp_it $THIS_DIR/run.sh $STAGING_DIR/opt/stack/run.sh
|