I had a bit of a challenge to figure out how to get the install.sh from the tarball to work behind a proxy.
I have modified it to work ok and I managed to get it working pretty well.
This allows you to install it behind a proxy AND configures docker to fetch via the proxy. There is a new argument --proxy which allows this to work optionally, and a couple of extra -E to sudo to make sure environment variables get passed in.
Feel free to test it out and see how it goes. might save someone some time.
Here is the entire new script:
#!/usr/bin/env bash
echo
echo "### MCS Install Script ###"
echo "### Version 1.4.1 ###"
echo
cd $(dirname $0)
PROXY_URL=""
POSITIONAL=()
while [[ $# -gt 0 ]]; do
case "$1" in
--proxy)
PROXY_URL="$2"
shift 2
;;
service|cloud|mcs) # keep the original modes working
POSITIONAL+=("$1")
shift
;;
*) # ignore any other flags for now
POSITIONAL+=("$1")
shift
;;
esac
done
set -- "${POSITIONAL[@]}"
run_as_root_with_proxy() {
if [[ -n "$PROXY_URL" ]]; then
sudo -E env \
"http_proxy=$PROXY_URL" "https_proxy=$PROXY_URL" \
"HTTP_PROXY=$PROXY_URL" "HTTPS_PROXY=$PROXY_URL" \
"no_proxy=$NO_PROXY" "NO_PROXY=$NO_PROXY" \
"$@"
else
sudo "$@"
fi
}
if [[ -n "$PROXY_URL" ]]; then
echo ">>> Proxy enabled: $PROXY_URL"
# shell-wide
export http_proxy="$PROXY_URL"
export https_proxy="$PROXY_URL"
export HTTP_PROXY="$PROXY_URL"
export HTTPS_PROXY="$PROXY_URL"
# metadata & loopback must bypass the proxy
export no_proxy="169.254.169.254,metadata.google.internal,localhost,127.0.0.1"
export NO_PROXY="$no_proxy"
# persist for future interactive shells (non-login shells read /etc/profile.d/*)
sudo tee /etc/profile.d/mcs_proxy.sh >/dev/null <<EOF
export http_proxy="$PROXY_URL"
export https_proxy="$PROXY_URL"
export HTTP_PROXY="$PROXY_URL"
export HTTPS_PROXY="$PROXY_URL"
export no_proxy="$no_proxy"
export NO_PROXY="$no_proxy"
EOF
fi
script_location=${PWD##*/}
script_location=${script_location,,}
service_update_mode=false
cloud_install_mode=false
manual_install_mode=false
if [[ $1 == "service" ]] && [[ $(cat ./current_state) != "svc_update" ]]; then
# Skip in case of systemd service stop without upgrade. ./install.sh service should not be used manually since it's missing the environment variables
exit 0
elif [[ $1 == "service" ]] && [[ $(cat ./current_state) == "svc_update" ]]; then
service_update_mode=true
elif [[ $1 == "cloud" ]]; then
echo "Manual Cloud Installation mode"
cloud_install_mode=true
elif [[ $script_location == "mcs" ]]; then
## Check if the script is running from the MCS folder ( manual install after extracting the archive )
manual_install_mode=true
fi
export MCS_GROUP="tagvs-mcs"
export MCS_GROUP_ID=82487
# Check if the mcs service is installed
systemctl list-unit-files --type=service | grep -q "^mcs.service" && echo "MCS service is already installed" &&
fresh_install=false || {
echo "MCS service is not installed"
fresh_install=true
}
echo "Checking if user $USER has sudo permissions..."
if sudo -nv 2>&1 | grep -q "^Sorry"; then
echo "$USER has no access to use 'sudo' command , which is required for package installation and fixing files permissions used by MCS"
echo "In order to continue , please add $USER to the sudoers group and re-run the script"
exit 1
fi
echo "Permissions are OK"
# group creation and assignment
existing_gid=$(getent group $MCS_GROUP | cut -d: -f3)
if [ -n "$existing_gid" ] && [ "$existing_gid" != "$MCS_GROUP_ID" ]; then
echo "Error: $MCS_GROUP group exists with gid $existing_gid, expected $MCS_GROUP_ID. Exiting..."
exit 1
elif [ -z "$existing_gid" ]; then
echo "Creating $MCS_GROUP group with gid - $MCS_GROUP_ID..."
sudo groupadd -g $MCS_GROUP_ID $MCS_GROUP && echo "Group $MCS_GROUP created successfully." || {
echo "Failed to create $MCS_GROUP group"
exit 1
}
fi
if $manual_install_mode; then
# installing from the MCS folder
uid=$(id -u)
if [[ $uid == 0 ]]; then
read -p "The script is running as root . If the MCS operation will be managed by other user , please switch to it or run the ./install.sh without 'sudo'.
Do you want to continue? (y/N)" -n 1 -r
echo
[[ $REPLY =~ ^[Yy]$ ]] || {
echo "Exiting..."
exit
}
fi
export MCS_PATH=$PWD
export USERNAME=$USER
[ -r /etc/os-release ] && . /etc/os-release && distro=$ID && distrov=$VERSION_ID && echo " Detected distro: $distro $distrov"
[[ $DOCKER_INSTALL == "true" ]] && DOCKER_INSTALL_ONLINE=y ||
read -p "Use online mode for docker installation? (Y/n)" -n 1 -r DOCKER_INSTALL_ONLINE
echo
if [[ -z $DOCKER_INSTALL_ONLINE ]] || [[ $DOCKER_INSTALL_ONLINE =~ ^[Yy]$ ]]; then #Online mode
# Install Docker Engine using the get-docker convenience script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo chmod 755 ./get-docker.sh
## Patching docker script for "rocky" linux
[[ $distro == 'rocky' ]] && sed -i 's/echo "$lsb_dist"/echo "centos"/' get-docker.sh && echo Modifying get-docker.sh script to install docker on Rocky linux
##
sudo -E ./get-docker.sh
rm ./get-docker.sh
#Install Docker Compose
#Latest version
#curl -L "https://github.com/docker/compose/releases/download/$(get_latest_release)/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#Old version
#sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#sudo curl -L "https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
elif [[ $distro == "ubuntu" && $distrov == "20.04" ]] && [[ $DOCKER_INSTALL_ONLINE =~ ^[Nn]$ ]]; then #Offlane mode
if [[ ! -x "$(command -v docker)" ]]; then
sudo dpkg -i docker/containerd.io_1.4.11-1_amd64.deb &&
sudo dpkg -i docker/docker-ce-cli_20.10.8~3-0~ubuntu-focal_amd64.deb &&
sudo dpkg -i docker/docker-ce_20.10.8~3-0~ubuntu-focal_amd64.deb &&
echo && echo Installation complete && echo || echo Something went wrong, Please install the latest Docker version manually
else
echo Docker is already installed, skipping installation
fi
else
[[ ! -x "$(command -v docker)" ]] && echo Please install the latest Docker version manually && exit || echo Docker is already installed
fi
configure_docker_proxy() {
[[ -z "$PROXY_URL" ]] && return 0
echo "Configuring Docker daemon to use proxy $PROXY_URL"
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/proxy.conf >/dev/null <<EOF
[Service]
Environment="HTTP_PROXY=$PROXY_URL" "HTTPS_PROXY=$PROXY_URL" "NO_PROXY=$no_proxy"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
}
configure_docker_proxy
sudo cp docker/docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
sudo chmod 755 /usr/local/bin/docker-compose
sudo ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
# disable autostart on service start ( eg after reboot or re-installation of the service)
autostart=false
mount_check=false
elif $fresh_install || $cloud_install_mode; then
# Install script is running from outside of the MCS folder ( instance startup ) Should be running as root
# Cloud installation can be manually triggered from the MCS folder with the "cloud" argument
PACKAGE_LIST=""
if command -v apt &>/dev/null; then
PKG_MANAGER="apt"
elif command -v yum &>/dev/null; then
PKG_MANAGER="yum"
else
echo "Unable to detect package manager. Unsupported OS."
exit 1
fi
user_handler() {
getent group sudo && SUDO_GRP=sudo
getent group wheel && SUDO_GRP=wheel
[[ -n $SUDO_GRP ]] || { echo "Unable to detect sudo or wheel group" && exit 1; }
# Check if the user is discovered in the metadata
if [[ -n $MCS_HOST_USER ]]; then
export USERNAME=$MCS_HOST_USER
echo "Using MCS_HOST_USER metadata: $USERNAME"
# Check if the user exists
if id -u $USERNAME >/dev/null; then
echo "User $USERNAME already exists."
else
echo "User $USERNAME does not exist. Creating..."
useradd -m -s /bin/bash -g $MCS_GROUP_ID -G $SUDO_GRP $USERNAME &&
echo "User $USERNAME created successfully." || { echo "Unable to create user $USERNAME" && exit 1; }
fi
elif id -run 1000 >/dev/null; then
export USERNAME=$(id -run 1000)
echo "FAILED TO GET THE MCS_HOST_USER METADATA, using default user: $USERNAME"
else
# In case there is no user existing (eg if no ssh-key metadata configured and no default user existing in the vm image), create one with uid 1000
useradd -m -s /bin/bash -u 1000 -g $MCS_GROUP_ID -G $SUDO_GRP mcs &&
export USERNAME=mcs &&
echo "User mcs created successfully" || { echo "Unable to create user mcs" && exit 1; }
fi
# Check if the user is in the sudo group
if id -nG "$USERNAME" | grep -qw "$SUDO_GRP"; then
echo "User $USERNAME is already in the $SUDO_GRP group."
else
echo "Adding $USERNAME to $SUDO_GRP group..."
usermod -aG $SUDO_GRP $USERNAME &&
echo "User $USERNAME added to $SUDO_GRP group successfully." || { echo "Unable to add user $USERNAME to $SUDO_GRP group" && exit 1; }
fi
export uid=$(id -u $USERNAME)
echo 'if [ "$(id -gn)" = "'$USERNAME'" ]; then umask 0002; fi ' | sudo tee /etc/profile.d/mcs_umask.sh
}
# Cloud type detection
if [[ $(curl --max-time 5 -f http://169.254.169.254/computeMetadata -i | grep Metadata-Flavor) =~ "Google" ]]; then
echo "Detected Google Cloud"
MCS_HOST_USER=$(curl -f http://metadata.google.internal/computeMetadata/v1/instance/attributes/MCS_HOST_USER -H "Metadata-Flavor: Google")
user_handler
MCS_PATH=$(curl -f http://metadata.google.internal/computeMetadata/v1/instance/attributes/MCS_PATH -H "Metadata-Flavor: Google")
if [[ -z $MCS_PATH ]]; then
echo "FAILED TO GET THE MCS_PATH"
exit 1
fi
BUCKET_NAME=$(curl -f http://metadata.google.internal/computeMetadata/v1/instance/attributes/MCS_STORAGE_BUCKET_NAME -H "Metadata-Flavor: Google")
if [[ -z $BUCKET_NAME ]]; then
echo "FAILED TO GET THE MCS_STORAGE_BUCKET_NAME"
exit 1
fi
# Check if gcsfuse is already installed
if ! command -v gcsfuse >/dev/null; then
if [[ $PKG_MANAGER == "apt" ]]; then
# Ubuntu/Debian
GCSFUSE_REPO=gcsfuse-$(lsb_release -c -s)
echo "deb https://packages.cloud.google.com/apt $GCSFUSE_REPO main" | tee /etc/apt/sources.list.d/gcsfuse.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
else
# CentOS/RHEL/Rocky Linux
tee /etc/yum.repos.d/gcsfuse.repo >/dev/null <<EOF
[gcsfuse]
name=gcsfuse (packages.cloud.google.com)
baseurl=https://packages.cloud.google.com/yum/repos/gcsfuse-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
fi
PACKAGE_LIST+=" fuse gcsfuse "
fi
# fstab entry
grep -q "$MCS_PATH/storage" /etc/fstab || {
echo "Adding $BUCKET_NAME mount into $MCS_PATH/storage to fstab"
if [[ $PKG_MANAGER == "apt" ]]; then
# fstab entry for ubuntu - currently will work with nonempty flag
echo "$BUCKET_NAME $MCS_PATH/storage gcsfuse user,nonempty,rw,_netdev,allow_other,uid=${uid},gid=${MCS_GROUP_ID},file_mode=664,dir_mode=775,implicit_dirs" >>/etc/fstab
elif [[ $PKG_MANAGER == "yum" ]]; then
# fstab entry for rocky - currently will not work with nonempty flag
echo "$BUCKET_NAME $MCS_PATH/storage gcsfuse user,rw,_netdev,allow_other,uid=${uid},gid=${MCS_GROUP_ID},file_mode=664,dir_mode=775,implicit_dirs" >>/etc/fstab
fi
}
mount_command="sudo -H -u $USERNAME mount $MCS_PATH/storage"
mount_check=true
# "gcsfuse -o allow_other --implicit-dirs --uid=1000 --gid=1000 $BUCKET_NAME ${MCS_PATH}/storage"
# -o nonempty flag for non-root mounting
elif curl --max-time 5 -i http://169.254.169.254/latest/meta-data/ | grep -q "Server: EC2ws"; then
echo "Detected AWS Cloud"
if ! command -v s3fs >/dev/null; then
if [[ $PKG_MANAGER == "apt" ]]; then
PACKAGE_LIST+=" s3fs"
elif [[ $PKG_MANAGER == "yum" ]]; then
PACKAGE_LIST+=" s3fs-fuse"
fi
fi
TOKEN=$(curl -f -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
if [[ -z $TOKEN ]]; then
echo "FAILED TO GET AWS TOKEN"
exit 1
fi
MCS_PATH=$(curl -f -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/tags/instance/MCS_PATH)
if [[ -z $MCS_PATH ]]; then
echo "FAILED TO GET THE MCS_PATH"
exit 1
fi
BUCKET_NAME=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/tags/instance/MCS_STORAGE_BUCKET_NAME)
if [[ -z $BUCKET_NAME ]]; then
echo "FAILED TO GET THE BUCKET NAME"
exit 1
fi
BUCKET_REGION=$(curl --head $BUCKET_NAME.s3.amazonaws.com | grep bucket-region | awk '{print $2}')
if [[ -z $BUCKET_REGION ]]; then
echo "FAILED TO GET THE BUCKET REGION"
exit 1
fi
ROLE_NAME=$(curl -f -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/iam/security-credentials/)
if [[ -z $ROLE_NAME ]]; then
echo "FAILED TO GET THE ROLE NAME"
exit 1
fi
MCS_HOST_USER=$(curl -f -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/tags/instance/MCS_HOST_USER)
# Sanitize the Variables
sanitize() {
echo "$1" | tr -cd '[:alnum:]._/-'
}
BUCKET_NAME=$(sanitize "$BUCKET_NAME")
BUCKET_REGION=$(sanitize "$BUCKET_REGION")
ROLE_NAME=$(sanitize "$ROLE_NAME")
MCS_PATH=$(sanitize "$MCS_PATH")
MCS_HOST_USER=$(sanitize "$MCS_HOST_USER")
echo "BUCKET_NAME: $BUCKET_NAME"
echo "BUCKET_REGION: $BUCKET_REGION"
echo "ROLE_NAME: $ROLE_NAME"
echo "MCS_PATH: $MCS_PATH"
echo "MCS_HOST_USER: $MCS_HOST_USER"
user_handler
# fstab entry
if ! grep -q "$MCS_PATH/storage" /etc/fstab; then
echo "Adding $MCS_PATH/storage to fstab"
echo "$BUCKET_NAME $MCS_PATH/storage fuse.s3fs user,nonempty,_netdev,allow_other,iam_role=$ROLE_NAME,use_path_request_style,url=https://s3.$BUCKET_REGION.amazonaws.com,endpoint=$BUCKET_REGION,uid=${uid},gid=${MCS_GROUP_ID} 0 0" >>/etc/fstab
fi
mount_check=true
mount_command="sudo -H -u $USERNAME mount $MCS_PATH/storage"
else
echo "Unsupported cloud type, exiting ..."
exit 1
fi
mkdir -pm 775 $MCS_PATH/storage
if ! command -v docker >/dev/null; then
# Install Docker Engine using the get-docker convenience script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo chmod 755 ./get-docker.sh
distro=$(cat /etc/os-release | grep ^ID= | cut -d "=" -f 2 | tr -d '"')
## Patching docker script for "rocky" linux
[[ $distro == 'rocky' ]] && sed -i 's/echo "$lsb_dist"/echo "centos"/' get-docker.sh && echo Modifying get-docker.sh script to install docker on Rocky linux
##
sudo ./get-docker.sh &&
rm ./get-docker.sh ||
{
echo "Failed to install Docker"
exit 1
}
fi
# Install docker-compose
if ! command -v docker-compose >/dev/null; then
sudo curl -L "https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose &&
sudo chmod +x /usr/local/bin/docker-compose &&
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose ||
{
echo "Failed to install docker-compose"
exit 1
}
fi
# Packages installation
[[ -n $PACKAGE_LIST ]] && echo "Packages to install: $PACKAGE_LIST" &&
if [[ $PKG_MANAGER == "apt" ]]; then
export DEBIAN_FRONTEND=noninteractive &&
apt update -y &&
apt install -yq $PACKAGE_LIST nano ||
{
echo "Failed to install packages"
exit 1
}
elif [[ $PKG_MANAGER == "yum" ]]; then
# Install the EPEL repository
if ! dnf repolist | grep -q "epel"; then
echo "EPEL repository not found. Installing epel-release..."
dnf install -y epel-release ||
{
echo "Failed to install EPEL repository"
exit 1
}
else
echo "EPEL repository already enabled."
fi
# Install the packages
dnf install -yq $PACKAGE_LIST nano ||
{
echo "Failed to install packages"
exit 1
}
fi
[[ -f /etc/fuse.conf ]] && { grep "^user_allow_other$" /etc/fuse.conf || echo "user_allow_other" >>/etc/fuse.conf; }
# enable autostart on service start ( eg after reboot or 'systemctl restart mcs' )
autostart=true
fi
if $manual_install_mode || $fresh_install || $cloud_install_mode; then
## General settings - assigning user to the docker and mcs group, handling MCS folder permissions, disabling swap, increasing mmap count
sudo /bin/su -c "usermod -aG ${MCS_GROUP_ID} $USERNAME"
# docker group creation and assignment
getent group docker || sudo groupadd docker
sudo /bin/su -c "usermod -aG docker $USERNAME"
echo "Checking MCS folder owner and permissions..."
# MCS folder creation and permissions
sudo chown -R ${USERNAME}:${MCS_GROUP_ID} $MCS_PATH &&
find $MCS_PATH \( -path "${MCS_PATH}/postgres/data" -o -path "${MCS_PATH}/elasticsearch/data" \) -prune -o -type d \! -perm 2775 -exec sudo chmod 2775 '{}' \; &&
find $MCS_PATH \( -path "${MCS_PATH}/postgres/data" -o -path "${MCS_PATH}/elasticsearch/data" \) -prune -o -type f \! -perm -660 -exec sudo chmod ug+rw '{}' \; || {
echo "Failed to change permissions of the $MCS_PATH"
exit 1
}
mkdir -pm 2775 ${MCS_PATH}/storage || {
echo "Failed to create the ${MCS_PATH}/storage folder"
exit 1
}
# Mounting the storage (when bucket is used)
$mount_command || { echo "Failed to mount the storage: $?" && exit 1; }
mkdir -pm 2775 ${MCS_PATH}/storage/system || {
echo "Failed to create the ${MCS_PATH}/storage/system folder"
exit 1
}
mkdir -pm 2775 ${MCS_PATH}/storage/system/env || {
echo "Failed to create the ${MCS_PATH}/storage/system/env folder"
exit 1
}
#Disabling swap
sudo swapoff -a
#Commenting swap line in /etc/fstab
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
#Increasing mmap. Elasticsearch requirement the ability to create many memory-mapped areas
sudo cat /etc/sysctl.conf | grep 262144 || sudo /bin/su -c "echo 'vm.max_map_count = 262144' >> /etc/sysctl.conf"
sudo sysctl -p
sleep 3
# Adding delay to docker service startup
sudo mkdir -p /etc/systemd/system/docker.service.d/ &&
echo "[Service]
ExecStartPre=/bin/sleep 10
" | sudo tee /etc/systemd/system/docker.service.d/override.conf >/dev/null &&
sudo systemctl daemon-reload
sudo systemctl enable --now docker.service
sudo systemctl enable --now docker.socket
sleep 3
fi
if $manual_install_mode || $fresh_install || $service_update_mode || $cloud_install_mode; then
## Creating mcs service
# shellcheck disable=SC2016
# shellcheck disable=SC2028
echo '#!/usr/bin/env bash
MCS_PATH='${MCS_PATH}'
LOCAL_VERSION_FILE="${MCS_PATH}/current_version"
TARGET_VERSION_FILE="${MCS_PATH}/storage/system/version"
VERSIONS_PATH="${MCS_PATH}/storage/system/versions"
SHA_CHECKSUM=true
# Start MCS when the service is started
autostart='$autostart'
mount_check='$mount_check'
cd ${MCS_PATH} || {
echo "Failed to cd into ${MCS_PATH}"
exit 1
}
mkdir -pm 2775 ${MCS_PATH}/storage/logs
mkdir -pm 2775 ${MCS_PATH}/storage/system/versions
touch current_state
# Functions
mount_check() {
if $mount_check ; then
# mount check is enabled
# mount is OK
mountpoint -q ${MCS_PATH}/storage && ls ${MCS_PATH}/storage >/dev/null && return 0
# mount is not OK, try to remount
umount ${MCS_PATH}/storage
sleep 1
if mount ${MCS_PATH}/storage ; then
write_log "${MCS_PATH}/storage was remounted"
mkdir -pm 2775 ${MCS_PATH}/storage/logs || {
echo "Failed to create ${MCS_PATH}/storage/logs"
exit 1
}
mkdir -pm 2775 ${MCS_PATH}/storage/system/versions || {
echo "Failed to create ${MCS_PATH}/storage/system/versions"
exit 1
}
return 0
else
# failed to remount
echo "Failed to mount ${MCS_PATH}/storage . Retrying in 10 seconds..."
sleep 10
return 1
fi
else
# mount check is off
return 0
fi
}
check_state() {
[[ -f current_state ]] && state=$(cat current_state) || state=""
[[ $state == "$1" ]] && return 0 || return 1
}
set_state() {
echo "$1" >current_state
}
write_status(){
date=$(date +"%H:%M:%S.%3N - %d-%m-%Y")
HOST_NAME=$(hostname)
uptime_output=$(uptime)
stats_output=$(docker stats --no-stream)
status="$date MCS_VERSION: $MCS_VERSION
uptime $uptime_output
Last event: $log_event
$stats_output"
printf "%s\n" "$status" > ${MCS_PATH}/storage/logs/${HOST_NAME}-status.log
}
write_log(){
log_event=$1
date=$(date +"%H:%M:%S.%3N - %d-%m-%Y")
HOST_NAME=$(hostname)
echo "$HOST_NAME - $date - $log_event" | tee -a ${MCS_PATH}/storage/logs/${HOST_NAME}-service.log
}
start_mcs(){
./run.sh start || {
write_log "Failed to start MCS"
return 1
}
write_log "MCS started"
set_state started
autostart=false
return 0
}
stop_mcs(){
check_state stopped && return 0
if [[ -f ${MCS_PATH}/.env ]] ; then
./run.sh stop &&
set_state stopped || {
write_log "Failed to stop MCS"
return 1
}
write_log "MCS stopped"
else
echo "Looks like the MCS is not installed"
fi
return 0
}
check_tar(){
set_state tar_check
if [[ $SHA_CHECKSUM == true ]] && command -v sha1sum &>/dev/null && tar axf $1 -O MCS/mcs.sha &>/dev/null ; then
tar xvf $1 MCS --to-command sha1sum >${MCS_PATH}/mcs.sha &&
exclude_sha=$(cat ${MCS_PATH}/mcs.sha | grep "mcs.sha" -A 1) &&
diff <(tar -axf $1 -O MCS/mcs.sha) <(cat ${MCS_PATH}/mcs.sha |grep -v "$exclude_sha") && echo "SHA checksums match" || {
write_log "SHA checksums do not match for $1"
sleep 5
return 1
}
else
tar tf $1 || {
write_log "Detected corrupted archive"
sleep 5
return 1
}
fi
return 0
}
extract_mcs(){
write_log "Checking archive $1"
check_tar $1 || return 1
set_state extracting
write_log "Extracting MCS from $1 to $MCS_PATH"
tar xf $1 -C ${MCS_PATH}/ --strip-components=1 || {
echo "Failed to extract $1"
return 1
}
MCS_VERSION=$(grep -E "^MCS_VERSION=" environment | cut -d "=" -f2 |tr -d \") || {
write_log "Failed to determine MCS version"
return 1
}
write_log "MCS was extracted from $1"
set_state svc_update
return 0
}
setup_mcs(){
if [[ -f ./storage/system/env/external.env ]] && [[ ! -f .env ]] && [[ ! -f ./storage/system/env/${MCS_VERSION}.env ]] ; then
# INITIAL INSTALL USING AUTOMATION, use generated external.env
write_log "Running MCS setup, using external.env file on fresh install"
cp ./storage/system/env/external.env .env &&
./setup.sh auto || {
write_log "MCS setup script failed: $?"
return 1
}
elif [[ ! -f ./storage/system/env/${MCS_VERSION}.env ]] && [[ ! -f .env ]]; then
# FRESH INSTALL , no environment configuration, idling for manual setup
[[ $idle_setup == true ]] ||
write_log "Fresh install $MCS_VERSION, idling for manual setup"
idle_setup=true
return 0
else
write_log "Running MCS setup, using existing environment configuration" &&
./setup.sh auto || {
write_log "MCS setup script failed: $?"
return 1
}
fi
idle_setup=false
set_state start
return 0
}
env_sync(){
MCS_VERSION=$(grep -E "^MCS_VERSION=" environment | cut -d "=" -f2 |tr -d \")
if [[ ! -f ./storage/system/env/${MCS_VERSION}.env ]] && [[ ! -f .env ]] ; then
# FRESH INSTALL , no environment configuration, idling for manual setup
return 1
elif [[ ! -f .env ]] ; then
write_log "Using ${MCS_VERSION}.env on fresh install"
setup_mcs || return 1
return 0 # OK to restart
fi
if pgrep -f " .env" >/dev/null ; then
# Check if .env is being edited
$env_is_closed && echo ".env file is opened... Not monitoring .env changes"
env_is_closed=false
return 1
fi
if pgrep -x setup.sh >/dev/null ; then
# Check if setup.sh is running (someone is configuring the environment)
$env_is_closed && echo "setup.sh is running... Not monitoring .env changes"
env_is_closed=false
return 1
fi
$env_is_closed || echo "Back to monitor .env changes"
env_is_closed=true
if cmp -s .env ./storage/system/env/"${MCS_VERSION}".env ; then
$env_in_sync || write_log ".env is in sync with storage/system/env/${MCS_VERSION}.env"
env_in_sync=true
$autostart && echo "mcs service is up , Starting MCS ..." &&
return 0
return 1
else
# finding which one is newer
if [[ .env -nt storage/system/env/${MCS_VERSION}.env ]] ;then
#write_log "local .env file is newer than $MCS_VERSION.env, updating"
#cp .env storage/system/env/"${MCS_VERSION}".env
#return 0
$env_in_sync && write_log ".env file is newer than storage/system/env/$MCS_VERSION.env, will be synced on successful start"
env_in_sync=false
return 1
else
[[ -s storage/system/env/"${MCS_VERSION}".env ]] &&
write_log ".env file is older than storage/system/env/${MCS_VERSION}.env, updating" &&
cp storage/system/env/"${MCS_VERSION}".env .env &&
return 0 || return 1
fi
fi
}
### MAIN LOOP ###
while true ; do
mount_check || continue
[[ -f $LOCAL_VERSION_FILE ]] && LOCAL_VERSION=$(cat "$LOCAL_VERSION_FILE") || LOCAL_VERSION=0
[[ -f $TARGET_VERSION_FILE ]] && TARGET_VERSION="${VERSIONS_PATH}/$(cat "$TARGET_VERSION_FILE")" || TARGET_VERSION=0
if [[ $(basename $TARGET_VERSION) != "$(basename $LOCAL_VERSION)" ]] && [[ $TARGET_VERSION != "0" ]]; then
### VERSION MISMATCH , NEED TO EXTRACT THE NEW VERSION
write_log "Version mismatch: current - $LOCAL_VERSION , desired - $TARGET_VERSION"
[[ -f $TARGET_VERSION ]] &&
set_state extract || {
write_log "$TARGET_VERSION package is not found "
## THE DESIRED TAR PACKAGE IS NOT FOUND IN VERSIONS FOLDER - STOP MCS IF RUNNING AND IDLE , TO AVOID MULTIPLE VERSIONS RUNNING AT THE SAME TIME
stop_mcs
sync=false
}
elif [[ $LOCAL_VERSION == "0" ]] && [[ $TARGET_VERSION == "0" ]]; then
### FRESH INSTALL , NEED TO USE THE LATEST VERSION WE CAN FIND IN THE STORAGE , IDLE IF NO VERSION FILE IS FOUND
TARGET_VERSION=$(ls -tA ${VERSIONS_PATH}/update_*.tar 2>/dev/null | head -1)
[[ -f $TARGET_VERSION ]] && echo ${TARGET_VERSION##*/} > $TARGET_VERSION_FILE &&
write_log "Fresh install - $TARGET_VERSION found" &&
set_state extract || sync=false
elif [[ $(basename $TARGET_VERSION) == "$(basename $LOCAL_VERSION)" ]] && [[ $LOCAL_VERSION != "0" ]]; then
### VERSION MATCH , NO NEED TO UPGRADE
sync=true
else
### LOCAL VERSION IS THERE , BUT NO TARGET VERSION FILE FOUND IN STORAGE FOLDER, IDLE . CAN BE A MOUNT POINT PROBLEM OR A LOCAL INSTALLATION
sync=false
fi
if check_state extract; then
stop_mcs &&
extract_mcs $TARGET_VERSION &&
echo $TARGET_VERSION > $LOCAL_VERSION_FILE
elif check_state svc_update; then
echo "Refreshing the mcs systemd service"
exit 0
elif check_state setup; then
setup_mcs
elif check_state start; then
start_mcs
elif $sync ; then
env_sync && set_state start
# writing status
if [[ $(jobs | wc -l) -lt 2 ]]; then
write_status &
fi
sleep 5
else
### IDLE
sleep 5
fi
sleep 1
done
' | sudo tee /usr/bin/mcs_deploy.sh >/dev/null
sudo chmod +x /usr/bin/mcs_deploy.sh
echo "[Unit]
Description=MCS Init service
Before=docker.service
After=network-online.target
Wants=network-online.target docker.service
StartLimitIntervalSec=10
StartLimitBurst=5
[Service]
User=${USERNAME}
Group=${MCS_GROUP_ID}
Environment=USERNAME=$USERNAME
Environment=autostart=$autostart
Environment=mount_check=$mount_check
Environment=HOST_NAME=$(hostname)
Environment=MCS_PATH=${MCS_PATH}
ExecStart=/usr/bin/mcs_deploy.sh
ExecStop=-/usr/bin/env bash -c \"${MCS_PATH}/run.sh stop\"
ExecStopPost=+/usr/bin/env bash -c \"${MCS_PATH}/install.sh service\"
UMask=0002
KillMode=process
RestartSec=10s
Restart=always
Type=simple
[Install]
WantedBy=multi-user.target
" | sudo tee /etc/systemd/system/mcs.service >/dev/null
sudo systemctl daemon-reload
if $service_update_mode; then
# Exit to restart the service and update the current_state to proceed with the installation
echo setup >current_state
exit 0
fi
sudo systemctl enable mcs.service
sudo systemctl restart mcs.service --no-block
echo "MCS Init service installed and started, you can check its status: 'systemctl status mcs.service' or 'journalctl -u mcs'"
echo "Please log out to apply the system changes. After logging back in, navigate to the $MCS_PATH directory and execute ./setup.sh"
fi