deploy-rs
deploy-rs copied to clipboard
deploy-rs builds derivations without considering flake attribute `nixConfig`
Problem
Currently, deploy-rs runs its nix build
command against a derivation path in /nix/store
. This style of running nix build misses any arguments in a defined flake.nix file, notably nixConfig
.
Details
When running deploy .#hostname
, deploy-rs will use the nix show-derivation
command to find the actual .drv
path of the NixOS configuration, and then later use it for the nix build step, for example nix build /nix/store/[...]-nixos-system-[hostname]-[...].drv
.
https://github.com/serokell/deploy-rs/blob/8c9ea9605eed20528bf60fae35a2b613b901fd77/src/push.rs#L241-L244
https://github.com/serokell/deploy-rs/blob/8c9ea9605eed20528bf60fae35a2b613b901fd77/src/push.rs#L71-L73
However, running nix build
in this way will never make it aware of the flake.nix
file its from, and any extra arguments to nixConfig
it was expect to be run against. This is problematic as it lets build steps skip any extra-substituters
that may be defined per repository.
Attempted solutions
The simplest solution would be to target the flake file /path/to/flake.nix#nixosConfigurations.[hostname].config.system.build.toplevel
instead as the argument for nix build
to let it be flake aware. But this causes us to have to re-evaluate our nix derivation for the build step. An example attempt at this was done in #206.
Current best idea
This gets sadly quite complicated to avoid doing a 2nd evaluation. But it goes as follows:
Use nix eval --json --file /path/to/flake.nix nixConfig
to quickly fetch nixConfig arguments, verify them against the running users ~/.local/share/nix/trusted-settings.json
to then append the arguments to nix build
with --option key val
if they are set to true
. Raise about missing trusted-settings or allow a user to answer y/n to append these into the json, also allow a --accept-flake-config
to avoid reading trusted settings and just append all settings without vaildation.
This was discovered during debugging odd behavior in the latest nix 2.15.0 release in #203.
CC: @rvem
Important clarification as some might not use the standard outputs.nixosConfigurations
location. So it would be required to be similar to nix build ${path_to_flake}#${nix_location_for_where_derivation_is_defined}.config.system.build.toplevel
.
There may also exist a different method to make nix aware again of the flake.nix
, but i could not find anything from a quick look.
One could also argue this could be a nix bug, but i do not have enough experience with how nixConfig
is implemented internally, if it has or should be part of the .drv
file, or have a link to the original flake.nix
file. So i am taking this as expected functionality, and a mistake with how the builder is currently implemented inside deploy-rs for flake enabled repositories.
Actually, a really simple method to solve this is using /path/to/flake.nix#deploy.nodes.[hostname].profile.system.path
instead of the .drv
path from the .path
directly.
I'm not sure about all the reasons why .drv
was used because I didn't really follow the initial stages of the development, but one thing I can think of is the fact that deploy-rs
also works for nix without flakes
Got a MVP working of what i described above with flake.path
.
However i think using --option
and adding nixConfig
to data
would be best. As using flake.path
would only work locally and not remotely.
From closer looking, there is no great solution for this. As an auto-accepting --option
may be dangerous, as nixConfig
can be partially applied by each user, or completely denied.
nixos-rebuild
uses --builders
for remote builders, which will use the nixConfig
on the local machine and not touch the builder unless needed. Deploy-rs uses ssh to run nix build
directly. While we could copy the flake.nix
instead on the remote, but it would not use the local nixConfig
list. So either an interactive mode to say yes/no to the options, or an automatic yes trough the --accept-flake-config
argument would be needed here.
All ways I have found to implement the remote-builder with nixConfig
would end with --accept-flake-config
or manually setting --option
for each nixConfig
manually. Would love feedback on what would be a nice default/expectation for when a remote build is used.