libstore: pass the derivation being built to the post-build-hook as JSON - #16413
libstore: pass the derivation being built to the post-build-hook as JSON#16413amaanq wants to merge 1 commit into
Conversation
0d58607 to
a47236c
Compare
|
I requested that @amaanq do this based on what I understand @NixOS/cuda-maintainers needs to upgrade their Hydra. |
|
Why JSON and not the stable ATerm? |
a47236c to
7df0419
Compare
|
@xokdvium because we don't have ATerm for resolved derivations, though I suppose we could fudge an empty |
|
I do agree we should |
Isn't that exactly what we want? empty inputDrvs is perfectly fine in this case |
|
If one wants to opt into converting ATerm -> json can't we carry a plumbing convenience command? |
|
Yes, empty |
But aren't we going to pass in the original derivation in case it didn't need to be resolved first? Or would that to be consistent everywhere with remote building? Wasn't the DRV_PATH the unresolved one in the local case at least? |
|
@xokdvium it is my view that morally we always build a resolved derivation --- the only reason we don't realize input-addressed ones is that it interferes with trustless remote building because of a design flaw in the "derivation masking" (née Think if we have two input-addressing derivations that produce the same paths, we're only going to build one of them, right? Then it would be a bit arbitrary which one ended up making it to the build hook, right? |
|
Indeed, I wouldn't expose the unresolved |
| if (dup2(drvJsonFd.get(), STDIN_FILENO) == -1) | ||
| throw SysError("dupping stdin"); |
There was a problem hiding this comment.
Seems not terribly extensible. What if we wanted to pass more info to the hook? Also how would the hook feature detect that the version of nix is new enough? Do a non-blocking read of stdin?
Can't we use a non-standard file descriptor maybe and pass its number in an env variable?
There was a problem hiding this comment.
Seems not terribly extensible. What if we wanted to pass more info to the hook?
That is why I asked @amaanq to make the top-level record to contain derivation (before I realized the we should include the output map for the CA case too). That puts us in compliance with the JSON guidelines re extensibility.
Can't we use a non-standard file descriptor maybe and pass its number in an env variable?
Yeah sure I am OK with that. I like the socket-activation vibes :)
Sounds like maybe we should also expose RESOLVED_DRV_PATH to the hook for more clarity. That way the hook wouldn't need to guess which case it is |
7df0419 to
bedd51c
Compare
CC #9272 (it's "pre-", but same logic)
FWIW it's also substantially easier to consume JSON in an external hook/plug-in, than it is to consume ATerm.
I've already argued this before, I believe the "proper" approach (conveniently, we don't necessarily need "proper", imo it's ok to change hook interfaces) would be to have in place a protocol that lets you inquire about any path referenced in the context of the current "build request". Essentially, my reasoning was: Details- pre-build-hook gets a drvPath, but it's basically a string of random characters, unless you can access the drv structure, so "why pass the drvPath in the first place?" - the drv structure contains inputDrvs and inputSrcs, but they are, too, basically random strings unless you can also access the corresponding drv structures or file paths, or access a database where you compare these ids against other ids. If can't access that, then by the same token "why include input{Drv,Src}s in the response at all?" |
|
@SomeoneSerge we could definitely e.g. rig up the hook to run with the daemon protocol or something so one can inquire about input and output paths to their heart's content :) |
Hence why my suggestion to have a plumbing command to convert the stable ATerm into the experimental and very unstable JSON variant that's only really available in the XP cli if one opts into that. Wouldn't want to use to even bother with that can of worms now and maybe we can just have the internal plumbing be in the usual representation. |
|
Maybe |
But that's already available in the DRV_PATH, no? |
bedd51c to
59e567b
Compare
|
True, it is. and we can do |
c210442 to
df9b767
Compare
| /* closeExtraFDs() closes everything above stderr, hence the detour via stdin and stdout. */ | ||
| if (dup2(STDIN_FILENO, drvAtermFdNum) == -1) | ||
| throw SysError("dupping the derivation file onto fd %d", drvAtermFdNum); | ||
| if (dup2(STDOUT_FILENO, buildInfoJsonFdNum) == -1) | ||
| throw SysError("dupping the build info file onto fd %d", buildInfoJsonFdNum); | ||
| if (dup2(STDERR_FILENO, STDOUT_FILENO) == -1) | ||
| throw SysError("cannot dup stderr into stdout"); | ||
| AutoCloseFD fdDevNull = open("/dev/null", O_RDONLY | O_CLOEXEC); | ||
| if (!fdDevNull) | ||
| throw SysError("opening /dev/null"); | ||
| if (dup2(fdDevNull.get(), STDIN_FILENO) == -1) | ||
| throw SysError("dupping /dev/null onto stdin"); |
There was a problem hiding this comment.
We should just have a generic FD dup action which handles all of this internally. I.e. not use startProcess but instead have spawnProgram that does all of this.
There was a problem hiding this comment.
We could land that in a prep PR as I think there are a few places that use it.
There was a problem hiding this comment.
I have started working on that locally, so maybe a couple of days until that's beat into shape?
Assisted-by: Claude-Code (Claude Opus 5)
df9b767 to
9cef817
Compare
|
Btw @Ericson2314, wasn't the issue with CUDA hydra the pre-build-hook, not post? I'm not sure why we are touching post- one here then. |
Hi! Here is the patch we apply to Hydra to fix our use case: https://github.com/nixos-cuda/infra/blob/master/hosts/hydra/hydra/0001-hydra-queue-runner-make-drv-available-to-remote-pre-build-hook.patch |
That's not great... because it ships around the whole derivation closure and unused sources. Hence why the idea here is to stuff ATerm into a side-channel and not write to the store (because then all the references have to be copied as well). |
Definitely. It's just a dirty workaround. I trust you on the better solution. |
Motivation
Currently, a post-build hook only gets
DRV_PATH, but the derivation the builder actually ran (the resolved derivation, for CA builds) may not exist on disk as a .drv file at all, so consumers like Hydra can't reconstruct what was actually built.Context
The hook now receives the JSON form of the
BasicDerivationthatDerivationBuildingGoalalready holds in memory on its standard input.Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.