diff --git a/ci/Makefile b/ci/Makefile deleted file mode 100644 index fe2d61bc..00000000 --- a/ci/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -PWD=$(shell pwd) - - -configure: - cd .. ; \ - bin/configure.sh config.demo ; - -setup: - docker kill kolab-tests || : ; \ - docker rm kolab-tests || : ; \ - cd .. && bin/quickstart.sh --nodev - -build: - cd .. && docker compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.build.yml build && cd ci - -lint: - docker kill kolab-tests || : ; \ - docker rm kolab-tests || : ; \ - docker run -v ${PWD}/../:/src/kolab.orig --name kolab-tests -t kolab-tests /lint.sh - -test: - docker kill kolab-tests || : ; \ - docker rm kolab-tests || : ; \ - docker run --network=kolab_kolab -v ${PWD}/../src:/src/kolabsrc.orig --name kolab-tests -t kolab-tests /init.sh testsuite - -quicktest: - docker kill kolab-tests || : ; \ - docker rm kolab-tests || : ; \ - docker run --network=kolab_kolab -v ${PWD}/../src:/src/kolabsrc.orig --name kolab-tests -t kolab-tests /init.sh quicktest - -browser: - docker kill kolab-tests || : ; \ - docker rm kolab-tests || : ; \ - docker run --network=kolab_kolab -v ${PWD}/../src:/src/kolabsrc.orig --name kolab-tests -t kolab-tests /init.sh suite-Browser - -shell: - docker kill kolab-tests || : ; \ - docker rm kolab-tests || : ; \ - docker run --network=kolab_kolab -v ${PWD}/../src:/src/kolabsrc.orig --name kolab-tests -ti kolab-tests /init.sh shell - -all: configure build setup lint test - diff --git a/ci/env b/ci/env new file mode 100644 index 00000000..f39f8ecc --- /dev/null +++ b/ci/env @@ -0,0 +1,180 @@ +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'; 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://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=mariadb +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@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_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=172.18.0.13 +SMTP_PORT=10587 + +COTURN_PUBLIC_IP='172.18.0.1' + +MEET_SERVER_URLS=https://kolab.local/meetmedia/api/ +MEET_SERVER_VERIFY_TLS=false + +MEET_WEBRTC_LISTEN_IP='172.18.0.1' +MEET_PUBLIC_DOMAIN=kolab.local +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= + +REDIS_HOST=redis +REDIS_PASSWORD=null +REDIS_PORT=6379 + +OCTANE_HTTP_HOST=kolab.local +SWOOLE_PACKAGE_MAX_LENGTH=10485760 + +MAIL_MAILER=smtp +MAIL_HOST=172.18.0.7 +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 + +OPENEXCHANGERATES_API_KEY= +FIREBASE_API_KEY= + +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 +COTURN_STATIC_SECRET=23436d70545a9c5a26f863b3e2d176033c79254036280acc7cc978c21e181fc8 +MEET_WEBHOOK_TOKEN=7d2bdcc94f42adc4e0a31e5a0274fc22b5f9401f122f446f8f8cbb30f3143bd2 +MEET_SERVER_TOKEN=0288a77f5455b726f1f4854b1e0cec090a9312746d12454582252969e8e048d6 +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=dev/mollekopf +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=dev/mollekopf +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/mollekopf +IMAP_GIT_REMOTE=https://git.kolab.org/source/cyrus-imapd diff --git a/ci/runchecks.sh b/ci/runchecks.sh index 881ca7bc..d41e2cb4 100755 --- a/ci/runchecks.sh +++ b/ci/runchecks.sh @@ -1,22 +1,18 @@ #!/bin/bash set -x set -e # Setup env HOST=kolab.local ADMIN_PASSWORD=simple123 bin/configure.sh config.demo # docker compose pull --ignore-buildable bin/quickstart.sh --nodev # Ensure the environment is functional # env ADMIN_USER=john@kolab.org ADMIN_PASSWORD=simple123 bin/selfcheck.sh ADMIN_USER=john@kolab.org ADMIN_PASSWORD=simple123 APP_DOMAIN=$(grep APP_DOMAIN .env | tail -n1 | sed "s/APP_DOMAIN=//") docker compose exec postfix testsaslauthd -u "$ADMIN_USER" -p "$ADMIN_PASSWORD" docker compose exec imap testsaslauthd -u "$ADMIN_USER" -p "$ADMIN_PASSWORD" docker compose -f docker-compose.yml -f docker-compose.build.yml 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" - -# Run the tests -docker rm kolab-tests >/dev/null 2>/dev/null || : -docker run --rm --network=kolab_kolab -v ${PWD}/src:/src/kolabsrc.orig --name kolab-tests -t kolab-tests /init.sh testsuite diff --git a/ci/testctl b/ci/testctl index 751fa818..95b7bf75 100755 --- a/ci/testctl +++ b/ci/testctl @@ -1,111 +1,350 @@ #!/bin/bash base_dir="$(dirname $(realpath "$0"))" pushd "${base_dir}" 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-----" +KOLAB_GIT_REF=dev/mollekopf +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=dev/mollekopf +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/mollekopf +IMAP_GIT_REMOTE=https://git.kolab.org/source/cyrus-imapd + +PODMAN="podman" # Teardown the currently running environment kolab__teardown() { - docker kill kolab-tests || : - docker rm kolab-tests || : - pushd .. - docker compose down - docker volume rm kolab_mariadb || : - docker volume rm kolab_imap || : - popd + $PODMAN pod rm --force tests } # Build all containers required for testing kolab__build() { pushd .. - docker compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.build.yml build mariadb redis swoole webapp imap tests roundcube minio + $PODMAN build docker/swoole/ -t apheleia/swoole + $PODMAN build docker/base/ -f almalinux8 -t apheleia/almalinux8 + $PODMAN build docker/base/ -f almalinux9 -t apheleia/almalinux9 + + $PODMAN build --ulimit nofile=65535:65535 docker/webapp -t kolab-webapp \ + --build-arg GIT_REMOTE=${KOLAB_GIT_REMOTE} --build-arg GIT_REF=${KOLAB_GIT_REF} + $PODMAN build --ulimit nofile=65535:65535 docker/meet -t kolab-meet \ + --build-arg GIT_REMOTE=${KOLAB_GIT_REMOTE} --build-arg GIT_REF=${KOLAB_GIT_REF} + $PODMAN build docker/postfix -t kolab-postfix + $PODMAN build docker/imap -t kolab-imap + $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 --ulimit nofile=65535:65535 docker/tests -t kolab-tests \ + --build-arg GIT_REMOTE=${KOLAB_GIT_REMOTE} --build-arg GIT_REF=${KOLAB_GIT_REF} + + $PODMAN build --ulimit nofile=65535:65535 docker/roundcube -t roundcube \ + --build-arg GIT_REMOTE=${GIT_REMOTE_ROUNDCUBEMAIL} --build-arg GIT_REF=${GIT_REF_ROUNDCUBEMAIL} \ + --build-arg GIT_REMOTE=${GIT_REMOTE_ROUNDCUBEMAIL_PLUGINS} --build-arg GIT_REF=${GIT_REF_ROUNDCUBEMAIL_PLUGINS} \ + --build-arg GIT_REMOTE=${GIT_REMOTE_CHWALA} --build-arg GIT_REF=${GIT_REF_CHWALA} \ + --build-arg GIT_REMOTE=${GIT_REMOTE_SYNCROTON} --build-arg GIT_REF=${GIT_REF_SYNCROTON} \ + --build-arg GIT_REMOTE=${GIT_REMOTE_AUTOCONF} --build-arg GIT_REF=${GIT_REF_AUTOCONF} \ + --build-arg GIT_REMOTE=${GIT_REMOTE_IRONY} --build-arg GIT_REF=${GIT_REF_IRONY} \ + --build-arg GIT_REMOTE=${GIT_REMOTE_FREEBUSY} --build-arg GIT_REF=${GIT_REF_FREEBUSY} + popd } # Setup the test environment kolab__setup() { kolab__teardown - pushd .. - bin/configure.sh config.demo - popd echo "Build" kolab__build echo "Setup" - # Starting the webapp container will trigger a migration - # Maybe just delete the mariadb contianer - # We need webapp for the services backend, minio for files, roundcube to initialize the roundcube db pushd .. - docker compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.build.yml up -d --wait mariadb redis imap minio roundcube webapp proxy + + # Create the pod first + $PODMAN pod create --name tests + + # Mariadb + $PODMAN run -dt --pod tests --name mariadb \ + --mount=type=tmpfs,tmpfs-size=512M,destination=/var/lib/mysql,U=true \ + -e MYSQL_ROOT_PASSWORD=simple123 \ + -e TZ="+02:00" \ + -e DB_HKCCP_DATABASE=kolabdev \ + -e DB_HKCCP_USERNAME=kolabdev \ + -e DB_HKCCP_PASSWORD=simple123 \ + -e DB_KOLAB_DATABASE=kolab \ + -e DB_KOLAB_USERNAME=kolab \ + -e DB_KOLAB_PASSWORD=simple123 \ + -e DB_RC_DATABASE=roundcube \ + -e DB_RC_USERNAME=roundcube \ + -e DB_RC_PASSWORD=simple123 \ + --health-cmd "mysqladmin -u root ping && test -e /tmp/initialized" \ + mariadb:latest + + # redis + $PODMAN run -dt --pod tests --name redis \ + --mount=type=tmpfs,tmpfs-size=128M,destination=/var/lib/redis,U=true \ + --health-cmd "redis-cli ping || exit 1" \ + redis:latest + + echo "Waiting for dependencies" + $PODMAN wait --condition healthy mariadb redis + + # We run with a fixed config.demo overlay and override the environment with ci/env + $PODMAN run -dt --pod tests --name webapp \ + --env-file=ci/env \ + -v ./src:/src/kolabsrc.orig:ro \ + -v ./config.demo/src:/src/overlay:ro \ + -e NOENVFILE=true \ + -e APP_SERVICES_DOMAINS="webapp" \ + -e PASSPORT_PRIVATE_KEY="$PASSPORT_PRIVATE_KEY" \ + -e PASSPORT_PUBLIC_KEY="$PASSPORT_PUBLIC_KEY" \ + --health-cmd "./artisan octane:status || exit 1" \ + kolab-webapp:latest + echo "Wait for webapp" + $PODMAN wait --condition healthy webapp + + # IMAP + $PODMAN run -dt --pod tests --name imap --replace \ + --mount=type=tmpfs,tmpfs-size=128M,destination=/var/spool/imap,U=true \ + --mount=type=tmpfs,tmpfs-size=128M,destination=/var/lib/imap,U=true \ + -e APP_SERVICES_DOMAIN=webapp \ + -e SERVICES_PORT=8000 \ + -e IMAP_ADMIN_LOGIN=cyrus-admin \ + -e IMAP_ADMIN_PASSWORD=simple123 \ + --health-cmd "test -e /run/saslauthd/mux && kill -0 \$(cat /var/run/master.pid)" \ + kolab-imap:latest + echo "Waiting for dependencies" + $PODMAN wait --condition healthy imap + + # Ensure all commands are processed + echo "Flushing work queue" + $PODMAN exec -ti webapp ./artisan queue:work --stop-when-empty + + # minio + $PODMAN run -dt --pod tests --name minio --replace \ + --mount=type=tmpfs,tmpfs-size=128M,destination=/data,U=true \ + -e MINIO_ROOT_USER=minio \ + -e MINIO_ROOT_PASSWORD=simple123 \ + --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"' + echo "Waiting for dependencies" + $PODMAN wait --condition healthy minio + popd + + # Validate the test environment + kolab__validate } # "testsuite" # "quicktest" # "tests/Feature/Jobs/WalletCheckTest.php" kolab__test() { - docker kill kolab-tests || : - docker rm kolab-tests || : - docker run --network=kolab_kolab -v ${PWD}/../src:/src/kolabsrc.orig --name kolab-tests -t kolab-tests /init.sh $@ + pushd .. + $PODMAN run -ti --pod tests --name kolab-tests --replace \ + --env-file=ci/env \ + -v ./src:/src/kolabsrc.orig:ro \ + -e APP_SERVICES_DOMAINS="webapp" \ + -e PASSPORT_PRIVATE_KEY="$PASSPORT_PRIVATE_KEY" \ + -e PASSPORT_PUBLIC_KEY="$PASSPORT_PUBLIC_KEY" \ + kolab-tests:latest /init.sh $@ + popd } # Setup the test environment and run a complete testsuite kolab__testrun() { echo "Setup" kolab__setup echo "Test" kolab__test testsuite } # Get a shell inside the test container to run/debug tests kolab__shell() { - docker kill kolab-tests || : ; \ - docker rm kolab-tests || : ; \ - docker run --network=kolab_kolab -v ${PWD}/../src:/src/kolabsrc.orig --name kolab-tests -ti kolab-tests /init.sh shell + kolab__test shell } # Run the roundcube testsuite kolab__rctest() { - docker kill roundcube-tests || : - docker rm roundcube-tests || : pushd .. - docker compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml run --name roundcube-tests -ti roundcube ./init.sh $@ + $PODMAN run -t --pod tests --name roundcube --replace \ + -v ./ext:/src.orig:ro \ + -e APP_DOMAIN=kolab.test \ + -e DES_KEY=kBxUM/53N9p9abusAoT0ZEAxwI2pxFz/ \ + -e DB_HOST=mariadb \ + -e DB_RC_DATABASE=roundcube \ + -e DB_RC_USERNAME=roundcube \ + -e DB_RC_PASSWORD=simple123 \ + -e IMAP_HOST=imap \ + -e IMAP_PORT=11143 \ + -e IMAP_ADMIN_LOGIN=cyrus-admin \ + -e IMAP_ADMIN_PASSWORD=simple123 \ + -e MAIL_HOST=postfix \ + -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 testsuite popd } # Get a shell inside the roundcube test container to run/debug tests kolab__rcshell() { - docker kill roundcube-tests || : - docker rm roundcube-tests || : pushd .. - docker compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml run --name roundcube-tests -ti roundcube ./init.sh shell + $PODMAN run -t --pod tests --name roundcube --replace \ + -v ./ext:/src.orig:ro \ + -e APP_DOMAIN=kolab.test \ + -e DES_KEY=kBxUM/53N9p9abusAoT0ZEAxwI2pxFz/ \ + -e DB_HOST=mariadb \ + -e DB_RC_DATABASE=roundcube \ + -e DB_RC_USERNAME=roundcube \ + -e DB_RC_PASSWORD=simple123 \ + -e IMAP_HOST=imap \ + -e IMAP_PORT=11143 \ + -e IMAP_ADMIN_LOGIN=cyrus-admin \ + -e IMAP_ADMIN_PASSWORD=simple123 \ + -e MAIL_HOST=postfix \ + -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 shell popd } +kolab__validate() { + $PODMAN exec imap testsaslauthd -u cyrus-admin -p simple123 + $PODMAN exec imap testsaslauthd -u "john@kolab.org" -p simple123 + # Ensure the inbox is created + FOUND=false + for i in {1..60}; do + if $PODMAN exec 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 "Wating for mailbox"; + sleep 1; + fi + done + if ! $FOUND; then + echo "Failed to find the inbox for john@kolab.org" + exit 1 + fi +} + 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/docker/mariadb/rootfs/opt/app-root/src/mysql-data/init.sql b/docker/mariadb/rootfs/opt/app-root/src/mysql-data/init.sql deleted file mode 100644 index 31599829..00000000 --- a/docker/mariadb/rootfs/opt/app-root/src/mysql-data/init.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE products (id INTEGER, name VARCHAR(256), price FLOAT, variant INTEGER); -CREATE TABLE products_variant (id INTEGER, name VARCHAR(256)); -INSERT INTO products_variant (id, name) VALUES ('1', 'blue'), ('2', 'green'); - diff --git a/docker/mariadb/rootfs/opt/app-root/src/mysql-init/70-init-db.sh b/docker/mariadb/rootfs/opt/app-root/src/mysql-init/70-init-db.sh index 47f4f7cb..4896790d 100644 --- a/docker/mariadb/rootfs/opt/app-root/src/mysql-init/70-init-db.sh +++ b/docker/mariadb/rootfs/opt/app-root/src/mysql-init/70-init-db.sh @@ -1,106 +1,113 @@ init_arbitrary_database() { local thisdir local init_data_file thisdir=$(dirname ${BASH_SOURCE[0]}) mysql $mysql_flags << EOF -CREATE DATABASE ${DB_HKCCP_DATABASE}; -CREATE USER '${DB_HKCCP_USERNAME}'@'%' IDENTIFIED BY '${DB_HKCCP_PASSWORD}'; +CREATE DATABASE IF NOT EXISTS ${DB_HKCCP_DATABASE}; +CREATE USER IF NOT EXISTS '${DB_HKCCP_USERNAME}'@'%' IDENTIFIED BY '${DB_HKCCP_PASSWORD}'; +CREATE USER IF NOT EXISTS '${DB_HKCCP_USERNAME}'@'127.0.0.1' IDENTIFIED BY '${DB_HKCCP_PASSWORD}'; GRANT ALL PRIVILEGES ON ${DB_HKCCP_DATABASE}.* TO '${DB_HKCCP_USERNAME}'@'%' IDENTIFIED BY '${DB_HKCCP_PASSWORD}'; +GRANT ALL PRIVILEGES ON ${DB_HKCCP_DATABASE}.* TO '${DB_HKCCP_USERNAME}'@'127.0.0.1' IDENTIFIED BY '${DB_HKCCP_PASSWORD}'; FLUSH PRIVILEGES; EOF mysql $mysql_flags << EOF -CREATE DATABASE ${DB_KOLAB_DATABASE}; -CREATE USER ${DB_KOLAB_USERNAME}@'%' IDENTIFIED BY '${DB_KOLAB_PASSWORD}'; +CREATE DATABASE IF NOT EXISTS ${DB_KOLAB_DATABASE}; +CREATE USER IF NOT EXISTS ${DB_KOLAB_USERNAME}@'%' IDENTIFIED BY '${DB_KOLAB_PASSWORD}'; +CREATE USER IF NOT EXISTS ${DB_KOLAB_USERNAME}@'127.0.0.1' IDENTIFIED BY '${DB_KOLAB_PASSWORD}'; GRANT ALL PRIVILEGES ON ${DB_KOLAB_DATABASE}.* TO ${DB_KOLAB_USERNAME}@'%' IDENTIFIED BY '${DB_KOLAB_PASSWORD}'; +GRANT ALL PRIVILEGES ON ${DB_KOLAB_DATABASE}.* TO ${DB_KOLAB_USERNAME}@'127.0.0.1' IDENTIFIED BY '${DB_KOLAB_PASSWORD}'; FLUSH PRIVILEGES; EOF mysql $mysql_flags << EOF CREATE DATABASE IF NOT EXISTS $DB_RC_DATABASE CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS $DB_RC_USERNAME@'%' IDENTIFIED BY '$DB_RC_PASSWORD'; +CREATE USER IF NOT EXISTS $DB_RC_USERNAME@'127.0.0.1' IDENTIFIED BY '$DB_RC_PASSWORD'; ALTER USER $DB_RC_USERNAME@'%' IDENTIFIED BY '$DB_RC_PASSWORD'; +ALTER USER $DB_RC_USERNAME@'127.0.0.1' IDENTIFIED BY '$DB_RC_PASSWORD'; GRANT ALL PRIVILEGES ON $DB_RC_DATABASE.* TO $DB_RC_USERNAME@'%'; +GRANT ALL PRIVILEGES ON $DB_RC_DATABASE.* TO $DB_RC_USERNAME@'127.0.0.1'; FLUSH PRIVILEGES; EOF # Powerdns setup according to https://github.com/PowerDNS/pdns/blob/master/modules/gmysqlbackend/schema.mysql.sql # Required for the first boot, afterwards the laravel migration will take over. # This is only required so pdns can start cleanly, indexes etc are handled by the laravel migration. mysql $mysql_flags ${DB_HKCCP_DATABASE} << EOF CREATE TABLE powerdns_domains ( id INT AUTO_INCREMENT, name VARCHAR(255) NOT NULL, master VARCHAR(128) DEFAULT NULL, last_check INT DEFAULT NULL, type VARCHAR(8) NOT NULL, notified_serial INT UNSIGNED DEFAULT NULL, account VARCHAR(40) CHARACTER SET 'utf8' DEFAULT NULL, options VARCHAR(64000) DEFAULT NULL, catalog VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id) ) Engine=InnoDB CHARACTER SET 'latin1'; CREATE TABLE powerdns_records ( id BIGINT AUTO_INCREMENT, domain_id INT DEFAULT NULL, name VARCHAR(255) DEFAULT NULL, type VARCHAR(10) DEFAULT NULL, content VARCHAR(64000) DEFAULT NULL, ttl INT DEFAULT NULL, prio INT DEFAULT NULL, disabled TINYINT(1) DEFAULT 0, ordername VARCHAR(255) BINARY DEFAULT NULL, auth TINYINT(1) DEFAULT 1, PRIMARY KEY (id) ) Engine=InnoDB CHARACTER SET 'latin1'; CREATE TABLE powerdns_masters ( ip VARCHAR(64) NOT NULL, nameserver VARCHAR(255) NOT NULL, account VARCHAR(40) CHARACTER SET 'utf8' NOT NULL, PRIMARY KEY (ip, nameserver) ) Engine=InnoDB CHARACTER SET 'latin1'; CREATE TABLE powerdns_comments ( id INT AUTO_INCREMENT, domain_id INT NOT NULL, name VARCHAR(255) NOT NULL, type VARCHAR(10) NOT NULL, modified_at INT NOT NULL, account VARCHAR(40) CHARACTER SET 'utf8' DEFAULT NULL, comment TEXT CHARACTER SET 'utf8' NOT NULL, PRIMARY KEY (id) ) Engine=InnoDB CHARACTER SET 'latin1'; CREATE TABLE powerdns_cryptokeys ( id INT AUTO_INCREMENT, domain_id INT NOT NULL, flags INT NOT NULL, active BOOL, published BOOL DEFAULT 1, content TEXT, PRIMARY KEY(id) ) Engine=InnoDB CHARACTER SET 'latin1'; CREATE TABLE powerdns_tsigkeys ( id INT AUTO_INCREMENT, name VARCHAR(255), algorithm VARCHAR(50), secret VARCHAR(255), PRIMARY KEY (id) ) Engine=InnoDB CHARACTER SET 'latin1'; EOF init_data_file=$(readlink -f ${thisdir}/../mysql-data/roundcube.mysql.initial.sql) log_info "Initializing the arbitrary database from file ${init_data_file}..." mysql $mysql_flags ${DB_RC_DATABASE} < ${init_data_file} } if ! [ -v MYSQL_RUNNING_AS_SLAVE ] && $MYSQL_DATADIR_FIRST_INIT ; then init_arbitrary_database fi diff --git a/docker/roundcube/rootfs/opt/app-root/src/init.sh b/docker/roundcube/rootfs/opt/app-root/src/init.sh index 4218ce1c..df062d68 100755 --- a/docker/roundcube/rootfs/opt/app-root/src/init.sh +++ b/docker/roundcube/rootfs/opt/app-root/src/init.sh @@ -1,102 +1,118 @@ #!/bin/bash echo "Starting" set -e set -x mkdir -p /data/pgp-home chmod 777 /data/pgp-home pushd /opt/app-root/src/ pushd roundcubemail ## Copy our configs over the default ones cp /opt/app-root/src/roundcubemail-config-templates/* config/ # Initialize the db -cat > /tmp/kolab-setup-my.cnf << EOF +if [[ "$DB_ROOT_PASSWORD" == "" ]]; then + echo "Not using password" + cat > /tmp/kolab-setup-my.cnf << EOF +[client] +host=${DB_HOST} +user=root +EOF +else + cat > /tmp/kolab-setup-my.cnf << EOF [client] host=${DB_HOST} user=root password=${DB_ROOT_PASSWORD} EOF +fi mysql --defaults-file=/tmp/kolab-setup-my.cnf </dev/null 2>&1 || : done fi done popd roundcubemail/bin/initdb.sh --dir syncroton/docs/SQL/ || : roundcubemail/bin/initdb.sh --dir chwala/doc/SQL/ || : echo "Updating tables..." roundcubemail/bin/updatedb.sh --dir syncroton/docs/SQL/ --package syncroton || : roundcubemail/bin/updatedb.sh --dir roundcubemail/SQL/ --package roundcube || : roundcubemail/bin/updatedb.sh --dir roundcubemail/plugins/libkolab/SQL/ --package libkolab || : roundcubemail/bin/updatedb.sh --dir roundcubemail/plugins/kolab-calendar/SQL/ --package calendar-kolab || : echo "" echo "Done, starting httpd..." if [ "$1" == "testsuite" ]; then ./update-from-source.sh || : sed -i "s/?>/\$config['activesync_test_username'] = 'john@kolab.org';\n?>/" roundcubemail/config/config.inc.php sed -i "s/?>/\$config['activesync_test_password'] = 'simple123';\n?>/" roundcubemail/config/config.inc.php + sed -i "s/?>/\$config['activesync_test_host'] = 'http:\/\/localhost:8001';\n?>/" roundcubemail/config/config.inc.php sed -i -r -e "s/config\['activesync_init_subscriptions'\] =.*$/config['activesync_init_subscriptions'] = 0;/g" roundcubemail/config/kolab_syncroton.inc.php sed -i -r -e "s/config\['activesync_multifolder_blacklist_event'\] =.*$/config['activesync_multifolder_blacklist_event'] = array('windowsoutlook');/g" roundcubemail/config/kolab_syncroton.inc.php sed -i -r -e "s/config\['activesync_multifolder_blacklist_task'\] =.*$/config['activesync_multifolder_blacklist_task'] = array('windowsoutlook');/g" roundcubemail/config/kolab_syncroton.inc.php sed -i -r -e "s/config\['activesync_multifolder_blacklist_contact'\] =.*$/config['activesync_multifolder_blacklist_contact'] = array('windowsoutlook');/g" roundcubemail/config/kolab_syncroton.inc.php pushd syncroton - php -S localhost:8000 & + php -S localhost:8001 & pushd tests php \ -dmemory_limit=-1 \ ../vendor/bin/phpunit \ --verbose \ --testsuite Sync + if [ "$2" == "shell" ]; then + exec /bin/bash + fi elif [ "$1" == "phpstan" ]; then ./update-from-source.sh || : + pushd roundcubemail + cp /src.orig/roundcubemail-plugins-kolab/phpstan.neon . + cp /src.orig/roundcubemail-plugins-kolab/phpstan.bootstrap.php . php -dmemory_limit=-1 vendor/bin/phpstan analyse elif [ "$1" == "quicktest" ]; then pushd syncroton/tests php \ -dmemory_limit=-1 \ ../vendor/bin/phpunit \ --verbose \ --testsuite Unit elif [ "$1" == "shell" ]; then exec /bin/bash else /usr/sbin/php-fpm exec httpd -DFOREGROUND fi diff --git a/docker/roundcube/rootfs/opt/app-root/src/update-from-source.sh b/docker/roundcube/rootfs/opt/app-root/src/update-from-source.sh index f123a41a..90e1f1d3 100755 --- a/docker/roundcube/rootfs/opt/app-root/src/update-from-source.sh +++ b/docker/roundcube/rootfs/opt/app-root/src/update-from-source.sh @@ -1,35 +1,37 @@ #!/bin/bash #Update from source (rather than via composer which updates to the latest commit) -for repo in roundcubemail syncroton iRony chwala autoconf freebusy +for directory in roundcubemail syncroton iRony chwala autoconf freebusy do if [ -d /src.orig/$directory ]; then rsync -av \ --no-links \ --exclude=vendor \ --exclude=temp \ --exclude=config \ --exclude=logs \ --exclude=.git \ --exclude=config.inc.php \ --exclude=composer.json \ --exclude=composer.lock \ /src.orig/$directory/ /opt/app-root/src/$directory fi done -pushd /src.orig/roundcubemail-plugins-kolab/plugins +if [ -d /src.orig/roundcubemail-plugins-kolab/plugins ]; then + pushd /src.orig/roundcubemail-plugins-kolab/plugins -for plugin in $(ls -1d) -do - if [ -d /opt/app-root/src/roundcubemail/plugins/${plugin}/ ]; then - rsync -av \ - --exclude=vendor \ - --exclude=composer.json \ - --exclude=config.inc.php \ - $plugin/ /opt/app-root/src/roundcubemail/plugins/$plugin - fi -done -popd + for plugin in $(ls -1d) + do + if [ -d /opt/app-root/src/roundcubemail/plugins/${plugin}/ ]; then + rsync -av \ + --exclude=vendor \ + --exclude=composer.json \ + --exclude=config.inc.php \ + $plugin/ /opt/app-root/src/roundcubemail/plugins/$plugin + fi + done + popd +fi # ./reload.sh diff --git a/docker/tests/init.sh b/docker/tests/init.sh index 70747242..a7f07de3 100755 --- a/docker/tests/init.sh +++ b/docker/tests/init.sh @@ -1,157 +1,159 @@ #!/bin/bash set -e set -x rsync -av \ --exclude=vendor \ --exclude=composer.lock \ --exclude=node_modules \ --exclude=package-lock.json \ --exclude=public \ --exclude=storage \ --exclude=resources/build \ --exclude=bootstrap \ --exclude=.gitignore \ /src/kolabsrc.orig/ /opt/app-root/src/ | tee /tmp/rsync.output cd /opt/app-root/src/ if [ "$1" == "--refresh" ]; then rm -rf storage/framework mkdir -p storage/framework/{sessions,views,cache} find bootstrap/cache/ -type f ! -name ".gitignore" -delete ./artisan clear-compiled ./artisan cache:clear # FIXME seems to be required for db seed to function composer update if rpm -qv chromium 2>/dev/null; then chver=$(rpmquery --queryformat="%{VERSION}" chromium | awk -F'.' '{print $1}') ./artisan dusk:chrome-driver ${chver} fi # Only run npm if something relevant was updated if grep -e "package.json" -e "resources" /tmp/rsync.output; then npm run dev fi ./artisan db:ping --wait # Unconditionally get the database into shape php -dmemory_limit=512M ./artisan migrate:refresh --seed ./artisan data:import || : ./artisan queue:work --stop-when-empty shift fi +./artisan route:list + EXCLUDE_GROUPS="skipci,ldap,coinbase,mollie,stripe,meet,dns" if [ "$1" == "suite-Functional" ]; then php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group skipci,ldap \ --verbose \ --testsuite Unit php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group skipci,ldap \ --verbose \ --testsuite Functional elif [ "$1" == "suite-Feature" ]; then php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group "$EXCLUDE_GROUPS" \ --verbose \ --testsuite Feature elif [ "$1" == "suite-Browser" ]; then # Can't do browser tests over https echo "APP_URL=http://kolab.local" >> .env echo "APP_PUBLIC_URL=http://kolab.local" >> .env echo "ASSET_URL=http://kolab.local" >> .env echo "MEET_SERVER_URLS=http://kolab.local/meetmedia/api/" >> .env echo "APP_HEADER_CSP=" >> .env echo "APP_HEADER_XFO=" >> .env ./artisan octane:start --port=80 >/dev/null 2>&1 & echo "127.0.0.1 kolab.local admin.kolab.local reseller.kolab.local" >> /etc/hosts php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group skipci,ldap,meet,mollie \ --verbose \ --testsuite Browser elif [ "$1" == "testsuite" ]; then php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group "$EXCLUDE_GROUPS" \ --verbose \ --testsuite Unit php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group "$EXCLUDE_GROUPS" \ --verbose \ --testsuite Functional php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group "$EXCLUDE_GROUPS" \ --verbose \ --testsuite Feature elif [ "$1" == "quicktest" ]; then php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group "$EXCLUDE_GROUPS" \ --verbose \ --stop-on-defect \ --stop-on-error \ --stop-on-failure \ --testsuite Unit php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group "$EXCLUDE_GROUPS" \ --verbose \ --stop-on-defect \ --stop-on-error \ --stop-on-failure \ --testsuite Functional php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group "$EXCLUDE_GROUPS" \ --verbose \ --stop-on-defect \ --stop-on-error \ --stop-on-failure \ --testsuite Feature elif [ "$1" == "shell" ]; then exec /bin/bash else php \ -dmemory_limit=-1 \ vendor/bin/phpunit \ --exclude-group "$EXCLUDE_GROUPS" \ --verbose \ --stop-on-defect \ --stop-on-error \ --stop-on-failure \ "$1" fi diff --git a/docker/webapp/init.sh b/docker/webapp/init.sh index 4ba998e3..9263a2b3 100755 --- a/docker/webapp/init.sh +++ b/docker/webapp/init.sh @@ -1,119 +1,148 @@ #!/bin/bash set -e set -x cd /opt/app-root/src/ +REBUILD=false # Update the sourcecode if available. # This also copies the .env files that is required if we don't provide # a configuration via the environment. # So we need this for the docker-compose setup if [ -d /src/kolabsrc.orig ]; then echo "----> Updating source" rsync -av \ --exclude=vendor \ --exclude=composer.lock \ --exclude=node_modules \ --exclude=package-lock.json \ --exclude=public \ --exclude=storage \ --exclude=resources/build \ --exclude=bootstrap \ --exclude=.gitignore \ /src/kolabsrc.orig/ /opt/app-root/src/ | tee /tmp/rsync.output + REBUILD=true +fi + +if [ -d /src/overlay ]; then + echo "----> Applying overlay" + rsync -av \ + --exclude=vendor \ + --exclude=composer.lock \ + --exclude=node_modules \ + --exclude=package-lock.json \ + --exclude=public \ + --exclude=storage \ + --exclude=resources/build \ + --exclude=bootstrap \ + --exclude=.gitignore \ + /src/overlay/ /opt/app-root/src/ | tee /tmp/rsync-overlay.output + + REBUILD=true +fi + +# If we want to rely on the environment for configuration +if [ $NOENVFILE ]; then + echo "----> removing envfile" + rm -f .env +fi + + +if [ $REBUILD ]; then rm -rf storage/framework mkdir -p storage/framework/{sessions,views,cache} find bootstrap/cache/ -type f ! -name ".gitignore" -delete ./artisan clear-compiled ./artisan cache:clear php -dmemory_limit=-1 $(command -v composer) install fi if [ ! -f 'resources/countries.php' ]; then echo "----> Importing countries" ./artisan data:countries fi echo "----> Waiting for db" ./artisan db:ping --wait function is_not_initialized() { ROWCOUNT=$(echo "select count(*) from migrations;" | mysql -N -b -u "$DB_USERNAME" -p"$DB_PASSWORD" -h "$DB_HOST" "$DB_DATABASE") if [[ "$ROWCOUNT" == "" ]]; then # Treat an error in the above command as uninitialized ROWCOUNT="0" fi [[ "$ROWCOUNT" == "0" ]] } case ${KOLAB_ROLE} in seed|SEED) echo "----> Running seeder" # Only run the seeder if we haven't even migrated yet. if is_not_initialized; then echo "----> Seeding the database" # If we seed, we always drop all existing tables php -dmemory_limit=512M ./artisan migrate:fresh --seed fi ;; horizon|HORIZON) echo "----> Waiting for database to be seeded" while is_not_initialized; do sleep 1 echo "." done echo "----> Running migrations" php -dmemory_limit=512M ./artisan migrate --force || : echo "----> Starting horizon" ./artisan horizon ;; octane|OCTANE) echo "----> Running octane" echo "----> Waiting for database to be seeded" while is_not_initialized; do sleep 1 echo "." done exec ./artisan octane:start --host=0.0.0.0 ;; worker|WORKER ) ./artisan migrate --force || : echo "----> Running worker" exec ./artisan queue:work ;; combined|COMBINED ) # If there is no db at all then listing users will crash (resulting in us counting the lines of backtrace), # but migrate:status will just fail. if is_not_initialized; then echo "----> Seeding the database" php -dmemory_limit=512M ./artisan migrate --seed || : # If there is a db but no user we reseed elif test "$( env APP_DEBUG=false ./artisan -n users | wc -l )" -lt "1"; then echo "----> Initializing the database" php -dmemory_limit=512M ./artisan migrate:refresh --seed # Otherwise we just migrate else echo "----> Running migrations" php -dmemory_limit=512M ./artisan migrate --force fi ./artisan data:import || : nohup ./artisan horizon 2>&1 & exec ./artisan octane:start --host=$(env | grep OCTANE_HTTP_HOST | tail -n1 | sed "s/OCTANE_HTTP_HOST=//") ;; * ) echo "----> Sleeping" exec sleep 10000 ;; esac