blob: 82e290761a6fa6475c35372f976872dcf99e5181 [file] [log] [blame]
Serge Bazanski34d39cc2021-02-23 23:03:31 +00001local kube = import "../../kube/kube.libsonnet";
2
3{
4 local top = self,
5 env(ns, name):: {
6 local env = self,
7 local cfg = env.cfg,
8 cfg:: {
9 name: name,
10 displayName: name,
11 image: "mbround18/valheim:latest",
12 password: error "password must be set",
13 storageClassName: "waw-hdd-redundant-3",
14 port: 2456,
15 },
16
17 local named = function(component) "%s-%s" % [name, component],
18
19 game: {
20 local game = self,
21 pvcs: {
22 backups: ns.Contain(kube.PersistentVolumeClaim(named("backups"))) {
23 spec+: {
24 storageClassName: cfg.storageClassName,
25 accessModes: ["ReadWriteOnce"],
26 resources: {
27 requests: { storage: "10Gi" },
28 },
29 },
30 },
31 saves: ns.Contain(kube.PersistentVolumeClaim(named("saves"))) {
32 spec+: {
33 storageClassName: cfg.storageClassName,
34 accessModes: ["ReadWriteOnce"],
35 resources: {
36 requests: { storage: "10Gi" },
37 },
38 },
39 },
40 server: ns.Contain(kube.PersistentVolumeClaim(named("server"))) {
41 spec+: {
42 storageClassName: cfg.storageClassName,
43 accessModes: ["ReadWriteOnce"],
44 resources: {
45 requests: { storage: "10Gi" },
46 },
47 },
48 },
49 },
50 svc: ns.Contain(kube.Service(named("external"))) {
51 target_pod:: game.deployment.spec.template,
52 spec+: {
53 ports: kube.mapToNamedList({
54 zero: { port: cfg.port, targetPort: cfg.port, protocol: "UDP" },
55 one: { port: cfg.port+1, targetPort: cfg.port+1, protocol: "UDP" },
56 two: { port: cfg.port+2, targetPort: cfg.port+2, protocol: "UDP" },
57 }),
58 type: "LoadBalancer",
59 },
60 },
61
Serge Bazanski3c9b8252022-11-27 14:48:07 +000062 // Given to some external users/systems which manage a given valheim server in a namespace.
63 // TODO(q3k): only grant privileges to the same server
64 controlAccount: {
65 svcAccount: ns.Contain(kube.ServiceAccount(named("control"))),
66 role: ns.Contain(kube.Role("control")) {
67 rules: [
68 {
69 apiGroups: [""],
70 resources: ["pods"],
71 verbs: ["get", "list", "watch", "delete"],
72 },
73 {
74 apiGroups: [""],
75 resources: ["pods/log"],
76 verbs: ["get"],
77 },
78 {
79 apiGroups: ["apps"],
80 resources: ["deployments"],
81 verbs: ["get", "list", "watch"],
82 },
83 ],
84 },
85 roleBinding: ns.Contain(kube.RoleBinding(named("control"))) {
86 subjects_: [
87 game.controlAccount.svcAccount,
88 ],
89 roleRef_: game.controlAccount.role,
90 },
91 },
92
Serge Bazanski34d39cc2021-02-23 23:03:31 +000093 scripts: ns.Contain(kube.ConfigMap(named("scripts"))) {
94 data: {
95 # Based on https://github.com/mbround18/valheim-docker ,
96 # removed all reliance on running as root (thus removed
97 # autoupdater/autobackups).
98 "entrypoint.sh": |||
99 #!/usr/bin/env bash
100 log() {
101 PREFIX="[entrypoint]"
102 printf "%-16s: %s\n" "${PREFIX}" "$1"
103 }
104 line() {
105 log "==========================================================================="
106 }
107 setup_filesystem() {
108 log "Setting up file systems"
109 mkdir -p /home/steam/valheim
110 mkdir -p /home/steam/valheim/logs
111 mkdir -p /home/steam/backups
112 mkdir -p /home/steam/scripts
113 mkdir -p /home/steam/valheim
114 cp /home/steam/steamcmd/linux64/steamclient.so /home/steam/valheim
115 }
116 line
117 log "Valheim Server - $(date)"
118 log "Initializing your container..."
119 line
120 setup_filesystem
121 log "Launching the rest of the fucking owl"
Serge Bazanski5edcf582021-12-13 16:51:14 +0000122 export HOME=/home/steam
Serge Bazanski34d39cc2021-02-23 23:03:31 +0000123 cd /home/steam/valheim || exit 1
124 exec "$@"
125 |||
126 },
127 },
128 secret: ns.Contain(kube.Secret(named("game"))) {
129 data_: {
130 # public game password
131 public: cfg.password,
132 },
133 },
134 deployment: ns.Contain(kube.Deployment(named("game"))) {
135 spec+: {
136 template+: {
137 spec+: {
138 containers_: {
139 default: kube.Container("default") {
140 image: cfg.image,
141 command: [
142 "/bin/bash", "/scripts/entrypoint.sh", "/home/steam/scripts/start_valheim.sh",
143 ],
144 volumeMounts_: {
145 backups: { mountPath: "/home/steam/backups" },
146 saves: { mountPath: "/home/steam/.config/unity3d/IronGate/Valheim" },
147 server: { mountPath: "/home/steam/valheim" },
148 scripts: { mountPath: "/scripts" },
149 },
150 ports_: {
151 zero: { containerPort: cfg.port },
152 one: { containerPort: cfg.port + 1 },
153 two: { containerPort: cfg.port + 2 },
154 },
155 env_: {
156 PUBLIC: "1",
157 PASSWORD: kube.SecretKeyRef(game.secret, "public"),
158 NAME: cfg.displayName,
Serge Bazanskib4de3f22021-02-25 13:22:27 +0100159 # Always attempt to update valheim on startup.
160 FORCE_INSTALL: "1",
Serge Bazanski34d39cc2021-02-23 23:03:31 +0000161 },
162 resources: {
163 requests: {
164 cpu: "500m",
165 memory: "2Gi",
166 },
167 limits: {
168 cpu: "1000m",
169 memory: "4Gi",
170 },
171 },
172 },
173 },
174 securityContext: {
175 runAsUser: 1000,
176 runAsGroup: 1000,
177 fsGroup: 1000,
178 },
179 volumes_: {
180 backups: kube.PersistentVolumeClaimVolume(game.pvcs.backups),
181 saves: kube.PersistentVolumeClaimVolume(game.pvcs.saves),
182 server: kube.PersistentVolumeClaimVolume(game.pvcs.server),
183 scripts: kube.ConfigMapVolume(game.scripts),
184 },
185 },
186 },
187 },
188 },
189 },
190 },
191
Serge Bazanski2371ca92021-02-25 12:05:58 +0100192 # Make namespace for valheim.
193 ns: kube.Namespace("valheim"),
194
195 # Allow patryk and palid to administer this namespace via the namespace-admin clusterrole.
196 adminRB: top.ns.Contain(kube.RoleBinding("sso:admins")) {
197 subjects: [
198 { apiGroup: "rbac.authorization.k8s.io", kind: "User", name: "%s@hackerspace.pl" % [u] }
199 for u in ["patryk", "palid"]
200 ],
201 roleRef: {
202 apiGroup: "rbac.authorization.k8s.io",
203 kind: "ClusterRole",
204 name: "system:admin-namespace",
205 },
Serge Bazanski34d39cc2021-02-23 23:03:31 +0000206 },
207
208 q3k: top.env(top.ns, "q3k") {
209 cfg+: {
210 ns: "valheim",
211 password: (std.split(importstr "secrets/plain/q3k-public", "\n"))[0],
212 displayName: "wypierdol z polski xD",
213 },
214 },
Serge Bazanski5edcf582021-12-13 16:51:14 +0000215 q3k2: top.env(top.ns, "q3k2") {
216 cfg+: {
217 ns: "valheim",
218 password: (std.split(importstr "secrets/plain/q3k2-public", "\n"))[0],
219 displayName: "walhajm",
220 },
221 },
Serge Bazanski34d39cc2021-02-23 23:03:31 +0000222}