mirror of
https://github.com/games-on-whales/fenrir.git
synced 2026-10-15 12:51:53 +00:00
[PR #54] [CLOSED] Wolf-Agent DRA: Implementing the Wolf DRA driver #55
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
games-on-whales/fenrir#55
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/games-on-whales/fenrir/pull/54
Author: @axolotlite
Created: 8/1/2026
Status: ❌ Closed
Base:
staging← Head:feature/wolf-dra-driver📝 Commits (10+)
3559540[go] update go from 1.24 to 1.26 for dra v1d817ca0[go] update code and references to newer GA Kind (gatewayapi v1)6b5bf3e[codegen] update generated code7cb8bfa[wolf-dra] initial implementation2bd8ca7[lint] apply linter recommendations4407af0[dev] add resources for testing the wolf-draea5da51[dev] add initial readmes for wolf dra manual resources7aaaff9[wolf-dra] add pulse audio mount8667076[wolf-dra] add wolf-dra standalone deployment and firefox app pod manifests4958bc0[wolf-dra] add informers to watch for status updates, so it can join sessions to lobbies📊 Changes
64 files changed (+4419 additions, -805 deletions)
View changed files
📝
.dockerignore(+0 -1)📝
Dockerfile(+1 -1)📝
Dockerfile.dev(+5 -3)📝
cmd/operator/main.go(+2 -2)📝
cmd/wolf-agent/main.go(+200 -177)📝
crds/direwolf.games-on-whales.github.io_apps.yaml(+524 -83)📝
crds/direwolf.games-on-whales.github.io_lobbies.yaml(+3 -0)📝
crds/direwolf.games-on-whales.github.io_profiles.yaml(+257 -29)📝
crds/direwolf.games-on-whales.github.io_sessions.yaml(+4 -0)📝
go.mod(+57 -42)📝
go.sum(+146 -90)➕
hack/deploy/01-wolf-agent-standalone.yaml(+231 -0)📝
hack/deploy/01-wolf-agent.yaml(+137 -17)📝
hack/deploy/02-moonlight-proxy.yaml(+0 -61)📝
hack/deploy/03-misc.yaml(+240 -1)➕
hack/resources/device_classes/README.md(+6 -0)➕
hack/resources/device_classes/default_device_class.yaml(+11 -0)➕
hack/resources/device_classes/multi_gpu_class.yaml(+22 -0)➕
hack/resources/dra_tests/README.md(+8 -0)➕
hack/resources/dra_tests/deployment_resource_claim_template.yaml(+63 -0)...and 44 more files
📄 Description
This PR aims to create the initial wolf dra driver for use with the direwolf-operator & moonlight proxy.
My aim while writing this was to seperate the DRA from the rest of the components, they're not supposed to directly communicate with the wolf-dra, instead create resources that the dra monitors / creates for the other operators
The following kubernetes resources are translated into wolf specific resources:
Wolf-Agent
The Wolf-Agent Pod consists of 2 Containers:
Wolf-DRA Container
The wolf-dra container was previous the wolf-agent container, which was a "per-app" container, as in; each application had 4 containers (wolf, wolf-agent, pulseaudio and the application itself).
Now, it's a daemonset whose purpose is to recieve resourceClaims from the kubelet and then call wolf to create a lobby, before mounting the resulting sockets, alongside their relevant env vars into the application pod created on the same node.
Each Wolf-DRA also watches the status of the resourceClaims it created, to check if someone or something (most likely the direwolf-operator) updated the session_ids of this resourceClaim:
The user is responsible for setting up the daemonsets on GPU enabled nodes, since both wolf and the application will require access to some form of GPU compute.
Wolf Container
The wolf container works the same way it does on docker, it gets a call from wolf-dra to create/stop a lobby or session, then another call to join or remove a session from a lobby.
It creates:
Lobby
When an application statefulset(pod) is created with a resourceClaim targetting driverName="wolf.dra.io", the kubernetes scheduler will pick a node with the wolf-agent installed on it, and once the pod is scheduled there, the kubelet will call the wolf-dra plugin to prepare the wayland socket, alongside the pulseaudio sink for this pod.
The wolf-dra will call LobbyCreateRequest to the wolf container
Once the resources (wayland-N, pulse.sink) are created by the wolf container, it takes their path on the node host(/var/run/wolf-sockets) and where they're supposed to be placed on the application pod (XDG_RUNTIME_DIR) alongside the env vars that configure the application to use them in the CDI it passes to the kubelet.
The application pod is scheduled and will be created after the claims(sockets) are ready to be mounted into the pod.
Session
I have not yet decided on session creation mechanism, mostly because it will depend on the how the user's moonlight client reaching the specific node where the application is and that will likely require it's own mechanism that involves the moonlight-proxy (next PR).
Development and Example Resources
Different Resources in the hack directory alongside their purpose and relevant to this PR.
Wolf-Agent
in the
hack/deploythere are 2 different manifests for wolf-agent:DeviceClasses
The device class implementation is kinda weak? I've not worked with device classes before, so I'm not fully aware of what they're capable of, so I just assigned it the role of Wolf Configuration.
I will need to expose more relevant information about wolf on the node, the main example that comes to mind is Render Nodes, so that people can use selectors to have more control on which GPU each wolf-agent can use to stream stuff.
This change should affect
hack/resources/device_classes/multi_gpu_class.yaml:also, the parameters in the DeviceClass work as an override for the parameters in the ResourceClaims.
ResourceClaims
The direwolf-operator will take an application CRD and create a statefulset, alongside a resourceClaim for the Wolf-Agent to create a lobby for.
The resourceClaim Parameters are a json object similar to wolf's lobbyCreationRequest.
and example of this is
hack/resources/dra_tests/firefox.yaml:Additional Notes:
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.