Allow running without container with nix - #345
Conversation
|
Cool! it's definitely a start. |
1b5f6ca to
4e30e32
Compare
f3490d2 to
325f2a4
Compare
|
@avandecreme I appreciate the work you are doing here. But you keep force pushing a single commit with ~1500 lines changed, I'm not sure how to review that and understand all the changes, I can't follow your reasoning if it's a single commit. |
| inputs = { | ||
| nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; | ||
|
|
||
| runfromprocess-rs.url = "github:quietvoid/runfromprocess-rs?rev=a3d003c07d1bd11ff93c4cac96d2c3aa5deb8471"; |
There was a problem hiding this comment.
This is not ideal because it pulls an old rust compiler. Maybe we should just embed a built binary in this repo?
There was a problem hiding this comment.
Why would it pull an old compiler? There's nothing in the flake indicating a specific version.
There could be a release with a pre-built binary which can be downloaded, instead.
There was a problem hiding this comment.
Why would it pull an old compiler?
Because it picks the one in the lockfile.
Apparently, I could write this to avoid that though:
runfromprocess-rs = {
url = "github:quietvoid/runfromprocess-rs?rev=a3d003c07d1bd11ff93c4cac96d2c3aa5deb8471";
inputs.nixpkgs.follows = "nixpkgs";
inputs.fenix.follows = "fenix";
};Using a pre-built binary would be better in my opinion. This would avoid having to pull any rust compiler.
Would you accept a PR on https://github.com/quietvoid/runfromprocess-rs to make it publish a binary on release?
There was a problem hiding this comment.
I don't know Nix but there's no mention of the compiler in the lockfile either, only rust-analyzer.
I know @glennvl has forked this so maybe you guys should figure out if mine should be replaced, I don't really intend to maintain it.
There was a problem hiding this comment.
Fenix is the package bringing the rust toolchain. It is locked on a 2023 version in the lockfile.
There was a problem hiding this comment.
When running Zwift without a container, there is no container image to provide the latest Zwift version. So updates have to be done locally. Why not just use the Zwift launcher instead of bypassing it?
There was a problem hiding this comment.
There is this comment saying that the launcher is not fully functional under wine:
Lines 143 to 145 in 0872729
It seems to work now though, albeit with some display glitches sometimes.
I will try to add a commit in that direction
There was a problem hiding this comment.
Commit added. I would still like to check which packages are really necessary in the FHS as well as checking what options still make sense when using the launcher (and update the doc accordingly).
c7658ca to
440ba48
Compare
Move the container package wrapper, common derivation helpers, and NixOS module out of flake.nix into separate files under nix/. flake.nix becomes a thin orchestrator. No behavioral change.
Add support for running Zwift natively using Wine in a FHS environment as an alternative to containers. Introduces src/zwift-nix-fhs.sh as the FHS launch script, extends run_zwift.sh and update_zwift.sh to handle the nix-fhs container tool, adds nix/zwift-fhs-package.nix, wires up the new runfromprocess-rs input, and extends the NixOS module with containerTool = "fhs".
Parametrize the NixOS test flake to build all three containerTool values (podman, docker, fhs) and update CI to check all three.
Update the NixOS documentation with containerTool = "fhs" and winePrefix.
I split in four commits. Hopefully, this is more approachable. I also cleaned up stuff from claude. |
|
Took a proper look through this, really like where it's heading 🙌 getting a ride done natively is a great milestone. Being critical below since you asked, and since a few things need sorting before this can go in. The thing that stands out most: this is basically 3 PRs in one (the flake refactor into nix/, the nixpkgs unstable → nixos-26.05 bump, and the fhs backend), and the "no behavioral change" refactor actually breaks the existing container path in two spots. Those are the real blockers for me: Blockers (these hit the working container path, not just fhs)
fhs stuff to sort
Smaller things
On the nixpkgs bump, no objection to pinning stable, but it's really its own change. For the container path nixpkgs only affects the wrapper script + devshell, for fhs it pins the wine version which is what drives game compat, so it deserves its own reasoning. My suggestion: split it up, land the pure refactor first (with the two blockers fixed and verified actually no-op), then bring fhs in on top. Happy to help review the pieces. Nice work getting this far 👍 |
There was a problem hiding this comment.
I'm thinking this should be a separate project entirely. We have netbrain/zwift for the container-based solution. Why not create netbrain/zwift-nix for the native nix solution? Combining two projects that barely have anything in common creates a difficult to maintain mess in my opinion.
What are we doing in netbrain/zwift?
- We have a container image with wine and zwift in it
- A github action keeps zwift up-to-date in the container image
- The end user uses the container and never updates zwift itself on his system
- The zwift launcher is bypassed entirely (it used to not work in the past, it does now, but we don't need it because the latest zwift version is baked into the image)
- Because we bypass the launcher, the end user's zwift credentials are not persisted automatically. So we work around this by having our custom login script and way to persist credentials.
- We need a lot of configuration options to make hardware accelerated graphics work in the container
- We provide some convenience options because it is hard to access data inside the container
- We have a script that launches the zwift container image with all the right parameters, this launcher script is installed on the end-user's system using an installer script or through the nix flake
What should be done in netbrain/zwift-nix?
- Updates happen on the end-user's system, so it cannot bypass the launcher
- The nix flake should install the necessary dependencies (wine, winetricks, gamemode)
- The nix flake should install zwift (wine ZwiftInstaller.exe)
- The nix flake should start the zwift launcher, which then automatically handles persisting login info, updating zwift, ..., just the way it works on windows
- After the launcher is started, its job is done, no need kill the launcher, wait for zwift to exit, ...
- No need for fancy helper scripts that bypass the launcher, update zwift, login, ...
Which options still make sense in netbrain/zwift-nix?
- Gamemode: If enabled, launch the zwift launcher using gamemode
- Wayland: If enabled, set DISPLAY= before launching the zwift launcher
- EGL/GLX: Potentially add an option that let's the end-user select whether wine should use EGL (default) or GLX as OpenGL backend
- Anything related to zwift data and configuration (override graphics, override resolution, mapping directories): Document where to find/modify it instead, since it's easily accessible on the end user's system.
I'm not seeing a common base that justifies keeping these two projects together.
Obviously @avandecreme knows his way around nix, so if a new netbrain/zwift-nix project is created, I'd still like him to have a look at the nix stuff in the netbrain/zwift project to see what can be improved there.
|
Really solid breakdown, you nailed why the two paths feel so different, and i agree the current module is a mess with the container options bleeding into the native path. But i'd push back on the separate repo, i think we'd be fixing a structure problem with a repo boundary. What i don't want to lose by splitting: the single front door for "zwift on linux" (one repo, one issue tracker, one docs site, pick a backend), and we'd end up duplicating the flake/desktop/icon scaffolding across two repos. Honestly the PR is already 90% a monorepo, one flake exposing So i'd rather fix the module than move the code. Rough shape: programs.zwift = {
enable = true;
backend = "container"; # "container" | "native" (default container)
# shared
username = "...";
password = "..."; # native: only if we add token login, otherwise drop
debug = false;
verbosity = 1;
container = {
image; version;
dontCheck; dontPull; dontClean; dryRun; interactive;
networking; uid; gid; vgaDeviceFlag; privilegedContainer; extraArgs;
overrideGraphics; overrideResolution;
workoutDir; activityDir; logDir; screenshotsDir;
};
native = {
winePrefix;
gamemode = true; # launch the launcher via gamemoderun
wayland = false; # DISPLAY= / wine wayland driver
openglBackend = "egl"; # "egl" | "glx"
# data/config: documented (it's on the user's own fs), not options
};
};plus assertions so setting File layout stays close to what's already there: flake keeps exposing Fair warning: nesting like this is a breaking change for existing container configs ( And i fully agree with your option triage, native basically collapses to gamemode + wayland + egl/glx + "your data lives here" docs. That's a feature, the native module ends up tiny and sits happily next to the container one. The one thing that'd flip me to a separate repo: if the plan is for the native path to move on its own cadence/CI without being gated on this repo. If that's where this is heading, split makes sense. If not, i'd keep it here. What do you both think? |
|
Thanks a lot for the extensive review! At some point I wondered whether it should be a separate repo too. But I agree with @netbrain that having a single point of entry for zwift on linux is valuable. I tried to avoid breaking changes until now but this probably would not be too much of a problem for nix users if we can make the error messages explicit on what the change should be.
I don't really see that happening. On the other hand, even if the common code is low, it still exists. Having one doc for everything is nice too in my opinion. So keeping one repo is preferable in my opinion. |
This is variant number 3 in #28
This is very much not ready for merge but since I was able to make my first ride with it, I figured I would share it already.
Things to fix before merging: