games/valheim: init
This creates a valheim game server, using a public image but slightly
nerfing it to be able to run it unprivileged.
We also deploy our first server. The password is Well Known To Those
Versed In Hackerspace Lore.
Change-Id: Ic24262a3b02d3c17d2f00aa2967e240ea4eee7fb
diff --git a/games/valheim/prod.jsonnet b/games/valheim/prod.jsonnet
new file mode 100644
index 0000000..6c10b8b
--- /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",
+ },
+ },
+}