test/lib/functions.sh
2023-04-17 15:45:47 +00:00

333 lines
12 KiB
Bash

# Federated Computer functions
fail() {
echo -ne "FAILED\n\n$1\n\n"
kill -9 $SPINPID &> /dev/null
# [ -d "apps/dns" ] && rm -rf apps/dns
# docker network rm fstack &> /dev/null
exit 2;
}
failcheck() {
echo -ne "\n\nFAILED - $1\n\n"
exit 2;
}
cleanup() {
kill -9 $SPINPID &> /dev/null
exit 2
}
spin() {
spinner="/|\\-/|\\-"
while :
do
for i in `seq 0 7`
do
echo -n "${spinner:$i:1}"
echo -en "\010"
sleep 1
done
done
}
add_cron() {
(crontab -l; echo "30 23 * * * /federated/bin/backup.sh >> /federated/logs/backup.log 2>&1") | sort -u | crontab -
(crontab -l; echo "0 2 * * * /federated/bin/upgrade.sh >> /federated/logs/upgrade.log 2>&1") | sort -u | crontab -
}
install_federated() {
[ -d "/federated" ] && fail "Directory /federated already exists. Already installed?"
API_TOKEN="92d97f5aa371d420ebce7bc9a008ea8c6ec5d334"
git clone https://derek:$API_TOKEN@code.federated.company/federatedcomputer/Core /federated
}
upgrade_federated() {
echo -ne "\n* Updating federated install.."
[ ! -d "/federated" ] && fail "Directory /federated doesn't exist."
echo -ne "\n* Grabbing the latest version from Gitea.."
API_TOKEN="92d97f5aa371d420ebce7bc9a008ea8c6ec5d334"
cd /federated && git pull https://derek:$API_TOKEN@code.federated.company/federatedcomputer/Core &> /dev/null
[ $? -ne 0 ] && fail "Git pull not working on update of federated."
echo -ne "\n* Checking installed app versions with the latest.."
[ ! -f "/federated/lib/latest-versions" ] && fail "File /federated/lib/latest-version doesn't exist."
for i in `cat /federated/lib/latest-versions`; do
SERVICE=(${i//=/ });
APP="${SERVICE[0]}"
VERSION="${SERVICE[1]}"
echo -ne "\n** Checking $APP.."
[ ! -f "/federated/apps/$APP/.env" ] && fail "File /federated/apps/$APP/.env doesn't exist."
APP_VERSION_RAW=`grep IMAGE_VERSION /federated/apps/$APP/.env | awk -F= '{ print $2 }'`
APP_VERSION="${APP_VERSION_RAW//\"}"
if [ "$APP_VERSION" = "$VERSION" ]; then
echo -ne "\n $APP is already at the latest version."
else
NC_COMMAND=`grep start_service /federated/lib/$APP.sh | awk -F\" '{ print $4 }'`
echo -ne "\n Upgrading $APP.."
echo -ne "\n Shutting Down $APP.."
cd /federated/apps/$APP && docker-compose -f docker-compose.yml -p $APP down
sed -i "s#VERSION=.*#VERSION=$VERSION#g" /federated/apps/$APP/.env
echo -ne "\n Starting Up $APP.."
start_service_upgrade "$APP" "$NC_COMMAND"
echo -ne "\n Done Updating $APP to $VERSION."
fi
done
echo -ne "\n\n"
}
create_password() {
# eval $1_var=$1
# echo "$postgres_var"
SECRET=`tr -cd '[:alnum:]' < /dev/urandom | fold -w32 | head -n1`
echo "$SECRET";
}
start_service_upgrade() {
SERVICE="$1"
COMMAND="$2"
# Start /federated/apps/SERVICE with output to /dev/null
echo -ne "\n* Starting /federated/apps/$SERVICE service.."
if [ $DEBUG ]; then
# Start /federated/apps/SERVICE with output to console for debug
docker-compose -f /federated/apps/$SERVICE/docker-compose.yml -p $SERVICE up
[ $? -eq 0 ] && echo -ne "done.\n" || fail "There was a problem starting service /federated/apps/$SERVICE"
else
docker-compose -f /federated/apps/$SERVICE/docker-compose.yml -p $SERVICE up -d &> /dev/null
# Keep trying service port to make sure it's up before
# we proceed
RETRY="30"
while [ $RETRY -gt 0 ]; do
bash -c "$COMMAND" &> /dev/null
if [ $? -eq 0 ]; then
break
else
if [ "$RETRY" == 1 ]; then
docker-compose -f /federated/apps/$SERVICE/docker-compose.yml -p $SERVICE down &> /dev/null
fail "There was a problem starting service /federated/apps/$SERVICE\nCheck the output of 'docker logs $SERVICE' or turn on\ndebug with -d"
fi
((RETRY--))
sleep 7
fi
done
fi
}
start_service() {
SERVICE="$1"
COMMAND="$2"
# Start /federated/apps/SERVICE with output to /dev/null
echo -ne "\n* Starting /federated/apps/$SERVICE service.."
spin &
SPINPID=$!
if [ $DEBUG ]; then
# Start /federated/apps/SERVICE with output to console for debug
docker-compose -f /federated/apps/$SERVICE/docker-compose.yml -p $SERVICE up
[ $? -eq 0 ] && echo -ne "done.\n" || fail "There was a problem starting service /federated/apps/$SERVICE"
else
docker-compose -f /federated/apps/$SERVICE/docker-compose.yml -p $SERVICE up -d &> /dev/null
# Keep trying service port to make sure it's up before
# we proceed
RETRY="30"
while [ $RETRY -gt 0 ]; do
bash -c "$COMMAND" &> /dev/null
if [ $? -eq 0 ]; then
break
else
if [ "$RETRY" == 1 ]; then
docker-compose -f /federated/apps/$SERVICE/docker-compose.yml -p $SERVICE down &> /dev/null
kill -9 $SPINPID &> /dev/null
fail "There was a problem starting service /federated/apps/$SERVICE\nCheck the output of 'docker logs $SERVICE' or turn on\ndebug with -d"
fi
((RETRY--))
sleep 7
fi
done
fi
}
print_details() {
cat > /federated/apps/mail/data/root/certs/mailfile <<EOF
Panel: User Management
https://panel.$DOMAIN
You must also log in as an admin user to https://vaultwarden.$DOMAIN
to create an organization for your team. Open the URL
(https://vaultwarden.$DOMAIN) and click the text below "Continue"
that says "Create account".
You will need this information for the VPN that can be set up by
users of your system. Please keep it private.
EOF
cat /federated/apps/wireguard/data/config/peer1/peer1.conf >> /federated/apps/mail/data/root/certs/mailfile
cat >> /federated/apps/mail/data/root/certs/mailfile <<EOF
All documentation for administration of your Federated Core can
be found at: https://documentation.federated.computer/administration.
Users can then log into the following services to use Federated Core:
Nextcloud: The Nextcloud suite provides web apps and services
covering mail, calendar, contacts, notes, tasks, files, project
management (deck), bookmarks, forms, team talk, pictures, and an
activity monitor. It can be accessed at: https://nextcloud.$DOMAIN
Jitsi: Video-conferencing. The current installation supports (4)
users and can be extended by adding more RAM to the system. It can
be found at: https://jitsi.$DOMAIN
Element: Worldwide Federated Chat. This chat client uses Matrix and
can be used chat with users outside your team and can even interact
with other chat servers around the world including Signal, Whatsapp,
and other services. It is found at: https://element.$DOMAIN
Listmonk: Marketing Email Service. Use Listmonk the way you would use
Mailchimp. Found here: https://listmonk.$DOMAIN
Vaultwarden: Password Management. Open source equivalent of Bitwarden
and is a widely used replacement for 1password, Lastpass, and other
password managers. https://vaultwarden.$DOMAIN
Baserow: Easy Database. Replacement for Airtable. Build amazing, easy
to create on-line databases to be used by your team.
https://baserow.$DOMAIN
Cal.com: Easy scheduling. Create easy links so that others can easily
schedule time on your calendar without the annoying back-and-forth.
https://calcom.$DOMAIN
Connector: a utility to automatically configure all your applications
on macOS, iOS, Windows, Android for use with your Federated Core.
https://connector.$DOMAIN
All documentation for users can be found at
https://documentation.federated.computer/users.
EOF
# Send out e-mail from mail container with details
docker exec -it mail bash -c "mail -r admin@$DOMAIN -s \"Welcome to Federated\" admin@$DOMAIN < /root/certs/mailfile"
cat /federated/apps/mail/data/root/certs/mailfile
rm /federated/apps/mail/data/root/certs/mailfile
}
check_docker() {
OSRELEASE=`lsb_release -a 2>/dev/null | grep ID | awk -F: '{ print $2 }' | xargs`
if ! command -v docker &> /dev/null; then
echo -ne "\n* Couldn't find docker, installing.."
spin &
SPINPID=$!
# Install Docker on Ubuntu
if [ $OSRELEASE == "Ubuntu" ]; then
# Update list of packages
sudo apt-get update -y &> /dev/null
[ $? -ne 0 ] && failcheck "Couldn't run sudo apt-get update"
# Install packages which let apt use packages over HTTPS
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y &> /dev/null
[ $? -ne 0 ] && failcheck "Couldn't run sudo apt install for https packages"
# Add GPG key for the official Docker repository to this system
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - &> /dev/null
[ $? -ne 0 ] && failcheck "Couldn't run curl to add Docker GPG key"
# Add the docker repository to our APT sources list
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu jammy stable" -y &> /dev/null
[ $? -ne 0 ] && failcheck "Couldn't run sudo add-apt-repository"
# Install docker packages
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-compose -y &> /dev/null
[ $? -ne 0 ] && failcheck "Couldn't run sudo apt install docker packages"
# Install extra packages
sudo apt-get install duplicity python3-b2sdk uuid -y &> /dev/null
[ $? -ne 0 ] && failcheck "Couldn't run sudo apt install extra packages"
fi
kill -9 $SPINPID &> /dev/null
echo -ne "done."
fi
if ! command -v docker-compose &> /dev/null; then
echo -ne "\n* Couldn't find docker-compose, installing.."
spin &
SPINPID=$!
# Install Docker compose on Ubuntu
if [ $OSRELEASE == "Ubuntu" ]; then
sudo apt-get install docker-compose -y &> /dev/null
fi
kill -9 $SPINPID &> /dev/null
echo -ne "done."
fi
}
check_ports() {
EXTERNALIP=`dig @resolver4.opendns.com myip.opendns.com +short 2> /dev/null`
[ $? -ne 0 ] && failcheck "Couldn't run dig, dns is not working"
# Check if ss command exists
if command -v ss &> /dev/null; then
# Check every port we need if it's in use (only if we have never run before)
if [ $(ls /federated/apps | wc -l) -eq "0" ]; then
for i in 25 53 80 143 389 587 993 8000; do
SS=`ss -tulwn | grep LISTEN | awk '{ print $5 }' | awk -F: '{ print $NF }' | grep "^$i$" | head -1`
# If port 53 (dns) in use by system-resolvd (Ubuntu) then auto fix
if [ "$SS" == 53 ]; then
if [ $OSRELEASE == "Ubuntu" ]; then
if [ `pgrep -x systemd-resolve` ]; then
echo -ne "\n* Port 53 in use by systemd-resolved, fixing.."
spin &
SPINPID=$!
# Install resolvconf to fix
sudo apt install resolvconf -y &> /dev/null
[ $? -eq 0 ] && echo -ne "." || failcheck "Failed running sudo apt install resolvconf"
# Shut down systemd-resolved
systemctl stop systemd-resolved &> /dev/null
[ $? -ne 0 ] && failcheck "Failed running systemctl stop systemd-resolved"
systemctl disable systemd-resolved &> /dev/null
[ $? -ne 0 ] && failcheck "Failed running systemctl stop systemd-resolved"
# Put nameserver entries so will exist on reboot
echo "nameserver 8.8.8.8" > /etc/resolvconf/resolv.conf.d/tail
echo "nameserver 8.8.8.8" > /run/resolvconf/resolv.conf
kill -9 $SPINPID &> /dev/null
echo -ne "done."
else
echo -ne "\nFAILED - Port 53 (dns) is already in use\n\n" && exit 2
fi
fi
elif [ "$SS" == "$i" ]; then
failcheck "FAILED - Port $i is already in use"
fi
done
fi
fi
}
check_os() {
VERSIONID=`grep "VERSION_ID=" /etc/os-release | awk -F\" '{ print $2 }'`
if [ "$VERSIONID" != "22.04" ]; then
echo -ne "\nFederated requires a minimum of 4G of RAM and 25G of storage\n \
running Ubuntu 22.04 LTS. Your system is not supported. Please contact\n \
Federated @ support@federated.computer for assistance or choose our\n \
cloud offerings at https://cloud.federated.computer.\n\n"
exit 2;
fi
}
check_memory() {
MEMTOTAL=`awk '/MemTotal/ { printf "%.3d \n", $2/1024 }' /proc/meminfo`
if [ "$MEMTOTAL" -lt "3700" ]; then
echo -ne "\nFederated requires a minimum of 4G of RAM and 25G of storage\n \
running Ubuntu 22.04 LTS. Your system is not supported. Please contact\n \
Federated @ support@federated.computer for assistance or choose our\n \
cloud offerings at https://cloud.federated.computer.\n\n"
exit 2;
fi
}