Page MenuHomePhorge

kolabctl
No OneTemporary

Authored By
Unknown
Size
15 KB
Referenced Files
None
Subscribers
None

kolabctl

#!/bin/bash
set -e
export CONFIG=${CONFIG:-"config.prod"}
export HOST=${HOST:-"kolab.local"}
OPENEXCHANGERATES_API_KEY=${OPENEXCHANGERATES_API_KEY}
FIREBASE_API_KEY=${FIREBASE_API_KEY}
PUBLIC_IP=${PUBLIC_IP:-"127.0.0.1"}
export CERTS_PATH=./docker/certs
export POD=kolab-prod
export IMAP_SPOOL_STORAGE="--mount=type=volume,src=$POD-imap-spool,destination=/var/spool/imap,U=true"
export IMAP_LIB_STORAGE="--mount=type=volume,src=$POD-imap-lib,destination=/var/lib/imap,U=true"
export POSTFIX_SPOOL_STORAGE="--mount=type=volume,src=$POD-postfix-spool,destination=/var/spool/imap,U=true"
export POSTFIX_LIB_STORAGE="--mount=type=volume,src=$POD-postfix-lib,destination=/var/lib/imap,U=true"
export SYNAPSE_STORAGE="--mount=type=volume,src=$POD-synapse-data,destination=/data,U=true"
export MARIADB_STORAGE="--mount=type=volume,src=$POD-mariadb-data,destination=/var/lib/mysql,U=true"
export REDIS_STORAGE="--mount=type=volume,src=$POD-redis-data,destination=/var/lib/redis,U=true"
export MINIO_STORAGE="--mount=type=volume,src=$POD-minio-data,destination=/data,U=true"
export ENV_FILE=src/.env
export PODMAN_IGNORE_CGROUPSV1_WARNING=true
source bin/podman_shared
__export_env() {
source src/.env
export APP_WEBSITE_DOMAIN
export APP_DOMAIN
export DB_HOST
export IMAP_HOST
export IMAP_PORT
export IMAP_ADMIN_LOGIN
export IMAP_ADMIN_PASSWORD
export MAIL_HOST
export MAIL_PORT
export IMAP_DEBUG
export FILEAPI_WOPI_OFFICE
export CALENDAR_CALDAV_SERVER
export KOLAB_ADDRESSBOOK_CARDDAV_SERVER
export DB_ROOT_PASSWORD
export DB_USERNAME
export DB_PASSWORD
export DB_DATABASE
export REDIS_HOST
export REDIS_PASSWORD
export MINIO_USER
export MINIO_PASSWORD
export PASSPORT_PRIVATE_KEY
export PASSPORT_PUBLIC_KEY
export DES_KEY
export MEET_SERVER_TOKEN
export MEET_WEBHOOK_TOKEN
export KOLAB_SSL_CERTIFICATE
export KOLAB_SSL_CERTIFICATE_FULLCHAIN
export KOLAB_SSL_CERTIFICATE_KEY
export PUBLIC_IP
}
kolab__configure() {
if [[ "$1" == "--force" ]]; then
rm src/.env
fi
# Generate the .env once with all the necessary secrets
if [[ -f src/.env ]]; then
echo "src/.env already exists, not regenerating"
return
fi
cp "$CONFIG/src/.env" src/.env
if [[ -z $ADMIN_PASSWORD ]]; then
echo "Please enter your new infrastructure admin password used for various infrastructure components (mysql, imap, ...):"
read -r ADMIN_PASSWORD
fi
if [[ -z $PUBLIC_IP ]]; then
PUBLIC_IP=$(ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p')
fi
# Generate random secrets
if ! grep -q "COTURN_STATIC_SECRET" src/.env; then
COTURN_STATIC_SECRET=$(openssl rand -hex 32);
echo "COTURN_STATIC_SECRET=${COTURN_STATIC_SECRET}" >> src/.env
fi
if ! grep -q "MEET_WEBHOOK_TOKEN" src/.env; then
MEET_WEBHOOK_TOKEN=$(openssl rand -hex 32);
echo "MEET_WEBHOOK_TOKEN=${MEET_WEBHOOK_TOKEN}" >> src/.env
fi
if ! grep -q "MEET_SERVER_TOKEN" src/.env; then
MEET_SERVER_TOKEN=$(openssl rand -hex 32);
echo "MEET_SERVER_TOKEN=${MEET_SERVER_TOKEN}" >> src/.env
fi
if ! grep -q "APP_KEY=base64:" src/.env; then
APP_KEY=$(openssl rand -base64 32);
echo "APP_KEY=base64:${APP_KEY}" >> src/.env
fi
if ! grep -q "PASSPORT_PROXY_OAUTH_CLIENT_ID=" src/.env; then
PASSPORT_PROXY_OAUTH_CLIENT_ID=$(uuidgen);
echo "PASSPORT_PROXY_OAUTH_CLIENT_ID=${PASSPORT_PROXY_OAUTH_CLIENT_ID}" >> src/.env
fi
if ! grep -q "PASSPORT_PROXY_OAUTH_CLIENT_SECRET=" src/.env; then
PASSPORT_PROXY_OAUTH_CLIENT_SECRET=$(openssl rand -base64 32);
echo "PASSPORT_PROXY_OAUTH_CLIENT_SECRET=${PASSPORT_PROXY_OAUTH_CLIENT_SECRET}" >> src/.env
fi
if ! grep -q "PASSPORT_SYNAPSE_OAUTH_CLIENT_ID=" src/.env; then
PASSPORT_SYNAPSE_OAUTH_CLIENT_ID=$(uuidgen);
echo "PASSPORT_SYNAPSE_OAUTH_CLIENT_ID=${PASSPORT_SYNAPSE_OAUTH_CLIENT_ID}" >> src/.env
fi
if ! grep -q "PASSPORT_SYNAPSE_OAUTH_CLIENT_SECRET=" src/.env; then
PASSPORT_SYNAPSE_OAUTH_CLIENT_SECRET=$(openssl rand -base64 32);
echo "PASSPORT_SYNAPSE_OAUTH_CLIENT_SECRET=${PASSPORT_SYNAPSE_OAUTH_CLIENT_SECRET}" >> src/.env
fi
if ! grep -q "PASSPORT_WEBMAIL_SSO_CLIENT_ID=" src/.env; then
PASSPORT_WEBMAIL_SSO_CLIENT_ID=$(uuidgen);
echo "PASSPORT_WEBMAIL_SSO_CLIENT_ID=${PASSPORT_WEBMAIL_SSO_CLIENT_ID}" >> src/.env
fi
if ! grep -q "PASSPORT_WEBMAIL_SSO_CLIENT_SECRET=" src/.env; then
PASSPORT_WEBMAIL_SSO_CLIENT_SECRET=$(openssl rand -base64 32);
echo "PASSPORT_WEBMAIL_SSO_CLIENT_SECRET=${PASSPORT_WEBMAIL_SSO_CLIENT_SECRET}" >> src/.env
fi
if ! grep -q "PASSPORT_PUBLIC_KEY=|PASSPORT_PRIVATE_KEY=" src/.env; then
PASSPORT_PRIVATE_KEY=$(openssl genrsa 4096);
echo "PASSPORT_PRIVATE_KEY=\"${PASSPORT_PRIVATE_KEY}\"" >> src/.env
PASSPORT_PUBLIC_KEY=$(echo "$PASSPORT_PRIVATE_KEY" | openssl rsa -pubout 2>/dev/null)
echo "PASSPORT_PUBLIC_KEY=\"${PASSPORT_PUBLIC_KEY}\"" >> src/.env
fi
if ! grep -q "DES_KEY=" src/.env; then
DES_KEY=$(openssl rand -base64 24);
echo "DES_KEY=${DES_KEY}" >> src/.env
fi
# Customize configuration
sed -i \
-e "s/{{ host }}/${HOST}/g" \
-e "s/{{ openexchangerates_api_key }}/${OPENEXCHANGERATES_API_KEY}/g" \
-e "s/{{ firebase_api_key }}/${FIREBASE_API_KEY}/g" \
-e "s/{{ public_ip }}/${PUBLIC_IP}/g" \
-e "s/{{ admin_password }}/${ADMIN_PASSWORD}/g" \
src/.env
if [ -f /etc/letsencrypt/live/${HOST}/cert.pem ]; then
echo "Using the available letsencrypt certificate for ${HOST}"
cat >> src/.env << EOF
KOLAB_SSL_CERTIFICATE=/etc/letsencrypt/live/${HOST}/cert.pem
KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/letsencrypt/live/${HOST}/fullchain.pem
KOLAB_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/${HOST}/privkey.pem
EOF
fi
}
kolab__deploy() {
if [[ -z $ADMIN_PASSWORD ]]; then
echo "Please enter your new admin password for the admin@$HOST user:"
read -r ADMIN_PASSWORD
fi
echo "Deploying $CONFIG on $HOST"
if [ `getenforce` == "Enforcing" ]; then
# Patches on how to correctly configure selinux are welcome
echo "selinux breaks networking, please disable"
exit 1
fi
if [[ ! -f src/.env ]]; then
echo "Missing src/.env file, run 'kolabctl configure' to generate"
exit 1
fi
if [[ "$1" == "--reset" ]]; then
kolab__reset --force
fi
__export_env
podman volume create $POD-imap-spool --ignore -l=kolab
podman volume create $POD-imap-lib --ignore -l=kolab
podman volume create $POD-postfix-spool --ignore -l=kolab
podman volume create $POD-postfix-lib --ignore -l=kolab
podman volume create $POD-synapse-data --ignore -l=kolab
podman volume create $POD-mariadb-data --ignore -l=kolab
podman volume create $POD-redis-data --ignore -l=kolab
podman volume create $POD-minio-data --ignore -l=kolab
kolab__build
# Create the pod first
$PODMAN pod create \
--replace \
--add-host=$HOST:127.0.0.1 \
--publish "443:6443" \
--publish "465:6465" \
--publish "587:6587" \
--publish "143:6143" \
--publish "993:6993" \
--publish "44444:44444/udp" \
--publish "44444:44444/tcp" \
--name $POD
podman__run_mariadb
podman__run_redis
podman__healthcheck $POD-mariadb $POD-redis
# IMAP must be avialable for the seeder
podman__run_imap
podman__healthcheck $POD-imap
podman__run_webapp
podman__healthcheck $POD-webapp
# Ensure all commands are processed
echo "Flushing work queue"
$PODMAN exec -ti $POD-webapp ./artisan queue:work --stop-when-empty
if [[ -n $ADMIN_PASSWORD ]]; then
podman exec $POD-webapp ./artisan user:password "admin@$APP_DOMAIN" "$ADMIN_PASSWORD"
fi
podman__run_synapse
podman__run_element
podman__run_minio
podman__healthcheck $POD-minio
podman__run_meet
podman__run_roundcube
podman__run_postfix
podman__run_amavis
podman__run_collabora
podman__run_proxy
echo "Deployment complete!"
}
kolab__reset() {
if [[ "$1" == "--force" ]]; then
REPLY="y"
else
read -p "Are you sure? This will delete the pod including all data. Type y to confirm." -n 1 -r
echo
fi
if [[ "$REPLY" =~ ^[Yy]$ ]];
then
podman pod rm --force $POD
volumes=($(podman volume ls -f name=$POD | awk '{if (NR > 1) print $2}'))
for v in "${volumes[@]}"
do
podman volume rm --force $v
done
fi
}
kolab__start() {
podman pod start $POD
}
kolab__stop() {
podman pod stop $POD
}
kolab__update() {
kolab__stop
podman pull quay.io/sclorg/mariadb-105-c9s
podman pull minio/minio:latest
podman pull almalinux:9
kolab__build
kolab__start
}
kolab__backup() {
backup_path="$(pwd)/backup/"
mkdir -p "$backup_path"
echo "Stopping containers"
kolab__stop
echo "Backing up volumes"
volumes=($(podman volume ls -f name=$POD | awk '{if (NR > 1) print $2}'))
for v in "${volumes[@]}"
do
podman export -o="$backup_path/$v.tar"
done
echo "Restarting containers"
kolab__start
}
kolab__restore() {
backup_path="$(pwd)/backup/"
echo "Stopping containers"
kolab__stop
# We currently expect the volumes to exist.
# We could alternatively create volumes form existing tar files
# for f in backup/*.tar; do
# echo "$(basename $f .tar)" ;
# done
echo "Restoring volumes"
volumes=($(podman volume ls -f name=$POD | awk '{if (NR > 1) print $2}'))
for v in "${volumes[@]}"
do
podman import $v "$backup_path/$v.tar"
done
echo "Restarting containers"
kolab__start
}
kolab__selfcheck() {
set -e
APP_DOMAIN=$(grep APP_DOMAIN src/.env | tail -n1 | sed "s/APP_DOMAIN=//")
if [ -z "$ADMIN_PASSWORD" ]; then
echo "Please enter your new admin password for the admin@$HOST user:"
read -r ADMIN_PASSWORD
fi
if [ -z "$ADMIN_USER" ]; then
ADMIN_USER="admin@$APP_DOMAIN"
fi
echo "Checking for containers"
podman__is_ready $POD-imap
podman__is_ready $POD-mariadb
podman__is_ready $POD-redis
podman__is_ready $POD-webapp
podman__is_ready $POD-minio
podman__is_ready $POD-meet
podman__is_ready $POD-roundcube
podman__is_ready $POD-postfix
podman__is_ready $POD-amavis
podman__is_ready $POD-collabora
podman__is_ready $POD-proxy
echo "All containers are available"
# We skip mollie and openexchange
podman exec $POD-webapp env APP_DEBUG=false ./artisan status:health --user="$ADMIN_USER" --password="$ADMIN_PASSWORD" --check DB --check Redis --check IMAP --check Roundcube --check Meet --check DAV --check Auth
echo "Checking postfix authentication"
podman exec $POD-postfix testsaslauthd -u "$ADMIN_USER" -p "$ADMIN_PASSWORD"
echo "Checking imap authentication"
podman exec $POD-imap testsaslauthd -u "$ADMIN_USER" -p "$ADMIN_PASSWORD"
# podman run -ti --rm utils ./mailtransporttest.py --sender-username "$ADMIN_USER" --sender-password "$ADMIN_PASSWORD" --sender-host "127.0.0.1" --recipient-username "$ADMIN_USER" --recipient-password "$ADMIN_PASSWORD" --recipient-host "127.0.0.1" --recipient-port "11143"
# podman run -ti --rm utils ./kolabendpointtester.py --verbose --host "$APP_DOMAIN" --dav "https://$APP_DOMAIN/dav/" --imap "$APP_DOMAIN" --activesync "$APP_DOMAIN" --user "$ADMIN_USER" --password "$ADMIN_PASSWORD"
echo "All tests have passed!"
}
kolab__ps() {
command podman ps | grep $POD
}
kolab__exec() {
container=$1
shift
command podman exec -ti $POD-$container $@
}
kolab__run() {
__export_env
podman__run_$1
}
kolab__pull() {
podman pull quay.io/apheleiait/kolab/imap:latest
podman tag kolab/imap:latest kolab-imap:latest
podman pull quay.io/apheleiait/kolab/webapp:latest
podman tag kolab/webapp:latest kolab-webapp:latest
podman pull quay.io/apheleiait/kolab/collabora:latest
podman tag kolab/collabora:latest kolab-collabora:latest
podman pull quay.io/apheleiait/kolab/redis:latest
podman tag kolab/redis:latest redis:latest
podman pull quay.io/apheleiait/kolab/roundcube:latest
podman tag kolab/roundcube:latest roundcube:latest
podman pull quay.io/apheleiait/kolab/mariadb:latest
podman tag kolab/mariadb:latest mariadb:latest
podman pull quay.io/apheleiait/kolab/meet:latest
podman tag kolab/meet:latest kolab-meet:latest
podman pull quay.io/apheleiait/kolab/coturn:latest
podman tag kolab/coturn:latest kolab-coturn:latest
podman pull quay.io/apheleiait/kolab/postfix:latest
podman tag kolab/postfix:latest kolab-postfix:latest
podman pull quay.io/apheleiait/kolab/amavis:latest
podman tag kolab/amavis:latest kolab-amavis:latest
podman pull quay.io/apheleiait/kolab/utils:latest
podman tag kolab/utils:latest kolab-utils:latest
podman pull quay.io/apheleiait/kolab/minio:latest
podman tag kolab/minio:latest minio/minio:latest
podman pull quay.io/apheleiait/kolab/proxy:latest
podman tag kolab/proxy:latest kolab-proxy:latest
# podman pull quay.io/apheleiait/kolab/synapse:latest
# podman tag kolab/synapse:latest synapse:latest
# podman pull quay.io/apheleiait/kolab/element:latest
# podman tag kolab/element:latest element:latest
}
kolab__build() {
pin_git_refs
if [[ $1 != "" ]]; then
podman__build_$1
else
podman__build_base
podman__build_webapp
podman__build_meet
podman__build_imap
podman__build docker/mariadb mariadb
podman__build docker/redis redis
podman__build_proxy
podman__build docker/synapse synapse
podman__build docker/element element
podman__build_roundcube
podman__build_utils
podman__build_postfix
podman__build_amavis
podman__build_collabora
podman__build docker/vector vector
podman pull docker.io/minio/minio:latest
env CERT_DIR=docker/certs APP_DOMAIN=$HOST bin/regen-certs
fi
}
kolab__cyradm() {
# command podman exec -ti $POD-imap cyradm --auth PLAIN -u admin@kolab.local -w simple123 --port 11143 localhost
if [[ "$@" ]]; then
command podman exec -ti $POD-imap echo "$@" | cyradm --auth PLAIN -u $(grep IMAP_ADMIN_LOGIN src/.env | cut -d '=' -f 2 ) -w $(grep IMAP_ADMIN_PASSWORD src/.env | cut -d '=' -f 2 ) --port 11143 localhost
else
command podman exec -ti $POD-imap cyradm --auth PLAIN -u $(grep IMAP_ADMIN_LOGIN src/.env | cut -d '=' -f 2 ) -w $(grep IMAP_ADMIN_PASSWORD src/.env | cut -d '=' -f 2 ) --port 11143 localhost
fi
}
kolab__shell() {
kolab__exec $1 /bin/bash
}
kolab__run() {
__export_env
podman__run_$1
}
kolab__logs() {
command podman logs -f $POD-$1
}
kolab__help() {
cat <<EOF
This is the kolab commandline utility.
The following commands are available:
configure: Initial configuration.
deploy: Deploy kolab in the kolab-prod pod. Can be re-executed without loosing data.
build: Build all containers (Automatically executed as part of deploy).
reset: Remove pod and all volumes. Will delete all data.
start: Start pod
stop: Stop pod
update: This will update all containers.
backup: Create a backup in backup/
restore: Restore a backup from backup/
selfcheck: Run a selfcheck to ensure kolab is functional
shell: Get a shell in the given container.
run: Re-run an individual container.
exec: exec inside the given container.
logs: Access logs of the given container.
cyradm: Get a cyradm shell
EOF
}
cmdname=$1
shift
# make sure we actually *did* get passed a valid function name
if declare -f "kolab__$cmdname" >/dev/null 2>&1; then
"kolab__$cmdname" "${@:1}"
else
echo "Function $cmdname not recognized" >&2
kolab__help
exit 1
fi

File Metadata

Mime Type
text/x-shellscript
Expires
Mon, Apr 6, 12:08 AM (1 w, 3 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
02/c6/878fe43f74f23d1aa2cf44335cd0
Default Alt Text
kolabctl (15 KB)

Event Timeline