#!/bin/bash # Exits on first failed command set -e # Errors on undefined variable set -u XVA_URL=https://xoa.io/proxy/xva # Welcome message printf "\nπŸ‘‹ \033[1mWelcome to the XO Proxy Appliance auto-deploy script!\033[0m\n\n" if ! which xe 2> /dev/null >&2 then echo echo 'πŸ”΄ Sorry, the "xe" command is required for this auto-deploy.' echo echo 'πŸš€ Please, make sure you are on a XCP-ng host.' echo exit 1 fi # Basic check: are we on a XS/CH/XCP-ng host? if grep -Fxq "XenServer\|Citrix Hypervisor\|XCP-ng" /etc/issue then printf "\nπŸ”΄ Sorry, it seems you are not on a XenServer or XCP-ng host.\n\n" printf "\nπŸš€ \033[1mThis script is meant to be deployed on XenServer or XCP-ng only.\033[0m\n\n" exit 1 fi # Initial choice on network settings: fixed IP or DHCP? (default) printf "βš™οΈ STEP 1: XO Proxy configuration \n\n" printf "Network settings:\n" read -p "IP address? [dhcp] " ip ip=${ip:-dhcp} if [ "$ip" != 'dhcp' ] then read -p "Netmask? [255.255.255.0] " netmask netmask=${netmask:-255.255.255.0} read -p "Gateway? " gateway read -p "dns? [8.8.8.8] " dns dns=${dns:-8.8.8.8} else printf "\nYour XO Proxy Appliance will be started using DHCP\n" fi printf '\n' # Default or custom NTP servers read -p 'Custom NTP servers (separated by spaces)? [] ' ntp printf '\n' # Registration account read -p "Your Xen Orchestra account (email)? " registrationEmail read -srp "Your Xen Orchestra account password? (hidden) " registrationPassword printf '\n\n' # Athentication token generation authenticationToken=$(cat /dev/urandom | tr -dc '[:alnum:]' | head -c 40) # Downloading and importing the VM printf "πŸ“₯ STEP 2: XO Proxy Download\n\n" printf "Importing XO Proxy VM: this might take a while..." if ! { if [ $# -ge 1 ] then # import from file uuid=$(xe vm-import filename="$1" 2>&1) else # import from URL if ! uuid=$(xe vm-import url="$XVA_URL" 2>&1) then # if it fails (likely due to XS < 7.0 but maybe HTTP proxy) # use wget uuid=$(wget --no-check-certificate --no-verbose -O- "$XVA_URL" | xe vm-import filename=/dev/stdin 2>&1) fi fi } then printf "\n\nAuto deploy failed. Please contact us on help@vates.fr for assistance.\nError:\n\n %s\n\n" "$uuid" exit 0 fi # If static IP selected, fill the xenstore if [ "$ip" != 'dhcp' ] then xe vm-param-set uuid="$uuid" xenstore-data:vm-data/ip="$ip" xenstore-data:vm-data/netmask="$netmask" xenstore-data:vm-data/gateway="$gateway" xenstore-data:vm-data/dns="$dns" fi # If custom NTP servers are provided, fill the xenstore if [ -n "$ntp" ] then xe vm-param-set uuid="$uuid" xenstore-data:vm-data/ntp="$ntp" fi # Set the registration email/pwd and authentication token xe vm-param-set uuid="$uuid" xenstore-data:vm-data/xoa-updater-credentials='{"email":"'"$registrationEmail"'","password":"'"$registrationPassword"'"}' xe vm-param-set uuid="$uuid" xenstore-data:vm-data/xo-proxy-authenticationToken='"'"$authenticationToken"'"' # By default, the deploy script will make sure we boot XO Proxy with a VIF on the mgmt network networkUuid=$(xe pif-list params=network-uuid minimal=true management=true | cut -d , -f 1) vifUuid=$(xe vm-vif-list uuid="$uuid" params=uuid minimal=true) # Warning: vif-move only works from XenServer 7.1 and higher xe vif-move uuid="$vifUuid" network-uuid="$networkUuid" # Starting the VM printf "Booting XO Proxy Appliance...\n" xe vm-start uuid="$uuid" sleep 2 # Waiting for the VM IP from Xen tools for 60 secs printf "Waiting for your XO Proxy Appliance to be ready…\n" # list VM IP addresses and returns the first non link local addresses # # IPv6 addresses are enclosed in brackets for use in URL get_hostname() { local address addresses i n IFS=';' read -r -a addresses <<<"$(xe vm-param-get uuid="$uuid" param-name=networks)" # Bash < 4.4 reports unbound variable if array is empty set +u n=${#addresses[@]} set -u if [ $n -eq 0 ] then return 1 fi # Remove prefixes and dedup readarray -t addresses <<<"$(printf '%s\n' "${addresses[@]#*': '}" | sort -u)" for i in "${!addresses[@]}" do address=${addresses[$i]} case "$address" in fe80:*) # ignore link local address unset "addresses[$i]" continue ;; *:*) address="[$address]" ;; esac addresses[$i]=$address done set +u n=${#addresses[@]} set -u if [ $n -eq 0 ] then return 1 fi printf '\n\033[1m' if [ "$ip" = dhcp ] then printf "🟒 Your XO Proxy Appliance IP address is:\n" for address in "${addresses[@]}" do printf " %s\n" "$address" done else # If we use a fixed IP but on a DHCP enabled network # We don't want to get the first IP displayed by the tools # But the fixed one printf "🟒 Your XO Proxy Appliance is ready and deployed at %s\n" "$ip" # clean the xenstore data xe vm-param-remove uuid="$uuid" param-name=xenstore-data param-key=vm-data/dns param-key=vm-data/ip param-key=vm-data/netmask param-key=vm-data/gateway param-key=vm-data/xo-proxy-authenticationToken param-key=vm-data/xoa-updater-credentials &> /dev/null fi printf '\033[0m' } wait=0 limit=60 while { ! get_hostname && \ [ "$wait" -lt "$limit" ] } do let wait=wait+1 sleep 1 done if [ $wait -eq $limit ] then printf "\n🟠 \033[1mYour XO Proxy booted but we couldn't fetch its IP address\033[0m\n" fi printf "\nXO Proxy Appliance UUID: %s\n" "$uuid" printf "\nXO Proxy authentication token: %s\n\n" "$authenticationToken"