From 4149c33b1c09c20cd93b0964f845c716c286c74d Mon Sep 17 00:00:00 2001
From: decentral1se <hi@decentral1.se>
Date: Fri, 14 May 2021 17:32:04 +0200
Subject: [PATCH] Use upstream entrypoint

---
 entrypoint.core.sh.tmpl | 240 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 236 insertions(+), 4 deletions(-)

diff --git a/entrypoint.core.sh.tmpl b/entrypoint.core.sh.tmpl
index 6b9bba6..a445d92 100644
--- a/entrypoint.core.sh.tmpl
+++ b/entrypoint.core.sh.tmpl
@@ -1,6 +1,9 @@
-#!/bin/bash
+#! /bin/bash
 
-set -eu
+# Note(decentral1se): This is a copy/pasta of the upstream entrypoint
+# because https://github.com/maxking/docker-mailman/issues/86
+
+set -e
 
 file_env() {
   local var="$1"
@@ -23,10 +26,239 @@ file_env() {
   unset "$fileVar"
 }
 
+function wait_for_postgres () {
+	# Check if the postgres database is up and accepting connections before
+	# moving forward.
+	# TODO: Use python3's psycopg2 module to do this in python3 instead of
+	# installing postgres-client in the image.
+	until psql $DATABASE_URL -c '\l'; do
+		>&2 echo "Postgres is unavailable - sleeping"
+		sleep 1
+	done
+	>&2 echo "Postgres is up - continuing"
+}
+
+function wait_for_mysql () {
+	# Check if MySQL is up and accepting connections.
+	HOSTNAME=$(python3 -c "from urllib.parse import urlparse; o = urlparse('$DATABASE_URL'); print(o.hostname);")
+	until mysqladmin ping --host "$HOSTNAME" --silent; do
+		>&2 echo "MySQL is unavailable - sleeping"
+		sleep 1
+	done
+	>&2 echo "MySQL is up - continuing"
+}
+
+# Empty the config file.
+echo "# This file is autogenerated at container startup." > /etc/mailman.cfg
+
+# Check if $MM_HOSTNAME is set, if not, set it to the value returned by
+# `hostname -i` command to set it to whatever IP address is assigned to the
+# container.
+if [[ ! -v MM_HOSTNAME ]]; then
+	export MM_HOSTNAME=`hostname -i`
+fi
+
+# SMTP_HOST defaults to the gateway
+if [[ ! -v SMTP_HOST ]]; then
+	export SMTP_HOST=$(/sbin/ip route | awk '/default/ { print $3 }')
+	echo "SMPT_HOST not specified, using the gateway ($SMTP_HOST) as default"
+fi
+
+if [[ ! -v SMTP_PORT ]]; then
+	export SMTP_PORT=25
+fi
+
+# Check if REST port, username, and password are set, if not, set them
+# to default values.
+if [[ ! -v MAILMAN_REST_PORT ]]; then
+	export MAILMAN_REST_PORT='8001'
+fi
+
+if [[ ! -v MAILMAN_REST_USER ]]; then
+	export MAILMAN_REST_USER='restadmin'
+fi
+
+if [[ ! -v MAILMAN_REST_PASSWORD ]]; then
+	export MAILMAN_REST_PASSWORD='restpass'
+fi
+
+function setup_database () {
+	if [[ ! -v DATABASE_URL ]]
+	then
+		echo "Environment variable DATABASE_URL should be defined..."
+		exit 1
+	fi
+
+	# Translate mysql:// urls to mysql+mysql:// backend:
+	if [[ "$DATABASE_URL" == mysql://* ]]; then
+		DATABASE_URL="mysql+pymysql://${DATABASE_URL:8}"
+		echo "Database URL was automatically rewritten to: $DATABASE_URL"
+	fi
+
+	# If DATABASE_CLASS is not set, guess it for common databases:
+	if [ -z "$DATABASE_CLASS" ]; then
+		if [[ ("$DATABASE_URL" == mysql:*) ||
+				("$DATABASE_URL" == mysql+*) ]]; then
+			DATABASE_CLASS=mailman.database.mysql.MySQLDatabase
+		fi
+		if [[ ("$DATABASE_URL" == postgres:*) ||
+				("$DATABASE_URL" == postgres+*) ]]; then
+			DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase
+		fi
+	fi
+
+	cat >> /etc/mailman.cfg <<EOF
+[database]
+class: $DATABASE_CLASS
+url: $DATABASE_URL
+EOF
+}
+
+
+# Check if $DATABASE_URL is defined, if not, use a standard sqlite database.
+#
+# If the $DATABASE_URL is defined and is postgres, check if it is available
+# yet. Do not start the container before the postgresql boots up.
+#
+# TODO: If the $DATABASE_URL is defined and is mysql, check if the database is
+# available before the container boots up.
+#
+# TODO: Check the database type and detect if it is up based on that. For now,
+# assume that postgres is being used if DATABASE_URL is defined.
+if [[ ! -v DATABASE_URL ]]; then
+	echo "DATABASE_URL is not defined. Using sqlite database..."
+else
+	setup_database
+fi
+
+
+if [[ "$DATABASE_TYPE" = 'postgres' ]]
+then
+	wait_for_postgres
+elif [[ "$DATABASE_TYPE" = 'mysql' ]]
+then
+	wait_for_mysql
+fi
+
+# Generate a basic mailman.cfg.
+cat >> /etc/mailman.cfg << EOF
+[runner.retry]
+sleep_time: 10s
+
+[webservice]
+hostname: $MM_HOSTNAME
+port: $MAILMAN_REST_PORT
+admin_user: $MAILMAN_REST_USER
+admin_pass: $MAILMAN_REST_PASSWORD
+configuration: /etc/gunicorn.cfg
+
+EOF
+
+# Generate a basic gunicorn.cfg.
+SITE_DIR=$(python3 -c 'import site; print(site.getsitepackages()[0])')
+cp "${SITE_DIR}/mailman/config/gunicorn.cfg" /etc/gunicorn.cfg
+
+# Generate a basic configuration to use exim
+cat > /tmp/exim-mailman.cfg <<EOF
+[mta]
+incoming: mailman.mta.exim4.LMTP
+outgoing: mailman.mta.deliver.deliver
+lmtp_host: $MM_HOSTNAME
+lmtp_port: 8024
+smtp_host: $SMTP_HOST
+smtp_port: $SMTP_PORT
+configuration: python:mailman.config.exim4
+
+EOF
+
+cat > /etc/postfix-mailman.cfg << EOF
+[postfix]
+transport_file_type: regex
+# While in regex mode, postmap_command is never used, a placeholder
+# is added here so that it doesn't break anything.
+postmap_command: true
+EOF
+
+# Generate a basic configuration to use postfix.
+cat > /tmp/postfix-mailman.cfg <<EOF
+[mta]
+incoming: mailman.mta.postfix.LMTP
+outgoing: mailman.mta.deliver.deliver
+lmtp_host: $MM_HOSTNAME
+lmtp_port: 8024
+smtp_host: $SMTP_HOST
+smtp_port: $SMTP_PORT
+configuration: /etc/postfix-mailman.cfg
+
+EOF
+
+if [ "$MTA" == "exim" ]
+then
+	echo "Using Exim configuration"
+	cat /tmp/exim-mailman.cfg >> /etc/mailman.cfg
+elif [ "$MTA" == "postfix" ]
+then
+	echo "Using Postfix configuration"
+	cat /tmp/postfix-mailman.cfg >> /etc/mailman.cfg
+else
+	echo "No MTA environment variable found, defaulting to Exim"
+	cat /tmp/exim-mailman.cfg >> /etc/mailman.cfg
+fi
+
+rm -f /tmp/{postfix,exim}-mailman.cfg
+
+if [[ -e /opt/mailman/mailman-extra.cfg ]]
+then
+	echo "Found configuration file at /opt/mailman/mailman-extra.cfg"
+	cat /opt/mailman/mailman-extra.cfg >> /etc/mailman.cfg
+fi
+
+if [[ -e /opt/mailman/gunicorn-extra.cfg ]]
+then
+       echo "Found [webserver] configuration file at /opt/mailman/gunicorn-extra.cfg"
+       cat /opt/mailman/gunicorn-extra.cfg > /etc/gunicorn.cfg
+fi
+
+if [[ -v HYPERKITTY_API_KEY ]]; then
+
+echo "HYPERKITTY_API_KEY found, setting up HyperKitty archiver..."
+
+cat >> /etc/mailman.cfg << EOF
+[archiver.hyperkitty]
+class: mailman_hyperkitty.Archiver
+enable: yes
+configuration: /etc/mailman-hyperkitty.cfg
+
+EOF
+
+if [[ ! -v HYPERKITTY_URL ]]; then
+	echo "HYPERKITTY_URL not set, using the default value of http://mailman-web:8000/hyperkitty"
+	export HYPERKITTY_URL="http://mailman-web:8000/hyperkitty/"
+fi
+
+# Generate a basic mailman-hyperkitty.cfg.
+cat > /etc/mailman-hyperkitty.cfg <<EOF
+[general]
+base_url: $HYPERKITTY_URL
+api_key: $HYPERKITTY_API_KEY
+EOF
+
+else
+
+echo "HYPERKITTY_API_KEY not defined, skipping HyperKitty setup..."
+
+fi
+
+# Generate the LMTP files for postfix if needed.
+mailman aliases
+
+# Now chown the places where mailman wants to write stuff.
+chown -Rf mailman /opt/mailman
+
+# Load secrets and expose env vars
 file_env "DATABASE_PASSWORD"
 file_env "HYPERKITTY_API_KEY"
 file_env "MAILMAN_REST_PASSWORD"
-
 export DATABASE_URL="postgres://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}/${DATABASE_NAME}"
 
-/usr/local/bin/docker-entrypoint.sh "$@"
+exec su-exec mailman "$@"