diff --git a/setup/.env b/setup/.env new file mode 100644 index 00000000..2c1113ce --- /dev/null +++ b/setup/.env @@ -0,0 +1,8 @@ +# Hostname passed to Traefik +ADDRESS=setup.mailu.io + +# Current release +RELEASE=master + +# Comma separated list of versions the user can choose. +VERSIONS=master diff --git a/setup/Dockerfile b/setup/Dockerfile index e39d7c3b..7c4ba773 100644 --- a/setup/Dockerfile +++ b/setup/Dockerfile @@ -4,20 +4,15 @@ 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 diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 42e7ee18..7c31d2cd 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -6,9 +6,37 @@ 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 + networks: + - web + env_file: .env + environment: + this_version: "master" + labels: + - traefik.enable=true + - traefik.port=80 + - traefik.main.frontend.rule=Host:${ADDRESS};PathPrefix:/master/ + depends_on: + - redis + setup_release: + image: mailu/setup:${RELEASE} + networks: + - web + 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:${ADDRESS};PathPrefix:/ + - traefik.main.frontend.rule=Host:${ADDRESS};PathPrefix:/${RELEASE}/ + depends_on: + - redis + +networks: + web: + external: true 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" 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