matrix: refactor synapse into library
This is in prepration for bringing up a Matrix server for hsp.sh.
Verified to cause no diff on prod.
Change-Id: Ied2de210692e3ddfdb1d3f37b12893b214c34b0b
diff --git a/app/matrix/lib/appservice-telegram.libsonnet b/app/matrix/lib/appservice-telegram.libsonnet
new file mode 100644
index 0000000..fd2a9a0
--- /dev/null
+++ b/app/matrix/lib/appservice-telegram.libsonnet
@@ -0,0 +1,157 @@
+local kube = import "../../../kube/kube.libsonnet";
+
+{
+ AppServiceTelegram(name):: {
+ local bridge = self,
+ local cfg = bridge.cfg,
+ cfg:: {
+ metadata: {},
+ image: error "image must be set",
+ storageClassName: error "storageClassName must be set",
+
+ // Data that will be serialized into the appservice's config.yaml.
+ // This is taken straight from a YAML that was generated by
+ // dock.mau.dev/tulir/mautrix-telegram:v0.8.2. We override here
+ // fields that we know are strictly necessary to be configured when
+ // instantiating this template.
+ config: (std.native("parseYaml")(importstr "appservice/appservice-telegram.yaml")[0]) + {
+ homeserver+: {
+ address: error "homeserver.address must be set",
+ domain: error "homeserver.domain must be set",
+ },
+ appservice+: {
+ address: bridge.svc.http_url,
+ // We disable this. I have no idea what it does, but it
+ // wants a secret. ~q3k
+ provisioning+: {
+ enabled: false,
+ shared_secret: if self.enabled then error "appservice.provisioning.shared_secret must be set" else "hackme",
+ },
+ id: error "appservice.id must be set",
+ as_token: "This value is generated when generating the registration",
+ hs_token: "This value is generated when generating the registration",
+ },
+ telegram+: {
+ api_id: error "telegram.api_id must be set",
+ api_hash: error "telegram.api_hash must be set",
+ bot_token: error "telegram.bot_token must be set",
+ },
+ bridge+: {
+ permissions: {
+ '*': "relaybot",
+ },
+ },
+ },
+ },
+
+ config: kube.Secret("appservice-telegram-%s" % [name]) {
+ metadata+: cfg.metadata,
+ data: {
+ "config.yaml": std.base64(std.manifestYamlDoc(cfg.config)),
+ },
+ },
+
+ dataVolume: kube.PersistentVolumeClaim("appservice-telegram-%s" % [name]) {
+ metadata+: cfg.metadata,
+ spec+: {
+ storageClassName: cfg.storageClassName,
+ accessModes: [ "ReadWriteOnce" ],
+ resources: {
+ requests: {
+ storage: "10Gi",
+ },
+ },
+ },
+ },
+
+ bootstrapJob: kube.Job("appservice-telegram-%s-bootstrap" % [name]) {
+ metadata+: cfg.metadata {
+ labels: {
+ "job-name": "appservice-telegram-%s-bootstrap" % [name],
+ },
+ },
+ spec+: {
+ template+: {
+ spec+: {
+ volumes_: {
+ config: kube.SecretVolume(bridge.config),
+ },
+ containers_: {
+ bootstrap: kube.Container("appservice-telegram-%s-bootstrap" % [name]) {
+ image: cfg.image,
+ command: [
+ "sh", "-c",
+ "python3 -m mautrix_telegram -g -c /config/config.yaml -r /tmp/registration.yaml && echo SNIPSNIP && cat /tmp/registration.yaml",
+ ],
+ volumeMounts_: {
+ config: { mountPath: "/config" },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ deployment: kube.Deployment("appservice-telegram-%s" % [name]) {
+ metadata+: cfg.metadata,
+ spec+: {
+ replicas: 1,
+ template+: {
+ spec+: {
+ volumes_: {
+ config: kube.SecretVolume(bridge.config),
+ data: kube.PersistentVolumeClaimVolume(bridge.dataVolume),
+ registration: { secret: { secretName: "appservice-telegram-%s-registration" % [name] } },
+ },
+ initContainers: [
+ // This container takes the stateless config from the Secret, and
+ // updates it with the registration secrets from the registration token.
+ kube.Container("generate-config") {
+ volumeMounts_: {
+ config: { mountPath: "/config", },
+ registration: { mountPath: "/registration", },
+ data: { mountPath: "/data" },
+ },
+ // Ow, the edge! We need yq.
+ // See: https://github.com/mikefarah/yq/issues/190#issuecomment-667519015
+ image: "alpine@sha256:156f59dc1cbe233827642e09ed06e259ef6fa1ca9b2e29d52ae14d5e7b79d7f0",
+ command: [
+ "sh", "-c", |||
+ set -e -x
+ apk add --no-cache yq
+ cp /config/config.yaml /data/config.yaml
+ yq w -i /data/config.yaml appservice.as_token $(yq r /registration/registration.yaml as_token)
+ yq w -i /data/config.yaml appservice.hs_token $(yq r /registration/registration.yaml hs_token)
+ |||
+ ],
+ },
+ ],
+ containers_: {
+ appserviceIrc: kube.Container("appservice-telegram-%s" % [name]) {
+ image: cfg.image,
+ command: [
+ "sh", "-c", |||
+ alembic -x config=/data/config.yaml upgrade head
+ python3 -m mautrix_telegram -n -c /data/config.yaml
+ |||
+ ],
+ ports_: {
+ http: { containerPort: 29317 },
+ },
+ volumeMounts_: {
+ data: { mountPath: "/data" },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ svc: kube.Service("appservice-telegram-%s" % [name]) {
+ metadata+: cfg.metadata,
+ target_pod:: bridge.deployment.spec.template,
+ },
+ },
+}