Merge pull request #105 from ronivay/feat/xo-proxy

Add backup proxy installation
This commit is contained in:
Roni Väyrynen
2022-01-02 12:45:30 +02:00
committed by GitHub
5 changed files with 467 additions and 206 deletions

View File

@@ -5,5 +5,5 @@ tab_width = 8
end_of_line = lf end_of_line = lf
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
function_next_line = true function_next_line = false
switch_case_indent = true switch_case_indent = true

View File

@@ -12,7 +12,7 @@ How about docker? No worries, check [Docker hub](https://hub.docker.com/r/roniva
### What is Xen Orchestra? ### What is Xen Orchestra?
Xen Orchestra is a web interface used to manage XenServer/XCP-ng hosts and pools. It runs separately and one can manage multiple different virtualization environments from one single management interface. Xen Orchestra is a web interface used to manage XenServer/XCP-ng hosts and pools. It runs separately and one can manage multiple different virtualization environments from one single management interface.
Xen Orchestra is developed by company called [Vates](https://vates.fr/). They offer Xen Orchestra as a turnkey appliance with different pricing models for different needs and even a free version with limited capabilities. This is the preferred and only supported method of using Xen Orchestra product as the appliance goes through QA and each of the plans come with support. I highly recommend using the official appliance if you plan on using Xen Orchestra in production environment, to support a great product and it's development now, and in the future. Xen Orchestra is developed by company called [Vates](https://vates.fr/). They offer Xen Orchestra as a turnkey appliance with different pricing models for different needs and even a free version with limited capabilities. This is the preferred and only supported method of using Xen Orchestra product as the appliance goes through QA and each of the plans come with support. I highly recommend using the official appliance if you plan on using Xen Orchestra in production environment, to support a great product and it's development now, and in the future.
@@ -23,7 +23,7 @@ If you're a home user/enthusiast with simple environment you want to manage but
Since Xen Orchestra is open source and majority of the paid features included in the official appliance are part of the sources, one can build it themself. This [procedure](https://xen-orchestra.com/docs/from_the_sources.html) is even documented. Note that even though this method is documented, it's not supported way of using Xen Orchestra and is intended to be used only for testing purposes and not in production. Since Xen Orchestra is open source and majority of the paid features included in the official appliance are part of the sources, one can build it themself. This [procedure](https://xen-orchestra.com/docs/from_the_sources.html) is even documented. Note that even though this method is documented, it's not supported way of using Xen Orchestra and is intended to be used only for testing purposes and not in production.
This script offers an easy way to install all dependencies, fetch source code, compile it and do all the little details for you which you'd have to do manually otherwise. Other than that, it follows the steps described in the official documentation. All source code for Xen Orchestra is by default pulled from the official [repository](https://github.com/vatesfr/xen-orchestra). This script offers an easy way to install all dependencies, fetch source code, compile it and do all the little details for you which you'd have to do manually otherwise. Other than that, it follows the steps described in the official documentation. All source code for Xen Orchestra is by default pulled from the official [repository](https://github.com/vatesfr/xen-orchestra).
**This script is not supported or endorsed by Xen Orchestra. Any issue you may have, please report it first to this repository.** **This script is not supported or endorsed by Xen Orchestra. Any issue you may have, please report it first to this repository.**
@@ -80,11 +80,20 @@ update existing installation to the newest version available
should be self explanatory. if you wish to rollback to another installation after doing update or whatever should be self explanatory. if you wish to rollback to another installation after doing update or whatever
* `Install proxy`
install all dependencies, necessary configuration and xen orchestra backup proxy
* `Update proxy`
update existing proxy installation to newest version available
Each of these options can be run non interactively like so: Each of these options can be run non interactively like so:
``` ```
sudo ./xo-install.sh --install sudo ./xo-install.sh --install [--proxy]
sudo ./xo-install.sh --update [--force] sudo ./xo-install.sh --update [--proxy] [--force]
sudo ./xo-install.sh --rollback sudo ./xo-install.sh --rollback
``` ```
@@ -134,6 +143,22 @@ deb:
- sudo (if set in xo-install.cfg) - sudo (if set in xo-install.cfg)
``` ```
#### Backup proxy
**Proxy installation method is experimental, use at your own risk. Proxy installation from sources is not documented by Xen Orchestra team. Method used here is the outcome of trial and error.**
Backup proxy can be used to offload backup tasks from the main Xen Orchestra instance to a proxy which has a direct connection to remote where backups are stored.
Requirements for proxy VM are otherwise the same as mentioned above, in addition the VM needs to live inside XCP-ng/XenServer pool managed by Xen Orchestra instance and have xen tools installed. VM needs to have access to pool master host and Xen Orchestra needs to be able to access this VM via TCP/443.
Majority of xo-install.cfg variables have no effect to proxy installation. Proxy process will always run as root user and in port 443.
Since there is no way in Xen Orchestra from sources to register a proxy via UI, the installation will output a piece of json after the proxy is installed. You need to copy this json string and save to a file. Then use the config import option in Xen Orchestra settings to import this piece of json to add proxy. This works as a partial config import and won't overwrite any existing config. Although it's good to take a config export backup just in case.
Xen Orchestra figures out the correct connection address from the VM UUID which is part of this json. This is why the VM needs to be part of pool managed by Xen Orchestra. Connection details cannot be changed manually.
Note that for obvious reasons some of the proxy features seen in Xen Orchestra UI aren't working, like upgrade button, upgrade check, redeploy, update appliance settings.
#### Plugins #### Plugins
Plugins are installed according to what is specified in `PLUGINS` variable inside `xo-install.cfg` configuration file. By default all available plugins that are part of xen orchestra repository are installed. This list can be narrowed down if needed and 3rd party plugins included. Plugins are installed according to what is specified in `PLUGINS` variable inside `xo-install.cfg` configuration file. By default all available plugins that are part of xen orchestra repository are installed. This list can be narrowed down if needed and 3rd party plugins included.
@@ -174,4 +199,4 @@ VM image is also built totally by me and distributed from webservers i maintain.
### Contributing ### Contributing
Pull requests and issues (either real issues or just suggestions) are more than welcome. Note that i do not wish to make any modifications to Xen Orchestra source code as part of this script. Pull requests and issues (either real issues or just suggestions) are more than welcome. Note that i do not wish to make any modifications to Xen Orchestra source code as part of this script.

View File

@@ -1,18 +1,22 @@
# Optional user that runs the service # Optional user that runs the service
# default: root # default: root
# no effect to Xen Orchestra proxy
#XOUSER= #XOUSER=
# Optional parameter if running as non privileged user to use sudo when mounting/umounting shares inside Xen Orchestra # Optional parameter if running as non privileged user to use sudo when mounting/umounting shares inside Xen Orchestra
# no effect if XOUSER is root # no effect if XOUSER is root
# options true/false # options true/false
# no effect to Xen Orchestra proxy
#USESUDO=false #USESUDO=false
# Optional parameter to generate sudoers config when missing completely if USESUDO is set to true # Optional parameter to generate sudoers config when missing completely if USESUDO is set to true
# no effect if XOUSER is root # no effect if XOUSER is root
# options true/false # options true/false
# no effect to Xen Orchestra proxy
#GENSUDO=false #GENSUDO=false
# Port number where xen-orchestra service is bound # Port number where xen-orchestra service is bound
# no effect to Xen Orchestra proxy
PORT="80" PORT="80"
# Base dir for installation and future updates # Base dir for installation and future updates
@@ -25,6 +29,7 @@ SELFUPGRADE=true
# Xen Orchestra configuration file is stored in XOUSER's home directory ($HOME/.config/xo-server/config.toml) and by default will be overwritten with every update done by this script. # Xen Orchestra configuration file is stored in XOUSER's home directory ($HOME/.config/xo-server/config.toml) and by default will be overwritten with every update done by this script.
# You may disable this if you edit configuration by hand and don't want an update to overwrite it. Note that some of the options defined here won't be applied even if changed if this is set to false. # You may disable this if you edit configuration by hand and don't want an update to overwrite it. Note that some of the options defined here won't be applied even if changed if this is set to false.
# options: true/false # options: true/false
# no effect to Xen Orchestra proxy
CONFIGUPDATE=true CONFIGUPDATE=true
# Location of Xen Orchestra repository where source code is fetched # Location of Xen Orchestra repository where source code is fetched
@@ -65,6 +70,8 @@ ARCH_CHECK="true"
# Define the number of previous successful installations you want to keep. Needs to be at least 1. Determines how far the rollback feature can be used. # Define the number of previous successful installations you want to keep. Needs to be at least 1. Determines how far the rollback feature can be used.
PRESERVE="3" PRESERVE="3"
# certificate settings have no effect to Xen Orchestra proxy, it'll generate it's own self-signed certificates always
# Location of pem certificate/key files. Installation will automatically configure HTTPS if these are defined. Remember to change PORT variable as well. # Location of pem certificate/key files. Installation will automatically configure HTTPS if these are defined. Remember to change PORT variable as well.
#PATH_TO_HTTPS_CERT=$INSTALLDIR/xo.crt #PATH_TO_HTTPS_CERT=$INSTALLDIR/xo.crt
#PATH_TO_HTTPS_KEY=$INSTALLDIR/xo.key #PATH_TO_HTTPS_KEY=$INSTALLDIR/xo.key

View File

@@ -505,26 +505,13 @@ function InstallSudo {
} }
# run actual xen orchestra installation. procedure is the same for new installation and update. we always build it from scratch. function PrepInstall {
function InstallXO {
set -uo pipefail if [[ "$XO_SVC" == "xo-server" ]]; then
local XO_SVC_DESC="Xen Orchestra"
trap ErrorHandling ERR INT fi
if [[ "$XO_SVC" == "xo-proxy" ]]; then
# Create user if doesn't exist (if defined) local XO_SVC_DESC="Xen Orchestra Proxy"
if [[ "$XOUSER" != "root" ]]; then
if [[ -z $(runcmd_stdout "getent passwd $XOUSER") ]]; then
echo
printprog "Creating missing $XOUSER user"
runcmd "useradd -s /sbin/nologin $XOUSER -m"
printok "Creating missing $XOUSER user"
CONFIGPATH=$(getent passwd "$XOUSER" | cut -d: -f6)
fi
if [[ "$USESUDO" == "true" ]]; then
InstallSudo
fi
fi fi
# Create installation directory if doesn't exist already # Create installation directory if doesn't exist already
@@ -543,7 +530,7 @@ function InstallXO {
echo echo
# keep the actual source code in one directory and either clone or git pull depending on if directory exists already # keep the actual source code in one directory and either clone or git pull depending on if directory exists already
printinfo "Fetching Xen Orchestra source code" printinfo "Fetching $XO_SVC_DESC source code"
if [[ ! -d "$XO_SRC_DIR" ]]; then if [[ ! -d "$XO_SRC_DIR" ]]; then
runcmd "mkdir -p \"$XO_SRC_DIR\"" runcmd "mkdir -p \"$XO_SRC_DIR\""
runcmd "git clone \"${REPOSITORY}\" \"$XO_SRC_DIR\"" runcmd "git clone \"${REPOSITORY}\" \"$XO_SRC_DIR\""
@@ -587,9 +574,9 @@ function InstallXO {
# Get the commit ID of the currently-installed xen-orchestra (if one # Get the commit ID of the currently-installed xen-orchestra (if one
# exists). # exists).
if [[ -L "$INSTALLDIR/xo-server" ]] && [[ -n $(runcmd_stdout "readlink -e $INSTALLDIR/xo-server") ]]; then if [[ -L "$INSTALLDIR/$XO_SVC" ]] && [[ -n $(runcmd_stdout "readlink -e $INSTALLDIR/$XO_SVC") ]]; then
local OLD_REPO_HASH=$(runcmd_stdout "cd $INSTALLDIR/xo-server && git rev-parse HEAD") local OLD_REPO_HASH=$(runcmd_stdout "cd $INSTALLDIR/$XO_SVC && git rev-parse HEAD")
local OLD_REPO_HASH_SHORT=$(runcmd_stdout "cd $INSTALLDIR/xo-server && git rev-parse --short HEAD") local OLD_REPO_HASH_SHORT=$(runcmd_stdout "cd $INSTALLDIR/$XO_SVC && git rev-parse --short HEAD")
runcmd "cd $SCRIPT_DIR" runcmd "cd $SCRIPT_DIR"
else else
# If there's no existing installation, then we definitely want # If there's no existing installation, then we definitely want
@@ -604,27 +591,69 @@ function InstallXO {
echo echo
# if any non interactive arguments used in script startup, we don't want to show any prompts # if any non interactive arguments used in script startup, we don't want to show any prompts
if [[ "$INTERACTIVE" == "true" ]]; then if [[ "$INTERACTIVE" == "true" ]]; then
printinfo "No changes to xen-orchestra since previous install. Run update anyway?" printinfo "No changes to $XO_SVC_DESC since previous install. Run update anyway?"
read -r -p "[y/N]: " answer read -r -p "[y/N]: " answer
answer="${answer:-n}" answer="${answer:-n}"
case "$answer" in case "$answer" in
y) y)
: :
;; ;;
n) n)
printinfo "Cleaning up install directory: $INSTALLDIR/xo-builds/xen-orchestra-$TIME" printinfo "Cleaning up install directory: $INSTALLDIR/xo-builds/xen-orchestra-$TIME"
runcmd "rm -rf $INSTALLDIR/xo-builds/xen-orchestra-$TIME" runcmd "rm -rf $INSTALLDIR/xo-builds/xen-orchestra-$TIME"
exit 0 exit 0
;; ;;
esac esac
else else
printinfo "No changes to xen-orchestra since previous install. Skipping xo-server and xo-web build. Use the --force to update anyway." printinfo "No changes to $XO_SVC_DESC since previous install. Skipping build. Use the --force to update anyway."
printinfo "Cleaning up install directory: $INSTALLDIR/xo-builds/xen-orchestra-$TIME" printinfo "Cleaning up install directory: $INSTALLDIR/xo-builds/xen-orchestra-$TIME"
runcmd "rm -rf $INSTALLDIR/xo-builds/xen-orchestra-$TIME" runcmd "rm -rf $INSTALLDIR/xo-builds/xen-orchestra-$TIME"
exit 0 exit 0
fi fi
fi fi
# If this isn't a fresh install, then list the upgrade the user is making.
if [[ -n "$OLD_REPO_HASH" ]]; then
echo
if [[ "$FORCE" != "true" ]]; then
printinfo "Updating $XO_SVC_DESC from '$OLD_REPO_HASH_SHORT' to '$NEW_REPO_HASH_SHORT'"
echo "Updating $XO_SVC_DESC from '$OLD_REPO_HASH_SHORT' to '$NEW_REPO_HASH_SHORT'" >>"$LOGFILE"
else
printinfo "Updating $XO_SVC_DESC (forced) from '$OLD_REPO_HASH_SHORT' to '$NEW_REPO_HASH_SHORT'"
echo "Updating $XO_SVC_DESC (forced) from '$OLD_REPO_HASH_SHORT' to '$NEW_REPO_HASH_SHORT'" >>"$LOGFILE"
fi
else
printinfo "Installing $XO_SVC_DESC from branch: $BRANCH - commit: $NEW_REPO_HASH_SHORT"
echo "Installing $XO_SVC_DESC from branch: $BRANCH - commit: $NEW_REPO_HASH_SHORT" >>"$LOGFILE"
TASK="Installation"
fi
}
# run actual xen orchestra installation. procedure is the same for new installation and update. we always build it from scratch.
function InstallXO {
set -uo pipefail
trap ErrorHandling ERR INT
# Create user if doesn't exist (if defined)
if [[ "$XOUSER" != "root" ]]; then
if [[ -z $(runcmd_stdout "getent passwd $XOUSER") ]]; then
echo
printprog "Creating missing $XOUSER user"
runcmd "useradd -s /sbin/nologin $XOUSER -m"
printok "Creating missing $XOUSER user"
CONFIGPATH=$(getent passwd "$XOUSER" | cut -d: -f6)
fi
if [[ "$USESUDO" == "true" ]]; then
InstallSudo
fi
fi
PrepInstall
# Now that we know we're going to be building a new xen-orchestra, make # Now that we know we're going to be building a new xen-orchestra, make
# sure there's no already-running xo-server process. # sure there's no already-running xo-server process.
if [[ $(runcmd_stdout "pgrep -f xo-server") ]]; then if [[ $(runcmd_stdout "pgrep -f xo-server") ]]; then
@@ -637,22 +666,6 @@ function InstallXO {
printok "Shutting down xo-server" printok "Shutting down xo-server"
fi fi
# If this isn't a fresh install, then list the upgrade the user is making.
if [[ -n "$OLD_REPO_HASH" ]]; then
echo
if [[ "$FORCE" != "true" ]]; then
printinfo "Updating xen-orchestra from '$OLD_REPO_HASH_SHORT' to '$NEW_REPO_HASH_SHORT'"
echo "Updating xen-orchestra from '$OLD_REPO_HASH_SHORT' to '$NEW_REPO_HASH_SHORT'" >>"$LOGFILE"
else
printinfo "Updating xen-orchestra (forced) from '$OLD_REPO_HASH_SHORT' to '$NEW_REPO_HASH_SHORT'"
echo "Updating xen-orchestra (forced) from '$OLD_REPO_HASH_SHORT' to '$NEW_REPO_HASH_SHORT'" >>"$LOGFILE"
fi
else
printinfo "Installing xen-orchestra from branch: $BRANCH - commit: $NEW_REPO_HASH_SHORT"
echo "Installing xen-orchestra from branch: $BRANCH - commit: $NEW_REPO_HASH_SHORT" >>"$LOGFILE"
TASK="Installation"
fi
# Fetch 3rd party plugins source code # Fetch 3rd party plugins source code
InstallAdditionalXOPlugins InstallAdditionalXOPlugins
@@ -788,45 +801,69 @@ function InstallXO {
set +eo pipefail set +eo pipefail
trap - ERR INT trap - ERR INT
# loop xo-server service logs for 60 seconds and look for line that indicates service was started. we only care about lines generated after script was started (LOGTIME) VerifyServiceStart
}
function VerifyServiceStart {
set -u
if [[ "$XO_SVC" == "xo-proxy" ]]; then
local PORT="443"
fi
PROXY_CONFIG_UPDATED=${PROXY_CONFIG_UPDATED:-"false"}
# loop service logs for 60 seconds and look for line that indicates service was started. we only care about lines generated after script was started (LOGTIME)
local count=0 local count=0
local limit=6 local limit=6
# shellcheck disable=SC1117 # shellcheck disable=SC1117
local servicestatus="$(runcmd_stdout "journalctl --since '$LOGTIME' -u xo-server | grep 'Web server listening on https\{0,1\}:\/\/.*:$PORT'")" local servicestatus="$(runcmd_stdout "journalctl --since '$LOGTIME' -u $XO_SVC | grep 'Web server listening on https\{0,1\}:\/\/.*:$PORT'")"
while [[ -z "$servicestatus" ]] && [[ "$count" -lt "$limit" ]]; do while [[ -z "$servicestatus" ]] && [[ "$count" -lt "$limit" ]]; do
echo " waiting for port to be open" echo " waiting for port to be open"
sleep 10 sleep 10
# shellcheck disable=SC1117 # shellcheck disable=SC1117
local servicestatus="$(runcmd_stdout "journalctl --since '$LOGTIME' -u xo-server | grep 'Web server listening on https\{0,1\}:\/\/.*:$PORT'")" local servicestatus="$(runcmd_stdout "journalctl --since '$LOGTIME' -u $XO_SVC | grep 'Web server listening on https\{0,1\}:\/\/.*:$PORT'")"
((count++)) ((count++))
done done
# if it looks like service started successfully based on logs.. # if it looks like service started successfully based on logs..
if [[ -n "$servicestatus" ]]; then if [[ -n "$servicestatus" ]]; then
echo echo
echo -e " ${COLOR_GREEN}WebUI started in port $PORT. Make sure you have firewall rules in place to allow access.${COLOR_N}" if [[ "$XO_SVC" == "xo-server" ]]; then
# print username and password only when install was ran and skip while updating echo -e " ${COLOR_GREEN}WebUI started in port $PORT. Make sure you have firewall rules in place to allow access.${COLOR_N}"
if [[ "$TASK" == "Installation" ]]; then # print username and password only when install was ran and skip while updating
echo -e " ${COLOR_GREEN}Default username: admin@admin.net password: admin${COLOR_N}" if [[ "$TASK" == "Installation" ]]; then
echo -e " ${COLOR_GREEN}Default username: admin@admin.net password: admin${COLOR_N}"
fi
fi
if [[ "$XO_SVC" == "xo-proxy" ]]; then
echo -e " ${COLOR_GREEN}Proxy started in port $PORT. Make sure you have firewall rules in place to allow access from xen orchestra.${COLOR_N}"
# print json config only when install was ran and skip while Updating
if [[ "$TASK" == "Installation" ]] && [[ "$PROXY_CONFIG_UPDATED" == "true" ]]; then
echo -e " ${COLOR_GREEN}Save following line as json file and use config import in Xen Orchestra to add proxy${COLOR_N}"
echo
echo "{\"proxies\":[{\"authenticationToken\":\"${PROXY_TOKEN}\",\"name\":\"${PROXY_NAME}\",\"vmUuid\":\"${PROXY_VM_UUID}\",\"id\":\"${PROXY_RANDOM_UUID}\"}]}"
fi
fi fi
echo echo
printinfo "$TASK successful. Enabling xo-server service to start on reboot" printinfo "$TASK successful. Enabling $XO_SVC service to start on reboot"
echo "" >>"$LOGFILE" echo "" >>"$LOGFILE"
echo "$TASK succesful" >>"$LOGFILE" echo "$TASK succesful" >>"$LOGFILE"
runcmd "/bin/systemctl enable xo-server" runcmd "/bin/systemctl enable $XO_SVC"
echo echo
# if service startup failed... # if service startup failed...
else else
echo echo
printfail "$TASK completed, but looks like there was a problem when starting xo-server/reading journalctl. Please see logs for more details" printfail "$TASK completed, but looks like there was a problem when starting $XO_SVC. Please see logs for more details"
# shellcheck disable=SC2129 # shellcheck disable=SC2129
echo "" >>"$LOGFILE" echo "" >>"$LOGFILE"
echo "$TASK failed" >>"$LOGFILE" echo "$TASK failed" >>"$LOGFILE"
echo "xo-server service log:" >>"$LOGFILE" echo "$XO_SVC service log:" >>"$LOGFILE"
echo "" >>"$LOGFILE" echo "" >>"$LOGFILE"
runcmd "journalctl --since '$LOGTIME' -u xo-server >> $LOGFILE" runcmd "journalctl --since '$LOGTIME' -u $XO_SVC >> $LOGFILE"
echo echo
echo "Control xo-server service with systemctl for stop/start/restart etc." echo "Control $SERVICE service with systemctl for stop/start/restart etc."
exit 1 exit 1
fi fi
@@ -835,7 +872,12 @@ function InstallXO {
# run xen orchestra installation but also cleanup old installations based on value in xo-install.cfg # run xen orchestra installation but also cleanup old installations based on value in xo-install.cfg
function UpdateXO { function UpdateXO {
InstallXO if [[ "$XO_SVC" == "xo-server" ]]; then
InstallXO
fi
if [[ "$XO_SVC" == "xo-proxy" ]]; then
InstallXOProxy
fi
set -uo pipefail set -uo pipefail
@@ -846,20 +888,101 @@ function UpdateXO {
# remove old builds. leave as many as defined in PRESERVE variable # remove old builds. leave as many as defined in PRESERVE variable
echo echo
printprog "Removing old installations. Leaving $PRESERVE latest" printprog "Removing old inactive installations. Leaving $PRESERVE latest"
runcmd "find $INSTALLDIR/xo-builds/ -maxdepth 1 -type d -name \"xen-orchestra*\" -printf \"%T@ %p\\n\" | sort -n | cut -d' ' -f2- | head -n -$PRESERVE | xargs -r rm -r" local INSTALLATIONS="$(runcmd_stdout "find $INSTALLDIR/xo-builds/ -maxdepth 1 -type d -name \"xen-orchestra*\" -printf \"%T@ %p\\n\" | sort -n | cut -d' ' -f2- | head -n -$PRESERVE")"
printok "Removing old installations. Leaving $PRESERVE latest" local XO_SERVER_ACTIVE="$(runcmd_stdout "readlink -e $INSTALLDIR/xo-server")"
local XO_WEB_ACTIVE="$(runcmd_stdout "readlink -e $INSTALLDIR/xo-web")"
local XO_PROXY_ACTIVE="$(runcmd_stdout "readlink -e $INSTALLDIR/xo-proxy")"
for DELETABLE in $INSTALLATIONS; do
if [[ "$XO_SERVER_ACTIVE" != "${DELETABLE}"* ]] && [[ "$XO_WEB_ACTIVE" != "${DELETABLE}"* ]] && [[ "$XO_PROXY_ACTIVE" != "${DELETABLE}"* ]]; then
runcmd "rm -rf $DELETABLE"
fi
done
printok "Removing old inactive installations. Leaving $PRESERVE latest"
}
function InstallXOProxy {
set -uo pipefail
PrepInstall
# check that xo-proxy is not running
if [[ $(runcmd_stdout "pgrep -f xo-proxy") ]]; then
echo
printprog "Shutting down xo-proxy"
runcmd "/bin/systemctl stop xo-proxy" || {
printfail "failed to stop service, exiting..."
exit 1
}
printok "Shutting down xo-proxy"
fi
echo
printinfo "xo-proxy build takes quite a while. Grab a cup of coffee and lay back"
echo
printprog "Running installation"
runcmd "cd $INSTALLDIR/xo-builds/xen-orchestra-$TIME && yarn && yarn build"
runcmd "cd $INSTALLDIR/xo-builds/xen-orchestra-$TIME/@xen-orchestra/proxy && yarn cross-env NODE_ENV=development yarn run _build"
printok "Running installation"
echo
printinfo "Generate systemd service configuration file"
cat <<EOF >/etc/systemd/system/xo-proxy.service
[Unit]
Description=xo-proxy
After=network-online.target
[Service]
ExecStart=$INSTALLDIR/xo-proxy/dist/index.mjs
Restart=always
SyslogIdentifier=xo-proxy
[Install]
WantedBy=multi-user.target
EOF
printinfo "Reloading systemd configuration"
runcmd "/bin/systemctl daemon-reload"
# if xen orchestra proxy configuration file doesn't exist or configuration update is not disabled in xo-install.cfg, we create it
if [[ ! -f "$CONFIGPATH/.config/xo-proxy/config.toml" ]]; then
PROXY_VM_UUID="$(dmidecode -t system | grep UUID | awk '{print $NF}')"
PROXY_RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
PROXY_TOKEN="$(tr -dc A-Z-a-z0-9_- </dev/urandom | head -c 43)"
PROXY_NAME="xo-ce-proxy-$TIME"
PROXY_CONFIG_UPDATED="true"
printinfo "No xo-proxy configuration present, copying default config to $CONFIGPATH/.config/xo-proxy/config.toml"
runcmd "mkdir -p $CONFIGPATH/.config/xo-proxy"
runcmd "cp $INSTALLDIR/xo-builds/xen-orchestra-$TIME/@xen-orchestra/proxy/config.toml $CONFIGPATH/.config/xo-proxy/config.toml"
printinfo "Adding authentication token to xo-proxy config"
runcmd "sed -i \"s/^authenticationToken = .*/authenticationToken = '$PROXY_TOKEN'/\" $CONFIGPATH/.config/xo-proxy/config.toml"
fi
printinfo "Symlinking fresh xo-proxy install/update to $INSTALLDIR/xo-proxy"
runcmd "ln -sfn $INSTALLDIR/xo-builds/xen-orchestra-$TIME/@xen-orchestra/proxy $INSTALLDIR/xo-proxy"
echo
printinfo "Starting xo-proxy..."
runcmd "/bin/systemctl start xo-proxy"
# no need to exit/trap on errors anymore
set +eo pipefail
trap - ERR INT
VerifyServiceStart
} }
# if any arguments were given to script, handle them here # if any arguments were given to script, handle them here
function HandleArgs { function HandleArgs {
OPTS=$(getopt -o: --long force,rollback,update,install -- "$@") OPTS=$(getopt -o: --long force,rollback,update,install,proxy -- "$@")
#shellcheck disable=SC2181 #shellcheck disable=SC2181
if [[ $? != 0 ]]; then if [[ $? != 0 ]]; then
echo "Usage: $SCRIPT_DIR/$(basename "$0") [--install | --update | --rollback ] [--force]" echo "Usage: $SCRIPT_DIR/$(basename "$0") [--install | --update | --rollback ] [--proxy] [--force]"
exit 1 exit 1
fi fi
@@ -868,35 +991,40 @@ function HandleArgs {
local UPDATEARG=0 local UPDATEARG=0
local INSTALLARG=0 local INSTALLARG=0
local ROLLBACKARG=0 local ROLLBACKARG=0
local PROXYARG=0
while true; do while true; do
case "$1" in case "$1" in
--force) --force)
shift shift
FORCE="true" FORCE="true"
;; ;;
--update) --update)
shift shift
local UPDATEARG=1 local UPDATEARG=1
TASK="Update" TASK="Update"
;; ;;
--install) --install)
shift shift
local INSTALLARG=1 local INSTALLARG=1
TASK="Installation" TASK="Installation"
;; ;;
--rollback) --rollback)
shift shift
local ROLLBACKARG=1 local ROLLBACKARG=1
;; ;;
--) --proxy)
shift shift
break local PROXYARG=1
;; ;;
*) --)
shift shift
break break
;; ;;
*)
shift
break
;;
esac esac
done done
@@ -908,20 +1036,31 @@ function HandleArgs {
if [[ "$UPDATEARG" -gt 0 ]]; then if [[ "$UPDATEARG" -gt 0 ]]; then
UpdateNodeYarn UpdateNodeYarn
UpdateXO if [[ "$PROXYARG" -gt 0 ]]; then
XO_SVC="xo-proxy"
UpdateXO
else
XO_SVC="xo-server"
UpdateXO
fi
exit exit
fi fi
if [[ "$INSTALLARG" -gt 0 ]]; then if [[ "$INSTALLARG" -gt 0 ]]; then
if [ "$PKG_FORMAT" == "rpm" ]; then if [ "$PKG_FORMAT" == "rpm" ]; then
InstallDependenciesRPM InstallDependenciesRPM
InstallXO
exit
else else
InstallDependenciesDeb InstallDependenciesDeb
InstallXO
exit
fi fi
if [[ "$PROXYARG" -gt 0 ]]; then
XO_SVC="xo-proxy"
InstallXOProxy
else
XO_SVC="xo-server"
InstallXO
fi
exit
fi fi
if [[ "$ROLLBACKARG" -gt 0 ]]; then if [[ "$ROLLBACKARG" -gt 0 ]]; then
@@ -943,31 +1082,70 @@ function RollBackInstallation {
exit 0 exit 0
fi fi
if [[ -L "$INSTALLDIR/xo-proxy" ]] && [[ -n $(runcmd_stdout "readlink -e $INSTALLDIR/xo-proxy") ]]; then
if [[ -L "$INSTALLDIR/xo-server" ]] && [[ -n $(runcmd_stdout "readlink -e $INSTALLDIR/xo-server") ]]; then
echo "Looks like proxy AND xen orchestra are installed. Which one you want to rollback?"
echo "1. Xen Orchestra"
echo "2. Xen Orchestra Proxy"
echo "3. Exit"
read -r -p ": " answer
case $answer in
1)
XO_SVC="xo-server"
;;
2)
XO_SVC="xo-proxy"
;;
3)
exit
;;
*)
exit
;;
esac
else
XO_SVC="xo-proxy"
fi
else
XO_SVC="xo-server"
fi
echo "Which installation to roll back?" echo "Which installation to roll back?"
echo echo
local PS3="Pick a number. CTRL+C to exit: " local PS3="Pick a number. CTRL+C to exit: "
local INSTALLATION local INSTALLATION
select INSTALLATION in "${INSTALLATIONS[@]}"; do select INSTALLATION in "${INSTALLATIONS[@]}"; do
case $INSTALLATION in case $INSTALLATION in
*xen-orchestra*) *xen-orchestra*)
echo echo
printinfo "Setting $INSTALLDIR/xo-server symlink to $INSTALLATION/packages/xo-server" if [[ "$XO_SVC" == "xo-server" ]]; then
runcmd "ln -sfn $INSTALLATION/packages/xo-server $INSTALLDIR/xo-server" printinfo "Setting $INSTALLDIR/xo-server symlink to $INSTALLATION/packages/xo-server"
printinfo "Setting $INSTALLDIR/xo-web symlink to $INSTALLATION/packages/xo-web" runcmd "ln -sfn $INSTALLATION/packages/xo-server $INSTALLDIR/xo-server"
runcmd "ln -sfn $INSTALLATION/packages/xo-web $INSTALLDIR/xo-web" printinfo "Setting $INSTALLDIR/xo-web symlink to $INSTALLATION/packages/xo-web"
echo runcmd "ln -sfn $INSTALLATION/packages/xo-web $INSTALLDIR/xo-web"
printinfo "Replacing xo.server.service systemd configuration file" echo
runcmd "/bin/cp -f $INSTALLATION/packages/xo-server/xo-server.service /etc/systemd/system/xo-server.service" printinfo "Replacing xo.server.service systemd configuration file"
runcmd "/bin/systemctl daemon-reload" runcmd "/bin/cp -f $INSTALLATION/packages/xo-server/xo-server.service /etc/systemd/system/xo-server.service"
echo runcmd "/bin/systemctl daemon-reload"
printinfo "Restarting xo-server..." echo
runcmd "/bin/systemctl restart xo-server" printinfo "Restarting xo-server..."
echo runcmd "/bin/systemctl restart xo-server"
break echo
;; break
*) fi
printfail "Try again" if [[ "$XO_SVC" == "xo-proxy" ]]; then
;; printinfo "Setting $INSTALLDIR/xo-proxy symlink to $INSTALLATION/@xen-orchestra/proxy"
runcmd "ln -sfn $INSTALLATION/@xen-orchestra/proxy $INSTALLDIR/xo-proxy"
echo
printinfo "Restating xo-proxy..."
runcmd "/bin/systemctl restart xo-proxy"
echo
break
fi
;;
*)
printfail "Try again"
;;
esac esac
done done
@@ -1111,15 +1289,15 @@ function CheckMemory {
fi fi
read -r -p "continue anyway? y/N: " answer read -r -p "continue anyway? y/N: " answer
case $answer in case $answer in
y) y)
: :
;; ;;
n) n)
exit 0 exit 0
;; ;;
*) *)
exit 0 exit 0
;; ;;
esac esac
fi fi
@@ -1137,15 +1315,15 @@ function CheckDiskFree {
fi fi
read -r -p "continue anyway? y/N: " answer read -r -p "continue anyway? y/N: " answer
case $answer in case $answer in
y) y)
: :
;; ;;
n) n)
exit 0 exit 0
;; ;;
*) *)
exit 0 exit 0
;; ;;
esac esac
fi fi
} }
@@ -1171,71 +1349,122 @@ function StartUpScreen {
echo echo
echo -e "Errorlog is stored to ${COLOR_WHITE}$LOGFILE${COLOR_N} for debug purposes" echo -e "Errorlog is stored to ${COLOR_WHITE}$LOGFILE${COLOR_N} for debug purposes"
echo echo
echo "Depending on which installation is chosen:"
echo
echo -e "Xen Orchestra configuration will be stored to ${COLOR_WHITE}$CONFIGPATH/.config/xo-server/config.toml${COLOR_N}, if you don't want it to be replaced with every update, set ${COLOR_WHITE}CONFIGUPDATE${COLOR_N} to false in ${COLOR_WHITE}xo-install.cfg${COLOR_N}" echo -e "Xen Orchestra configuration will be stored to ${COLOR_WHITE}$CONFIGPATH/.config/xo-server/config.toml${COLOR_N}, if you don't want it to be replaced with every update, set ${COLOR_WHITE}CONFIGUPDATE${COLOR_N} to false in ${COLOR_WHITE}xo-install.cfg${COLOR_N}"
echo -e "Xen Orchestra Proxy configuration will be stored to ${COLOR_WHITE}$CONFIGPATH/.config/xo-proxy/config.toml${COLOR_N}. Config won't be overwritten during update, ever"
echo "-----------------------------------------" echo "-----------------------------------------"
echo echo
echo -e "${COLOR_WHITE}1. Install${COLOR_N}" echo -e "${COLOR_WHITE}1. Install${COLOR_N}"
echo -e "${COLOR_WHITE}2. Update${COLOR_N}" echo -e "${COLOR_WHITE}2. Update${COLOR_N}"
echo -e "${COLOR_WHITE}3. Rollback${COLOR_N}" echo -e "${COLOR_WHITE}3. Rollback${COLOR_N}"
echo -e "${COLOR_WHITE}4. Exit${COLOR_N}" echo -e "${COLOR_WHITE}4. Install proxy${COLOR_N}"
echo -e "${COLOR_WHITE}5. Update proxy${COLOR_N}"
echo -e "${COLOR_WHITE}6. Exit${COLOR_N}"
echo echo
read -r -p ": " option read -r -p ": " option
case $option in case $option in
1) 1)
if [[ $(runcmd_stdout "pgrep -f xo-server") ]]; then if [[ $(runcmd_stdout "pgrep -f xo-server") ]]; then
echo "Looks like xo-server process is already running, consider running update instead. Continue anyway?" echo "Looks like xo-server process is already running, consider running update instead. Continue anyway?"
read -r -p "[y/N]: " answer read -r -p "[y/N]: " answer
case $answer in case $answer in
y) y)
echo "Stopping xo-server..." echo "Stopping xo-server..."
runcmd "/bin/systemctl stop xo-server" || runcmd "/bin/systemctl stop xo-server" ||
{ {
printfail "failed to stop service, exiting..." printfail "failed to stop service, exiting..."
exit 1 exit 1
} }
;; ;;
n) n)
exit 0 exit 0
;; ;;
*) *)
exit 0 exit 0
;; ;;
esac esac
fi fi
if [ "$PKG_FORMAT" == "rpm" ]; then
TASK="Installation" TASK="Installation"
InstallDependenciesRPM XO_SVC="xo-server"
InstallXO
if [ "$PKG_FORMAT" == "rpm" ]; then
InstallDependenciesRPM
InstallXO
exit 0
fi
if [ "$PKG_FORMAT" == "deb" ]; then
InstallDependenciesDeb
InstallXO
exit 0
fi
;;
2)
TASK="Update"
XO_SVC="xo-server"
UpdateNodeYarn
UpdateXO
exit 0 exit 0
fi ;;
if [ "$PKG_FORMAT" == "deb" ]; then 3)
RollBackInstallation
exit 0
;;
4)
if [[ $(runcmd_stdout "pgrep -f xo-proxy") ]]; then
echo "Looks like xo-proxy process is already running, consider running update instead. Continue anyway?"
read -r -p "[y/N]: " answer
case $answer in
y)
echo "Stopping xo-proxy..."
runcmd "/bin/systemctl stop xo-proxy" ||
{
printfail "failed to stop service, exiting..."
exit 1
}
;;
n)
exit 0
;;
*)
exit 0
;;
esac
fi
TASK="Installation" TASK="Installation"
InstallDependenciesDeb XO_SVC="xo-proxy"
InstallXO
if [[ "$PKG_FORMAT" == "rpm" ]]; then
InstallDependenciesRPM
InstallXOProxy
exit 0
fi
if [[ "$PKG_FORMAT" == "deb" ]]; then
InstallDependenciesDeb
InstallXOProxy
exit 0
fi
;;
5)
TASK="Update"
XO_SVC="xo-proxy"
UpdateNodeYarn
UpdateXO
exit 0 exit 0
fi ;;
;; 6)
2) exit 0
TASK="Update" ;;
UpdateNodeYarn *)
UpdateXO echo "Please choose one of the options"
exit 0 echo
;; exit 0
3) ;;
RollBackInstallation
exit 0
;;
4)
exit 0
;;
*)
echo "Please choose one of the options"
echo
exit 0
;;
esac esac
} }

View File

@@ -45,11 +45,11 @@ function NetworkChoose {
# print a menu where to choose network from # print a menu where to choose network from
case $network in case $network in
*) *)
# save network uuid for later # save network uuid for later
vifuuid="$networkuuid" vifuuid="$networkuuid"
break break
;; ;;
esac esac
done done
@@ -81,16 +81,16 @@ function StorageChoose {
# print a menu where to choose storage from # print a menu where to choose storage from
case $storage in case $storage in
default) default)
# this value is handled during import if set to default # this value is handled during import if set to default
sruuid=default sruuid=default
break break
;; ;;
*) *)
# save storage uuid for later # save storage uuid for later
sruuid=$storageuuid sruuid=$storageuuid
break break
;; ;;
esac esac
done done