#!/bin/bash ## Modify to your need ## #XOUSER="node" PORT="80" INSTALLDIR="/etc/xo" BRANCH="stable" LOGFILE=$(dirname $0)/xo-install.log ## Modify to your need ## function CheckUser { # Make sure the script is ran as root if [[ ! $(whoami) == "root" ]]; then echo "This script needs to be ran as root" exit 0 fi } function InstallDependenciesCentOS { set -e # Install necessary dependencies for XO build # only run automated node install if package not found if [[ -z $(rpm -qa | grep ^node) ]]; then echo echo -n "Installing node.js..." curl -s -L https://rpm.nodesource.com/setup_6.x | bash - >/dev/null 2>$LOGFILE echo "done" fi # only install yarn repo and package if not found if [[ -z $(rpm -qa | grep yarn) ]]; then echo echo -n "Installing yarn..." curl -s -o /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo >/dev/null 2>$LOGFILE && \ yum -y install yarn >/dev/null 2>$LOGFILE echo "done" fi # only install epel-release if doesn't exist if [[ -z $(rpm -qa | grep epel-release) ]]; then echo echo -n "Installing epel-repo..." yum -y install epel-release >/dev/null 2>$LOGFILE echo "done" fi # install echo echo -n "Installing build dependencies, redis server, python and git..." yum -y install gcc gcc-c++ make openssl-devel redis libpng-devel python git >/dev/null 2>$LOGFILE echo "done" echo echo "Enabling and starting redis service" /bin/systemctl enable redis >/dev/null 2>$LOGFILE && /bin/systemctl start redis >/dev/null 2>$LOGFILE } function InstallDependenciesDebian { # Install necessary dependencies for XO build set -e echo echo -n "Running apt-get update..." apt-get update >/dev/null 2>$LOGFILE echo "done" # Install apt-transport-https and ca-certificates because of yarn https repo url echo echo -n "Installing apt-transport-https and ca-certificates packages to support https repos" apt-get install -y apt-transport-https ca-certificates >/dev/null 2>$LOGFILE echo "done" # install curl for later tasks if missing if [[ ! $(which curl) ]]; then echo echo -n "Installing curl..." apt-get install -y curl >/dev/null 2>$LOGFILE echo "done" fi # only install yarn repo and package if not found if [[ -z $(dpkg -l | grep yarn) ]]; then echo echo -n "Installing yarn..." curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - >/dev/null 2>$LOGFILE echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list >/dev/null 2>$LOGFILE apt-get update >/dev/null 2>$LOGFILE apt-get install -y yarn >/dev/null 2>$LOGFILE echo "done" fi # only run automated node install if package not found if [[ -z $(dpkg -l | grep node) ]] || [[ -z $(which npm) ]]; then echo echo -n "Installing node.js..." curl -sL https://deb.nodesource.com/setup_6.x | bash - >/dev/null 2>$LOGFILE apt-get install -y nodejs >/dev/null 2>$LOGFILE echo "done" fi # install packages echo echo -n "Installing build dependencies, redis server, python and git..." apt-get install -y build-essential redis-server libpng-dev git python-minimal >/dev/null 2>$LOGFILE echo "Enabling and starting redis service" /bin/systemctl enable redis-server >/dev/null 2>$LOGFILE && /bin/systemctl start redis-server >/dev/null 2>$LOGFILE } function InstallXO { set -e TIME=`date +%Y%d%m%H%M` # Create user if doesn't exist (if defined) if [ $XOUSER ]; then if [[ -z $(getent passwd $XOUSER) ]]; then echo echo "Creating $XOUSER user" useradd -s /sbin/nologin $XOUSER echo sleep 2 fi fi # Create installation directory if doesn't exist already if [[ ! -d "$INSTALLDIR" ]] ; then echo "Creating missing basedir to $INSTALLDIR" mkdir -p "$INSTALLDIR" fi echo echo "Creating install directory: $INSTALLDIR/xo-builds/xo-server-$TIME" mkdir -p "$INSTALLDIR/xo-builds/xo-server-$TIME" sleep 2 echo "Creating install directory: $INSTALLDIR/xo-builds/xo-web-$TIME" mkdir -p "$INSTALLDIR/xo-builds/xo-web-$TIME" sleep 2 echo echo "Fetching source code from branch: $BRANCH ..." echo git clone -b $BRANCH http://github.com/vatesfr/xo-server $INSTALLDIR/xo-builds/xo-server-$TIME echo echo git clone -b $BRANCH http://github.com/vatesfr/xo-web $INSTALLDIR/xo-builds/xo-web-$TIME echo echo "done" echo echo "xo-server and xo-web build quite a while. Grab a cup of coffee and lay back" echo echo -n "Running xo-server install..." cd $INSTALLDIR/xo-builds/xo-server-$TIME && yarn >/dev/null 2>$LOGFILE && yarn run build >/dev/null 2>$LOGFILE echo "done" echo -n "Running xo-web install..." cd $INSTALLDIR/xo-builds/xo-web-$TIME && yarn >/dev/null 2>$LOGFILE && yarn run build >/dev/null 2>$LOGFILE echo "done" echo echo "Fixing binary path in systemd service configuration and symlinking to /etc/systemd/system/xo-server.service" sed -i "s#ExecStart=.*#ExecStart=$INSTALLDIR\/xo-server\/bin\/xo-server#" $INSTALLDIR/xo-builds/xo-server-$TIME/xo-server.service echo echo "Adding WorkingDirectory parameter to systemd service configuration" sed -i "/ExecStart=.*/a WorkingDirectory=/etc/xo/xo-server" $INSTALLDIR/xo-builds/xo-server-$TIME/xo-server.service if [ $XOUSER ]; then echo "Adding user to systemd config" sed -i "/SyslogIdentifier=.*/a User=$XOUSER" $INSTALLDIR/xo-builds/xo-server-$TIME/xo-server.service if [ $OSNAME == "CentOS" ]; then echo -n "Attempting to set cap_net_bind_service permission for /usr/bin/node..." setcap 'cap_net_bind_service=+ep' /usr/bin/node >/dev/null 2>$LOGFILE \ && echo "Success" || echo "Failed. Non-privileged user might not be able to bind to <1024 port" else echo -n "Attempting to set cap_net_bind_service permission for /usr/bin/nodejs..." setcap 'cap_net_bind_service=+ep' /usr/bin/nodejs >/dev/null 2>$LOGFILE \ && echo "Success" || echo "Failed. Non-privileged user might not be able to bind to <1024 port" fi fi ln -sfn $INSTALLDIR/xo-builds/xo-server-$TIME/xo-server.service /etc/systemd/system/xo-server.service sleep 2 echo "Reloading systemd configuration" echo /bin/systemctl daemon-reload sleep 2 echo "Fixing relative path to xo-web installation in xo-server configuration file" sed -i "s/#'\/': '\/path\/to\/xo-web\/dist\//'\/': '..\/..\/xo-web\/dist\//" $INSTALLDIR/xo-builds/xo-server-$TIME/sample.config.yaml sleep 2 if [[ $PORT != "80" ]]; then echo "Changing port in xo-server configuration file" sed -i "s/port: 80/port: $PORT/" $INSTALLDIR/xo-builds/xo-server-$TIME/sample.config.yaml sleep 2 fi echo "Activating modified configuration file" mv $INSTALLDIR/xo-builds/xo-server-$TIME/sample.config.yaml $INSTALLDIR/xo-builds/xo-server-$TIME/.xo-server.yaml echo echo "Symlinking fresh xo-server install/update to $INSTALLDIR/xo-server" ln -sfn $INSTALLDIR/xo-builds/xo-server-$TIME $INSTALLDIR/xo-server sleep 2 echo "Symlinking fresh xo-web install/update to $INSTALLDIR/xo-web" ln -sfn $INSTALLDIR/xo-builds/xo-web-$TIME $INSTALLDIR/xo-web if [ $XOUSER ]; then chown -R $XOUSER:$XOUSER $INSTALLDIR/xo-builds/xo-web-$TIME chown -R $XOUSER:$XOUSER $INSTALLDIR/xo-builds/xo-server-$TIME if [ ! -d /var/lib/xo-server ]; then mkdir /var/lib/xo-server 2>/dev/null fi chown $XOUSER:$XOUSER /var/lib/xo-server fi echo echo "Starting xo-server..." /bin/systemctl start xo-server >/dev/null timeout 60 bash <<-"EOF" while [[ -z $(journalctl -u xo-server | grep "http:\/\/\[::\]:$PORT") ]]; do echo "waiting port to be open" sleep 10 done EOF if [[ $(journalctl -u xo-server | grep "http:\/\/\[::\]:$PORT") ]]; then echo echo "WebUI started in port $PORT" echo "Default username: admin@admin.net password: admin" else echo echo "Looks like there was a problem when starting xo-server/reading journalctl. Please see logs for more details" fi } function UpdateXO { /bin/systemctl stop xo-server || { echo "failed to stop service, exiting..." ; exit 1; } InstallXO # remove old builds. leave 5 latest find $INSTALLDIR/xo-builds/ -maxdepth 1 -type d -name "xo-web*" -printf "%T@ %p\n" | sort -n | cut -d' ' -f2- | head -n -5 | xargs -r rm -r find $INSTALLDIR/xo-builds/ -maxdepth 1 -type d -name "xo-server*" -printf "%T@ %p\n" | sort -n | cut -d' ' -f2- | head -n -5 | xargs -r rm -r } function CheckOS { if [ -f /etc/centos-release ] ; then OSVERSION=$(grep -Eo "[0-9]" /etc/centos-release | head -1) OSNAME="CentOS" if [[ ! $OSVERSION == "7" ]]; then echo "Only CentOS 7 supported" exit 0 fi elif [[ -f /etc/os-release ]]; then OSVERSION=$(grep ^VERSION_ID /etc/os-release | cut -d'=' -f2 | grep -Eo "[0-9]{1,2}" | head -1) OSNAME=$(grep ^NAME /etc/os-release | cut -d'=' -f2 | sed 's/"//g' | awk '{print $1}') if [[ $OSNAME == "Debian" ]] && [[ ! $OSVERSION =~ ^(8|9)$ ]]; then echo "Only Debian 8/9 supported" exit 0 elif [[ $OSNAME == "Ubuntu" ]] && [[ ! $OSVERSION == "16" ]]; then echo "Only Ubuntu 16 supported" exit 0 fi else echo "Only CentOS 7 / Ubuntu 16 and Debian 8/9 supported" exit 0 fi } function CheckSystemd { if [ ! $(which systemctl) ]; then echo "This tool is implemented to work with systemd enabled systems only" exit 0 fi } CheckUser CheckOS CheckSystemd echo "-----------------------------------------" echo echo "This script will automatically install/update Xen-Orchestra" echo echo "- By default xo-server will be running as root to prevent issues with permissions and port binding." echo " uncomment and edit XOUSER variable in this script to add this custom user to XO-config" echo " (Notice that you might have to make other changes depending on your system for this to work)" echo " This method only changes the user which runs the service. Other install tasks like node packages are still installed as root" echo echo "- Updating will result in a completely fresh source compile and only active symlink will be changed" echo "- Data stored in redis and /var/lib/xo-server/data will not be touched" echo "- Update option will only work for installations originally done with this tool" echo echo "Following options will be used for installation:" echo echo "OS: $OSNAME $OSVERSION" echo "Basedir: $INSTALLDIR" if [ $XOUSER ]; then echo "User: $XOUSER" else echo "User: root" fi echo "Port: $PORT" echo "Git Branch for source: $BRANCH" echo echo "Errorlog is stored to $LOGFILE for debug purposes" echo "-----------------------------------------" echo echo "1. Install" echo "2. Update" echo "3. Exit" echo read -p ": " option case $option in 1) if [[ $(ps aux | grep xo-server | grep -v grep) ]]; then echo "Looks like xo-server process is already running, consider running update instead. Continue anyway?" read -p "[y/N]: " answer case $answer in y) echo "Stopping xo-server..." /bin/systemctl stop xo-server || { echo "failed to stop service, exiting..." ; exit 1; } ;; n) exit 0 ;; *) exit 0 ;; esac fi if [ $OSNAME == "CentOS" ]; then InstallDependenciesCentOS InstallXO exit 0 else InstallDependenciesDebian InstallXO exit 0 fi ;; 2) UpdateXO exit 0 ;; 3) exit 0 ;; *) echo "Please choose one of the options" echo exit 0 ;; esac