Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117881789
kolabctl
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
15 KB
Referenced Files
None
Subscribers
None
kolabctl
View Options
#!/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
Details
Attached
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)
Attached To
Mode
rK kolab
Attached
Detach File
Event Timeline