Page MenuHomeDevCentral

D2597.id7577.diff
No OneTemporary

D2597.id7577.diff

diff --git a/PORTS b/PORTS
--- a/PORTS
+++ b/PORTS
@@ -17,6 +17,8 @@
paas-docker
5000 Docker registry HTTP
9090 Openfire HTTP
+ 17080 Penpot - back-end
+ 17300 Penpot - exporter
19080 Nasqueron API - Datasources
20080 Nasqueron API - Docker registry API
22220 Phabricator Aphlict (client)
diff --git a/_modules/convert.py b/_modules/convert.py
--- a/_modules/convert.py
+++ b/_modules/convert.py
@@ -80,3 +80,10 @@
return salt.serializers.yaml.serialize(
_to_dictionary(data, root), default_flow_style=False
)
+
+
+def to_flags(data, enable_prefix="enable-", separator=" "):
+ """
+ A function to convert a list of flags in a string to enable them.
+ """
+ return separator.join([enable_prefix + item for item in data])
diff --git a/_tests/modules/test_convert.py b/_tests/modules/test_convert.py
new file mode 100755
--- /dev/null
+++ b/_tests/modules/test_convert.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+
+from importlib.machinery import SourceFileLoader
+import unittest
+
+salt_test_case = SourceFileLoader("salt_test_case", "salt_test_case.py").load_module()
+convert = SourceFileLoader("rust", "../_modules/convert.py").load_module()
+
+
+class Testinstance(unittest.TestCase, salt_test_case.SaltTestCase):
+ def setUp(self):
+ self.initialize_mocks()
+ self.instance = convert
+
+ def test_to_flags(self):
+ features = ["foo", "bar"]
+
+ self.assertEqual("enable-foo enable-bar", convert.to_flags(features))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/pillar/credentials/vault.sls b/pillar/credentials/vault.sls
--- a/pillar/credentials/vault.sls
+++ b/pillar/credentials/vault.sls
@@ -109,6 +109,10 @@
- ops/secrets/nasqueron/airflow/sentry
- ops/secrets/dbserver/cluster-A/users/airflow
+ - ops/secrets/nasqueron/penpot/github
+ - ops/secrets/nasqueron/penpot/postgresql
+ - ops/secrets/nasqueron/penpot/secret_key
+
- ops/secrets/nasqueron/rabbitmq/white-rabbit/erlang-cookie
- ops/secrets/nasqueron/rabbitmq/white-rabbit/root
diff --git a/pillar/paas/docker/docker-002/penpot.sls b/pillar/paas/docker/docker-002/penpot.sls
new file mode 100644
--- /dev/null
+++ b/pillar/paas/docker/docker-002/penpot.sls
@@ -0,0 +1,85 @@
+# -------------------------------------------------------------
+# Salt — Provision Docker engine
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# Service: Penpot
+# Note: If compared with upstream installation method,
+# the frontend part is skipped. This is to avoid
+# PaaS nginx -> frontend nginx -> backend server.
+# Frontend content is directly served by our nginx.
+# -------------------------------------------------------------
+
+docker_networks:
+ penpot:
+ subnet: 172.21.2.0/24
+
+docker_images:
+ - penpotapp/backend
+ - penpotapp/exporter
+
+docker_containers:
+
+ #
+ # Core services used by Penpot
+ #
+
+ exim:
+ penpot_smtp:
+ mailname: mx.design.nasqueron.org
+ network: penpot
+
+ postgresql:
+ penpot_db:
+ network: penpot
+ version: 15
+ credential: nasqueron/penpot/postgresql
+ db: penpot
+ initdb_args: --data-checksums
+
+ redis:
+ penpot_redis:
+ network: penpot
+ version: 7
+
+ #
+ # Penpot applications
+ #
+
+ penpot_web:
+ penpot_web:
+ realm: penpot
+ network: penpot
+ host: design.nasqueron.org
+ app_port: 17080
+ db:
+ uri: postgresql://penpot_db/penpot
+ services:
+ postgresql: penpot_db
+ redis: penpot_redis
+ smtp: penpot_smtp
+ exporter: http://localhost:17300
+ credentials:
+ github: nasqueron/penpot/github
+ postgresql: nasqueron/penpot/postgresql
+ secret_key: nasqueron/penpot/secret_key
+ features: &features
+ # Features relevant for both frontend and backend
+ - registration
+ - login-with-password
+ - login-with-github
+ - secure-session-cookies
+ - webhooks
+
+ # Features specific to the backend
+ - prepl-server
+ - smtp
+
+ penpot_exporter:
+ penpot_exporter:
+ realm: penpot
+ network: penpot
+ app_port: 17300
+ services:
+ frontend: https://design.nasqueron.org
+ redis: penpot_redis
diff --git a/roles/paas-docker/containers/penpot_exporter.sls b/roles/paas-docker/containers/penpot_exporter.sls
new file mode 100644
--- /dev/null
+++ b/roles/paas-docker/containers/penpot_exporter.sls
@@ -0,0 +1,32 @@
+# -------------------------------------------------------------
+# Salt — Provision Penpot
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# -------------------------------------------------------------
+
+{% set containers = pillar["docker_containers"] %}
+
+{% for instance, container in containers["penpot_exporter"].items() %}
+
+# -------------------------------------------------------------
+# Container
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{{ instance }}:
+ docker_container.running:
+ - detach: True
+ - interactive: True
+ - image: penpotapp/exporter
+ - networks:
+ - {{ container["network"] }}
+ - binds: /srv/{{ container["realm"] }}/assets:/opt/data/assets
+ - environment:
+ - PENPOT_PUBLIC_URI: {{ container["services"]["frontend"] }}
+ - PENPOT_REDIS_URI: redis://{{ container["services"]["redis"] }}/0
+ - ports:
+ - 80
+ - port_bindings:
+ - {{ container['app_port'] }}:80
+
+{% endfor %}
diff --git a/roles/paas-docker/containers/penpot_web.sls b/roles/paas-docker/containers/penpot_web.sls
new file mode 100644
--- /dev/null
+++ b/roles/paas-docker/containers/penpot_web.sls
@@ -0,0 +1,119 @@
+# -------------------------------------------------------------
+# Salt — Provision Penpot
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# -------------------------------------------------------------
+
+{% set has_selinux = salt["grains.get"]("selinux:enabled", False) %}
+{% set containers = pillar["docker_containers"] %}
+
+{% for instance, container in containers["penpot_web"].items() %}
+
+{% set flags = salt["convert.to_flags"](container["features"]) %}
+
+# -------------------------------------------------------------
+# Storage directory
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+/srv/{{ container["realm"] }}/assets:
+ file.directory:
+ - makedirs: True
+ - user: 1001
+ - group: 1001
+
+{% if has_selinux %}
+selinux_context_penpot_data:
+ selinux.fcontext_policy_present:
+ - name: /srv/{{ container["realm"] }}/assets
+ - sel_type: container_file_t
+
+selinux_context_penpot_data_applied:
+ selinux.fcontext_policy_applied:
+ - name: /srv/{{ container["realm"] }}/assets
+{% endif %}
+
+# -------------------------------------------------------------
+# Front-end assets
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+/srv/{{ container["realm"] }}/public:
+ file.directory:
+ - makedirs: True
+
+penpot_{{ container["realm"] }}_public_content:
+ cmd.run:
+ - name: |
+ wget https://artifacts.nasqueron.org/penpot/penpot.tar.gz && \
+ tar xzf penpot.tar.gz --strip 1 && \
+ rm penpot.tar.gz
+ - cwd: /srv/{{ container["realm"] }}/public
+ - creates: /srv/{{ container["realm"] }}/public/version.txt
+
+/srv/{{ container["realm"] }}/public/js/config.js:
+ file.managed:
+ - mode: 444
+ - contents: |
+ var penpotFlags = "{{ flags }}";
+
+{% if has_selinux %}
+selinux_context_penpot_public_data:
+ selinux.fcontext_policy_present:
+ - name: /srv/{{ container["realm"] }}/public
+ - sel_type: container_file_t
+
+selinux_context_penpot_public_data_applied:
+ selinux.fcontext_policy_applied:
+ - name: /srv/{{ container["realm"] }}/public
+{% endif %}
+
+# -------------------------------------------------------------
+# Container
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{{ instance }}:
+ docker_container.running:
+ - detach: True
+ - interactive: True
+ - image: penpotapp/backend
+ - networks:
+ - {{ container["network"] }}
+ - binds: /srv/{{ container["realm"] }}/assets:/opt/data/assets
+ - environment:
+ PENPOT_FLAGS: {{ flags }}
+ PENPOT_SECRET_KEY: {{ salt["credentials.get_password"](container["credentials"]["secret_key"]) }}
+
+ PENPOT_PREPL_HOST: 0.0.0.0
+ PENPOT_PUBLIC_URI: https://{{ container["host"] }}
+
+ PENPOT_DATABASE_URI: postgresql://{{ container["services"]["postgresql"] }}/penpot
+ PENPOT_DATABASE_USERNAME: {{ salt["credentials.get_username"](container["credentials"]["postgresql"]) }}
+ PENPOT_DATABASE_PASSWORD: {{ salt["credentials.get_password"](container["credentials"]["postgresql"]) }}
+
+ PENPOT_REDIS_URI: redis://{{ container["services"]["redis"] }}/0
+
+ PENPOT_ASSETS_STORAGE_BACKEND: assets-fs
+ PENPOT_STORAGE_ASSETS_FS_DIRECTORY: /opt/data/assets
+
+ # Our privacy policy explicitly states we don't transfer data
+ # to third parties.
+ PENPOT_TELEMETRY_ENABLED: "false"
+
+ {% if "smtp" in container["features"] %}
+ PENPOT_SMTP_HOST: {{ container["services"]["smtp"] }}
+ PENPOT_SMTP_PORT: 25
+ PENPOT_SMTP_TLS: "false"
+ {% endif %}
+ PENPOT_SMTP_DEFAULT_FROM: no-reply@{{ container["host"] }}
+ PENPOT_SMTP_DEFAULT_REPLY_TO: no-reply@{{ container["host"] }}
+
+ {% if "login-with-github" in container["features"] %}
+ PENPOT_GITHUB_CLIENT_ID: {{ salt["credentials.get_username"](container["credentials"]["github"]) }}
+ PENPOT_GITHUB_CLIENT_SECRET: {{ salt["credentials.get_password"](container["credentials"]["github"]) }}
+ {% endif %}
+ - ports:
+ - 6060
+ - port_bindings:
+ - {{ container['app_port'] }}:6060
+
+{% endfor %}
diff --git a/roles/paas-docker/containers/postgresql.sls b/roles/paas-docker/containers/postgresql.sls
--- a/roles/paas-docker/containers/postgresql.sls
+++ b/roles/paas-docker/containers/postgresql.sls
@@ -47,6 +47,15 @@
- environment:
POSTGRES_USER: {{ salt['credentials.get_username'](container['credential']) }}
POSTGRES_PASSWORD: {{ salt['credentials.get_password'](container['credential']) }}
+
+ {% if 'db' in container %}
+ POSTGRES_DB: {{ container['db'] }}
+ {% endif %}
+
+ {% if 'initdb_args' in container %}
+ POSTGRES_INITDB_ARGS: {{ container['initdb_args'] }}
+ {% endif %}
+
{% if 'network' in container %}
- networks:
- {{ container['network'] }}
diff --git a/roles/paas-docker/nginx/files/vhosts/penpot_web.conf b/roles/paas-docker/nginx/files/vhosts/penpot_web.conf
new file mode 100644
--- /dev/null
+++ b/roles/paas-docker/nginx/files/vhosts/penpot_web.conf
@@ -0,0 +1,106 @@
+# -------------------------------------------------------------
+# Configuration for Docker PaaS front-end nginx
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Source file: roles/paas-docker/nginx/files/vhosts/penpot_web.conf
+# -------------------------------------------------------------
+#
+# <auto-generated>
+# This file is managed by our rOPS SaltStack repository.
+#
+# Changes to this file may cause incorrect behavior
+# and will be lost if the state is redeployed.
+# </auto-generated>
+
+# -------------------------------------------------------------
+# Application - {{ fqdn }}
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name {{ fqdn }};
+
+ include includes/letsencrypt;
+
+ return 301 https://$host$request_uri;
+}
+
+server {
+ server_name {{ fqdn }};
+
+ include includes/tls;
+ ssl_certificate /srv/letsencrypt/etc/live/{{ fqdn }}/fullchain.pem;
+ ssl_certificate_key /srv/letsencrypt/etc/live/{{ fqdn }}/privkey.pem;
+
+ include includes/letsencrypt;
+
+ client_max_body_size 100M;
+ charset utf-8;
+
+ proxy_http_version 1.1;
+ proxy_set_header Host $http_host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Scheme $scheme;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+ etag off;
+
+ location @handle_redirect {
+ set $redirect_uri "$upstream_http_location";
+ set $redirect_host "$upstream_http_x_host";
+ set $redirect_cache_control "$upstream_http_cache_control";
+
+ proxy_buffering off;
+
+ proxy_set_header Host "$redirect_host";
+ proxy_hide_header etag;
+ proxy_pass $redirect_uri;
+
+ add_header x-internal-redirect "$redirect_uri";
+ add_header x-cache-control "$redirect_cache_control";
+ add_header cache-control "$redirect_cache_control";
+ }
+
+ location /assets {
+ proxy_pass http://localhost:{{ app_port }}/assets;
+ recursive_error_pages on;
+ proxy_intercept_errors on;
+ error_page 301 302 307 = @handle_redirect;
+ }
+
+ location /internal/assets {
+ internal;
+ alias /srv/{{ args["realm"] }}/assets;
+ add_header x-internal-redirect "$upstream_http_x_accel_redirect";
+ }
+
+ location /api/export {
+ proxy_pass {{ args["services"]["exporter"] }};
+ }
+
+ location /api {
+ proxy_pass http://localhost:{{ app_port }}/api;
+ }
+
+ location /ws/notifications {
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection 'upgrade';
+ proxy_pass http://localhost:{{ app_port }}/ws/notifications;
+ }
+
+ location / {
+ location ~* \.(js|css).*$ {
+ add_header Cache-Control "max-age=86400" always; # 24 hours
+ }
+
+ location ~* \.(html).*$ {
+ add_header Cache-Control "no-cache, max-age=0" always;
+ }
+ root /srv/{{ args["realm"] }}/public;
+ }
+
+ root /var/wwwroot-502/_default;
+ error_page 502 /502.html;
+ location /502.html {}
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 22, 16:13 (19 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2256304
Default Alt Text
D2597.id7577.diff (14 KB)

Event Timeline