From 8c8fb0e436e9a92b7f457953dbf9bdef5d76767a Mon Sep 17 00:00:00 2001 From: Greg Taylor Date: Fri, 21 Oct 2016 23:48:31 -0700 Subject: [PATCH] Add factorio chart to stable. --- stable/factorio/.helmignore | 21 +++++ stable/factorio/Chart.yaml | 11 +++ stable/factorio/README.md | 71 +++++++++++++++ stable/factorio/templates/NOTES.txt | 40 +++++++++ stable/factorio/templates/_helpers.tpl | 16 ++++ stable/factorio/templates/deployment.yaml | 99 +++++++++++++++++++++ stable/factorio/templates/factorio-svc.yaml | 18 ++++ stable/factorio/templates/mods-pvc.yaml | 14 +++ stable/factorio/templates/rcon-svc.yaml | 20 +++++ stable/factorio/templates/saves-pvc.yaml | 14 +++ stable/factorio/templates/secrets.yaml | 15 ++++ stable/factorio/values.yaml | 58 ++++++++++++ 12 files changed, 397 insertions(+) create mode 100644 stable/factorio/.helmignore create mode 100755 stable/factorio/Chart.yaml create mode 100644 stable/factorio/README.md create mode 100644 stable/factorio/templates/NOTES.txt create mode 100644 stable/factorio/templates/_helpers.tpl create mode 100644 stable/factorio/templates/deployment.yaml create mode 100644 stable/factorio/templates/factorio-svc.yaml create mode 100644 stable/factorio/templates/mods-pvc.yaml create mode 100644 stable/factorio/templates/rcon-svc.yaml create mode 100644 stable/factorio/templates/saves-pvc.yaml create mode 100644 stable/factorio/templates/secrets.yaml create mode 100644 stable/factorio/values.yaml diff --git a/stable/factorio/.helmignore b/stable/factorio/.helmignore new file mode 100644 index 0000000000..f0c1319444 --- /dev/null +++ b/stable/factorio/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/stable/factorio/Chart.yaml b/stable/factorio/Chart.yaml new file mode 100755 index 0000000000..5d250d74c1 --- /dev/null +++ b/stable/factorio/Chart.yaml @@ -0,0 +1,11 @@ +name: factorio +version: 0.1.0 +description: Factorio dedicated server. +keywords: +- game +- server +sources: +- https://github.com/games-on-k8s/docker-factorio +maintainers: +- name: Greg Taylor + email: gtaylor@gc-taylor.com diff --git a/stable/factorio/README.md b/stable/factorio/README.md new file mode 100644 index 0000000000..789b14a319 --- /dev/null +++ b/stable/factorio/README.md @@ -0,0 +1,71 @@ +# Factorio + +[Factorio](https://www.factorio.com/) is a game in which you build and maintain factories. + +## Introduction + +This chart creates a single [Factorio Headless](https://www.factorio.com/download-headless) Pod, plus Services for the Factorio server and RCON. + +## Prerequisites + +- Kubernetes 1.4+ with Beta APIs enabled +- PV provisioner support in the underlying infrastructure + +## Provider-specific Prerequisites + +Amazon's Elastic Loadbalancer lacks support for UDP. You'll need to set `factorioServer.ServiceType` to `NodePort` and expose the port that gets selected (see `kubectl describe svc `) via a security group. You may need to do something similar for certain bare metal deployments. + +You need not worry about this on Google Cloud Platform. + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```bash +$ helm install --name my-release incubator/factorio +``` + +This command deploys a Factorio dedicated server with sane defaults. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```bash +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +Refer to `values.yaml` for the full run-down on defaults. These are a mixture of Kubernetes and Factorio-related directives that map to environment variables in [docker-factorio](https://github.com/games-on-k8s/docker-factorio). + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```bash +$ helm install --name my-release \ + --set factorioServer.factorioServer=My Server,ImageTag=0.14.15 \ + incubator/factorio +``` + +The above command deploys Factorio dedicated with a server name of `My Server` and docker-factorio image version `0.14.15`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +$ helm install --name my-release -f values.yaml incubator/factorio +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## Persistence + +The [docker-factorio](https://github.com/games-on-k8s/docker-factorio) image stores the saved games and mods under /opt/factorio. + +By default a PersistentVolumeClaim is created and mounted for saves but not mods. In order to disable this functionality +you can change the values.yaml to disable persistence under the sub-sections under `Persistence`. + +> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* diff --git a/stable/factorio/templates/NOTES.txt b/stable/factorio/templates/NOTES.txt new file mode 100644 index 0000000000..a83174bfb1 --- /dev/null +++ b/stable/factorio/templates/NOTES.txt @@ -0,0 +1,40 @@ +Get the IP address of your Factorio server by running these commands in the +same shell: + +{{- if contains "NodePort" .Values.factorioServer.serviceType }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} \ + -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} \ + -o jsonpath="{.items[0].status.addresses[0].address}") + echo "You'll need to expose this node through your security groups/firewall" + echo "for it to be world-accessible." + echo $NODE_IP:$NODE_PORT + +{{- else if contains "LoadBalancer" .Values.factorioServer.serviceType }} +!! NOTE: It may take a few minutes for the LoadBalancer IP to be available. + +!! NOTE: If you installed this on an AWS cluster, your game will be + un-reachable. AWS ELB does not support UDP. You'll need to use a NodePort + value for factorioServer.serviceType. See the README.md for more info. + +You can watch for EXTERNAL-IP to populate by running: + kubectl get svc -w {{ template "fullname" . }} + +{{- else if contains "ClusterIP" .Values.factorioServer.serviceType }} + export POD_NAME=$(kubectl get pods \ + --namespace {{ .Release.Namespace }} \ + -l "component={{ template "fullname" . }}" \ + -o jsonpath="{.items[0].metadata.name}") + kubectl port-forward $POD_NAME 34197:34197 + echo "Point your Minecraft client at 127.0.0.1:34197" + +{{- end }} + +{{- if .Values.persistence.savedGames.enabled }} +{{- else }} +############################################################################ +### WARNING: Persistence is disabled!!! You will lose your game state ### +### when the Factorio pod is terminated. ### +### See values.yaml's Persistence.SavedGames.Enabled directive. ### +############################################################################ +{{- end }} diff --git a/stable/factorio/templates/_helpers.tpl b/stable/factorio/templates/_helpers.tpl new file mode 100644 index 0000000000..234480de71 --- /dev/null +++ b/stable/factorio/templates/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 24 -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 24 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 24 -}} +{{- end -}} diff --git a/stable/factorio/templates/deployment.yaml b/stable/factorio/templates/deployment.yaml new file mode 100644 index 0000000000..ca7f3beaab --- /dev/null +++ b/stable/factorio/templates/deployment.yaml @@ -0,0 +1,99 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: {{ template "fullname" . }} + labels: + app: {{ template "fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + template: + metadata: + labels: + app: {{ template "fullname" . }} + spec: + containers: + - name: {{ template "fullname" . }} + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: Always + resources: +{{ toYaml .Values.resources | indent 10 }} + env: + - name: FACTORIO_SERVER_NAME + value: {{ .Values.factorioServer.name | quote }} + - name: FACTORIO_DESCRIPTION + value: {{ .Values.factorioServer.description | quote }} + - name: FACTORIO_MAX_PLAYERS + value: {{ .Values.factorioServer.maxPlayers | quote }} + - name: FACTORIO_IS_PUBLIC + value: {{ .Values.factorioServer.isPublic | quote }} + - name: FACTORIO_REQUIRE_USER_VERIFICATION + value: {{ .Values.factorioServer.verifyIdentity | quote }} + - name: FACTORIO_ALLOW_COMMANDS + value: {{ .Values.factorioServer.allowCommands | quote }} + - name: FACTORIO_NO_AUTO_PAUSE + value: {{ .Values.factorioServer.noAutoPause | quote }} + - name: FACTORIO_AUTOSAVE_INTERVAL + value: {{ .Values.factorioServer.autosave.interval | quote }} + - name: FACTORIO_AUTOSAVE_SLOTS + value: {{ .Values.factorioServer.autosave.slots | quote }} + + {{- if .Values.factorioServer.password }} + - name: FACTORIO_SERVER_GAME_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "fullname" . }} + key: server-password + {{- end }} + + {{- if .Values.factorioServer.isPublic }} + - name: FACTORIO_USER_USERNAME + valueFrom: + secretKeyRef: + name: {{ template "fullname" . }} + key: factorio-username + - name: FACTORIO_USER_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "fullname" . }} + key: factorio-password + {{- end }} + + {{- if .Values.factorioServer.rcon.enabled }} + - name: FACTORIO_RCON_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "fullname" . }} + key: rcon-password + {{- end }} + + ports: + - name: factorio + containerPort: 34197 + protocol: UDP + {{- if .Values.factorioServer.rcon.enabled }} + - name: rcon + containerPort: {{ .Values.factorioServer.rcon.port }} + protocol: TCP + {{- end}} + volumeMounts: + - name: saves + mountPath: /opt/factorio/saves + - name: mods + mountPath: /opt/factorio/mods + volumes: + - name: saves + {{- if .Values.persistence.savedGames.enabled }} + persistentVolumeClaim: + claimName: {{template "fullname" .}}-savedgames + {{- else }} + emptyDir: {} + {{- end }} + - name: mods + {{- if .Values.persistence.mods.enabled }} + persistentVolumeClaim: + claimName: {{template "fullname" .}}-mods + {{- else }} + emptyDir: {} + {{- end }} diff --git a/stable/factorio/templates/factorio-svc.yaml b/stable/factorio/templates/factorio-svc.yaml new file mode 100644 index 0000000000..753921855c --- /dev/null +++ b/stable/factorio/templates/factorio-svc.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "fullname" . }} + labels: + app: {{ template "fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Name }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + type: {{ .Values.factorioServer.serviceType }} + ports: + - name: factorio + port: 34197 + targetPort: factorio + protocol: UDP + selector: + app: {{ template "fullname" . }} diff --git a/stable/factorio/templates/mods-pvc.yaml b/stable/factorio/templates/mods-pvc.yaml new file mode 100644 index 0000000000..07629972b4 --- /dev/null +++ b/stable/factorio/templates/mods-pvc.yaml @@ -0,0 +1,14 @@ +{{- if .Values.persistence.mods.enabled -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "fullname" . }}-mods + annotations: + volume.alpha.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.mods.size | quote }} +{{- end -}} diff --git a/stable/factorio/templates/rcon-svc.yaml b/stable/factorio/templates/rcon-svc.yaml new file mode 100644 index 0000000000..fb3deca1f8 --- /dev/null +++ b/stable/factorio/templates/rcon-svc.yaml @@ -0,0 +1,20 @@ +{{- if default "" .Values.factorioServer.rcon.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "fullname" . }}-rcon" + labels: + app: {{ template "fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Name }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + type: {{ .Values.factorioServer.rcon.serviceType }} + ports: + - name: rcon + port: {{ .Values.factorioServer.rcon.port }} + targetPort: rcon + protocol: TCP + selector: + app: {{ template "fullname" . }} +{{- end }} diff --git a/stable/factorio/templates/saves-pvc.yaml b/stable/factorio/templates/saves-pvc.yaml new file mode 100644 index 0000000000..c715baf331 --- /dev/null +++ b/stable/factorio/templates/saves-pvc.yaml @@ -0,0 +1,14 @@ +{{- if .Values.persistence.savedGames.enabled -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "fullname" . }}-savedgames + annotations: + volume.alpha.kubernetes.io/storage-class: {{ .Values.persistence.storageClass | quote }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.savedGames.size | quote }} +{{- end -}} diff --git a/stable/factorio/templates/secrets.yaml b/stable/factorio/templates/secrets.yaml new file mode 100644 index 0000000000..6017f56abc --- /dev/null +++ b/stable/factorio/templates/secrets.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "fullname" . }} + labels: + app: {{ template "fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +type: Opaque +data: + server-password: {{ default "" .Values.factorioServer.password | b64enc | quote }} + rcon-password: {{ default "" .Values.factorioServer.rcon.password | b64enc | quote }} + factorio-username: {{ default "" .Values.factorio.user.username | b64enc | quote }} + factorio-password: {{ default "" .Values.factorio.user.password | b64enc | quote }} diff --git a/stable/factorio/values.yaml b/stable/factorio/values.yaml new file mode 100644 index 0000000000..b935fd8e99 --- /dev/null +++ b/stable/factorio/values.yaml @@ -0,0 +1,58 @@ +# Factorio image version +# ref: https://quay.io/repository/games_on_k8s/factorio?tab=tags +image: quay.io/games_on_k8s/factorio +imageTag: "0.14.18" + +# Configure resource requests and limits +# ref: http://kubernetes.io/docs/user-guide/compute-resources/ +resources: + requests: + memory: 512Mi + cpu: 500m + +# Most of these map to environment variables. See docker-factorio for details: +# https://github.com/games-on-k8s/docker-factorio/blob/master/README.md#environment-variable-reference +factorioServer: + name: Kubernetes Server + description: Factorio running on Kubernetes + # Lock this server down with a password. + #password: change.me + maxPlayers: 255 + # Publishes this server in the server browser if true. + # You'll want to set Factorio.User below if true, as it becomes required. + isPublic: false + verifyIdentity: false + # Allows or disallows console commands. Must be one of: `true`, `false`, or `admins-only`. + allowCommands: admins-only + # Pause the server when nobody is connected? + noAutoPause: "false" + # You'll want to change this to NodePort if you are on AWS. + serviceType: LoadBalancer + + autosave: + # Auto-save interval in minutes. + interval: 2 + slots: 3 + + rcon: + enabled: false + port: 27015 + # Empty value here enables an auto-generated password. + password: "" + serviceType: LoadBalancer + +factorio: + # Your factorio.com User/pass is needed if factorioServer.IsPublic is true. + user: + username: your.username + password: your.password + +persistence: + storageClass: generic + savedGames: + # Set this to false if you don't care to persist saved games between restarts. + enabled: true + size: 1Gi + mods: + enabled: false + size: 128Mi