Files
installer-tool/install.sh
2023-06-15 11:35:18 +00:00

573 lines
16 KiB
Bash
Executable File

#!/bin/bash
ask_envs() {
echo "Smarthost proxy? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "n" ] || [ "$ANSWER" == "N" ]; then
SMARTHOST_PROXY="no";
else
SMARTHOST_PROXY="yes";
echo "Please fill in the domain name: (localhost)";
read -r DOMAIN;
if [ "$DOMAIN" == "" ]; then
DOMAIN="localhost";
fi
A=$(echo $DOMAIN | cut -d '.' -f1)
B=$(echo $DOMAIN | cut -d '.' -f2)
# if not FQDN
if [ "$A" == "$B" ]; then
echo "Warning! It seems it's not a FQDN. Self-signed certificate will be created only.";
SELF_SIGNED_CERTIFICATE="true";
fi;
fi
echo "Local proxy? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "n" ] || [ "$ANSWER" == "N" ]; then
LOCAL_PROXY="no";
else
LOCAL_PROXY="yes";
if [ "$SMARTHOST_PROXY" == "no" ]; then
echo "Warning! Local proxy will not work without smarthost proxy service.";
fi;
fi
echo "VPN proxy? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "n" ] || [ "$ANSWER" == "N" ]; then
VPN_PROXY="no";
else
VPN_PROXY="yes";
echo "Please add a valid vpn hash key:";
while read -r VPN_HASH; do
if [ "$VPN_HASH" != "" ]; then
$SUDO_CMD mkdir -p /etc/user/secret/vpn-proxy;
echo $VPN_HASH | base64 -d > /tmp/wg0.conf;
$SUDO_CMD mv /tmp/wg0.conf /etc/user/secret/vpn-proxy/;
break;
fi;
done
fi
echo "Cron? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "n" ] || [ "$ANSWER" == "N" ]; then
CRON="no";
else
CRON="yes";
fi
echo "Please add the letsencrypt mail address:";
while read -r LETSENCRYPT_MAIL; do
if [ "$LETSENCRYPT_MAIL" != "" ]; then
if [ "$(echo "$LETSENCRYPT_MAIL" | grep '@')" != "" ]; then
if [ "$(echo "$LETSENCRYPT_MAIL" | grep '\.')" != "" ]; then
break;
fi;
fi;
fi;
echo "Invalid email address.";
done
echo "Would you like to discover services? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "n" ] || [ "$ANSWER" == "N" ]; then
DISCOVERY="no";
else
DISCOVERY="yes";
echo "Path of service discovery scripts: (/usr/local/bin/)";
read -r DISCOVERY_DIR;
if [ "$DISCOVERY_DIR" == "" ] ; then
DISCOVERY_DIR="/usr/local/bin/"
else
# while not an absolute path
while [ ${DISCOVERY_DIR:0:1} != "/" ]; do
echo "The path must be absolute, for example /usr/local/bin/. Please type it again."
read -r DISCOVERY_DIR;
done
fi
echo "Path of the discovery config file: (discovery.conf)";
read -r DISCOVERY_CONFIG_FILE;
if [ "$DISCOVERY_CONFIG_FILE" == "" ] ; then
DISCOVERY_CONFIG_FILE=$PWD"/discovery.conf";
fi
DISCOVERY_CONFIG_DIR=$(dirname $DISCOVERY_CONFIG_FILE)
fi
}
check_dirs_and_files() {
if [ ! -d "/etc/user/config" ]; then
$SUDO_CMD mkdir -p "/etc/user/config"
fi;
if [ ! -d "/etc/system" ]; then
$SUDO_CMD mkdir "/etc/system"
fi;
if [ ! -d "/etc/user/secret" ]; then
$SUDO_CMD mkdir -p "/etc/user/secret"
fi;
if [ ! -f "/etc/user/config/system.json" ]; then
{
echo '
{
"NETWORK": {
"IP_POOL_START": "172.19.0.0",
"IP_POOL_END": "172.19.254.0",
"IP_SUBNET": "24"
}
}
';
} > /tmp/system.json
$SUDO_CMD mv /tmp/system.json /etc/user/config/system.json
fi;
{
echo "alias service-debian='$SUDO_CMD docker run --rm \
-w /services/ \
-e DOCKER_REGISTRY_URL=registry.format.hu \
-e USER_INIT_PATH=/etc/user/config \
-e CA_PATH=/etc/ssl/certs \
-e DNS_DIR=/etc/system/data/dns \
-e HOST_FILE=/etc/dns/hosts.local \
-v /etc/system/data/dns:/etc/dns:rw \
-v /etc/ssl/certs:/etc/ssl/certs:ro \
-v /etc/user/config/user.json:/etc/user/config/user.json:ro \
-v /etc/user/config/system.json:/etc/user/config/system.json:ro \
-v /etc/user/config/services/:/services/:ro \
-v /etc/user/config/services/tmp:/services/tmp:rw \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker:ro \
registry.format.hu/setup'";
} > $HOME/.bash_aliases
}
check_running() {
DOCKERD_STATUS=$($SUDO_CMD systemctl status docker | grep running | wc -l)
if [ "$DOCKERD_STATUS" == "0" ]; then
$SUDO_CMD systemctl start docker
sleep 5;
DOCKERD_STATUS=$($SUDO_CMD systemctl status docker | grep running | wc -l)
if [ "$DOCKERD_STATUS" == "0" ]; then
echo "Docker daemon not running, please check and execute again the install script";
exit;
fi
fi
# bridge check
BRIDGE_NUM=$($SUDO_CMD docker network ls | grep bridge | awk '{print $2":"$3}' | sort | uniq | wc -l);
CONTAINER_NUM=$($SUDO_CMD docker ps -a | wc -l);
if [ "$BRIDGE_NUM" != "1" ] && [ "$CONTAINER_NUM" != "1" ]; then
echo "There are existing containers and/or networks.";
echo "Please select from the following options (1/2/3):";
echo "1 - Delete all existing containers and networks before installation";
echo "2 - Stop the installation process";
echo "3 - Just continue on my own risk";
read -r ANSWER;
if [ "$ANSWER" == "1" ]; then
echo "1 - Removing exising containers and networks";
# delete and continue
$SUDO_CMD docker stop $($SUDO_CMD docker ps |grep Up | awk '{print $1}')
$SUDO_CMD docker system prune -a
elif [ "$ANSWER" == "3" ]; then
echo "3 - You have chosen to continue installation process."
else # default: 2 - stop installastion
echo "2 - Installation process was stopped";
exit;
fi;
fi;
}
install_docker_apt() {
#echo exit 101 > /usr/sbin/policy-rc.d
echo exit 101 > /tmp/p-rc; $SUDO_CMD mv /tmp/p-rc /usr/sbin/policy-rc.d
$SUDO_CMD chmod +x /usr/sbin/policy-rc.d
$SUDO_CMD apt-get update
$SUDO_CMD apt-get install ca-certificates curl gnupg
$SUDO_CMD install -m 0755 -d /etc/apt/keyrings
$SUDO_CMD curl -fsSL https://download.docker.com/linux/debian/gpg | $SUDO_CMD gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$SUDO_CMD chmod a+r /etc/apt/keyrings/docker.gpg
. /etc/os-release; # set variable VERSION_CODENAME
DOCKER_SOURCE=$($SUDO_CMD cat /etc/apt/sources.list.d/docker.list | grep 'bullseye stable' | wc -l)
if [ "$DOCKER_SOURCE" == "0" ]; then
# add docker source to the source list
$SUDO_CMD echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian "$VERSION_CODENAME" stable" | $SUDO_CMD tee /etc/apt/sources.list.d/docker.list > /dev/null
$SUDO_CMD apt-get update
fi
$SUDO_CMD apt-get -y install --no-install-recommends docker-ce docker-ce-cli containerd.io
}
install_docker_deb() {
# set variables to install docker from debian packages
DOCKER_URL="https://download.docker.com/linux/debian/dists/bullseye/pool/stable/amd64/";
CONTAINERD_VERSION="1.6.20-1";
DOCKER_VERSION="23.0.5-1~debian.11~bullseye";
DOCKER_ARCH="amd64";
PKG_DIR="/tmp"
# set package names
CONTAINERD="containerd.io_"$CONTAINERD_VERSION"_"$DOCKER_ARCH".deb";
DOCKER_CE="docker-ce_"$DOCKER_VERSION"_"$DOCKER_ARCH".deb";
DOCKER_CE_CLI="docker-ce-cli_"$DOCKER_VERSION"_"$DOCKER_ARCH".deb";
#DOCKER_BUILDX="docker-buildx-plugin_"$DOCKER_VERSION"_"$DOCKER_ARCH".deb";
#DOCKER_COMPOSE="docker-compose-plugin_"$DOCKER_VERSION"_"$DOCKER_ARCH".deb";
CONTAINERD_INSTALLED=$(dpkg -s containerd.io | wc -l);
if [ "$CONTAINERD_INSTALLED" == "0" ]; then
# Download debian package
echo "Download package from: " $DOCKER_URL$CONTAINERD;
wget -O $PKG_DIR/$CONTAINERD $DOCKER_URL$CONTAINERD;
# Install package
dpkg -i $PKG_DIR/$CONTAINERD;
fi;
DOCKERCE_INSTALLED=$(dpkg -s docker-ce | wc -l);
if [ "$DOCKERCE_INSTALLED" == "0" ]; then
# Download debian package
echo "Download package from: " $DOCKER_URL$DOCKER_CE;
wget -O $PKG_DIR/$DOCKER_CE $DOCKER_URL$DOCKER_CE;
# Install package
dpkg -i $PKG_DIR/$DOCKER_CE;
fi;
DOCKERCECLI_INSTALLED=$(dpkg -s docker-ce-cli | wc -l);
if [ "$DOCKERCECLI_INSTALLED" == "0" ]; then
# Download debian package
echo "Download package from: " $DOCKER_URL$DOCKER_CE_CLI;
wget -O $PKG_DIR/$DOCKER_CE_CLI $DOCKER_URL$DOCKER_CE_CLI;
# Install package
dpkg -i $PKG_DIR/$DOCKER_CE_CLI;
fi;
# verify ???
systemctl start docker
# remove downloaded packages ???
# rm $PKG_DIR/$CONTAINERD $PKG_DIR/$DOCKER_CE $PKG_DIR/$DOCKER_CE_CLI $PKG_DIR/$DOCKER_BUILDX $PKG_DIR/$DOCKER_COMPOSE
}
ask_additionals() {
echo "Please add directory path of service files: (/etc/user/config/services/)";
read -r SERVICE_DIR;
if [ "$SERVICE_DIR" == "" ] ; then
SERVICE_DIR="/etc/user/config/services";
else
# while not an absolute path
while [ ${SERVICE_DIR:0:1} != "/" ]; do
echo "The path must be absolute, for example /etc/user/config/services/. Please type it again."
read -r SERVICE_DIR;
done
fi
echo "Do you want to install nextcloud? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "" ]; then
NEXTCLOUD="true";
echo "Please add nextcloud domain: ";
while read -r NEXTCLOUD_DOMAIN; do
if [ "$NEXTCLOUD_DOMAIN" != "" ]; then
break;
fi;
done
echo "Please add nextcloud username: ";
while read -r NEXTCLOUD_USERNAME; do
if [ "$NEXTCLOUD_USERNAME" != "" ]; then
break;
fi;
done
echo "Please add nextcloud password: ";
while read -r -s NEXTCLOUD_PASSWORD; do
if [ "$NEXTCLOUD_PASSWORD" != "" ]; then
break;
fi;
done
fi
echo "Do you want to install bitwarden? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "" ]; then
BITWARDEN="true";
echo "Please add bitwarden domain: ";
while read -r BITWARDEN_DOMAIN; do
if [ "$BITWARDEN_DOMAIN" != "" ]; then
break;
fi;
done
fi
}
SUDO_CMD="";
if [ "$USER" != "root" ] ; then
echo "You are not logged in as root."
echo "Do you want to continue and run install script as "$USER" user using sudo? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "n" ] || [ "$ANSWER" == "N" ]; then
echo "Bye."
exit;
else
SUDO_CMD="sudo ";
fi;
fi;
echo "Would you like to install/update docker? (y/N)";
read -r ANSWER;
if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ]; then
#install_docker_deb;
# install docker using apt-get
install_docker_apt
echo "Wait..."
sleep 5
fi
check_running;
check_dirs_and_files;
ask_envs;
$SUDO_CMD docker pull registry.format.hu/installer-tool
# Validating previously created vaiables
if [ "$SMARTHOST_PROXY" != "" ]; then
VAR_SMARTHOST_PROXY="--env SMARTHOST_PROXY=$SMARTHOST_PROXY";
fi
if [ "$LOCAL_PROXY" != "" ]; then
VAR_LOCAL_PROXY="--env LOCAL_PROXY=$LOCAL_PROXY";
fi
if [ "$VPN_PROXY" != "" ]; then
VAR_VPN_PROXY="--env VPN_PROXY=$VPN_PROXY";
fi
if [ "$DOMAIN" != "" ]; then
VAR_DOMAIN="--env DOMAIN=$DOMAIN";
fi
if [ "$CRON" != "" ]; then
VAR_CRON="--env CRON=$CRON";
fi
if [ "$DISCOVERY" != "" ]; then
VAR_DISCOVERY="--env DISCOVERY=$DISCOVERY";
fi
if [ "$DISCOVERY_DIR" != "" ]; then
VAR_DISCOVERY_DIR="--env DISCOVERY_DIR=$DISCOVERY_DIR";
VAR_DISCOVERY_DIRECTORY="--volume $DISCOVERY_DIR/:$DISCOVERY_DIR/";
fi
if [ "$DISCOVERY_CONFIG_FILE" != "" ]; then
VAR_DISCOVERY_CONFIG_FILE="--env DISCOVERY_CONFIG_FILE=$DISCOVERY_CONFIG_FILE";
VAR_DISCOVERY_CONFIG_DIRECTORY="--volume $DISCOVERY_CONFIG_DIR/:$DISCOVERY_CONFIG_DIR/";
fi
# Run installer tool
$SUDO_CMD docker run \
$VAR_SMARTHOST_PROXY \
$VAR_LOCAL_PROXY \
$VAR_VPN_PROXY \
$VAR_DOMAIN \
$VAR_CRON \
$VAR_DISCOVERY \
$VAR_DISCOVERY_DIR \
$VAR_DISCOVERY_DIRECTORY \
$VAR_DISCOVERY_CONFIG_FILE \
$VAR_DISCOVERY_CONFIG_DIRECTORY \
--volume $HOME/.ssh/installer:/root/.ssh/id_rsa \
--volume /etc/user/:/etc/user/ \
--volume /etc/system/:/etc/system/ \
--env LETSENCRYPT_MAIL=$LETSENCRYPT_MAIL registry.format.hu/installer-tool
# test - alias doesn't work inside a function
shopt -s expand_aliases
source $HOME/.bash_aliases
INIT_SERVICE_PATH=/etc/user/config/services
service-debian core-dns start
echo "$INIT_SERVICE_PATH/core-dns.json" >> $PWD/.init_services
if [ "$CRON" == "yes" ]; then
service-debian cron start
echo "$INIT_SERVICE_PATH/cron.json" >> $PWD/.init_services
fi
if [ "$VPN_PROXY" == "yes" ]; then
service-debian vpn-proxy start
echo "$INIT_SERVICE_PATH/vpn-proxy.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-vpn-smarthost-loadbalancer" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-vpn-proxy-postrouting" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-vpn-proxy-prerouting" >> $PWD/.init_services
fi
if [ "$SMARTHOST_PROXY" == "yes" ]; then
service-debian smarthost-proxy start
service-debian smarthost-proxy-scheduler start
service-debian local-proxy start
echo "$INIT_SERVICE_PATH/smarthost-proxy.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-smarthost-loadbalancer-dns.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-letsencrypt.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-smarthostloadbalancer-from-publicbackend.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-smarthost-backend-dns.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-smarthost-to-backend.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/smarthost-proxy-scheduler.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/local-proxy.json" >> $PWD/.init_services
echo "Would you like to run local backend? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "" ] ; then
service-debian local-backend start
echo "$INIT_SERVICE_PATH/local-backend.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/firewall-local-backend.json" >> $PWD/.init_services
echo "$INIT_SERVICE_PATH/domain-local-backend.json" >> $PWD/.init_services
fi
fi
if [ "$DISCOVERY" == "yes" ] ; then
$SUDO_CMD chmod a+x $DISCOVERY_DIR/service-discovery.sh
$DISCOVERY_DIR/service-discovery.sh $DISCOVERY_CONFIG_FILE;
source $DISCOVERY_CONFIG_FILE;
cat $DEST_FILE;
echo "Would you like to run discovered services? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "" ] ; then
$SUDO_CMD chmod a+x $DISCOVERY_DIR/service-files.sh
$DISCOVERY_DIR/service-files.sh $DEST_FILE &
fi;
fi;
echo "Do you want to start the discovered and actually started services at the next time when your system restarting? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "" ] ; then
cp $DISCOVERY_CONFIG_FILE $DISCOVERY_CONFIG_FILE".copy";
cp $DEST_FILE $DEST_FILE".copy";
DISCOVERY_CONFIG_FILENAME=$(basename $DISCOVERY_CONFIG_FILE);
source $DISCOVERY_CONFIG_FILE;
{
echo '#!/bin/bash';
echo 'SOURCE_DIRS="'$SOURCE_DIRS'"; # separator space or |';
echo 'DIRNAME="'$DIRNAME'"; # separator space or |';
echo 'FILENAME="'$FILENAME'"; # separator space or |';
echo 'KEYS="'$KEYS'"; # separator space or |';
echo 'DEST_FILE="/usr/local/etc/results.txt";';
echo 'USE_SUDO=0;';
} > /tmp/$DISCOVERY_CONFIG_FILENAME
$SUDO_CMD mv /tmp/$DISCOVERY_CONFIG_FILENAME /usr/local/etc/$DISCOVERY_CONFIG_FILENAME
{
cat $PWD/.init_services;
cat $DEST_FILE;
} > /tmp/$DEST_FILE
$SUDO_CMD mv /tmp/$DEST_FILE /usr/local/etc/$DEST_FILE
{
echo "
[Unit]
Description=Discover services
[Service]
Type=oneshot
ExecStart=/usr/local/bin/service-files.sh /usr/local/etc/results.txt
[Install]
WantedBy=multi-user.target
";
} > /tmp/discovery.service
$SUDO_CMD mv /tmp/discovery.service /etc/systemd/system/discovery.service
$SUDO_CMD systemctl enable discovery.service
fi;
rm $PWD/.init_services
# install additionals - run installer-tool again but additional_install.sh instead of deploy.sh
echo "Would you like to install additional applications? (Y/n)";
read -r ANSWER;
if [ "$ANSWER" == "y" ] || [ "$ANSWER" == "Y" ] || [ "$ANSWER" == "" ]; then
ask_additionals;
if [ "$NEXTCLOUD" != "" ]; then
VAR_NEXTCLOUD="--env NEXTCLOUD=$NEXTCLOUD";
VAR_NEXTCLOUD="$VAR_NEXTCLOUD --env NEXTCLOUD_DOMAIN=$NEXTCLOUD_DOMAIN";
VAR_NEXTCLOUD="$VAR_NEXTCLOUD --env NEXTCLOUD_USERNAME=$NEXTCLOUD_USERNAME";
VAR_NEXTCLOUD="$VAR_NEXTCLOUD --env NEXTCLOUD_PASSWORD=$NEXTCLOUD_PASSWORD";
if [ ! -d "/etc/user/data/nextcloud" ]; then
$SUDO_CMD mkdir -p "/etc/user/data/nextcloud"
$SUDO_CMD chown -R 82:82 "/etc/user/data/nextcloud"
fi;
fi
if [ "$BITWARDEN" != "" ]; then
VAR_BITWARDEN="--env BITWARDEN=$BITWARDEN";
VAR_BITWARDEN="$VAR_BITWARDEN --env BITWARDEN_DOMAIN=$BITWARDEN_DOMAIN";
echo "You can access your bitwarden admin page here: https://$BITWARDEN_DOMAIN/admin";
echo "You will find ADMIN TOKEN in this file: /etc/user/secret/bitwarden-secret.json";
fi
# Run installer tool
$SUDO_CMD docker run \
--env ADDITIONALS=true \
--env SERVICE_DIR=$SERVICE_DIR\
$VAR_NEXTCLOUD \
$VAR_BITWARDEN \
--volume $HOME/.ssh/installer:/root/.ssh/id_rsa \
--volume /etc/user/:/etc/user/ \
--volume /etc/system/:/etc/system/ \
registry.format.hu/installer-tool
fi