[games-of-whales] Initial release (#1133)

Co-authored-by: angelnu <git@angelnucom>
This commit is contained in:
Angel Nunez Mencias 2021-08-24 00:35:16 +02:00 committed by GitHub
parent 4e258501c8
commit 6f1690ab2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 805 additions and 0 deletions

View File

@ -0,0 +1,26 @@
# 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
.vscode/
# OWNERS file for Kubernetes
OWNERS
# helm-docs templates
*.gotmpl

View File

@ -0,0 +1,24 @@
apiVersion: v2
appVersion: 1.0.0
description: Streams graphic applications/games (retroarch, firefox, steam) runing on Kubernetes
name: games-on-whales
version: 1.0.0
kubeVersion: ">=1.19.0-0"
keywords:
- games-on-whales
- steam
- X11
- pulse
- stream
- retroarch
home: https://github.com/k8s-at-home/charts/tree/master/charts/stable/games-on-whales
icon: https://github.com/games-on-whales/gow/raw/master/docs/assets/img/gow-logo.png
sources:
- https://github.com/games-on-whales/gow
maintainers:
- name: angelnu
email: gits@angelnu.com
dependencies:
- name: common
repository: https://library-charts.k8s-at-home.com
version: 4.0.0

View File

@ -0,0 +1,154 @@
# games-on-whales
![Version: 1.0.0](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) ![AppVersion: 1.0.0](https://img.shields.io/badge/AppVersion-1.0.0-informational?style=flat-square)
Streams graphic applications/games (retroarch, firefox, steam) runing on Kubernetes
**This chart is not maintained by the upstream project and any issues with the chart should be raised [here](https://github.com/k8s-at-home/charts/issues/new/choose)**
## Source Code
* <https://github.com/games-on-whales/gow>
## Requirements
Kubernetes: `>=1.19.0-0`
## Dependencies
| Repository | Name | Version |
|------------|------|---------|
| https://library-charts.k8s-at-home.com | common | 4.0.0 |
## TL;DR
```console
helm repo add k8s-at-home https://k8s-at-home.com/charts/
helm repo update
helm install games-on-whales k8s-at-home/games-on-whales
```
## Installing the Chart
To install the chart with the release name `games-on-whales`
```console
helm install games-on-whales k8s-at-home/games-on-whales
```
## Uninstalling the Chart
To uninstall the `games-on-whales` deployment
```console
helm uninstall games-on-whales
```
The command removes all the Kubernetes components associated with the chart **including persistent volumes** and deletes the release.
## Configuration
Read through the [values.yaml](./values.yaml) file. It has several commented out suggested values.
Other values may be used from the [values.yaml](https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common/values.yaml) from the [common library](https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common).
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`.
```console
helm install games-on-whales \
--set env.TZ="America/New York" \
k8s-at-home/games-on-whales
```
Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart.
```console
helm install games-on-whales k8s-at-home/games-on-whales -f values.yaml
```
## Custom configuration
You need a real graphic card in your Kubernetes node to run Games on Whales.
If you use Proxmox you might use PCI pass-through but you also need to ensure
the host does not load any modules for the graphic card. See the
[instructions](https://pve.proxmox.com/wiki/Pci_passthrough).
## Values
**Important**: When deploying an application Helm chart you can add more values from our common library chart [here](https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common)
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| firefox.enabled | bool | `true` | enable/disable firefox container |
| firefox.image.pullPolicy | string | `"IfNotPresent"` | image pull policy |
| firefox.image.repository | string | `"andrewmackrodt/firefox-x11"` | image repository |
| firefox.image.tag | string | `"latest"` | image tag |
| firefox.logLevel | string | `"info"` | firefox log level |
| firefox.volumeMounts | object | `{}` | firefox extra volume mounts |
| ingress.main | object | See values.yaml | Enable and configure ingress settings for the chart under this key. |
| mkhomeretrodirs.image.pullPolicy | string | `"IfNotPresent"` | image pull policy |
| mkhomeretrodirs.image.repository | string | `"busybox"` | image repository |
| mkhomeretrodirs.image.tag | string | `"1.34.0"` | image tag |
| persistence | object | See values.yaml | Configure persistence settings for the chart under this key. |
| pulse | object | See values.yaml | Configure pulse audio settings |
| pulseaudio.image.pullPolicy | string | `"IfNotPresent"` | pulseaudio image pull policy |
| pulseaudio.image.repository | string | `"gameonwhales/pulseaudio"` | pulseaudio image repository |
| pulseaudio.image.tag | string | `"latest"` | pulseaudio image tag |
| retroarch.enabled | bool | `true` | enable/disable retroarch container |
| retroarch.image.pullPolicy | string | `"IfNotPresent"` | retroarch image pull policy |
| retroarch.image.repository | string | `"gameonwhales/retroarch"` | retroarch image repository |
| retroarch.image.tag | string | `"latest"` | retroarch image tag |
| retroarch.logLevel | string | `"info"` | retroarch log level |
| retroarch.volumeMounts | object | `{}` | retroarch extra volume mounts |
| service.main | object | See values.yaml | Enable and configure service settings for the chart under this key. |
| steam.enabled | bool | `true` | enable/disable steam container |
| steam.image.pullPolicy | string | `"IfNotPresent"` | steam image pull policy |
| steam.image.repository | string | `"gameonwhales/steam"` | steam image repository |
| steam.image.tag | string | `"latest"` | steam image tag |
| steam.protonLog | int | `1` | enable proton log |
| steam.volumeMounts | object | `{}` | steam extra volume mounts |
| sunshine.env | object | `{}` | sunshine additional env settings |
| sunshine.image.pullPolicy | string | `"IfNotPresent"` | sunshine image pull policy |
| sunshine.image.repository | string | `"gameonwhales/sunshine"` | sunshine image repository |
| sunshine.image.tag | string | `"latest"` | sunshine image tag |
| sunshine.logLevel | string | `"info"` | sunshine log level |
| sunshine.password | string | `"admin"` | sunshine web interface pasword |
| sunshine.user | string | `"admin"` | sunshine web interface user |
| xorg.display | string | `":99"` | xorg display ID |
| xorg.image.pullPolicy | string | `"IfNotPresent"` | xorg image pull policy |
| xorg.image.repository | string | `"gameonwhales/xorg"` | xorg image repository |
| xorg.image.tag | string | `"latest"` | xorg image tag |
| xorg.refreshrate | int | `60` | xorg refresh rate |
| xorg.resolution | string | `"1920x1080"` | xorg resolution |
## Changelog
All notable changes to this application Helm chart will be documented in this file but does not include changes from our common library. To read those click [here](https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common#changelog).
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### [1.0.0]
#### Added
- Initial version
#### Changed
- N/A
#### Removed
- N/A
[1.0.0]: #100
## Support
- See the [Docs](https://docs.k8s-at-home.com/our-helm-charts/getting-started/)
- Open an [issue](https://github.com/k8s-at-home/charts/issues/new/choose)
- Ask a [question](https://github.com/k8s-at-home/organization/discussions)
- Join our [Discord](https://discord.gg/sTMX7Vh) community
----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.5.0](https://github.com/norwoodj/helm-docs/releases/v1.5.0)

View File

@ -0,0 +1,146 @@
{{- define "custom.repository.organization" -}}
k8s-at-home
{{- end -}}
{{- define "custom.repository.url" -}}
https://github.com/k8s-at-home/charts
{{- end -}}
{{- define "custom.helm.url" -}}
https://k8s-at-home.com/charts/
{{- end -}}
{{- define "custom.helm.path" -}}
{{ template "custom.repository.organization" . }}/{{ template "chart.name" . }}
{{- end -}}
{{- define "custom.notes" -}}
**This chart is not maintained by the upstream project and any issues with the chart should be raised [here](https://github.com/k8s-at-home/charts/issues/new/choose)**
{{- end -}}
{{- define "custom.requirements" -}}
## Requirements
{{ template "chart.kubeVersionLine" . }}
{{- end -}}
{{- define "custom.dependencies" -}}
## Dependencies
{{ template "chart.requirementsTable" . }}
{{- end -}}
{{- define "custom.install.tldr" -}}
## TL;DR
```console
helm repo add {{ template "custom.repository.organization" . }} {{ template "custom.helm.url" . }}
helm repo update
helm install {{ template "chart.name" . }} {{ template "custom.helm.path" . }}
```
{{- end -}}
{{- define "custom.install" -}}
## Installing the Chart
To install the chart with the release name `{{ template "chart.name" . }}`
```console
helm install {{ template "chart.name" . }} {{ template "custom.helm.path" . }}
```
{{- end -}}
{{- define "custom.uninstall" -}}
## Uninstalling the Chart
To uninstall the `{{ template "chart.name" . }}` deployment
```console
helm uninstall {{ template "chart.name" . }}
```
The command removes all the Kubernetes components associated with the chart **including persistent volumes** and deletes the release.
{{- end -}}
{{- define "custom.configuration.header" -}}
## Configuration
{{- end -}}
{{- define "custom.configuration.readValues" -}}
Read through the [values.yaml](./values.yaml) file. It has several commented out suggested values.
Other values may be used from the [values.yaml](https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common/values.yaml) from the [common library](https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common).
{{- end -}}
{{- define "custom.configuration.example.set" -}}
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`.
```console
helm install {{ template "chart.name" . }} \
--set env.TZ="America/New York" \
{{ template "custom.helm.path" . }}
```
{{- end -}}
{{- define "custom.configuration.example.file" -}}
Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart.
```console
helm install {{ template "chart.name" . }} {{ template "custom.helm.path" . }} -f values.yaml
```
{{- end -}}
{{- define "custom.valuesSection" -}}
## Values
**Important**: When deploying an application Helm chart you can add more values from our common library chart [here](https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common)
{{ template "chart.valuesTable" . }}
{{- end -}}
{{- define "custom.support" -}}
## Support
- See the [Docs](https://docs.k8s-at-home.com/our-helm-charts/getting-started/)
- Open an [issue](https://github.com/k8s-at-home/charts/issues/new/choose)
- Ask a [question](https://github.com/k8s-at-home/organization/discussions)
- Join our [Discord](https://discord.gg/sTMX7Vh) community
{{- end -}}
{{ template "chart.header" . }}
{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
{{ template "chart.description" . }}
{{ template "custom.notes" . }}
{{ template "chart.sourcesSection" . }}
{{ template "custom.requirements" . }}
{{ template "custom.dependencies" . }}
{{ template "custom.install.tldr" . }}
{{ template "custom.install" . }}
{{ template "custom.uninstall" . }}
{{ template "custom.configuration.header" . }}
{{ template "custom.configuration.readValues" . }}
{{ template "custom.configuration.example.set" . }}
{{ template "custom.configuration.example.file" . }}
{{ template "custom.custom.configuration" . }}
{{ template "custom.valuesSection" . }}
{{ template "custom.changelog" . }}
{{ template "custom.support" . }}
{{ template "helm-docs.versionFooter" . }}
{{ "" }}

View File

@ -0,0 +1,27 @@
{{- define "custom.changelog.header" -}}
## Changelog
{{- end -}}
{{- define "custom.changelog" -}}
{{ template "custom.changelog.header" . }}
All notable changes to this application Helm chart will be documented in this file but does not include changes from our common library. To read those click [here](https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common#changelog).
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### [1.0.0]
#### Added
- Initial version
#### Changed
- N/A
#### Removed
- N/A
[1.0.0]: #100
{{- end -}}

View File

@ -0,0 +1,14 @@
{{- define "custom.custom.configuration.header" -}}
## Custom configuration
{{- end -}}
{{- define "custom.custom.configuration" -}}
{{ template "custom.custom.configuration.header" . }}
You need a real graphic card in your Kubernetes node to run Games on Whales.
If you use Proxmox you might use PCI pass-through but you also need to ensure
the host does not load any modules for the graphic card. See the
[instructions](https://pve.proxmox.com/wiki/Pci_passthrough).
{{- end -}}

View File

@ -0,0 +1 @@
{{- include "common.notes.defaultNotes" . -}}

View File

@ -0,0 +1,272 @@
{{/* Make sure all variables are set properly */}}
{{- include "common.values.setup" . }}
{{/* Append the hardcoded settings */}}
{{- define "games-on-whales.harcodedValues" -}}
image:
{{ .Values.sunshine.image | toYaml | nindent 2 }}
securityContext:
privileged: true
env:
DISPLAY: {{ .Values.xorg.display }}
LOG_LEVEL: {{ .Values.sunshine.logLevel }}
PULSE_SERVER: /tmp/pulse/pulse-socket
SUNSHINE_PASS: {{ .Values.sunshine.password }}
SUNSHINE_USER: {{ .Values.sunshine.user }}
GOW_REQUIRED_DEVICES: /dev/uinput /dev/input/event* /dev/dri/*
XDG_RUNTIME_DIR: /tmp/.X11-unix
{{- if .Values.sunshine.env }}
{{ .Values.sunshine.env | toYaml | nindent 2 }}
{{- end }}
initContainers:
mkhomeretrodirs:
image: {{.Values.mkhomeretrodirs.image.repository }}:{{ .Values.mkhomeretrodirs.image.tag }}
imagePullPolicy: {{ .Values.mkhomeretrodirs.image.pullPolicy }}
command:
- sh
- -c
- chown -R 1000:1000 /home/retro
{{- if .Values.persistence.home.enabled }}
volumeMounts:
- name: home
mountPath: /home/retro
{{- end }}
additionalContainers:
xorg:
image: {{.Values.xorg.image.repository }}:{{ .Values.xorg.image.tag }}
imagePullPolicy: {{ .Values.xorg.image.pullPolicy }}
securityContext:
privileged: true
env:
- name: DISPLAY
value: {{ .Values.xorg.display | quote }}
- name: REFRESH_RATE
value: {{ .Values.xorg.refreshrate | quote}}
- name: RESOLUTION
value: {{ .Values.xorg.resolution | quote }}
volumeMounts:
- name: dev-input
mountPath: /dev/input
readOnly: true
- name: udev
mountPath: /run/udev
readOnly: true
- name: xorg
mountPath: /tmp/.X11-unix
- name: var-log
mountPath: /var/log
pulseaudio:
image: {{.Values.pulseaudio.image.repository }}:{{ .Values.pulseaudio.image.tag }}
imagePullPolicy: {{ .Values.pulseaudio.image.pullPolicy }}
volumeMounts:
- name: audio-socket
mountPath: /tmp/pulse
- name: pulse-conf
mountPath: /etc/pulse
{{- if .Values.retroarch.enabled }}
retroarch:
image: {{.Values.retroarch.image.repository }}:{{ .Values.retroarch.image.tag }}
imagePullPolicy: {{ .Values.retroarch.image.pullPolicy }}
securityContext:
privileged: true
env:
- name: DISPLAY
value: {{ .Values.xorg.display | quote }}
- name: LOG_LEVEL
value: {{ .Values.retroarch.logLevel | quote }}
- name: PULSE_SERVER
value: "/tmp/pulse/pulse-socket"
volumeMounts:
- name: audio-socket
mountPath: /tmp/pulse
- name: dev-input
mountPath: /dev/input
readOnly: true
- name: udev
mountPath: /run/udev
readOnly: true
- name: xorg
mountPath: /tmp/.X11-unix
{{- if .Values.persistence.home.enabled }}
- name: home
mountPath: /home/retro
{{- end }}
{{- if .Values.retroarch.volumeMounts }}
{{ .Values.retroarch.volumeMounts | toYaml | nindent 4 }}
{{- end }}
{{- end }}
{{- if .Values.steam.enabled }}
steam:
image: {{.Values.steam.image.repository }}:{{ .Values.steam.image.tag }}
imagePullPolicy: {{ .Values.steam.image.pullPolicy }}
securityContext:
privileged: true
env:
- name: DISPLAY
value: {{ .Values.xorg.display | quote }}
- name: PROTON_LOG
value: {{ .Values.steam.protonLog | quote }}
- name: PULSE_SERVER
value: "/tmp/pulse/pulse-socket"
volumeMounts:
- name: audio-socket
mountPath: /tmp/pulse
- name: dev-input
mountPath: /dev/input
readOnly: true
- name: udev
mountPath: /run/udev
readOnly: true
- name: xorg
mountPath: /tmp/.X11-unix
{{- if .Values.persistence.home.enabled }}
- name: home
mountPath: /home/retro
{{- end }}
# The following is needed by the webview otherwise you'll get Less than 64MB of free space in temporary directory (https://github.com/microsoft/vscode/issues/111729#issuecomment-737399692)
- name: dshm
mountPath: /dev/shm
{{- if .Values.steam.volumeMounts }}
{{ .Values.steam.volumeMounts | toYaml | nindent 4 }}
{{- end }}
{{- end }}
{{- if .Values.firefox.enabled }}
firefox:
image: {{.Values.firefox.image.repository }}:{{ .Values.firefox.image.tag }}
imagePullPolicy: {{ .Values.firefox.image.pullPolicy }}
env:
- name: DISPLAY
value: {{ .Values.xorg.display | quote }}
- name: LOG_LEVEL
value: {{ .Values.firefox.logLevel | quote }}
- name: PULSE_SERVER
value: "/tmp/pulse/pulse-socket"
volumeMounts:
- name: audio-socket
mountPath: /tmp/pulse
- name: xorg
mountPath: /tmp/.X11-unix
{{- if .Values.persistence.home.enabled }}
- name: home
mountPath: /run/user/1000
{{- end }}
{{- if .Values.firefox.volumeMounts }}
{{ .Values.firefox.volumeMounts | toYaml | nindent 4 }}
{{- end }}
{{- end }}
# -- Configures service settings for the chart.
# @default -- See values.yaml
service:
main:
primary: true
ports:
http:
enabled: false
primary: false
sunshine:
enabled: true
port: 48010
protocol: TCP
sunshine-tcp1:
enabled: true
port: 47984
protocol: TCP
sunshine-tcp2:
enabled: true
port: 47985
protocol: TCP
sunshine-tcp3:
enabled: true
port: 47986
protocol: TCP
sunshine-tcp4:
enabled: true
port: 47987
protocol: TCP
sunshine-tcp5:
enabled: true
port: 47988
protocol: TCP
sunshine-tcp6:
enabled: true
port: 47989
protocol: TCP
sunshine-tcp7:
enabled: true
primary: true
port: 47990
protocol: HTTPS
sunshine-udp1:
enabled: true
port: 47998
protocol: UDP
sunshine-udp2:
enabled: true
port: 47999
protocol: UDP
sunshine-udp3:
enabled: true
port: 48000
protocol: UDP
externalTrafficPolicy: Local
# Required for udev to work
hostNetwork: true
persistence:
dev-input:
enabled: true
type: hostPath
mountPath: /dev/input
hostPath: /dev/input
udev:
enabled: true
type: hostPath
mountPath: /run/udev
hostPath: /run/udev
xorg:
enabled: true
type: hostPath
mountPath: /tmp/.X11-unix
hostPath: /tmp/.X11-unix
var-log:
enabled: true
type: hostPath
mountPath: /var/log
hostPath: /var/log
audio-socket:
enabled: true
type: hostPath
mountPath: /tmp/pulse
hostPath: /tmp/pulse
dshm:
enabled: true
type: emptyDir
medium: Memory
pulse-conf:
enabled: true
type: custom
volumeSpec:
configMap:
name: {{ include "common.names.fullname" . }}-pulse
items:
- key: default.pa
path: default.pa
- key: client.conf
path: client.conf
- key: daemon.conf
path: daemon.conf
{{- end -}}
{{- $_ := mergeOverwrite .Values (include "games-on-whales.harcodedValues" . | fromYaml) -}}
{{/* Render the templates */}}
{{ include "common.all" . }}

View File

@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "common.names.fullname" . }}-pulse
labels:
{{- include "common.labels" . | nindent 4 }}
data:
{{- tpl (.Values.pulse.config | toYaml) $ | nindent 2 }}

View File

@ -0,0 +1,133 @@
#
# IMPORTANT NOTE
#
# This chart inherits from our common library chart. You can check the default values/options here:
# https://github.com/k8s-at-home/library-charts/tree/main/charts/stable/common/values.yaml
#
ingress:
# -- Enable and configure ingress settings for the chart under this key.
# @default -- See values.yaml
main:
enabled: false
service:
# -- Enable and configure service settings for the chart under this key.
# @default -- See values.yaml
main: {}
# type: LoadBalancer
# loadBalancerIP: 192.168.1.129
# -- Configure persistence settings for the chart under this key.
# @default -- See values.yaml
persistence:
home:
enabled: true
type: emptyDir
mountPath: /home/retro
sunshine:
image:
# -- sunshine image repository
repository: gameonwhales/sunshine
# -- sunshine image tag
tag: latest
# -- sunshine image pull policy
pullPolicy: IfNotPresent
# -- sunshine web interface user
user: admin
# -- sunshine web interface pasword
password: admin
# -- sunshine log level
logLevel: info
# -- sunshine additional env settings
env: {}
xorg:
image:
# -- xorg image repository
repository: gameonwhales/xorg
# -- xorg image tag
tag: latest
# -- xorg image pull policy
pullPolicy: IfNotPresent
# -- xorg display ID
display: :99
# -- xorg refresh rate
refreshrate: 60
# -- xorg resolution
resolution: 1920x1080
pulseaudio:
image:
# -- pulseaudio image repository
repository: gameonwhales/pulseaudio
# -- pulseaudio image tag
tag: latest
# -- pulseaudio image pull policy
pullPolicy: IfNotPresent
retroarch:
# -- enable/disable retroarch container
enabled: true
image:
# -- retroarch image repository
repository: gameonwhales/retroarch
# -- retroarch image tag
tag: latest
# -- retroarch image pull policy
pullPolicy: IfNotPresent
# -- retroarch log level
logLevel: info
# -- retroarch extra volume mounts
volumeMounts: {}
steam:
# -- enable/disable steam container
enabled: true
image:
# -- steam image repository
repository: gameonwhales/steam
# -- steam image tag
tag: latest
# -- steam image pull policy
pullPolicy: IfNotPresent
# -- enable proton log
protonLog: 1
# -- steam extra volume mounts
volumeMounts: {}
firefox:
# -- enable/disable firefox container
enabled: true
image:
# -- image repository
repository: andrewmackrodt/firefox-x11
# -- image tag
tag: latest
# -- image pull policy
pullPolicy: IfNotPresent
# -- firefox log level
logLevel: info
# -- firefox extra volume mounts
volumeMounts: {}
mkhomeretrodirs:
image:
# -- image repository
repository: busybox
# -- image tag
tag: 1.34.0
# -- image pull policy
pullPolicy: IfNotPresent
# -- Configure pulse audio settings
# @default -- See values.yaml
pulse:
config:
default.pa: |-
.fail
load-module module-null-sink sink_name=sunshine
set-default-sink sunshine
load-module module-native-protocol-unix auth-anonymous=1 socket=/tmp/pulse/pulse-socket
client.conf: |-
default-sink = sink-sunshine-stereo
autospawn = no
daemon-binary = /bin/true
daemon.conf: |-
exit-idle-time = -1
flat-volumes = yes