diff --git a/games/valheim/README.md b/games/valheim/README.md new file mode 100644 index 00000000..cf02ce53 --- /dev/null +++ b/games/valheim/README.md @@ -0,0 +1,10 @@ +Valheim +======= + +This is our (tiny) Valheim game server infrastructure. We run it on prod on k0, using an existing Docker image. + +Updating +-------- + + kubecfg update prod.jsonnet + diff --git a/games/valheim/prod.jsonnet b/games/valheim/prod.jsonnet new file mode 100644 index 00000000..6c10b8b0 --- /dev/null +++ b/games/valheim/prod.jsonnet @@ -0,0 +1,168 @@ +local kube = import "../../kube/kube.libsonnet"; + +{ + local top = self, + env(ns, name):: { + local env = self, + local cfg = env.cfg, + cfg:: { + name: name, + displayName: name, + image: "mbround18/valheim:latest", + password: error "password must be set", + storageClassName: "waw-hdd-redundant-3", + port: 2456, + }, + + local named = function(component) "%s-%s" % [name, component], + + game: { + local game = self, + pvcs: { + backups: ns.Contain(kube.PersistentVolumeClaim(named("backups"))) { + spec+: { + storageClassName: cfg.storageClassName, + accessModes: ["ReadWriteOnce"], + resources: { + requests: { storage: "10Gi" }, + }, + }, + }, + saves: ns.Contain(kube.PersistentVolumeClaim(named("saves"))) { + spec+: { + storageClassName: cfg.storageClassName, + accessModes: ["ReadWriteOnce"], + resources: { + requests: { storage: "10Gi" }, + }, + }, + }, + server: ns.Contain(kube.PersistentVolumeClaim(named("server"))) { + spec+: { + storageClassName: cfg.storageClassName, + accessModes: ["ReadWriteOnce"], + resources: { + requests: { storage: "10Gi" }, + }, + }, + }, + }, + svc: ns.Contain(kube.Service(named("external"))) { + target_pod:: game.deployment.spec.template, + spec+: { + ports: kube.mapToNamedList({ + zero: { port: cfg.port, targetPort: cfg.port, protocol: "UDP" }, + one: { port: cfg.port+1, targetPort: cfg.port+1, protocol: "UDP" }, + two: { port: cfg.port+2, targetPort: cfg.port+2, protocol: "UDP" }, + }), + type: "LoadBalancer", + }, + }, + + scripts: ns.Contain(kube.ConfigMap(named("scripts"))) { + data: { + # Based on https://github.com/mbround18/valheim-docker , + # removed all reliance on running as root (thus removed + # autoupdater/autobackups). + "entrypoint.sh": ||| + #!/usr/bin/env bash + log() { + PREFIX="[entrypoint]" + printf "%-16s: %s\n" "${PREFIX}" "$1" + } + line() { + log "===========================================================================" + } + setup_filesystem() { + log "Setting up file systems" + mkdir -p /home/steam/valheim + mkdir -p /home/steam/valheim/logs + mkdir -p /home/steam/backups + mkdir -p /home/steam/scripts + mkdir -p /home/steam/valheim + cp /home/steam/steamcmd/linux64/steamclient.so /home/steam/valheim + } + line + log "Valheim Server - $(date)" + log "Initializing your container..." + line + setup_filesystem + log "Launching the rest of the fucking owl" + cd /home/steam/valheim || exit 1 + exec "$@" + ||| + }, + }, + secret: ns.Contain(kube.Secret(named("game"))) { + data_: { + # public game password + public: cfg.password, + }, + }, + deployment: ns.Contain(kube.Deployment(named("game"))) { + spec+: { + template+: { + spec+: { + containers_: { + default: kube.Container("default") { + image: cfg.image, + command: [ + "/bin/bash", "/scripts/entrypoint.sh", "/home/steam/scripts/start_valheim.sh", + ], + volumeMounts_: { + backups: { mountPath: "/home/steam/backups" }, + saves: { mountPath: "/home/steam/.config/unity3d/IronGate/Valheim" }, + server: { mountPath: "/home/steam/valheim" }, + scripts: { mountPath: "/scripts" }, + }, + ports_: { + zero: { containerPort: cfg.port }, + one: { containerPort: cfg.port + 1 }, + two: { containerPort: cfg.port + 2 }, + }, + env_: { + PUBLIC: "1", + PASSWORD: kube.SecretKeyRef(game.secret, "public"), + NAME: cfg.displayName, + }, + resources: { + requests: { + cpu: "500m", + memory: "2Gi", + }, + limits: { + cpu: "1000m", + memory: "4Gi", + }, + }, + }, + }, + securityContext: { + runAsUser: 1000, + runAsGroup: 1000, + fsGroup: 1000, + }, + volumes_: { + backups: kube.PersistentVolumeClaimVolume(game.pvcs.backups), + saves: kube.PersistentVolumeClaimVolume(game.pvcs.saves), + server: kube.PersistentVolumeClaimVolume(game.pvcs.server), + scripts: kube.ConfigMapVolume(game.scripts), + }, + }, + }, + }, + }, + }, + }, + + ns: kube.Namespace("valheim") { + }, + + q3k: top.env(top.ns, "q3k") { + cfg+: { + ns: "valheim", + password: (std.split(importstr "secrets/plain/q3k-public", "\n"))[0], + displayName: "wypierdol z polski xD", + }, + }, +} diff --git a/games/valheim/secrets/cipher/q3k-public b/games/valheim/secrets/cipher/q3k-public new file mode 100644 index 00000000..b95f2a85 --- /dev/null +++ b/games/valheim/secrets/cipher/q3k-public @@ -0,0 +1,39 @@ +-----BEGIN PGP MESSAGE----- + +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 +=YmoD +-----END PGP MESSAGE----- diff --git a/games/valheim/secrets/plain/.gitignore b/games/valheim/secrets/plain/.gitignore new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/games/valheim/secrets/plain/.gitignore @@ -0,0 +1 @@ +*