games/factorio: add modproxy
This adds a mod proxy system, called, well, modproxy.
It sits between Factorio server instances and the Factorio mod portal,
allowing for arbitrary mod download without needing the servers to know
Factorio credentials.
Change-Id: I7bc405a25b6f9559cae1f23295249f186761f212
diff --git a/personal/q3k/factorio/kube/factorio.libsonnet b/personal/q3k/factorio/kube/factorio.libsonnet
index fc64aaa..4f2ff39 100644
--- a/personal/q3k/factorio/kube/factorio.libsonnet
+++ b/personal/q3k/factorio/kube/factorio.libsonnet
@@ -11,6 +11,7 @@
appName: "factorio",
storageClassName: "waw-hdd-redundant-2",
prefix: "", # if set, should be 'foo-'
+ proxyImage: error "proxyImage must be set",
rconPort: 2137,
rconPassword: "farts",
@@ -27,6 +28,8 @@
memory: "1Gi",
},
},
+
+ mods: [],
},
@@ -67,6 +70,16 @@
},
},
+ configMap: kube.ConfigMap(factorio.makeName("config")) {
+ metadata+: factorio.metadata,
+ data: {
+ "mods.pb.text": std.join("\n", [
+ "mod { name: \"%s\" version: \"%s\" }" % [m.name, m.version],
+ for m in cfg.mods
+ ]),
+ },
+ },
+
deployment: kube.Deployment(factorio.makeName("factorio")) {
metadata+: factorio.metadata,
spec+: {
@@ -76,6 +89,23 @@
volumes_: {
data: kube.PersistentVolumeClaimVolume(factorio.volumeClaimData),
mods: kube.PersistentVolumeClaimVolume(factorio.volumeClaimMods),
+ config: kube.ConfigMapVolume(factorio.configMap),
+ },
+ initContainers_: {
+ modproxy: kube.Container("modproxy") {
+ image: cfg.proxyImage,
+ command: [
+ "/games/factorio/modproxy/client",
+ "-hspki_disable",
+ "-factorio_path", "/factorio",
+ "-proxy", "proxy.factorio.svc.cluster.local:4200",
+ "-config_path", "/factorio/mods.pb.text",
+ ],
+ volumeMounts_: {
+ mods: { mountPath: "/factorio/mods" },
+ config: { mountPath: "/factorio/mods.pb.text", subPath: "mods.pb.text" },
+ },
+ },
},
containers_: {
factorio: kube.Container(factorio.makeName("factorio")) {
diff --git a/personal/q3k/factorio/kube/prod.jsonnet b/personal/q3k/factorio/kube/prod.jsonnet
index 7a8a060..27dd38d 100644
--- a/personal/q3k/factorio/kube/prod.jsonnet
+++ b/personal/q3k/factorio/kube/prod.jsonnet
@@ -9,15 +9,106 @@
{
local prod = self,
+ proxyImage:: "registry.k0.hswaw.net/games/factorio/modproxy:1589157915-eafe7be328477e8a6590c4210466ef12901f1b9a",
+
namespace: kube.Namespace("factorio"),
instance(name, tag):: factorio {
cfg+: {
namespace: "factorio",
prefix: name + "-",
tag: tag,
+ proxyImage: prod.proxyImage,
}
},
- q3k: prod.instance("q3k", "1.0.0-1"),
- pymods: prod.instance("pymods", "1.0.0-1"),
+ proxy: {
+ pvc: kube.PersistentVolumeClaim("proxy-cas") {
+ metadata+: {
+ namespace: "factorio",
+ },
+ spec+: {
+ storageClassName: "waw-hdd-redundant-3",
+ accessModes: [ "ReadWriteOnce" ],
+ resources: {
+ requests: {
+ storage: "32Gi",
+ },
+ },
+ },
+ },
+ deploy: kube.Deployment("proxy") {
+ metadata+: {
+ namespace: "factorio",
+ },
+ spec+: {
+ template+: {
+ spec+: {
+ volumes_: {
+ cas: kube.PersistentVolumeClaimVolume(prod.proxy.pvc),
+ },
+ containers_: {
+ proxy: kube.Container("proxy") {
+ image:prod.proxyImage,
+ command: [
+ "/games/factorio/modproxy/modproxy",
+ "-hspki_disable",
+ "-cas_directory", "/mnt/cas",
+ "-listen_address", "0.0.0.0:4200",
+ ],
+ volumeMounts_: {
+ cas: { mountPath: "/mnt/cas" },
+ },
+ ports_: {
+ client: { containerPort: 4200 },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ svc: kube.Service("proxy") {
+ metadata+: {
+ namespace: "factorio",
+ },
+ target_pod:: prod.proxy.deploy.spec.template,
+ spec+: {
+ ports: [
+ { name: "client", port: 4200, targetPort: 4200, protocol: "TCP" },
+ ],
+ },
+ },
+ },
+
+ local mod = function(name, version) { name: name, version: version },
+
+ q3k: prod.instance("q3k", "1.0.0-1") {
+ cfg+: {
+ mods: [
+ mod("Squeak Through", "1.8.0"),
+ mod("Bottleneck", "0.11.4"),
+ ],
+ },
+ },
+ pymods: prod.instance("pymods", "1.0.0-1") {
+ cfg+: {
+ mods: [
+ mod("Bottleneck", "0.11.4"),
+ mod("FARL", "4.0.2"),
+ mod("Squeak Through", "1.8.0"),
+ mod("pycoalprocessing", "1.8.3"),
+ mod("pycoalprocessinggraphics", "1.0.7"),
+ mod("pyfusionenergy", "1.6.3"),
+ mod("pyfusionenergygraphics", "1.0.5"),
+ mod("pyhightech", "1.6.2"),
+ mod("pyhightechgraphics", "1.0.8"),
+ mod("pyindustry", "1.4.7"),
+ mod("pyrawores", "2.1.5"),
+ mod("pyraworesgraphics", "1.0.4"),
+ mod("rso-mod", "6.0.11"),
+ mod("stdlib", "1.4.3"),
+ mod("what-is-it-really-used-for", "1.5.13"),
+ ],
+ },
+ },
}