app/matrix: finish parametrization, fix running as non-root

This should allow us to run matrix on our default podsecuritypolicy.

Change-Id: I054f527ebab2f499e7a6595e618281a58c82e283
diff --git a/app/matrix/lib/matrix.libsonnet b/app/matrix/lib/matrix.libsonnet
index ed033bb..a881aaf 100644
--- a/app/matrix/lib/matrix.libsonnet
+++ b/app/matrix/lib/matrix.libsonnet
@@ -4,6 +4,17 @@
 #    kubectl -n $ns create secret generic synapse --from-literal=postgres_password=$(pwgen 24 1) --from-literal=macaroon_secret_key=$(pwgen 32 1) --from-literal=registration_shared_secret=$(pwgen 32 1)
 #    kubectl -n $ns create secret generic oauth2-cas-proxy --from-literal=oauth2_secret=...
 #
+# After starting, re-create the postgres database (because docker/postgres won't let you set ENCODING):
+#  postgres=# drop database synapse;
+#  DROP DATABASE
+#  postgres=# CREATE DATABASE synapse
+#  postgres-#  ENCODING 'UTF8'
+#  postgres-#  LC_COLLATE='C'
+#  postgres-#  LC_CTYPE='C'
+#  postgres-#  template=template0
+#  postgres-#  OWNER synapse;
+#  CREATE DATABASE
+#
 # Sequencing appservices is fun. The appservice needs to run first (for
 # instance, via a bootstrap job), and on startup it will spit out a
 # registration file.  This registration file then needs to be fed to synapse -
@@ -83,30 +94,31 @@
         },
     },
 
-    // homeserver.yaml that will be used to run synapse (in synapseConfig ConfigMap).
+    // homeserver.yaml that will be used to run synapse (in synapseConfigMap).
     // This is based off of //app/matrix/lib/synapse/homeserver.yaml with some fields overriden per
     // deployment.
     // Note this is a templated yaml - {{}}/{%%} style. This templatization is consumed by the Docker
     // container startup magic.
-    homeserverYaml:: (std.native("parseYaml"))(importstr "synapse/homeserver.yaml")[0] {
+    synapseConfig:: (std.native("parseYaml"))(importstr "synapse/homeserver.yaml")[0] {
         server_name: cfg.serverName,
         public_baseurl: "https://%s" % [cfg.webDomain],
         signing_key_path: "/data/%s.signing.key" % [cfg.serverName],
-        cas_config+: if cfg.cas.enable then {
+        app_service_config_files: [
+            "/appservices/%s/registration.yaml" % [k]
+            for k in std.objectFields(app.appservices)
+        ],
+    } + (if cfg.cas.enable then {
+        cas_config: {
             enabled: true,
             server_url: "https://%s/_cas" % [cfg.webDomain],
             service_url: "https://%s" % [cfg.webDomain],
-        } else {},
-        app_service_config_files: [
-            "/data/appservices/%s.yaml" % [k]
-            for k in std.objectFields(app.appservices)
-        ],
-    },
+        },
+    } else {}),
 
-    synapseConfig: kube.ConfigMap("synapse") {
+    synapseConfigMap: kube.ConfigMap("synapse") {
         metadata+: app.metadata("synapse"),
         data: {
-            "homeserver.yaml": std.manifestYamlDoc(app.homeserverYaml),
+            "homeserver.yaml": std.manifestYamlDoc(app.synapseConfig),
             "log.config": importstr "synapse/log.config",
         },
     },
@@ -149,7 +161,7 @@
                 spec+: {
                     volumes_: {
                         data: kube.PersistentVolumeClaimVolume(app.dataVolume),
-                        config_template: kube.ConfigMapVolume(app.synapseConfig),
+                        config: kube.ConfigMapVolume(app.synapseConfigMap),
                     } + {
                         [k]: { secret: { secretName: "appservice-%s-registration" % [k] } }
                         for k in std.objectFields(app.appservices)
@@ -163,8 +175,8 @@
                                 metrics: { containerPort: 9092 },
                             },
                             env_: {
-                                SYNAPSE_CONFIG_DIR: "/config",
-                                SYNAPSE_CONFIG_PATH: "/config/homeserver.yaml",
+                                SYNAPSE_CONFIG_DIR: "/tmp/config",
+                                SYNAPSE_CONFIG_PATH: "/tmp/config/homeserver.yaml",
 
                                 # These values are not used in a template, but
                                 # are required by /start.py migrate_config
@@ -177,16 +189,18 @@
                             },
                             volumeMounts_: {
                                 data: { mountPath: "/data" },
-                                config_template: {
-                                    mountPath: "/conf/homeserver.yaml",
-                                    subPath: "homeserver.yaml",
-                                },
+                                config: { mountPath: "/conf", },
                             } + {
                                 [k]: { mountPath: "/appservices/%s" % [k] }
                                 for k in std.objectFields(app.appservices)
                             },
                         },
                     },
+                    securityContext: {
+                        runAsUser: 991,
+                        runAsGroup: 991,
+                        fsGroup: 991,
+                    },
                 },
             },
         },
@@ -229,6 +243,50 @@
                     "https://matrix.org": false
                 }
             }, ""),
+            // Standard nginx.conf, made to work when running as unprivileged user.
+            "nginx.conf": |||
+                worker_processes  auto;
+                
+                error_log  /tmp/nginx_error.log warn;
+                pid        /tmp/nginx.pid;
+                
+                events {
+                    worker_connections  1024;
+                }
+                
+                
+                http {
+                    client_body_temp_path /tmp/nginx_client_temp;
+                    proxy_temp_path /tmp/nginx_proxy_temp;
+                    fastcgi_temp_path /tmp/nginx_fastcgi_temp;
+                    uwsgi_temp_path /tmp/nginx_uwsgi_temp;
+                    scgi_temp_path /tmp/nginx_scgi_temp;
+
+                    include       /etc/nginx/mime.types;
+                    default_type  application/octet-stream;
+                    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                                      '$status $body_bytes_sent "$http_referer" '
+                                      '"$http_user_agent" "$http_x_forwarded_for"';
+                    access_log  /tmp/nginx_access.log  main;
+                    sendfile        on;
+                    keepalive_timeout  65;
+                    
+                    server {
+                        listen       8080;
+                        server_name  localhost;
+                    
+                        location / {
+                            root   /usr/share/nginx/html;
+                            index  index.html index.htm;
+                        }
+                    
+                        error_page   500 502 503 504  /50x.html;
+                        location = /50x.html {
+                            root   /usr/share/nginx/html;
+                        }
+                    }
+                }
+            |||,
         },
     },
 
@@ -245,16 +303,27 @@
                         web: kube.Container("riot-web") {
                             image: cfg.images.riot,
                             ports_: {
-                                http: { containerPort: 80 },
+                                http: { containerPort: 8080 },
                             },
-                            volumeMounts_: {
-                                config: {
+                            volumeMounts: [
+                                {
+                                    name: "config",
                                     mountPath: "/app/config.json",
                                     subPath: "config.json",
                                 },
-                            },
+                                {
+                                    name: "config",
+                                    mountPath: "/etc/nginx/nginx.conf",
+                                    subPath: "nginx.conf",
+                                },
+                            ],
                         },
                     },
+                    securityContext: {
+                        // nginx:nginx
+                        runAsUser: 101,
+                        runAsGroup: 101,
+                    },
                 },
             },
         },
diff --git a/app/matrix/lib/synapse/homeserver.yaml b/app/matrix/lib/synapse/homeserver.yaml
index 2c39c23..05c4d00 100644
--- a/app/matrix/lib/synapse/homeserver.yaml
+++ b/app/matrix/lib/synapse/homeserver.yaml
@@ -7,7 +7,7 @@
 pid_file: /homeserver.pid

 web_client: False

 soft_file_limit: 0

-log_config: "/config/log.config"

+log_config: "/conf/log.config"

 

 ## Ports ##

 

@@ -137,5 +137,3 @@
 password_config:

    enabled: false

 

-cas_config:

-  enabled: false