matrix: use resource renderer
diff --git a/apps/matrix/capture-config/.gitignore b/apps/capture-config/.gitignore
similarity index 100%
rename from apps/matrix/capture-config/.gitignore
rename to apps/capture-config/.gitignore
diff --git a/apps/capture-config/Dockerfile b/apps/capture-config/Dockerfile
new file mode 100644
index 0000000..d5b4767
--- /dev/null
+++ b/apps/capture-config/Dockerfile
@@ -0,0 +1,4 @@
+FROM gcr.io/distroless/static:nonroot
+ARG TARGETARCH
+
+COPY capture-config_${TARGETARCH} /capture-config
diff --git a/apps/capture-config/Makefile b/apps/capture-config/Makefile
new file mode 100644
index 0000000..a5e3014
--- /dev/null
+++ b/apps/capture-config/Makefile
@@ -0,0 +1,29 @@
+clean:
+	rm -f capture-config_*
+
+build_arm64: export CGO_ENABLED=0
+build_arm64: export GO111MODULE=on
+build_arm64: export GOOS=linux
+build_arm64: export GOARCH=arm64
+build_arm64:
+	go build -o capture-config_arm64 *.go
+
+build_amd64: export CGO_ENABLED=0
+build_amd64: export GO111MODULE=on
+build_amd64: export GOOS=linux
+build_amd64: export GOARCH=amd64
+build_amd64:
+	go build -o capture-config_amd64 *.go
+
+push_arm64: clean build_arm64
+	podman build --platform linux/arm64 --tag=giolekva/capture-config:arm64 .
+	podman push giolekva/capture-config:arm64
+
+push_amd64: clean build_amd64
+	podman build --platform linux/amd64 --tag=giolekva/capture-config:amd64 .
+	podman push giolekva/capture-config:amd64
+
+push: push_arm64 push_amd64
+	podman manifest create giolekva/capture-config:latest giolekva/capture-config:arm64 giolekva/capture-config:amd64
+	podman manifest push giolekva/capture-config:latest docker://docker.io/giolekva/capture-config:latest
+	podman manifest rm giolekva/capture-config:latest
diff --git a/apps/matrix/capture-config/go.mod b/apps/capture-config/go.mod
similarity index 100%
rename from apps/matrix/capture-config/go.mod
rename to apps/capture-config/go.mod
diff --git a/apps/matrix/capture-config/go.sum b/apps/capture-config/go.sum
similarity index 100%
rename from apps/matrix/capture-config/go.sum
rename to apps/capture-config/go.sum
diff --git a/apps/matrix/capture-config/main.go b/apps/capture-config/main.go
similarity index 66%
rename from apps/matrix/capture-config/main.go
rename to apps/capture-config/main.go
index 08d7be2..73b94d6 100644
--- a/apps/matrix/capture-config/main.go
+++ b/apps/capture-config/main.go
@@ -3,6 +3,7 @@
 import (
 	"context"
 	"flag"
+	"fmt"
 	"io/ioutil"
 	"path"
 
@@ -14,9 +15,8 @@
 	"github.com/miracl/conflate"
 )
 
-var configFile = flag.String("config", "", "Path to the homeserver.yaml config file.")
-var configToMerge = flag.String("config-to-merge", "", "Name of the configmap to merge with generated one.")
-var toMergeFilename = flag.String("to-merge-filename", "", "Name of the file from config to merge.")
+var baseFile = flag.String("base", "", "Path to the homeserver.yaml config file.")
+var mergeWith = flag.String("merge-with", "", "Name of the file from config to merge.")
 var namespace = flag.String("namespace", "", "Namespace name.")
 var configMapName = flag.String("config-map-name", "", "Name of the ConfigMap to create.")
 
@@ -32,7 +32,7 @@
 	return cs
 }
 
-func createConfig(data []byte) *v1.ConfigMap {
+func newConig(data []byte) *v1.ConfigMap {
 	return &v1.ConfigMap{
 		TypeMeta: metav1.TypeMeta{
 			Kind:       "ConfigMap",
@@ -42,7 +42,7 @@
 			Name: *configMapName,
 		},
 		Data: map[string]string{
-			path.Base(*configFile): string(data),
+			path.Base(*baseFile): string(data),
 		},
 	}
 }
@@ -51,25 +51,28 @@
 	flag.Parse()
 	client := createClient().CoreV1().ConfigMaps(*namespace)
 	conf := conflate.New()
-	generated, err := ioutil.ReadFile(*configFile)
+	generated, err := ioutil.ReadFile(*baseFile)
 	if err != nil {
 		panic(err)
 	}
+	fmt.Printf("--- BASE:\n%s\n", string(generated))
 	if err := conf.AddData(generated); err != nil {
 		panic(err)
 	}
-	toMerge, err := client.Get(context.TODO(), *configToMerge, metav1.GetOptions{})
+	mergeWith, err := ioutil.ReadFile(*mergeWith)
 	if err != nil {
 		panic(err)
 	}
-	if err := conf.AddData([]byte(toMerge.Data[*toMergeFilename])); err != nil {
+	fmt.Printf("--- MERGE WITH:\n%s\n", string(mergeWith))
+	if err := conf.AddData(mergeWith); err != nil {
 		panic(err)
 	}
 	merged, err := conf.MarshalYAML()
 	if err != nil {
 		panic(err)
 	}
-	config := createConfig(merged)
+	fmt.Printf("--- MERGED:\n%s\n", string(merged))
+	config := newConig(merged)
 	if _, err := client.Create(context.TODO(), config, metav1.CreateOptions{}); err != nil {
 		panic(err)
 	}
diff --git a/apps/matrix/capture-config/Dockerfile b/apps/matrix/capture-config/Dockerfile
deleted file mode 100644
index bcecf7b..0000000
--- a/apps/matrix/capture-config/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-FROM alpine:latest
-
-ARG TARGETARCH
-
-COPY capture-config_${TARGETARCH} /usr/bin/capture-config
-RUN chmod +x /usr/bin/capture-config
diff --git a/apps/matrix/capture-config/Makefile b/apps/matrix/capture-config/Makefile
deleted file mode 100644
index c05687d..0000000
--- a/apps/matrix/capture-config/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-clean:
-	rm -f capture-config_*
-
-build_arm64: export CGO_ENABLED=0
-build_arm64: export GO111MODULE=on
-build_arm64: export GOOS=linux
-build_arm64: export GOARCH=arm64
-build_arm64:
-	go build -o capture-config_arm64 *.go
-
-build_amd64: export CGO_ENABLED=0
-build_amd64: export GO111MODULE=on
-build_amd64: export GOOS=linux
-build_amd64: export GOARCH=amd64
-build_amd64:
-	go build -o capture-config_amd64 *.go
-
-build: clean build_arm64 build_amd64
-
-push: build
-	docker buildx build --tag=giolekva/capture-config:latest . --platform=linux/arm64,linux/amd64 --push
diff --git a/charts/matrix/templates/_helpers.tpl b/charts/matrix/templates/_helpers.tpl
deleted file mode 100644
index 063b2b4..0000000
--- a/charts/matrix/templates/_helpers.tpl
+++ /dev/null
@@ -1,7 +0,0 @@
-{{- define "clientSecret" -}}
-{{- if .Values.oauth2.clientSecret -}}
-{{- .Values.oauth2.clientSecret -}}
-{{- else -}}
-{{- randAlphaNum 32 -}}
-{{- end -}}
-{{- end -}}
diff --git a/charts/matrix/templates/config-to-merge.yaml b/charts/matrix/templates/config-to-merge.yaml
index f74f0c0..72f9af2 100644
--- a/charts/matrix/templates/config-to-merge.yaml
+++ b/charts/matrix/templates/config-to-merge.yaml
@@ -1,51 +1,44 @@
-{{- $secret := include "clientSecret" . -}}
----
-apiVersion: v1
-kind: Secret
-type: Opaque
+apiVersion: dodo.cloud.dodo.cloud/v1
+kind: ResourceRenderer
 metadata:
-  name: {{ .Values.oauth2.secretName }}
+  name: config-renderer
   namespace: {{ .Release.Namespace }}
   annotations:
     helm.sh/hook: pre-install
     helm.sh/hook-weight: "-10"
-data:
-  client_id: {{ .Values.oauth2.clientId | b64enc  }}
-  client_secret: {{ $secret | b64enc }}
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Values.configMerge.configName }}
-  namespace: {{ .Release.Namespace }}
-  annotations:
-    helm.sh/hook: pre-install
-    helm.sh/hook-weight: "-10"
-data:
-  {{ .Values.configMerge.fileName }}: |
-    public_baseurl: https://matrix.{{ .Values.domain }}/
-    enable_registration: false
-    database:
-     name: psycopg2
-     txn_limit: 10000
-     args:
-       host: {{ .Values.postgresql.host }}
-       port: {{ .Values.postgresql.port }}
-       database: {{ .Values.postgresql.database }}
-       user: {{ .Values.postgresql.user }}
-       password: {{ .Values.postgresql.password }}
-       cp_min: 5
-       cp_max: 10
-    oidc_providers:
-      - idp_id: pcloud
-        idp_name: "PCloud"
-        skip_verification: true
-        issuer: {{ .Values.oauth2.hydraPublic }}
-        client_id: {{ .Values.oauth2.clientId }}
-        client_secret: {{ $secret }}
-        scopes: ["openid", "profile"]
-        allow_existing_users: true
-        user_mapping_provider:
-          config:
-            localpart_template: {{`"{{ user.username }}"`}}
-            display_name_template: "{{`{{ user.username }}"`}}
+spec:
+  secretName: {{ .Values.oauth2.secretName }}
+  resourceTemplate: |
+    apiVersion: v1
+    kind: ConfigMap
+    metadata:
+      name: {{ .Values.configMerge.configName }}
+      namespace: {{ .Release.Namespace }}
+    data:
+      {{ .Values.configMerge.fileName }}: |
+        public_baseurl: https://{{ .Values.subdomain }}.{{ .Values.domain }}/
+        enable_registration: false
+        database:
+         name: psycopg2
+         txn_limit: 10000
+         args:
+           host: {{ .Values.postgresql.host }}
+           port: {{ .Values.postgresql.port }}
+           database: {{ .Values.postgresql.database }}
+           user: {{ .Values.postgresql.user }}
+           password: {{ .Values.postgresql.password }}
+           cp_min: 5
+           cp_max: 10
+        oidc_providers:
+          - idp_id: pcloud
+            idp_name: "PCloud"
+            skip_verification: true
+            issuer: {{ .Values.oauth2.hydraPublic }}
+            client_id: "{{`{{ .client_id }}`}}"
+            client_secret: "{{`{{ .client_secret }}`}}"
+            scopes: ["openid", "profile"]
+            allow_existing_users: true
+            user_mapping_provider:
+              config:
+                localpart_template: {{ cat "{{`" `{{ "{{" }} user.username {{ "}}" }}` "`}}" | squote }}
+                display_name_template: {{ cat "{{`" `{{ "{{" }} user.username {{ "}}" }}` "`}}" | squote }}
diff --git a/charts/matrix/templates/matrix.yaml b/charts/matrix/templates/matrix.yaml
index e400d33..e46667e 100644
--- a/charts/matrix/templates/matrix.yaml
+++ b/charts/matrix/templates/matrix.yaml
@@ -12,7 +12,6 @@
   resources:
   - configmaps
   verbs:
-  - get
   - create
 ---
 apiVersion: rbac.authorization.k8s.io/v1
@@ -47,34 +46,24 @@
     targetPort: http
     protocol: TCP
 ---
-apiVersion: cert-manager.io/v1
-kind: Certificate
-metadata:
-  name: matrix.{{ .Values.domain }}
-  namespace: {{ .Release.Namespace }}
-  annotations:
-    helm.sh/resource-policy: keep
-spec:
-  dnsNames:
-  - 'matrix.{{ .Values.domain }}'
-  issuerRef:
-    name: {{ .Values.certificateIssuer }}
-    kind: ClusterIssuer
-  secretName: cert-matrix.{{ .Values.domain }}
----
 apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: ingress
   namespace: {{ .Release.Namespace }}
+  {{- if .Values.certificateIssuer }}
+  annotations:
+    acme.cert-manager.io/http01-edit-in-place: "true"
+    cert-manager.io/cluster-issuer: {{ .Values.certificateIssuer }}
+  {{- end }}
 spec:
   ingressClassName: {{ .Values.ingressClassName }}
   tls:
   - hosts:
-    - matrix.{{ .Values.domain }}
-    secretName: cert-matrix.{{ .Values.domain }}
+    - {{ .Values.subdomain }}.{{ .Values.domain }}
+    secretName: cert-{{ .Values.subdomain }}.{{ .Values.domain }}
   rules:
-  - host: matrix.{{ .Values.domain }}
+  - host: {{ .Values.subdomain }}.{{ .Values.domain }}
     http:
       paths:
       - path: /
@@ -104,6 +93,9 @@
       - name: data
         persistentVolumeClaim:
           claimName: data
+      - name: config
+        configMap:
+          name: {{ .Values.configMerge.configName }}
       initContainers:
       - name: matrix
         image: matrixdotorg/synapse:v1.43.0
@@ -134,15 +126,16 @@
         image: giolekva/capture-config:latest
         imagePullPolicy: Always
         command:
-        - capture-config
-        - --config=/data/homeserver.yaml
+        - /capture-config
+        - --base=/data/homeserver.yaml
+        - --merge-with=/config-to-merge/{{ .Values.configMerge.fileName }}
         - --namespace={{ .Release.Namespace }}
         - --config-map-name=config
-        - --config-to-merge={{ .Values.configMerge.configName }}
-        - --to-merge-filename={{ .Values.configMerge.fileName }}
         volumeMounts:
         - name: data
           mountPath: /data
+        - name: config
+          mountPath: /config-to-merge
 ---
 apiVersion: apps/v1
 kind: Deployment
diff --git a/charts/matrix/templates/oauth2-client.yaml b/charts/matrix/templates/oauth2-client.yaml
index 2a23c4f..ffe6936 100644
--- a/charts/matrix/templates/oauth2-client.yaml
+++ b/charts/matrix/templates/oauth2-client.yaml
@@ -3,6 +3,9 @@
 metadata:
   name: matrix
   namespace: {{ .Release.Namespace }}
+  annotations:
+    helm.sh/hook: pre-install
+    helm.sh/hook-weight: "-10"
 spec:
   grantTypes:
   - authorization_code
@@ -11,9 +14,9 @@
   scope: "openid profile"
   secretName: {{ .Values.oauth2.secretName }}
   redirectUris:
-  - https://matrix.{{ .Values.domain }}/_synapse/client/oidc/callback
+  - https://{{ .Values.subdomain }}.{{ .Values.domain }}/_synapse/client/oidc/callback
   hydraAdmin:
     url: {{ .Values.oauth2.hydraAdmin }}
     port: 80
-    endpoint: /clients
+    endpoint: /admin/clients
     forwardedProto: https
diff --git a/charts/matrix/templates/well-known.yaml b/charts/matrix/templates/well-known.yaml
index cd235cd..ee2d41b 100644
--- a/charts/matrix/templates/well-known.yaml
+++ b/charts/matrix/templates/well-known.yaml
@@ -19,6 +19,11 @@
 metadata:
   name: well-known
   namespace: {{ .Release.Namespace }}
+  {{- if .Values.certificateIssuer }}
+  annotations:
+    acme.cert-manager.io/http01-edit-in-place: "true"
+    cert-manager.io/cluster-issuer: {{ .Values.certificateIssuer }}
+  {{- end }}
 spec:
   ingressClassName: {{ .Values.ingressClassName }}
   tls:
@@ -69,12 +74,12 @@
         server {
             listen 8080;
             location /.well-known/matrix/client {
-                return 200 '{"m.homeserver": {"base_url": "https://matrix.{{ .Values.domain }}:443"}}';
+                return 200 '{"m.homeserver": {"base_url": "https://{{ .Values.subdomain }}.{{ .Values.domain }}:443"}}';
                 default_type application/json;
                 add_header Access-Control-Allow-Origin *;
             }
             location /.well-known/matrix/server {
-                return 200 '{"m.server": "matrix.{{ .Values.domain }}:443"}';
+                return 200 '{"m.server": {{ .Values.subdomain }}.{{ .Values.domain }}:443"}';
                 default_type application/json;
                 add_header Access-Control-Allow-Origin *;
             }
diff --git a/charts/matrix/values.yaml b/charts/matrix/values.yaml
index 7add503..ba7bd9e 100644
--- a/charts/matrix/values.yaml
+++ b/charts/matrix/values.yaml
@@ -1,9 +1,8 @@
 domain: example.com
+subdomain: matrix
 oauth2:
   hydraAdmin: http://hydra-admin
   hydraPublic: https://hydra.example.com
-  clientId: matrix
-  clientSecret: ""
   secretName: oauth2-client
 postgresql:
   host: postgresql
diff --git a/core/installer/values-tmpl/matrix-storage.yaml b/core/installer/values-tmpl/matrix-storage.yaml
index 47ee9c0..7a4c129 100644
--- a/core/installer/values-tmpl/matrix-storage.yaml
+++ b/core/installer/values-tmpl/matrix-storage.yaml
@@ -6,34 +6,34 @@
 spec:
   chart:
     spec:
-      chart: postgresql
-      version: 10.13.5
+      chart: charts/postgresql
       sourceRef:
-        kind: HelmRepository
-        name: bitnami
-        namespace: {{ .Values.Id }}
+        kind: GitRepository
+        name: pcloud
+        namespace: {{ .Global.Id }}
   interval: 1m0s
   values:
     fullnameOverride: postgres
     image:
-      repository: arm64v8/postgres
-      tag: 13.4
+      repository: library/postgres # arm64v8/postgres
+      tag: 15.3 # 13.4
     service:
       type: ClusterIP
       port: 5432
-    postgresqlPassword: psswd
-    initdbScripts:
-      createdb.sh: |
-        #!/bin/sh
-        createdb -U postgres --encoding=UTF8 --locale=C --template=template0 --owner=postgres matrix
-    persistence:
-      size: {{ .Values.MatrixStorageSize }}
-    securityContext:
-      enabled: true
-      fsGroup: 0
-    containerSecurityContext:
-      enabled: true
-      runAsUser: 0
+    primary:
+      initdb:
+        scripts:
+          init.sql: |
+            CREATE USER matrix WITH PASSWORD 'matrix';
+            CREATE DATABASE matrix WITH OWNER = matrix ENCODING = UTF8 LOCALE = C TEMPLATE = template0;
+      persistence:
+        size: 10Gi
+      securityContext:
+        enabled: true
+        fsGroup: 0
+      containerSecurityContext:
+        enabled: true
+        runAsUser: 0
     volumePermissions:
       securityContext:
         runAsUser: 0
diff --git a/core/installer/values-tmpl/matrix.jsonschema b/core/installer/values-tmpl/matrix.jsonschema
index ec6a2c5..89f64ce 100644
--- a/core/installer/values-tmpl/matrix.jsonschema
+++ b/core/installer/values-tmpl/matrix.jsonschema
@@ -1,15 +1,7 @@
 {
   "type": "object",
   "properties": {
-    "Values": {
-      "type": "object",
-      "properties": {
-        "NamespacePrefix": { "type": "string" },
-        "Id": { "type": "string" },
-        "Domain": { "type": "string" }
-      },
-      "additionalProperties": false
-    }
+	"Subdomain": { "type": "string", "default": "matrix" }
   },
   "additionalProperties": false
 }
diff --git a/core/installer/values-tmpl/matrix.yaml b/core/installer/values-tmpl/matrix.yaml
index d3e3a03..da459dc 100644
--- a/core/installer/values-tmpl/matrix.yaml
+++ b/core/installer/values-tmpl/matrix.yaml
@@ -17,18 +17,17 @@
   interval: 1m0s
   values:
     domain: {{ .Global.Domain }}
+    subdomain: {{ .Values.Subdomain }}
     oauth2:
       hydraAdmin: http://hydra-admin.{{ .Global.NamespacePrefix }}core-auth.svc.cluster.local
       hydraPublic: https://hydra.{{ .Global.Domain }}
-      clientId: matrix
-      clientSecret: {{ .Values.MatrixOAuth2ClientSecret }}
       secretName: oauth2-client
     postgresql:
       host: postgres
       port: 5432
       database: matrix
-      user: postgres
-      password: psswd
+      user: matrix
+      password: matrix
     certificateIssuer: {{ .Global.Id }}-public
     ingressClassName: {{ .Global.PCloudEnvName }}-ingress-public
     configMerge: