From bb0fd896b39fce4679938c540d2f5b2119091e3f Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Tue, 11 Dec 2018 17:31:21 +0200 Subject: [PATCH 1/6] Fix some bugs in setup for stack flavor - Unbound and webmail images were hardcoded - Removed unnecesary environment keyword --- setup/flavors/stack/docker-compose.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup/flavors/stack/docker-compose.yml b/setup/flavors/stack/docker-compose.yml index eef8e334..217667e1 100644 --- a/setup/flavors/stack/docker-compose.yml +++ b/setup/flavors/stack/docker-compose.yml @@ -33,7 +33,7 @@ services: {% if resolver_enabled %} resolver: - image: mailu/unbound:{{ version }} + image: ${DOCKER_ORG:-mailu}/unbound:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} networks: default: @@ -56,7 +56,6 @@ services: imap: image: ${DOCKER_ORG:-mailu}/dovecot:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} - environment: volumes: - "{{ root }}/mail:/mail" - "{{ root }}/overrides:/overrides" @@ -130,7 +129,7 @@ services: {% if webmail_type != 'none' %} webmail: - image: ${DOCKER_ORG:-mailu}/roundcube:${MAILU_VERSION:-{{ version }}} + image: ${DOCKER_ORG:-mailu}/{{ webmail_type }}:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} volumes: - "{{ root }}/webmail:/data" From 9c284c4004e5451f85563e7429f8ea47ef3a5227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 16:26:45 +0200 Subject: [PATCH 2/6] Prepare setup for multi-ver deployment on docs server --- setup/.env | 8 ++++ setup/Dockerfile | 11 ++--- setup/docker-compose.yml | 30 ++++++++++--- setup/requirements.txt | 1 - setup/server.py | 90 +++++++++++++++++---------------------- setup/setup.py | 39 ----------------- setup/templates/base.html | 4 +- setup/test | 0 8 files changed, 79 insertions(+), 104 deletions(-) create mode 100644 setup/.env delete mode 100644 setup/setup.py delete mode 100644 setup/test diff --git a/setup/.env b/setup/.env new file mode 100644 index 00000000..47db5c89 --- /dev/null +++ b/setup/.env @@ -0,0 +1,8 @@ +# Hostname passed to Traefik +HOSTNAME=setup.mailu.io + +# Current release +RELEASE=test + +# Comma separated list of versions the user can choose. +VERSIONS=test,master diff --git a/setup/Dockerfile b/setup/Dockerfile index e39d7c3b..5787c003 100644 --- a/setup/Dockerfile +++ b/setup/Dockerfile @@ -4,20 +4,17 @@ RUN mkdir -p /app WORKDIR /app COPY requirements.txt requirements.txt -RUN apk add --no-cache git curl \ +RUN apk add --no-cache curl \ && pip install -r requirements.txt COPY server.py ./server.py -COPY setup.py ./setup.py COPY main.py ./main.py -COPY flavors /data/master/flavors -COPY templates /data/master/templates +COPY flavors /data/flavors +COPY templates /data/templates COPY static ./static -#RUN python setup.py https://github.com/mailu/mailu /data - EXPOSE 80/tcp CMD gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload main:app -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 +HEALTHCHECK CMD curl -f -L http://localhost/master/ || exit 1 diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 42e7ee18..317f9fd2 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -6,9 +6,29 @@ services: redis: image: redis:alpine - setup: - image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX}setup:${MAILU_VERSION:-master} - ports: - - "8000:80" - build: . + setup_master: + image: mailu/setup:master + env_file: .env + environment: + this_version: "master" + labels: + - traefik.enable=true + - traefik.port=80 + - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/master/ + depends_on: + - redis + setup_release: + image: mailu/setup:${RELEASE} + env_file: .env + environment: + this_version: ${RELEASE} + labels: + - traefik.enable=true + - traefik.port=80 + - traefik.root.frontend.redirect.regex=.* + - traefik.root.frontend.redirect.replacement=/${RELEASE}/ + - traefik.root.frontend.rule=Host:${HOSTNAME};PathPrefix:/ + - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/${RELEASE}/ + depends_on: + - redis diff --git a/setup/requirements.txt b/setup/requirements.txt index ea2a2c25..b6bf2120 100644 --- a/setup/requirements.txt +++ b/setup/requirements.txt @@ -1,5 +1,4 @@ flask flask-bootstrap redis -gitpython gunicorn diff --git a/setup/server.py b/setup/server.py index 6f60c3c0..456cb539 100644 --- a/setup/server.py +++ b/setup/server.py @@ -33,70 +33,60 @@ def secret(length=16): def build_app(path): - #Hardcoded master as the only version for test purposes - versions = [ - # version for version in os.listdir(path) - # if os.path.isdir(os.path.join(path, version)) - "master" - ] - app.jinja_env.trim_blocks = True app.jinja_env.lstrip_blocks = True @app.context_processor def app_context(): - return dict(versions=versions) + return dict(versions=os.getenv("VERSIONS","master").split(',')) - @app.route("/") - def index(): - return flask.redirect(flask.url_for('{}.wizard'.format(versions[-1]))) + version = os.getenv("this_version") - for version in versions: - bp = flask.Blueprint(version, __name__) - bp.jinja_loader = jinja2.ChoiceLoader([ - jinja2.FileSystemLoader(os.path.join(path, version, "templates")), - jinja2.FileSystemLoader(os.path.join(path, version, "flavors")) - ]) + bp = flask.Blueprint(version, __name__) + bp.jinja_loader = jinja2.ChoiceLoader([ + jinja2.FileSystemLoader(os.path.join(path, "templates")), + jinja2.FileSystemLoader(os.path.join(path, "flavors")) + ]) - @bp.context_processor - def bp_context(version=version): - return dict(version=version) + @bp.context_processor + def bp_context(version=version): + return dict(version=version) - @bp.route("/") - def wizard(): - return flask.render_template('wizard.html') + @bp.route("/") + def wizard(): + return flask.render_template('wizard.html') - @bp.route("/submit_flavor", methods=["POST"]) - def submit_flavor(): - data = flask.request.form.copy() - steps = sorted(os.listdir(path + "/" + version + "/templates/steps/" + data["flavor"])) - return flask.render_template('wizard.html', flavor=data["flavor"], steps=steps) + @bp.route("/submit_flavor", methods=["POST"]) + def submit_flavor(): + data = flask.request.form.copy() + steps = sorted(os.listdir(os.path.join(path, "templates", "steps", data["flavor"]))) + return flask.render_template('wizard.html', flavor=data["flavor"], steps=steps) - @bp.route("/submit", methods=["POST"]) - def submit(): - data = flask.request.form.copy() - data['uid'] = str(uuid.uuid4()) - data['dns'] = str(ipaddress.IPv4Network(data['subnet'])[-2]) - db.set(data['uid'], json.dumps(data)) - return flask.redirect(flask.url_for('.setup', uid=data['uid'])) + @bp.route("/submit", methods=["POST"]) + def submit(): + data = flask.request.form.copy() + data['uid'] = str(uuid.uuid4()) + data['dns'] = str(ipaddress.IPv4Network(data['subnet'])[-2]) + db.set(data['uid'], json.dumps(data)) + return flask.redirect(flask.url_for('.setup', uid=data['uid'])) - @bp.route("/setup/", methods=["GET"]) - def setup(uid): - data = json.loads(db.get(uid)) - flavor = data.get("flavor", "compose") - rendered = render_flavor(flavor, "setup.html", data) - return flask.render_template("setup.html", contents=rendered) + @bp.route("/setup/", methods=["GET"]) + def setup(uid): + data = json.loads(db.get(uid)) + flavor = data.get("flavor", "compose") + rendered = render_flavor(flavor, "setup.html", data) + return flask.render_template("setup.html", contents=rendered) - @bp.route("/file//", methods=["GET"]) - def file(uid, filepath): - data = json.loads(db.get(uid)) - flavor = data.get("flavor", "compose") - return flask.Response( - render_flavor(flavor, filepath, data), - mimetype="application/text" - ) + @bp.route("/file//", methods=["GET"]) + def file(uid, filepath): + data = json.loads(db.get(uid)) + flavor = data.get("flavor", "compose") + return flask.Response( + render_flavor(flavor, filepath, data), + mimetype="application/text" + ) - app.register_blueprint(bp, url_prefix="/{}".format(version)) + app.register_blueprint(bp, url_prefix="/{}".format(version)) if __name__ == "__main__": diff --git a/setup/setup.py b/setup/setup.py deleted file mode 100644 index e08c0092..00000000 --- a/setup/setup.py +++ /dev/null @@ -1,39 +0,0 @@ -import git -import tempfile -import argparse -import os -import shutil -import re - - -VERSION_BRANCH = re.compile("(master|\d+\.\d+)") - - -def main(upstream, dest, dev=True): - shutil.rmtree(dest, ignore_errors=True) - os.makedirs(dest, exist_ok=True) - with tempfile.TemporaryDirectory() as clone_path: - repo = git.Repo.clone_from(upstream, clone_path) - for branch in repo.refs: - if not branch.name.startswith("origin/"): - continue - name = branch.name[len("origin/"):] - if not VERSION_BRANCH.match(name): - continue - branch.checkout() - config_path = os.path.join(clone_path, "setup") - if os.path.exists(config_path): - shutil.copytree(config_path, os.path.join(dest, name)) - print("Imported branch {}".format(name)) - if dev: - shutil.copytree(".", os.path.join(dest, "dev")) - print("Imported dev") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--dev", action="store_true", help="Copy the local dir in /dev") - parser.add_argument("upstream", help="Path to Mailu git repository") - parser.add_argument("dest", help="Destination directory for data files") - args = parser.parse_args() - main(**vars(args)) diff --git a/setup/templates/base.html b/setup/templates/base.html index 5be0b1eb..c53bd1d1 100644 --- a/setup/templates/base.html +++ b/setup/templates/base.html @@ -9,8 +9,8 @@

Version

diff --git a/setup/test b/setup/test deleted file mode 100644 index e69de29b..00000000 From db9a3787b166fbccc14b50c332b79acb29103a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 22:31:13 +0200 Subject: [PATCH 3/6] Disable healthcheck, doen't work in versioned env --- setup/Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup/Dockerfile b/setup/Dockerfile index 5787c003..7c4ba773 100644 --- a/setup/Dockerfile +++ b/setup/Dockerfile @@ -16,5 +16,3 @@ COPY static ./static EXPOSE 80/tcp CMD gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload main:app - -HEALTHCHECK CMD curl -f -L http://localhost/master/ || exit 1 From 8ef0493f53913c1a08950ce50b5312ec11458330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 23:05:03 +0200 Subject: [PATCH 4/6] Define external web network for Traefik connections --- setup/docker-compose.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 317f9fd2..5a16e5b5 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -8,6 +8,8 @@ services: setup_master: image: mailu/setup:master + networks: + - web env_file: .env environment: this_version: "master" @@ -20,6 +22,8 @@ services: setup_release: image: mailu/setup:${RELEASE} + networks: + - web env_file: .env environment: this_version: ${RELEASE} @@ -32,3 +36,7 @@ services: - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/${RELEASE}/ depends_on: - redis + +networks: + web: + external: true From 1df3b464547736dac5e1b8f81ad46cc6a6d37f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 23:11:43 +0200 Subject: [PATCH 5/6] Use ADDRESS instead of HOSTNAME --- setup/.env | 2 +- setup/docker-compose.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/.env b/setup/.env index 47db5c89..9a8293fe 100644 --- a/setup/.env +++ b/setup/.env @@ -1,5 +1,5 @@ # Hostname passed to Traefik -HOSTNAME=setup.mailu.io +ADDRESS=setup.mailu.io # Current release RELEASE=test diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 5a16e5b5..7c31d2cd 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -16,7 +16,7 @@ services: labels: - traefik.enable=true - traefik.port=80 - - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/master/ + - traefik.main.frontend.rule=Host:${ADDRESS};PathPrefix:/master/ depends_on: - redis @@ -32,8 +32,8 @@ services: - traefik.port=80 - traefik.root.frontend.redirect.regex=.* - traefik.root.frontend.redirect.replacement=/${RELEASE}/ - - traefik.root.frontend.rule=Host:${HOSTNAME};PathPrefix:/ - - traefik.main.frontend.rule=Host:${HOSTNAME};PathPrefix:/${RELEASE}/ + - traefik.root.frontend.rule=Host:${ADDRESS};PathPrefix:/ + - traefik.main.frontend.rule=Host:${ADDRESS};PathPrefix:/${RELEASE}/ depends_on: - redis From e994fefb2d4e4b82ea780557f4e8aa6b8a1cc227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 16 Dec 2018 23:28:15 +0200 Subject: [PATCH 6/6] Remove the test branch --- setup/.env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/.env b/setup/.env index 9a8293fe..2c1113ce 100644 --- a/setup/.env +++ b/setup/.env @@ -2,7 +2,7 @@ ADDRESS=setup.mailu.io # Current release -RELEASE=test +RELEASE=master # Comma separated list of versions the user can choose. -VERSIONS=test,master +VERSIONS=master