diff --git a/bin/podman_shared b/bin/podman_shared index 271cbb52..9e0cb180 100644 --- a/bin/podman_shared +++ b/bin/podman_shared @@ -1,281 +1,281 @@ #!/bin/bash PODMAN=podman podman__build() { path=$1 shift name=$1 shift if [[ "$CACHE_REGISTRY" != "" ]]; then CACHE_ARGS="--layers --cache-from=$CACHE_REGISTRY/$name --cache-to=$CACHE_REGISTRY/$name --cache-ttl=24h" fi podman build $@ $CACHE_ARGS $path -t $name } podman__build_base() { podman__build docker/base/ apheleia/almalinux9 -f almalinux9 podman__build docker/swoole apheleia/swoole } podman__build_webapp() { podman__build docker/webapp kolab-webapp --ulimit nofile=65535:65535 \ ${KOLAB_GIT_REMOTE:+"--build-arg=GIT_REMOTE=$KOLAB_GIT_REMOTE"} \ ${KOLAB_GIT_REF:+"--build-arg=GIT_REF=$KOLAB_GIT_REF"} } podman__build_meet() { podman__build docker/meet kolab-meet --ulimit nofile=65535:65535 \ ${KOLAB_GIT_REMOTE:+"--build-arg=GIT_REMOTE=$KOLAB_GIT_REMOTE"} \ ${KOLAB_GIT_REF:+"--build-arg=GIT_REF=$KOLAB_GIT_REF"} } podman__build_roundcube() { podman__build docker/roundcube roundcube --ulimit nofile=65535:65535 \ ${GIT_REMOTE_ROUNDCUBEMAIL:+"--build-arg=GIT_REMOTE_ROUNDCUBEMAIL=$GIT_REMOTE_ROUNDCUBEMAIL"} \ ${GIT_REF_ROUNDCUBEMAIL:+"--build-arg=GIT_REF_ROUNDCUBEMAIL=$GIT_REF_ROUNDCUBEMAIL"} \ ${GIT_REMOTE_ROUNDCUBEMAIL_PLUGINS:+"--build-arg=GIT_REMOTE_ROUNDCUBEMAIL_PLUGINS=$GIT_REMOTE_ROUNDCUBEMAIL_PLUGINS"} \ ${GIT_REF_ROUNDCUBEMAIL_PLUGINS:+"--build-arg=GIT_REF_ROUNDCUBEMAIL_PLUGINS=$GIT_REF_ROUNDCUBEMAIL_PLUGINS"} \ ${GIT_REMOTE_CHWALA:+"--build-arg=GIT_REMOTE_CHWALA=$GIT_REMOTE_CHWALA"} \ ${GIT_REF_CHWALA:+"--build-arg=GIT_REF_CHWALA=$GIT_REF_CHWALA"} \ ${GIT_REMOTE_SYNCROTON:+"--build-arg=GIT_REMOTE_SYNCROTON=$GIT_REMOTE_SYNCROTON"} \ ${GIT_REF_SYNCROTON:+"--build-arg=GIT_REF_SYNCROTON=$GIT_REF_SYNCROTON"} \ ${GIT_REMOTE_AUTOCONF:+"--build-arg=GIT_REMOTE_AUTOCONF=$GIT_REMOTE_AUTOCONF"} \ ${GIT_REF_AUTOCONF:+"--build-arg=GIT_REF_AUTOCONF=$GIT_REF_AUTOCONF"} \ ${GIT_REMOTE_IRONY:+"--build-arg=GIT_REMOTE_IRONY=$GIT_REMOTE_IRONY"} \ ${GIT_REF_IRONY:+"--build-arg=GIT_REF_IRONY=$GIT_REF_IRONY"} \ ${GIT_REMOTE_FREEBUSY:+"--build-arg=GIT_REMOTE_FREEBUSY=$GIT_REMOTE_FREEBUSY"} \ ${GIT_REF_FREEBUSY:+"--build-arg=GIT_REF_FREEBUSY=$GIT_REF_FREEBUSY"} } podman__build_postfix() { podman__build docker/postfix kolab-postfix } podman__build_all() { podman__build_base podman__build_webapp podman__build_meet podman build docker/postfix -t kolab-postfix podman build docker/imap -t kolab-imap ${IMAP_GIT_REMOTE:+"--build-arg=GIT_REMOTE=$IMAP_GIT_REMOTE"} \ ${IMAP_GIT_REF:+"--build-arg=GIT_REF=$IMAP_GIT_REF"} podman build docker/amavis -t kolab-amavis podman build docker/collabora -t kolab-collabora --build-arg=REPOSITORY="https://www.collaboraoffice.com/repos/CollaboraOnline/23.05-CODE/CODE-rpm/" podman build docker/mariadb -t mariadb podman build docker/redis -t redis podman build docker/proxy -t kolab-proxy podman build docker/coturn -t kolab-coturn podman build docker/utils -t kolab-utils podman build docker/fluentbit -t fluentbit podman__build_roundcube } kolab__validate() { POD=$1 $PODMAN exec $POD-imap testsaslauthd -u cyrus-admin -p simple123 $PODMAN exec $POD-imap testsaslauthd -u "john@kolab.org" -p simple123 # Ensure the inbox is created FOUND=false for i in {1..60}; do if $PODMAN exec $POD-imap bash -c 'echo "lm" | cyradm --auth PLAIN -u cyrus-admin -w simple123 --port 11143 localhost | grep "user/john@kolab.org"'; then echo "Found mailbox"; FOUND=true break else echo "Waiting for mailbox"; sleep 1; fi done if ! $FOUND; then echo "Failed to find the inbox for john@kolab.org" exit 1 fi } podman__is_ready() { if [[ "$(timeout 5 podman wait --condition running $1)" != "-1" ]]; then echo "Container $1 is not running" return 1 fi # We can only wait for healthy if healthcheck is available return 0 } podman__healthcheck() { for CONTAINER in $@; do echo "Waiting for ${CONTAINER} become healthy " while [ $(podman healthcheck run ${CONTAINER}) ]; do echo -n "."; sleep 5; done done } podman__run_proxy() { $PODMAN run -dt --pod $POD --name $POD-proxy --replace \ -v $CERTS_PATH:/etc/certs:ro \ -v /etc/letsencrypt/:/etc/letsencrypt/:ro \ -e APP_WEBSITE_DOMAIN \ - -e SSL_CERTIFICATE=${KOLAB_SSL_CERTIFICATE:-"/etc/certs/imap.hosted.com.cert"} \ - -e SSL_CERTIFICATE_KEY=${KOLAB_SSL_CERTIFICATE_KEY:-"/etc/certs/imap.hosted.com.key"} \ + -e SSL_CERTIFICATE=${KOLAB_SSL_CERTIFICATE} \ + -e SSL_CERTIFICATE_KEY=${KOLAB_SSL_CERTIFICATE_KEY} \ -e WEBAPP_BACKEND="http://localhost:8000" \ -e MEET_BACKEND="http://localhost:12080" \ -e ROUNDCUBE_BACKEND="http://localhost:8080" \ -e DAV_BACKEND="http://localhost:11080/dav" \ -e COLLABORA_BACKEND="http://localhost:9980" \ -e MATRIX_BACKEND="http://localhost:8008" \ -e ELEMENT_BACKEND="http://localhost:8880" \ -e SIEVE_BACKEND="localhost:4190" \ kolab-proxy:latest } podman__run_roundcube() { $PODMAN run -dt --pod $POD --name $POD-roundcube --replace \ -v ./ext:/src.orig:ro \ -e APP_DOMAIN \ -e DES_KEY \ -e DB_HOST \ -e DB_RC_DATABASE="roundcube" \ -e DB_RC_USERNAME="roundcube" \ -e DB_RC_PASSWORD="${DB_PASSWORD:?"missing env variable"}" \ -e IMAP_HOST \ -e IMAP_PORT \ -e IMAP_ADMIN_LOGIN \ -e IMAP_ADMIN_PASSWORD \ -e MAIL_HOST \ -e MAIL_PORT \ -e IMAP_DEBUG \ -e KOLAB_FILES_SERVER_URL=http://localhost:8080/chwala \ -e FILEAPI_WOPI_OFFICE=http://localhost:9980 \ -e FILEAPI_KOLABFILES_BASEURI=http://localhost:8000/api \ -e FILE_API_SERVER_URL=http://localhost:8080/chwala/api/ \ -e KOLAB_ADDRESSBOOK_CARDDAV_SERVER=http://localhost:11080/dav \ -e CALENDAR_CALDAV_SERVER=http://localhost:11080/dav \ -e TASKLIST_CALDAV_SERVER=http://localhost:11080/dav \ roundcube:latest } podman__run_mariadb() { $PODMAN run -dt --pod $POD --name $POD-mariadb --replace \ $MARIADB_STORAGE \ -e MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD:?"missing env variable"} \ -e TZ="+02:00" \ -e DB_HKCCP_DATABASE="kolabdev" \ -e DB_HKCCP_USERNAME="kolabdev" \ -e DB_HKCCP_PASSWORD=${DB_PASSWORD:?"missing env variable"} \ -e DB_KOLAB_DATABASE="kolab" \ -e DB_KOLAB_USERNAME="kolab" \ -e DB_KOLAB_PASSWORD=${DB_PASSWORD:?"missing env variable"} \ -e DB_RC_DATABASE="roundcube" \ -e DB_RC_USERNAME="roundcube" \ -e DB_RC_PASSWORD=${DB_PASSWORD:?"missing env variable"} \ --health-cmd "mysqladmin -u root ping && test -e /tmp/initialized" \ mariadb:latest } podman__run_redis() { $PODMAN run -dt --pod $POD --name $POD-redis --replace \ $REDIS_STORAGE \ --health-cmd "redis-cli ping || exit 1" \ redis:latest } podman__run_minio() { $PODMAN run -dt --pod $POD --name $POD-minio --replace \ $MINIO_STORAGE \ -e MINIO_ROOT_USER=${MINIO_USER:?"missing env variable"} \ -e MINIO_ROOT_PASSWORD=${MINIO_PASSWORD:?"missing env variable"} \ --health-cmd "mc ready local || exit 1" \ --entrypoint sh \ quay.io/minio/minio:latest -c 'mkdir -p /data/kolab && minio server /data --console-address ":9001"' } podman__run_webapp() { # We run with a fixed config.demo overlay and override the environment with ci/env $PODMAN run -dt --pod $POD --name $POD-webapp --replace \ --env-file=$1 \ -v ./src:/src/kolabsrc.orig:ro \ -v ./$2/src:/src/overlay:ro \ -e NOENVFILE=true \ -e APP_SERVICES_ALLOWED_DOMAINS="webapp,localhost,services.$HOST" \ -e KOLAB_ROLE=combined \ -e PASSPORT_PRIVATE_KEY="$PASSPORT_PRIVATE_KEY" \ -e PASSPORT_PUBLIC_KEY="$PASSPORT_PUBLIC_KEY" \ -e MINIO_ENDPOINT="http://localhost:9000" \ -e MEET_SERVER_URLS="http://127.0.0.1:12080/meetmedia/api/" \ -e MEET_SERVER_VERIFY_TLS=false \ --health-cmd "./artisan octane:status || exit 1" \ kolab-webapp:latest } podman__run_imap() { $PODMAN run -dt --pod $POD --name $POD-imap --replace \ $IMAP_SPOOL_STORAGE \ $IMAP_LIB_STORAGE \ -e APP_SERVICES_DOMAIN="localhost" \ -e SERVICES_PORT=8000 \ -e IMAP_ADMIN_LOGIN \ -e IMAP_ADMIN_PASSWORD \ --health-cmd "test -e /run/saslauthd/mux && kill -0 \$(cat /var/run/master.pid)" \ kolab-imap:latest } podman__run_postfix() { $PODMAN run -dt --pod $POD --name $POD-postfix --replace \ --privileged \ $POSTFIX_SPOOL_STORAGE \ $POSTFIX_LIB_STORAGE \ -v $CERTS_PATH:/etc/certs:ro \ -v /etc/letsencrypt/:/etc/letsencrypt/:ro \ -e SSL_CERTIFICATE="$KOLAB_SSL_CERTIFICATE" \ -e SSL_CERTIFICATE_FULLCHAIN="$KOLAB_SSL_CERTIFICATE_FULLCHAIN" \ -e SSL_CERTIFICATE_KEY="$KOLAB_SSL_CERTIFICATE_KEY" \ -e APP_DOMAIN \ -e APP_SERVICES_DOMAIN="localhost" \ -e SERVICES_PORT=8000 \ -e AMAVIS_HOST=127.0.0.1 \ -e DB_HOST=127.0.0.1 \ -e DB_USERNAME \ -e DB_PASSWORD \ -e DB_DATABASE \ -e LMTP_DESTINATION="localhost:11024" \ --health-cmd "test -e /run/saslauthd/mux && kill -0 \$(cat /var/spool/postfix/pid/master.pid)" \ kolab-postfix:latest } podman__run_amavis() { $PODMAN run -dt --pod $POD --name $POD-amavis --replace \ -e APP_DOMAIN \ -e POSTFIX_HOST=localhost \ -e DB_HOST=localhost \ -e DB_USERNAME \ -e DB_PASSWORD \ -e DB_DATABASE \ kolab-amavis:latest } podman__run_collabora() { $PODMAN run -dt --pod $POD --name $POD-collabora --replace \ --privileged \ -e ALLOWED_HOSTS=${APP_DOMAIN} \ kolab-collabora:latest } podman__run_meet() { $PODMAN run -dt --pod $POD --name $POD-meet --replace \ -v ./meet/server:/src/meet:ro \ -e WEBRTC_LISTEN_IP=0.0.0.0 \ -e WEBRTC_ANNOUNCED_ADDRESS=${PUBLIC_IP:?"missing env variable"} \ -e PUBLIC_DOMAIN=$APP_DOMAIN \ -e LISTENING_HOST=127.0.0.1 \ -e LISTENING_PORT=12080 \ -e DEBUG="*" \ -e TURN_SERVER=none \ -e AUTH_TOKEN=${MEET_SERVER_TOKEN} \ -e WEBHOOK_TOKEN=${MEET_WEBHOOK_TOKEN} \ -e WEBHOOK_URL=$APP_DOMAIN/api/webhooks/meet \ -e SSL_CERT=none \ -e FORCE_WSS=true \ kolab-meet:latest } diff --git a/bin/regen-certs b/bin/regen-certs index 455f0045..81736235 100755 --- a/bin/regen-certs +++ b/bin/regen-certs @@ -1,78 +1,78 @@ #!/bin/bash base_dir=$(dirname $(dirname $0)) cert_dir=${CERT_DIR:-${base_dir}/docker/certs/} if [ ! -d "${cert_dir}" ]; then mkdir -p ${cert_dir} fi if [ ! -f "${cert_dir}/ca.key" ]; then openssl genrsa -out ${cert_dir}/ca.key 4096 openssl req \ -new \ -x509 \ -nodes \ -days 3650 \ -key ${cert_dir}/ca.key \ -out ${cert_dir}/ca.cert \ -subj '/O=Example CA/' fi if [ -f /etc/pki/tls/openssl.cnf ]; then openssl_cnf="/etc/pki/tls/openssl.cnf" elif [ -f /etc/ssl/openssl.cnf ]; then openssl_cnf="/etc/ssl/openssl.cnf" else echo "No openssl.cnf" exit 1 fi if [ "$#" -eq "0" ]; then if [[ "$APP_DOMAIN" == "" ]]; then - APP_DOMAIN=$(grep -P "^APP_DOMAIN=.*" .env | tail -n1 | sed "s/APP_DOMAIN=//") + APP_DOMAIN=$(grep -P "^APP_DOMAIN=.*" src/.env | tail -n1 | sed "s/APP_DOMAIN=//") fi - DOMAINS="kolab.mgmt.com kolab.hosted.com imap.hosted.com admin.${APP_DOMAIN} meet.${APP_DOMAIN}" + DOMAINS="${APP_DOMAIN}" else DOMAINS=$1 fi for name in $DOMAINS; do openssl genrsa -out ${cert_dir}/${name}.key 4096 openssl req \ -new \ -key ${cert_dir}/${name}.key \ -out ${cert_dir}/${name}.csr \ -subj "/O=Example CA/CN=${name}/" \ -reqexts SAN \ -config <(cat ${openssl_cnf} \ <(printf "[SAN]\nsubjectAltName=DNS:${name}")) openssl x509 \ -req \ -in ${cert_dir}/${name}.csr \ -CA ${cert_dir}/ca.cert \ -CAkey ${cert_dir}/ca.key \ -CAcreateserial \ -out ${cert_dir}/${name}.cert \ -days 28 \ -extfile <(cat ${openssl_cnf} \ <(printf "[SAN]\nsubjectAltName=DNS:${name}")) \ -extensions SAN # 'cause java ... openssl pkcs8 \ -topk8 \ -inform pem \ -in ${cert_dir}/${name}.key \ -outform pem \ -nocrypt \ -out ${cert_dir}/${name}_p8.key cat ${cert_dir}/${name}.cert \ ${cert_dir}/ca.cert > ${cert_dir}/${name}.chain.pem chmod 644 ${cert_dir}/*.{cert,key,pem} done diff --git a/ci/env b/ci/env index 0992e55f..e8d5530e 100644 --- a/ci/env +++ b/ci/env @@ -1,177 +1,174 @@ APP_NAME=Kolab APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=https://kolab.local APP_PUBLIC_URL=https://kolab.local APP_DOMAIN=kolab.local APP_WEBSITE_DOMAIN=kolab.local APP_THEME=default APP_TENANT_ID=5 APP_LOCALE=en APP_LOCALES= APP_WITH_ADMIN=1 APP_WITH_RESELLER=1 APP_WITH_SERVICES=1 APP_WITH_FILES=1 APP_WITH_WALLET=1 APP_WITH_SIGNUP=1 APP_LDAP=0 APP_IMAP=1 APP_HEADER_CSP="connect-src 'self'; child-src 'self'; font-src 'self'; form-action 'self' data:; frame-ancestors 'self'; img-src blob: data: 'self' *; media-src 'self';" APP_HEADER_XFO=sameorigin ASSET_URL=https://kolab.local WEBMAIL_URL=/roundcubemail/ SUPPORT_URL=/support LOG_CHANNEL=stdout LOG_SLOW_REQUESTS=5 LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug DB_CONNECTION=mysql DB_DATABASE=kolabdev DB_HOST=127.0.0.1 DB_PASSWORD=simple123 DB_ROOT_PASSWORD=simple123 DB_PORT=3306 DB_USERNAME=kolabdev BROADCAST_DRIVER=redis CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=file SESSION_LIFETIME=120 MFA_DSN=mysql://roundcube:simple123@127.0.0.1/roundcube MFA_TOTP_DIGITS=6 MFA_TOTP_INTERVAL=30 MFA_TOTP_DIGEST=sha1 IMAP_URI=localhost:11143 IMAP_HOST=localhost IMAP_PORT=11143 IMAP_GUAM_PORT=11143 IMAP_ADMIN_LOGIN=cyrus-admin IMAP_ADMIN_PASSWORD=simple123 IMAP_VERIFY_HOST=false IMAP_VERIFY_PEER=false IMAP_WITH_GROUPWARE_DEFAULT_FOLDERS=false SMTP_HOST=localhost SMTP_PORT=10587 MEET_SERVER_URLS=https://127.0.0.1:6443/meetmedia/api/ MEET_SERVER_VERIFY_TLS=false MEET_WEBRTC_LISTEN_IP='127.0.0.1' MEET_PUBLIC_DOMAIN=kolab.local MEET_LISTENING_HOST=127.0.0.1 PGP_ENABLE=true PGP_BINARY=/usr/bin/gpg PGP_AGENT=/usr/bin/gpg-agent PGP_GPGCONF=/usr/bin/gpgconf PGP_LENGTH= REDIS_HOST=localhost REDIS_PASSWORD=null REDIS_PORT=6379 OCTANE_HTTP_HOST=kolab.local SWOOLE_PACKAGE_MAX_LENGTH=10485760 MAIL_MAILER=smtp MAIL_HOST=localhost MAIL_PORT=587 MAIL_USERNAME="noreply@kolab.local" MAIL_PASSWORD="simple123" MAIL_ENCRYPTION=starttls MAIL_FROM_ADDRESS="noreply@kolab.local" MAIL_FROM_NAME="kolab.local" MAIL_REPLYTO_ADDRESS="noreply@kolab.local" MAIL_REPLYTO_NAME=null MAIL_VERIFY_PEER='false' RATELIMIT_WHITELIST="noreply@kolab.local" DNS_TTL=3600 DNS_SPF="v=spf1 mx -all" DNS_STATIC="%s. MX 10 ext-mx01.mykolab.com." DNS_COPY_FROM=null MIX_ASSET_PATH='/' PASSWORD_POLICY= COMPANY_NAME=kolab.org COMPANY_ADDRESS= COMPANY_DETAILS= COMPANY_EMAIL= COMPANY_LOGO= COMPANY_FOOTER= VAT_COUNTRIES=CH,LI VAT_RATE=7.7 KB_ACCOUNT_DELETE= KB_ACCOUNT_SUSPENDED= KB_PAYMENT_SYSTEM= -KOLAB_SSL_CERTIFICATE=/etc/certs/kolab.hosted.com.cert -KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/certs/kolab.hosted.com.chain.pem -KOLAB_SSL_CERTIFICATE_KEY=/etc/certs/kolab.hosted.com.key - -PROXY_SSL_CERTIFICATE=/etc/certs/imap.hosted.com.cert -PROXY_SSL_CERTIFICATE_KEY=/etc/certs/imap.hosted.com.key +KOLAB_SSL_CERTIFICATE=/etc/certs/kolab.local.cert +KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/certs/kolab.local.chain.pem +KOLAB_SSL_CERTIFICATE_KEY=/etc/certs/kolab.local.key OPENEXCHANGERATES_API_KEY= FIREBASE_API_KEY= MINIO_ENDPOINT=http://localhost:9000 MINIO_USER=minio MINIO_PASSWORD=simple123 MINIO_BUCKET=kolab FILESYSTEM_DISK=minio TRUSTED_PROXIES="172.18.0.7/8,127.0.0.1/8" MOLLIE_KEY= STRIPE_KEY= STRIPE_PUBLIC_KEY= STRIPE_WEBHOOK_SECRET= APP_PASSPHRASE=simple123 MEET_WEBHOOK_TOKEN=simple123 MEET_SERVER_TOKEN=simple123 APP_KEY=base64:EFXja/fHF01EMKiXW200b5zWOynbPzAHfUM78bOp+28= PASSPORT_PROXY_OAUTH_CLIENT_ID=5909ca4f-df7e-45fe-b355-e7c195aef117 PASSPORT_PROXY_OAUTH_CLIENT_SECRET=3URb+3JGJM9wPuDnlUSTPOw2mqmHsoOV8NXanx9xwQM= DES_KEY=kBxUM/53N9p9abusAoT0ZEAxwI2pxFz/ KOLAB_GIT_REF=master KOLAB_GIT_REMOTE=https://git.kolab.org/source/kolab GIT_REF_ROUNDCUBEMAIL=dev/kolab-1.5 GIT_REMOTE_ROUNDCUBEMAIL=https://git.kolab.org/source/roundcubemail.git GIT_REF_ROUNDCUBEMAIL_PLUGINS=master GIT_REMOTE_ROUNDCUBEMAIL_PLUGINS=https://git.kolab.org/diffusion/RPK/roundcubemail-plugins-kolab.git GIT_REF_CHWALA=master GIT_REMOTE_CHWALA=https://git.kolab.org/diffusion/C/chwala.git GIT_REF_SYNCROTON=master GIT_REMOTE_SYNCROTON=https://git.kolab.org/diffusion/S/syncroton.git GIT_REF_AUTOCONF=master GIT_REMOTE_AUTOCONF=https://git.kolab.org/diffusion/AC/autoconf.git GIT_REF_IRONY=master GIT_REMOTE_IRONY=https://git.kolab.org/source/iRony.git GIT_REF_FREEBUSY=master GIT_REMOTE_FREEBUSY=https://git.kolab.org/diffusion/F/freebusy.git IMAP_GIT_REF=dev/kolab-3.6 IMAP_GIT_REMOTE=https://git.kolab.org/source/cyrus-imapd diff --git a/ci/testctl b/ci/testctl index 8bc11889..56d80569 100755 --- a/ci/testctl +++ b/ci/testctl @@ -1,425 +1,430 @@ #!/bin/bash base_dir="$(dirname $(realpath "$0"))" pushd "${base_dir}" pushd .. set -e -set -x PASSPORT_PRIVATE_KEY="-----BEGIN PRIVATE KEY----- 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 bakhie7hJBP7BoOup+dD5NQPlXBQ434= -----END PRIVATE KEY-----" PASSPORT_PUBLIC_KEY="-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApmHkae115z3vMF9IjiUa XrJH1Ljifxqs+XbDCFhQenz2iOf/bZDBMqfrwhBe3hVywa13kIuhf1TZlcJ/nRhE IZIbg6BF6/GeHN998Cx/IjhBeFkG7f1hdxEXY5ibd7yq8vAfzizZpnCu4+LM/NvI ei9mU+hj3GxrDbpMQTHCDDqX5aNEix8uFU4XaOm9UOJw9ivz19cqcnxWqJ49znxw XUlS5k4Hewbwf2s2BWFhz+CDWPHMpWViLQ17qj5QRklNn39sUymP1kXKP3Y76zvW zNVniPvFt+hHixxEa7tUEaTdtk4FgkNnWy0bFa7DIPC8ukjHvHHg10LeQiygDduI xbdVJwYK/qitU68ZAbbufldlj2FoVLwSyP9qpxUIdRoljCop1kDu6xQiAq0VHEAV LtgMpZhtD/6D4z644QJ8atx4Ljp/HEtTngaTh+/vLc9AnhHclX0/JmlbP1VkWWxG 9FIxS0TVPolRBs8948kLioTif9lrltJicxd6T0OuA5fny8l6hdSlzaD3pnr5pkYw mVn5FgBAFnd/skX6DsRs+eb2lNahkvNZZ15z9UeU2Rl6J9uBx0vbkcB7eiSCPhRM IKq/CtkyEgz8ce4kG18fJHDFDASRvGjaBu91lV5h7NLmhFLFzMvb7XoHrv/yD6TV E5W47J/DrfrevJkzS1GV++MCAwEAAQ== -----END PUBLIC KEY-----" export HOST=kolab.local export APP_WEBSITE_DOMAIN="$HOST" -export SSL_CERTIFICATE="/etc/certs/imap.hosted.com.cert" -export SSL_CERTIFICATE_KEY="/etc/certs/imap.hosted.com.key" export APP_DOMAIN=$HOST export DES_KEY=kBxUM/53N9p9abusAoT0ZEAxwI2pxFz/ export DB_HOST=127.0.0.1 +export KOLAB_SSL_CERTIFICATE=/etc/certs/kolab.local.cert +export KOLAB_SSL_CERTIFICATE_KEY=/etc/certs/kolab.local.key export IMAP_HOST=localhost export IMAP_PORT=11143 export IMAP_ADMIN_LOGIN=cyrus-admin export IMAP_ADMIN_PASSWORD=simple123 export MAIL_HOST=localhost export MAIL_PORT=10587 export IMAP_DEBUG=true export FILEAPI_WOPI_OFFICE=https://$HOST export CALENDAR_CALDAV_SERVER=http://localhost:11080/dav export KOLAB_ADDRESSBOOK_CARDDAV_SERVER=http://localhost:11080/dav export DB_ROOT_PASSWORD=simple123 export DB_HKCCP_PASSWORD=simple123 export DB_KOLAB_PASSWORD=simple123 export DB_RC_PASSWORD=simple123 export DB_PASSWORD=simple123 export MINIO_ROOT_USER=minio export MINIO_ROOT_PASSWORD=simple123 export MINIO_USER=minio export MINIO_PASSWORD=simple123 export MEET_SERVER_TOKEN=simple123 export MEET_WEBHOOK_TOKEN=simple123 export PUBLIC_IP=127.0.0.1 export CERTS_PATH=./ci/certs export IMAP_SPOOL_STORAGE=--mount=type=tmpfs,tmpfs-size=128M,tmpfs-mode=777,destination=/var/spool/imap,U=true,notmpcopyup export IMAP_LIB_STORAGE=--mount=type=tmpfs,tmpfs-size=128M,tmpfs-mode=777,destination=/var/lib/imap,U=true,notmpcopyup export MARIADB_STORAGE=--mount=type=tmpfs,tmpfs-size=512M,destination=/var/lib/mysql,U=true export REDIS_STORAGE=--mount=type=tmpfs,tmpfs-size=128M,destination=/var/lib/redis,U=true export MINIO_STORAGE=--mount=type=tmpfs,tmpfs-size=128M,destination=/data,U=true export PODMAN_IGNORE_CGROUPSV1_WARNING=true PODMAN="podman" source bin/podman_shared # Teardown the currently running environment kolab__teardown() { $PODMAN pod rm --force tests $PODMAN pod rm --force dev } # Build all containers required for testing kolab__build() { if [[ $1 != "" ]]; then if declare -f "podman__build_$1" >/dev/null 2>&1; then podman__build_$1 else podman__build docker/$1 $1 fi else podman__build_base podman__build_webapp podman__build_meet podman__build docker/imap kolab-imap podman__build docker/mariadb mariadb podman__build docker/redis redis podman__build docker/proxy kolab-proxy podman__build_roundcube podman__build docker/tests kolab-tests --ulimit nofile=65535:65535 env CERT_DIR=ci/certs APP_DOMAIN=$HOST bin/regen-certs fi } # Setup the test environment kolab__setup() { echo "Build" kolab__build echo "Setup" export POD=tests # Create the pod first $PODMAN pod create --replace --name $POD podman__run_mariadb podman__run_redis podman__healthcheck $POD-mariadb $POD-redis podman__run_imap podman__run_webapp ci/env config.demo podman__healthcheck $POD-webapp podman__healthcheck $POD-imap # Ensure all commands are processed echo "Flushing work queue" $PODMAN exec -ti $POD-webapp ./artisan queue:work --stop-when-empty podman__run_minio podman__healthcheck $POD-minio # Validate the test environment kolab__validate $POD } # "testsuite" # "quicktest" # "tests/Feature/Jobs/WalletCheckTest.php" kolab__test() { export POD=tests $PODMAN run -ti --pod tests --name $POD-kolab-tests --replace \ --env-file=ci/env \ -v ./src:/src/kolabsrc.orig:ro \ -e APP_SERVICES_DOMAINS="localhost" \ -e PASSPORT_PRIVATE_KEY="$PASSPORT_PRIVATE_KEY" \ -e PASSPORT_PUBLIC_KEY="$PASSPORT_PUBLIC_KEY" \ -e APP_URL="http://kolab.local" \ -e APP_PUBLIC_URL="http://kolab.local" \ -e APP_HEADER_CSP="" \ -e APP_HEADER_XFO="" \ -e ASSET_URL="http://kolab.local" \ -e MEET_SERVER_URLS="http://kolab.local/meetmedia/api/" \ kolab-tests:latest /init.sh $@ } kolab__proxytest() { $PODMAN run -ti --pod tests --name $POD-proxy-tests --replace \ -v ./ci/certs/:/etc/certs/:ro \ --env-file=ci/env \ - -e SSL_CERTIFICATE=/etc/certs/imap.hosted.com.cert \ - -e SSL_CERTIFICATE_KEY=/etc/certs/imap.hosted.com.key \ + -e SSL_CERTIFICATE=${KOLAB_SSL_CERTIFICATE} \ + -e SSL_CERTIFICATE_KEY=${KOLAB_SSL_CERTIFICATE_KEY} \ kolab-proxy:latest /init.sh validate } kolab__lint() { $PODMAN run --rm -ti \ -v ./src:/src/kolabsrc.orig:ro \ kolab-tests:latest /init.sh lint } # Setup the test environment and run a complete testsuite kolab__testrun() { echo "Setup" kolab__setup echo "Test" kolab__test testsuite } # Setup the test environment and run all testsuites kolab__testrun_complete() { echo "Setup" kolab__setup echo "Test" kolab__test lint kolab__test testsuite kolab__rctest syncroton lint kolab__rctest syncroton testsuite kolab__rctest irony lint # kolab__rctest irony testsuite kolab__rctest roundcubemail-plugins-kolab lint # kolab__rctest roundcubemail-plugins-kolab testsuite } # Get a shell inside the test container to run/debug tests kolab__shell() { if [[ $1 != "" ]]; then POD="dev" container=$1 shift command podman exec -ti $POD-$container /bin/bash else kolab__test shell fi } # Run the roundcube testsuite kolab__rctest() { $PODMAN run -t --pod tests --name $POD-roundcube --replace \ -v ./ext:/src.orig:ro \ -e APP_DOMAIN=kolab.local \ -e DES_KEY=kBxUM/53N9p9abusAoT0ZEAxwI2pxFz/ \ -e DB_HOST=127.0.0.1 \ -e DB_RC_DATABASE=roundcube \ -e DB_RC_USERNAME=roundcube \ -e DB_RC_PASSWORD=simple123 \ -e IMAP_HOST=localhost \ -e IMAP_PORT=11143 \ -e IMAP_ADMIN_LOGIN=cyrus-admin \ -e IMAP_ADMIN_PASSWORD=simple123 \ -e IMAP_DEBUG=false \ -e SQL_DEBUG=false \ -e ACTIVESYNC_DEBUG=false \ -e RUN_MIGRATIONS=true \ -e MAIL_HOST=localhost \ -e MAIL_PORT=10587 \ -e FILEAPI_WOPI_OFFICE=https://kolab.local \ -e CALENDAR_CALDAV_SERVER=http://imap:11080/dav \ -e KOLAB_ADDRESSBOOK_CARDDAV_SERVER=http://imap:11080/dav \ roundcube:latest ./init.sh $@ } # Get a shell inside the roundcube test container to run/debug tests kolab__rcshell() { $PODMAN run -ti --pod tests --name $POD-roundcube --replace \ -v ./ext:/src.orig:ro \ -e APP_DOMAIN=kolab.local \ -e DES_KEY=kBxUM/53N9p9abusAoT0ZEAxwI2pxFz/ \ -e DB_HOST=127.0.0.1 \ -e DB_RC_DATABASE=roundcube \ -e DB_RC_USERNAME=roundcube \ -e DB_RC_PASSWORD=simple123 \ -e IMAP_HOST=localhost \ -e IMAP_PORT=11143 \ -e IMAP_ADMIN_LOGIN=cyrus-admin \ -e IMAP_ADMIN_PASSWORD=simple123 \ -e MAIL_HOST=localhost \ -e MAIL_PORT=10587 \ -e FILEAPI_WOPI_OFFICE=https://kolab.local \ -e CALENDAR_CALDAV_SERVER=http://localhost:11080/dav \ -e KOLAB_ADDRESSBOOK_CARDDAV_SERVER=http://localhost:11080/dav \ roundcube:latest ./init.sh shell } kolab__validate() { POD=$1 $PODMAN exec $POD-imap testsaslauthd -u cyrus-admin -p simple123 $PODMAN exec $POD-imap testsaslauthd -u "john@kolab.org" -p simple123 # Ensure the inbox is created FOUND=false for i in {1..60}; do if $PODMAN exec $POD-imap bash -c 'echo "lm" | cyradm --auth PLAIN -u cyrus-admin -w simple123 --port 11143 localhost | grep "user/john@kolab.org"'; then echo "Found mailbox"; FOUND=true break else echo "Waiting for mailbox"; sleep 1; fi done if ! $FOUND; then echo "Failed to find the inbox for john@kolab.org" exit 1 fi } kolab__run() { export POD=dev podman__run_$1 } kolab__deploy() { export POD=dev # Create the pod first $PODMAN pod create \ --replace \ --add-host=kolab.local: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 podman__run_imap podman__run_webapp ci/env config.prod podman__healthcheck $POD-webapp podman__healthcheck $POD-imap # Ensure all commands are processed echo "Flushing work queue" $PODMAN exec -ti $POD-webapp ./artisan queue:work --stop-when-empty $PODMAN exec $POD-webapp ./artisan user:password "admin@kolab.local" "simple123" podman__run_minio podman__healthcheck $POD-minio podman__run_meet podman__run_roundcube podman__run_proxy } # Monitor vue files for changes, and automatically reload the dev webapp container if anything changes. # Requires "entr" on the host kolab__watch() { trap 'kill $(jobs -p) 2>/dev/null' EXIT find src/resources/ src/app -regex '.*\.\(vue\|php\)$' | entr podman exec -ti dev-webapp bash -c "/update-source.sh; ./artisan octane:reload" & podman exec -ti dev-webapp npm run watch } +# Get the host to trust the generated ca +kolab__add_ca_trust() { + sudo trust anchor --store ci/certs/ca.cert + sudo update-ca-trust +} + kolab__generate_mail() { $PODMAN run --pod=dev -t --rm kolab-utils:latest ./generatemail.py --maxAttachmentSize=3 --type=mail --count 100 --username admin@kolab.local --password simple123 --host localhost --port 11143 INBOX } kolab__syncroton_sync() { $PODMAN run -t --network=host --add-host=kolab.local:127.0.0.1 --rm kolab-utils:latest ./activesynccli.py --host kolab.local --user admin@kolab.local --password simple123 sync 38b950ebd62cd9a66929c89615d0fc04 } kolab__db() { POD=dev $PODMAN exec -ti $POD-mariadb /bin/bash -c "mysql -h 127.0.0.1 -u kolabdev --password=simple123 kolabdev" } kolab__help() { cat </dev/null 2>&1; then "kolab__$cmdname" "${@:1}" else echo "Function $cmdname not recognized" >&2 kolab__help exit 1 fi diff --git a/config.demo/src/.env b/config.demo/src/.env index 3c6b47d2..2dcbbf4a 100644 --- a/config.demo/src/.env +++ b/config.demo/src/.env @@ -1,188 +1,185 @@ APP_NAME=Kolab APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=https://{{ host }} APP_PASSPHRASE=simple123 APP_PUBLIC_URL=https://{{ host }} APP_DOMAIN={{ host }} APP_WEBSITE_DOMAIN={{ host }} APP_THEME=default APP_TENANT_ID=5 APP_LOCALE=en APP_LOCALES= APP_WITH_ADMIN=1 APP_WITH_RESELLER=1 APP_WITH_SERVICES=1 APP_WITH_FILES=1 APP_LDAP=0 APP_IMAP=1 APP_HEADER_CSP="connect-src 'self'; child-src 'self'; font-src 'self'; form-action 'self' data:; frame-ancestors 'self'; img-src blob: data: 'self' *; media-src 'self'; object-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; default-src 'self';" APP_HEADER_XFO=sameorigin SIGNUP_LIMIT_EMAIL=0 SIGNUP_LIMIT_IP=0 ASSET_URL=https://{{ host }} WEBMAIL_URL=/roundcubemail/ SUPPORT_URL=/support SUPPORT_EMAIL=support@example.com LOG_CHANNEL=stdout LOG_SLOW_REQUESTS=5 LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug DB_CONNECTION=mysql DB_DATABASE=kolabdev DB_HOST=mariadb DB_PASSWORD=kolab DB_ROOT_PASSWORD=Welcome2KolabSystems DB_PORT=3306 DB_USERNAME=kolabdev BROADCAST_DRIVER=redis CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=file SESSION_LIFETIME=120 OPENEXCHANGERATES_API_KEY="from openexchangerates.org" MFA_DSN=mysql://roundcube:kolab@mariadb/roundcube MFA_TOTP_DIGITS=6 MFA_TOTP_INTERVAL=30 MFA_TOTP_DIGEST=sha1 IMAP_URI=imap:11143 IMAP_HOST=172.18.0.12 IMAP_PORT=11143 IMAP_ADMIN_LOGIN=cyrus-admin IMAP_ADMIN_PASSWORD=Welcome2KolabSystems IMAP_VERIFY_HOST=false IMAP_VERIFY_PEER=false SMTP_PORT=10587 SMTP_HOST=172.18.0.13 COTURN_PUBLIC_IP='{{ public_ip }}' COTURN_STATIC_SECRET="Welcome2KolabSystems" MEET_WEBHOOK_TOKEN=Welcome2KolabSystems MEET_SERVER_TOKEN=Welcome2KolabSystems MEET_SERVER_URLS=https://{{ host }}/meetmedia/api/ MEET_SERVER_VERIFY_TLS=false MEET_WEBRTC_LISTEN_IP='172.18.0.1' MEET_PUBLIC_DOMAIN={{ host }} MEET_TURN_SERVER='turn:172.18.0.1:3478' MEET_LISTENING_HOST=172.18.0.1 PGP_ENABLE=true PGP_BINARY=/usr/bin/gpg PGP_AGENT=/usr/bin/gpg-agent PGP_GPGCONF=/usr/bin/gpgconf PGP_LENGTH= # Set these to IP addresses you serve WOAT with. # Have the domain owner point _woat. NS RRs refer to ns0{1,2}. WOAT_NS1=ns01.domain.tld WOAT_NS2=ns02.domain.tld REDIS_HOST=redis REDIS_PASSWORD=null REDIS_PORT=6379 OCTANE_HTTP_HOST=0.0.0.0 SWOOLE_PACKAGE_MAX_LENGTH=10485760 PAYMENT_PROVIDER= MOLLIE_KEY= STRIPE_KEY= STRIPE_PUBLIC_KEY= STRIPE_WEBHOOK_SECRET= MAIL_DRIVER=log MAIL_MAILER=smtp MAIL_HOST=172.18.0.13 MAIL_PORT=10587 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="noreply@example.com" MAIL_FROM_NAME="Example.com" MAIL_REPLYTO_ADDRESS="replyto@example.com" MAIL_REPLYTO_NAME=null DNS_TTL=3600 DNS_SPF="v=spf1 mx -all" DNS_STATIC="%s. MX 10 ext-mx01.mykolab.com." DNS_COPY_FROM=null AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= AWS_USE_PATH_STYLE_ENDPOINT=false PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= PUSHER_APP_CLUSTER=mt1 MIX_ASSET_PATH='/' MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" PASSWORD_POLICY= COMPANY_NAME=kolab.org COMPANY_ADDRESS= COMPANY_DETAILS= COMPANY_EMAIL= COMPANY_LOGO= COMPANY_FOOTER= VAT_COUNTRIES=CH,LI VAT_RATE=7.7 KB_ACCOUNT_DELETE= KB_ACCOUNT_SUSPENDED= KB_PAYMENT_SYSTEM= -KOLAB_SSL_CERTIFICATE=/etc/certs/kolab.hosted.com.cert -KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/certs/kolab.hosted.com.chain.pem -KOLAB_SSL_CERTIFICATE_KEY=/etc/certs/kolab.hosted.com.key - -PROXY_SSL_CERTIFICATE=/etc/certs/imap.hosted.com.cert -PROXY_SSL_CERTIFICATE_KEY=/etc/certs/imap.hosted.com.key +KOLAB_SSL_CERTIFICATE=/etc/certs/{{ host }}.cert +KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/certs/{{ host }}.chain.pem +KOLAB_SSL_CERTIFICATE_KEY=/etc/certs/{{ host }}.key APP_KEY=base64:FG6ECzyAMSmyX+eYwO/FW3bwnarbKkBhqtO65vlMb1E= COTURN_STATIC_SECRET=uzYguvIl9tpZFMuQOE78DpOi6Jc7VFSD0UAnvgMsg5n4e74MgIf6vQvbc6LWzZjz MOLLIE_KEY="from mollie" STRIPE_KEY="from stripe" STRIPE_PUBLIC_KEY="from stripe" STRIPE_WEBHOOK_SECRET="from stripe" OX_API_KEY="from openexchange" FIREBASE_API_KEY="from firebase" #Generated by php artisan passport:client --password, but can be left hardcoded (the seeder will pick it up) PASSPORT_PROXY_OAUTH_CLIENT_ID=942edef5-3dbd-4a14-8e3e-d5d59b727bee PASSPORT_PROXY_OAUTH_CLIENT_SECRET=L6L0n56ecvjjK0cJMjeeV1pPAeffUBO0YSSH63wf MINIO_USER=minio MINIO_PASSWORD=W3lcom32@ph3lia MINIO_BUCKET=kolab FILESYSTEM_DISK=minio ACTIVESYNC_URI=https://proxy:6443/Microsoft-Server-ActiveSync DAV_URI=https://proxy:6443/ diff --git a/config.prod/src/.env b/config.prod/src/.env index 7d9a60fe..50787a77 100644 --- a/config.prod/src/.env +++ b/config.prod/src/.env @@ -1,147 +1,144 @@ APP_NAME=Kolab APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=https://{{ host }} APP_PUBLIC_URL=https://{{ host }} APP_DOMAIN={{ host }} APP_WEBSITE_DOMAIN={{ host }} APP_THEME=default APP_TENANT_ID=5 APP_LOCALE=en APP_LOCALES= APP_WITH_ADMIN=1 APP_WITH_RESELLER=1 APP_WITH_SERVICES=1 APP_WITH_FILES=1 APP_WITH_WALLET=0 APP_WITH_SIGNUP=0 APP_LDAP=0 APP_IMAP=1 APP_HEADER_CSP="connect-src 'self'; child-src 'self'; font-src 'self'; form-action 'self' data:; frame-ancestors 'self'; img-src blob: data: 'self' *; media-src 'self'; object-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; default-src 'self';" APP_HEADER_XFO=sameorigin ASSET_URL=https://{{ host }} WEBMAIL_URL=/roundcubemail/ SUPPORT_URL=/support LOG_CHANNEL=stdout LOG_SLOW_REQUESTS=5 LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug DB_CONNECTION=mysql DB_DATABASE=kolabdev DB_HOST=127.0.0.1 DB_PASSWORD={{ admin_password }} DB_ROOT_PASSWORD={{ admin_password }} DB_PORT=3306 DB_USERNAME=kolabdev BROADCAST_DRIVER=redis CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=file SESSION_LIFETIME=120 MFA_DSN=mysql://roundcube:{{ admin_password }}@127.0.0.1/roundcube MFA_TOTP_DIGITS=6 MFA_TOTP_INTERVAL=30 MFA_TOTP_DIGEST=sha1 IMAP_URI=127.0.0.1:11143 IMAP_HOST=127.0.0.1 IMAP_PORT=11143 IMAP_GUAM_PORT=11143 IMAP_ADMIN_LOGIN=cyrus-admin IMAP_ADMIN_PASSWORD={{ admin_password }} IMAP_VERIFY_HOST=false IMAP_VERIFY_PEER=false IMAP_WITH_GROUPWARE_DEFAULT_FOLDERS=false SMTP_HOST=127.0.0.1 SMTP_PORT=10587 PUBLIC_IP='{{ public_ip }}' MEET_SERVER_URLS=https://127.0.0.1:12443/meetmedia/api/ MEET_SERVER_VERIFY_TLS=false MEET_WEBRTC_LISTEN_IP='127.0.0.1' MEET_PUBLIC_DOMAIN={{ host }} MEET_TURN_SERVER='turn:127.0.0.1:3478' MEET_LISTENING_HOST=127.0.0.1 PGP_ENABLE=true PGP_BINARY=/usr/bin/gpg PGP_AGENT=/usr/bin/gpg-agent PGP_GPGCONF=/usr/bin/gpgconf PGP_LENGTH= REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 OCTANE_HTTP_HOST={{ host }} SWOOLE_PACKAGE_MAX_LENGTH=10485760 MAIL_MAILER=smtp MAIL_HOST=127.0.0.1 MAIL_PORT=10587 MAIL_USERNAME="noreply@{{ host }}" MAIL_PASSWORD="{{ admin_password }}" MAIL_ENCRYPTION=starttls MAIL_FROM_ADDRESS="noreply@{{ host }}" MAIL_FROM_NAME="{{ host }}" MAIL_REPLYTO_ADDRESS="noreply@{{ host }}" MAIL_REPLYTO_NAME=null MAIL_VERIFY_PEER='false' RATELIMIT_WHITELIST="noreply@{{ host }}" DNS_TTL=3600 DNS_SPF="v=spf1 mx -all" DNS_STATIC="%s. MX 10 ext-mx01.mykolab.com." DNS_COPY_FROM=null MIX_ASSET_PATH='/' PASSWORD_POLICY= COMPANY_NAME=kolab.org COMPANY_ADDRESS= COMPANY_DETAILS= COMPANY_EMAIL= COMPANY_LOGO= COMPANY_FOOTER= VAT_COUNTRIES=CH,LI VAT_RATE=7.7 KB_ACCOUNT_DELETE= KB_ACCOUNT_SUSPENDED= KB_PAYMENT_SYSTEM= -KOLAB_SSL_CERTIFICATE=/etc/certs/kolab.hosted.com.cert -KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/certs/kolab.hosted.com.chain.pem -KOLAB_SSL_CERTIFICATE_KEY=/etc/certs/kolab.hosted.com.key - -PROXY_SSL_CERTIFICATE=/etc/certs/imap.hosted.com.cert -PROXY_SSL_CERTIFICATE_KEY=/etc/certs/imap.hosted.com.key +KOLAB_SSL_CERTIFICATE=/etc/certs/{{ host }}.cert +KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/certs/{{ host }}.chain.pem +KOLAB_SSL_CERTIFICATE_KEY=/etc/certs/{{ host }}.key OPENEXCHANGERATES_API_KEY={{ openexchangerates_api_key }} FIREBASE_API_KEY={{ firebase_api_key }} MINIO_USER=minio MINIO_PASSWORD={{ admin_password }} MINIO_BUCKET=kolab FILESYSTEM_DISK=minio TRUSTED_PROXIES="::ffff:127.0.0.1/8" diff --git a/kolabctl b/kolabctl index abdb5fc1..aab127ce 100755 --- a/kolabctl +++ b/kolabctl @@ -1,420 +1,418 @@ #!/bin/bash set -e 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} +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 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 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 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 admin password for the admin@$HOST user:" 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_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 -PROXY_SSL_CERTIFICATE=/etc/letsencrypt/live/${HOST}/fullchain.pem -PROXY_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 [[ ! -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-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 # Make imap available to the webapp seeder, but don't expect it to be healthy until it can authenticate against the webapp podman__run_imap podman__run_webapp src/.env $CONFIG podman__healthcheck $POD-webapp podman__healthcheck $POD-imap # 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_minio podman__healthcheck $POD-minio podman__run_meet podman__run_roundcube podman__run_postfix podman__run_amavis podman__run_collabora podman__run_proxy } 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 ADMIN_PASSWORD="simple123" 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 --check DB --check Redis --check IMAP --check Roundcube --check Meet --check DAV podman exec $POD-postfix testsaslauthd -u "$ADMIN_USER" -p "$ADMIN_PASSWORD" 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 } kolab__exec() { container=$1 shift command podman exec -ti $POD-$container $@ } kolab__run() { __export_env podman__run_$1 } kolab__build() { if [[ $1 != "" ]]; then podman__build_$1 else podman__build_base podman__build_webapp podman__build_meet podman__build docker/imap kolab-imap podman__build docker/mariadb mariadb podman__build docker/redis redis podman__build docker/proxy kolab-proxy podman__build_roundcube podman__build docker/utils utils podman__build docker/postfix kolab-postfix podman__build docker/amavis kolab-amavis podman__build docker/collabora kolab-collabora --build-arg=REPOSITORY="https://www.collaboraoffice.com/repos/CollaboraOnline/23.05-CODE/CODE-rpm/" 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 </dev/null 2>&1; then "kolab__$cmdname" "${@:1}" else echo "Function $cmdname not recognized" >&2 kolab__help exit 1 fi