diff --git a/charts/palworld/VALUES_SUMMARY.md b/charts/palworld/VALUES_SUMMARY.md index 7526ee6bf..656df79d9 100644 --- a/charts/palworld/VALUES_SUMMARY.md +++ b/charts/palworld/VALUES_SUMMARY.md @@ -29,6 +29,10 @@ This chart will provide a Palworld server installation on a kubernetes cluster. | server.config.annotations | object | `{}` | Additional annotations to the resources | | server.config.community.enable | bool | `true` | Enables/disables the visibility of this server on Steam community servers list. | | server.config.community.password | string | `""` | If not provided, a random password will be generated and stored on the secret. | +| server.config.daily_reboot.enable | bool | `false` | Enable daily reboot. Disabled by default | +| server.config.daily_reboot.role | string | `"daily-reboot"` | The name of the role performing the daily reboot. | +| server.config.daily_reboot.serviceAccount | string | `"daily-reboot"` | The name of the Service Account used to perform the reboot. | +| server.config.daily_reboot.time | string | `"30 9 * * *"` | The time (UTC) the server will perform the reboot. By default, this schedules the restart at 9:30am UTC. Please note, this is using cron syntax. | | server.config.labels | object | `{}` | Additional labels to the resources | | server.config.max_players | int | `16` | The max number of players supported. | | server.config.multithreading | bool | `true` | Enables the multithreading, allowing the usage of up to 4 cores (needs citation) | diff --git a/charts/palworld/templates/configmaps.yaml b/charts/palworld/templates/configmaps.yaml index 58cfd91de..c9a73eb19 100644 --- a/charts/palworld/templates/configmaps.yaml +++ b/charts/palworld/templates/configmaps.yaml @@ -48,4 +48,30 @@ data: {{- with .Values.server.config.world_parameters }} {{- toYaml . | nindent 2 }} {{- end }} - {{ end }} \ No newline at end of file + {{ if .Values.server.config.daily_reboot.enable }} + restart-deployment.sh: | + #!/bin/bash + cont=$(kubectl -n {{ .Values.namespace }} get pods -o=jsonpath='{.items[?(@.metadata.labels.app\.kubernetes\.io/name=="{{ .Release.Name }}-server")].metadata.name}') + + function exec_rcon_cmd() { + kubectl exec -n {{ .Values.namespace }} -i pod/$cont rcon-cli "$1" + } + + exec_rcon_cmd "Broadcast Saving_Server_Data..." + exec_rcon_cmd save + sleep 30 + exec_rcon_cmd "Broadcast Backing_up_Server_Data..." + exec_rcon_cmd backup + sleep 30 + + step=5 + for i in $(seq 30 -$step 1); do + exec_rcon_cmd "Broadcast Rebooting_in_$i_seconds..." + sleep $step + done + + exec_rcon_cmd "Shutdown 1" + sleep 30 + kubectl -n {{ .Values.namespace }} rollout restart deployment/{{ .Release.Name }}-server + {{ end }} + {{ end }} diff --git a/charts/palworld/templates/cronjob.yaml b/charts/palworld/templates/cronjob.yaml new file mode 100644 index 000000000..dbdffb41c --- /dev/null +++ b/charts/palworld/templates/cronjob.yaml @@ -0,0 +1,37 @@ +{{ if .Values.server.config.daily_reboot.enable }} +apiVersion: batch/v1 +kind: CronJob +metadata: + name: "{{ .Values.server.config.daily_reboot.serviceAccount }}" + namespace: {{ .Values.namespace }} +spec: + concurrencyPolicy: Forbid + schedule: "{{ .Values.server.config.daily_reboot.time }}" + jobTemplate: + spec: + backoffLimit: 1 + activeDeadlineSeconds: 600 + template: + spec: + serviceAccountName: "{{ .Values.server.config.daily_reboot.serviceAccount }}" + restartPolicy: Never + containers: + - name: kubectl + image: bitnami/kubectl + command: + - /bin/sh + - -c + - /restart-script/restart-deployment.sh + volumeMounts: + - name: restart-script + mountPath: "/restart-script" + readOnly: true + volumes: + - name: restart-script + configMap: + name: "{{ .Release.Name }}-env-config" + defaultMode: 0777 + items: + - key: "restart-deployment.sh" + path: "restart-deployment.sh" +{{ end }} \ No newline at end of file diff --git a/charts/palworld/templates/role.yaml b/charts/palworld/templates/role.yaml new file mode 100644 index 000000000..f1c955027 --- /dev/null +++ b/charts/palworld/templates/role.yaml @@ -0,0 +1,14 @@ +{{ if .Values.server.config.daily_reboot.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ .Values.server.config.daily_reboot.role }}" + namespace: {{ .Values.namespace }} +rules: + - apiGroups: ["apps", "extensions"] + resources: ["deployments", "pods"] + verbs: ["get", "patch", "list", "watch"] + - apiGroups: [""] + resources: ["pods/exec", "pods"] + verbs: ["get", "list", "create"] +{{ end }} diff --git a/charts/palworld/templates/rolebinding.yaml b/charts/palworld/templates/rolebinding.yaml new file mode 100644 index 000000000..efd2f3f8b --- /dev/null +++ b/charts/palworld/templates/rolebinding.yaml @@ -0,0 +1,15 @@ +{{ if .Values.server.config.daily_reboot.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: "{{ .Values.server.config.daily_reboot.role }}-binding" + namespace: {{ .Values.namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "{{ .Values.server.config.daily_reboot.role }}" +subjects: + - kind: ServiceAccount + name: {{ .Values.server.config.daily_reboot.serviceAccount }} + namespace: {{ .Values.namespace }} +{{ end }} diff --git a/charts/palworld/templates/serviceaccount.yaml b/charts/palworld/templates/serviceaccount.yaml new file mode 100644 index 000000000..03419297a --- /dev/null +++ b/charts/palworld/templates/serviceaccount.yaml @@ -0,0 +1,7 @@ +{{ if .Values.server.config.daily_reboot.enable }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.server.config.daily_reboot.serviceAccount }} + namespace: {{ .Values.namespace }} +{{ end }} \ No newline at end of file diff --git a/charts/palworld/values.yaml b/charts/palworld/values.yaml index 4f3707433..ef12fbe66 100644 --- a/charts/palworld/values.yaml +++ b/charts/palworld/values.yaml @@ -151,6 +151,17 @@ server: # -- (string) Update/Install the server when the container starts. # THIS HAS TO BE ENABLED THE FIRST TIME YOU RUN THE CONTAINER update_on_boot: true + daily_reboot: + # -- (bool) Enable daily reboot. + # Disabled by default + enable: false + # -- (string) The time (UTC) the server will perform the reboot. + # By default, this schedules the restart at 9:30am UTC. Please note, this is using cron syntax. + time: "30 9 * * *" + # -- (string) The name of the role performing the daily reboot. + role: "daily-reboot" + # -- (string) The name of the Service Account used to perform the reboot. + serviceAccount: "daily-reboot" # -- (object) Configures the game world settings. # The key:values here should represent in game accepted values. # Wrap all values with quotes here to avoid validation issues. diff --git a/k8s/examples/cronjob-reboot/cm.yaml b/k8s/examples/cronjob-reboot/cm.yaml new file mode 100644 index 000000000..79ba5e879 --- /dev/null +++ b/k8s/examples/cronjob-reboot/cm.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: restart-deployment-configmap +data: + restart-deployment.sh: | + #!/bin/bash + cont=$(kubectl -n palworld get pods -o=jsonpath='{.items[?(@.metadata.labels.app=="palworld-server")].metadata.name}') + + function exec_rcon_cmd() { + kubectl exec -n palworld -i pod/$cont rcon-cli "$1" + } + + exec_rcon_cmd "Broadcast Saving_Server_Data..." + exec_rcon_cmd save + sleep 30 + exec_rcon_cmd "Broadcast Backing_up_Server_Data..." + kubectl exec -n palworld -i pod/$cont backup + sleep 30 + + step = 5 + for i in $(seq 30 -$step 1); do + exec_rcon_cmd "Broadcast Rebooting_in_$i_seconds..." + sleep $step + done + + exec_rcon_cmd "Shutdown 1" + sleep 30 + kubectl -n palworld rollout restart deployment/palworld-server + diff --git a/k8s/examples/cronjob-reboot/cronjob.yaml b/k8s/examples/cronjob-reboot/cronjob.yaml new file mode 100644 index 000000000..a52d5dfbd --- /dev/null +++ b/k8s/examples/cronjob-reboot/cronjob.yaml @@ -0,0 +1,34 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: restart-deployment +spec: + concurrencyPolicy: Forbid + schedule: '30 9 * * *' + jobTemplate: + spec: + backoffLimit: 1 + activeDeadlineSeconds: 600 + template: + spec: + serviceAccountName: restart-deploy + restartPolicy: Never + containers: + - name: kubectl + image: bitnami/kubectl + command: + - /bin/sh + - -c + - /restart-script/restart-deployment.sh + volumeMounts: + - name: restart-script + mountPath: "/restart-script" + readOnly: true + volumes: + - name: restart-script + configMap: + name: restart-deployment-configmap + defaultMode: 0777 + items: + - key: "restart-deployment.sh" + path: "restart-deployment.sh" diff --git a/k8s/examples/cronjob-reboot/role.yaml b/k8s/examples/cronjob-reboot/role.yaml new file mode 100644 index 000000000..2e2bc3bfc --- /dev/null +++ b/k8s/examples/cronjob-reboot/role.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: restart-deployment +rules: + - apiGroups: ["apps", "extensions"] + resources: ["deployments", "pods"] + verbs: ["get", "patch", "list", "watch"] + - apiGroups: [""] + resources: ["pods/exec", "pods"] + verbs: ["get", "list", "create"] diff --git a/k8s/examples/cronjob-reboot/rolebinding.yaml b/k8s/examples/cronjob-reboot/rolebinding.yaml new file mode 100644 index 000000000..4012b1714 --- /dev/null +++ b/k8s/examples/cronjob-reboot/rolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: restart-deployment +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: restart-deployment +subjects: + - kind: ServiceAccount + name: restart-deploy + namespace: palworld diff --git a/k8s/examples/cronjob-reboot/serviceaccount.yaml b/k8s/examples/cronjob-reboot/serviceaccount.yaml new file mode 100644 index 000000000..54f422bd8 --- /dev/null +++ b/k8s/examples/cronjob-reboot/serviceaccount.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: restart-deploy diff --git a/k8s/examples/readme.md b/k8s/examples/readme.md new file mode 100644 index 000000000..5953f9d14 --- /dev/null +++ b/k8s/examples/readme.md @@ -0,0 +1,9 @@ +# Example CronJob to Reboot Server Daily (9:30am UTC) + +Use the following commands to setup the cron job in the namespace palworld: + +* `kubectl apply -f cm.yaml` +* `kubectl apply -f role.yaml` +* `kubectl apply -f rolebinding.yaml` +* `kubectl apply -f serviceaccount.yaml` +* `kubectl apply -f cronjob.yaml`