app/matrix: matrix-media-repo RGW-based media storage

Change-Id: I459bd78eee52fd349a16f31a48346d3258ef50a4
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1081
Reviewed-by: q3k <q3k@hackerspace.pl>
diff --git a/app/matrix/lib/media-repo.libsonnet b/app/matrix/lib/media-repo.libsonnet
new file mode 100644
index 0000000..338dc78
--- /dev/null
+++ b/app/matrix/lib/media-repo.libsonnet
@@ -0,0 +1,97 @@
+local kube = import "../../../kube/kube.libsonnet";
+
+{
+    local app = self,
+    local cfg = app.cfg,
+    cfg:: {
+        image: error "cfg.image needs to be set",
+
+        homeservers: [],
+        admins: [],
+
+        s3: {
+            endpoint: error "cfg.s3.endpoint needs to be set",
+            accessKey: error "cfg.s3.accessKey needs to be set",
+            secretKey: error "cfg.s3.secretKey needs to be set",
+            bucketName: error "cfg.s3.bucketName needs to be set",
+            region: error "cfg.s3.region needs to be set",
+        },
+
+        db: {
+            username: error "cfg.db.username needs to be set",
+            password: error "cfg.db.password needs to be set",
+            database: error "cfg.db.database needs to be set",
+            host: error "cfg.db.host needs to be set",
+        },
+    },
+
+    ns:: error "ns needs to be a kube.Namespace object",
+
+    config:: {
+        repo: {
+            bindAddress: "0.0.0.0",
+            port: 8000,
+        },
+        database: {
+            postgres: "postgres://%s:%s@%s/%s?sslmode=disable" % [cfg.db.username, cfg.db.password, cfg.db.host, cfg.db.database],
+        },
+        homeservers: cfg.homeservers,
+        admins: cfg.admins,
+        datastores: [
+            {
+                type: "s3",
+                enabled: true,
+                forKinds: ["all"],
+                opts: {
+                    tempPath: "/tmp/mediarepo_s3_upload",
+                    endpoint: cfg.s3.endpoint,
+                    accessKeyId: cfg.s3.accessKey,
+                    accessSecret: cfg.s3.secretKey,
+                    ssl: false,
+                    bucketName: cfg.s3.bucketName,
+                    region: cfg.s3.region,
+                },
+            }
+        ],
+    },
+
+    configSecret: app.ns.Contain(kube.Secret("media-repo-config")) {
+        data_: {
+            "config.yaml": std.manifestJsonEx(app.config, ""),
+        },
+    },
+
+    deployment: app.ns.Contain(kube.Deployment("media-repo")) {
+        spec+: {
+            replicas: 1,
+            template+: {
+                spec+: {
+                    volumes_: {
+                        config: kube.SecretVolume(app.configSecret),
+                        tempdir: kube.EmptyDirVolume(),
+                    },
+                    containers_: {
+                        repo: kube.Container("media-repo") {
+                            image: cfg.image,
+                            command: ["/usr/local/bin/media_repo"],
+                            ports_: {
+                                http: { containerPort: 8000 },
+                            },
+                            env_: {
+                                REPO_CONFIG: "/config",
+                            },
+                            volumeMounts_: {
+                                config: { mountPath: "/config" },
+                                tempdir: { mountPath: "/tmp/mediarepo_s3_upload" },
+                            },
+                        },
+                    },
+                },
+            },
+        },
+    },
+
+    svc: app.ns.Contain(kube.Service("media-repo")) {
+        target_pod:: app.deployment.spec.template,
+    },
+}