app/matrix: appservice-irc
diff --git a/app/matrix/prod.jsonnet b/app/matrix/prod.jsonnet
index e392bfb..baa48e4 100644
--- a/app/matrix/prod.jsonnet
+++ b/app/matrix/prod.jsonnet
@@ -1,6 +1,7 @@
# matrix.hackerspace.pl, a matrix/synapse instance
# This needs a secret provisioned, create with:
# kubectl -n matrix create secret generic synapse --from-literal=postgres_password=$(pwgen 24 1)
+# kubectl -n matrix create secret generic appservice-irc-freenode-registration --from-file=registration.yaml=<(kubectl logs -n matrix $(kubectl get pods -n matrix --selector=job-name=appservice-irc-freenode-bootstrap --output=jsonpath='{.items[*].metadata.name}') | tail -n +4)
local kube = import "../../kube/kube.libsonnet";
local postgres = import "../../kube/postgres.libsonnet";
@@ -10,11 +11,12 @@
local cfg = app.cfg,
cfg:: {
namespace: "matrix",
- image: "matrixdotorg/synapse:v0.99.3.2",
- riotImage: "bubuntux/riot-web:v1.1.0",
domain: "matrix.hackerspace.pl",
serverName: "hackerspace.pl",
storageClassName: "waw-hdd-redundant-1",
+
+ synapseImage: "matrixdotorg/synapse:v0.99.4",
+ riotImage: "bubuntux/riot-web:v1.1.0",
},
metadata(component):: {
@@ -51,7 +53,7 @@
},
},
- deployment: kube.Deployment("synapse") {
+ synapseDeployment: kube.Deployment("synapse") {
metadata+: app.metadata("synapse"),
spec+: {
replicas: 1,
@@ -59,10 +61,13 @@
spec+: {
volumes_: {
data: kube.PersistentVolumeClaimVolume(app.dataVolume),
+ } + {
+ [k]: { secret: { secretName: "appservice-%s-registration" % [k] } }
+ for k in std.objectFields(app.appservices)
},
containers_: {
web: kube.Container("synapse") {
- image: cfg.image,
+ image: cfg.synapseImage,
ports_: {
http: { containerPort: 8008 },
},
@@ -80,6 +85,9 @@
},
volumeMounts_: {
data: { mountPath: "/data" },
+ } + {
+ [k]: { mountPath: "/appservices/%s" % [k] }
+ for k in std.objectFields(app.appservices)
},
},
},
@@ -88,9 +96,9 @@
},
},
- svc: kube.Service("synapse") {
+ synapseSvc: kube.Service("synapse") {
metadata+: app.metadata("synapse"),
- target_pod:: app.deployment.spec.template,
+ target_pod:: app.synapseDeployment.spec.template,
},
riotConfig: kube.ConfigMap("riot-web-config") {
@@ -138,7 +146,7 @@
config: kube.ConfigMapVolume(app.riotConfig),
},
containers_: {
- web: kube.Container("synapse") {
+ web: kube.Container("riot-web") {
image: cfg.riotImage,
ports_: {
http: { containerPort: 80 },
@@ -161,8 +169,22 @@
target_pod:: app.riotDeployment.spec.template,
},
- ingress: kube.Ingress("synapse") {
- metadata+: app.metadata("synapse") {
+ appservices: {
+ "irc-freenode": app.AppServiceIrc("freenode") {
+ cfg+: {
+ metadata: app.metadata("appservice-irc-freenode"),
+ config+: {
+ homeserver+: {
+ url: "https://%s" % [cfg.domain],
+ domain: "%s" % [cfg.serverName],
+ },
+ },
+ },
+ },
+ },
+
+ ingress: kube.Ingress("matrix") {
+ metadata+: app.metadata("matrix") {
annotations+: {
"kubernetes.io/tls-acme": "true",
"certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
@@ -182,11 +204,103 @@
http: {
paths: [
{ path: "/", backend: app.riotSvc.name_port },
- { path: "/_matrix", backend: app.svc.name_port },
+ { path: "/_matrix", backend: app.synapseSvc.name_port },
]
},
}
],
},
},
+
+ AppServiceIrc(name):: {
+ local bridge = self,
+ local cfg = bridge.cfg,
+ cfg:: {
+ image: "registry.k0.hswaw.net/informatic/matrix-appservice-irc:0.11.2",
+ metadata: {},
+ config: std.native("parseYaml")(importstr "appservice-irc.yaml")[0],
+ storageClassName: "waw-hdd-redundant-1",
+ },
+
+ config: kube.ConfigMap("appservice-irc-%s" % [name]) {
+ metadata+: cfg.metadata,
+ data: {
+ "config.yaml": std.manifestJsonEx(cfg.config, ""),
+ },
+ },
+
+ dataVolume: kube.PersistentVolumeClaim("appservice-irc-%s" % [name]) {
+ metadata+: cfg.metadata,
+ spec+: {
+ storageClassName: cfg.storageClassName,
+ accessModes: [ "ReadWriteOnce" ],
+ resources: {
+ requests: {
+ storage: "10Gi",
+ },
+ },
+ },
+ },
+
+ bootstrapJob: kube.Job("appservice-irc-%s-bootstrap" % [name]) {
+ metadata+: cfg.metadata {
+ labels: {
+ "job-name": "appservice-irc-%s-bootstrap" % [name],
+ },
+ },
+ spec+: {
+ template+: {
+ spec+: {
+ volumes_: {
+ config: kube.ConfigMapVolume(bridge.config),
+ },
+ containers_: {
+ bootstrap: kube.Container("appservice-irc-%s-bootstrap" % [name]) {
+ image: cfg.image,
+ command: ["sh", "-c", "matrix-appservice-irc -r -u http://appservice-irc-%s:9999 -c /config/config.yaml -f /tmp/registration.yaml && cat /tmp/registration.yaml" % [name]],
+ volumeMounts_: {
+ config: { mountPath: "/config" },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ deployment: kube.Deployment("appservice-irc-%s" % [name]) {
+ metadata+: cfg.metadata,
+ spec+: {
+ replicas: 1,
+ template+: {
+ spec+: {
+ volumes_: {
+ config: kube.ConfigMapVolume(bridge.config),
+ data: kube.PersistentVolumeClaimVolume(bridge.dataVolume),
+ registration: { secret: { secretName: "appservice-irc-%s-registration" % [name] } },
+ },
+ containers_: {
+ appserviceIrc: kube.Container("appservice-irc-%s" % [name]) {
+ image: cfg.image,
+ command: ["matrix-appservice-irc", "-c", "/config/config.yaml", "-f", "/registration/registration.yaml", "-p", "9999"],
+ ports_: {
+ http: { containerPort: 9999 },
+ },
+ volumeMounts_: {
+ registration: { mountPath: "/registration", },
+ config: { mountPath: "/config", },
+ data: { mountPath: "/data" },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ svc: kube.Service("appservice-irc-%s" % [name]) {
+ metadata+: cfg.metadata,
+ target_pod:: bridge.deployment.spec.template,
+ },
+ },
}