aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build/derivation-goal.cc
AgeCommit message (Collapse)Author
2023-06-19Create `worker_proto::{Read,Write}Conn`John Ericson
Pass this around instead of `Source &` and `Sink &` directly. This will give us something to put the protocol version on once the time comes. To do this ergonomically, we need to expose `RemoteStore::Connection`, so do that too. Give it some more API docs while we are at it.
2023-06-19Put worker protocol items inside a `WorkerProto` structJohn Ericson
See API docs on that struct for why. The pasing as as template argument doesn't yet happen in that commit, but will instead happen in later commit. Also make `WorkerOp` (now `Op`) and enum struct. This led us to catch that two operations were not handled! Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
2023-06-19Split out worker protocol template definitions from declarationsJohn Ericson
This is generally a fine practice: Putting implementations in headers makes them harder to read and slows compilation. Unfortunately it is necessary for templates, but we can ameliorate that by putting them in a separate header. Only files which need to instantiate those templates will need to include the header with the implementation; the rest can just include the declaration. This is now documenting in the contributing guide. Also, it just happens that these polymorphic serializers are the protocol agnostic ones. (Worker and serve protocol have the same logic for these container types.) This means by doing this general template cleanup, we are also getting a head start on better indicating which code is protocol-specific and which code is shared between protocols.
2023-05-17Revert "Revert "Use template structs instead of phantoms""John Ericson
This is the more typically way to do [Argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)-leveraging generic serializers in C++. It makes the relationship between the `read` and `write` methods more clear and rigorous, and also looks more familiar to users coming from other languages that do not have C++'s libertine ad-hoc overloading. I am returning to this because during the review in https://github.com/NixOS/nix/pull/6223, it came up as something that would make the code easier to read --- easier today hopefully already, but definitely easier if we were have multiple codified protocols with code sharing between them as that PR seeks to accomplish. If I recall correctly, the main criticism of this the first time around (in 2020) was that having to specify the type when writing, e.g. `WorkerProto<MyType>::write`, was too verbose and cumbersome. This is now addressed with the `workerProtoWrite` wrapper function. This method is also the way `nlohmann::json`, which we have used for a number of years now, does its serializers, for what its worth. This reverts commit 45a0ed82f089158a79c8c25ef844c55e4a74fc35. That commit in turn reverted 9ab07e99f527d1fa3adfa02839da477a1528d64b.
2023-05-10Merge pull request #3959 from obsidiansystems/ca-drv-exoticJohn Ericson
Derivations can output "text-hashed" data
2023-05-08CA: rewrite hashes for all outputs, not just the wanted onesYorick van Pelt
2023-05-08libstore: also pass unwanted outputs to the post-build-hookYorick van Pelt
2023-04-19Remove references from fixed output derivation ab syntaxJohn Ericson
In other words, use a plain `ContentAddress` not `ContentAddressWithReferences` for `DerivationOutput::CAFixed`. Supporting fixed output derivations with (fixed) references would be a cool feature, but it is out of scope at this moment.
2023-04-15Introduce `SingleDrvOutputs`John Ericson
In many cases we are dealing with a collection of realisations, they are all outputs of the same derivation. In that case, we don't need "derivation hashes modulos" to be part of our map key, because the output names alone will be unique. Those hashes are still part of the realisation proper, so we aren't loosing any information, we're just "normalizing our schema" by narrowing the "primary key". Besides making our data model a bit "tighter" this allows us to avoid a double `for` loop in `DerivationGoal::waiteeDone`. The inner `for` loop was previously just to select the output we cared about without knowing its hash. Now we can just select the output by name directly. Note that neither protocol is changed as part of this: we are still transferring `DrvOutputs` over the wire for `BuildResult`s. I would only consider revising this once #6223 is merged, and we can mention protocol versions inside factored-out serialization logic. Until then it is better not change anything because it would come a the cost of code reuse.
2023-04-15Make restarting state machines explicitJohn Ericson
If my memory is correct, @edolstra objected to modifying `wantedOutputs` upon falling back to doing a build (as we did before), because we should only modify it in response to new requests --- *actual* wants --- and not because we are "incidentally" building all the outptus beyond what may have been requested. That's a fair point, and the alternative is to replace the boolean soup with proper enums: Instead of modifying `wantedOuputs` som more, we'll modify `needsRestart` to indicate we are passed the need.
2023-04-15Make `KeyedBuildResult`, `BuildResult` like before, and fix bug another wayJohn Ericson
In https://github.com/NixOS/nix/pull/6311#discussion_r834863823, I realized since derivation goals' wanted outputs can "grow" due to overlapping dependencies (See `DerivationGoal::addWantedOutputs`, called by `Worker::makeDerivationGoalCommon`), the previous bug fix had an unfortunate side effect of causing more pointless rebuilds. In paticular, we have this situation: 1. Goal made from `DerivedPath::Built { foo, {a} }`. 2. Goal gives on on substituting, starts building. 3. Goal made from `DerivedPath::Built { foo, {b} }`, in fact is just modified original goal. 4. Though the goal had gotten as far as building, so all outputs were going to be produced, `addWantedOutputs` no longer knows that and so the goal is flagged to be restarted. This might sound far-fetched with input-addressed drvs, where we usually basically have all our goals "planned out" before we start doing anything, but with CA derivation goals and especially RFC 92, where *drv resolution* means goals are created after some building is completed, it is more likely to happen. So the first thing to do was restore the clearing of `wantedOutputs` we used to do, and then filter the outputs in `buildPathsWithResults` to only get the ones we care about. But fix also has its own side effect in that the `DerivedPath` in the `BuildResult` in `DerivationGoal` cannot be trusted; it is merely the *first* `DerivedPath` for which this goal was originally created. To remedy this, I made `BuildResult` be like it was before, and instead made `KeyedBuildResult` be a subclass wit the path. Only `buildPathsWithResults` returns `KeyedBuildResult`s, everything else just becomes like it was before, where the "key" is unambiguous from context. I think separating the "primary key" field(s) from the other fields is good practical in general anyways. (I would like to do the same thing for `ValidPathInfo`.) Among other things, it allows constructions like `std::map<Key, ThingWithKey>` where doesn't contain duplicate keys and just precludes the possibility of those duplicate keys being out of sync. We might leverage the above someday to overload `buildPathsWithResults` to take a *set* of return a *map* per the above. ----- Unfortunately, we need to avoid C++20 strictness on designated initializers. (BTW https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2287r1.html this offers some new syntax for this use-case. Hopefully this will be adopted and we can eventually use it.) No having that yet, maybe it would be better to not make `KeyedBuildResult` a subclass to just avoid this. Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
2023-03-28Don't recommend 'nix log' unless experimental feature is enabledBjørn Forsman
This fixes the issue that `nix-build`, without experimental feature 'nix-command' enabled, recommends the experimental CLI `nix log` to view build logs. Now it'll recommend the stable `nix-store -l` CLI instead. Fixes https://github.com/NixOS/nix/issues/8118
2023-03-20Move enabled experimental feature to libutil structJohn Ericson
This is needed in subsequent commits to allow the settings and CLI args infrastructure itself to read this setting.
2023-03-02Remove FormatOrString and remaining uses of format()Eelco Dolstra
2023-01-12Split `OutputsSpec::merge` into `OuputsSpec::{union_, isSubsetOf}`John Ericson
Additionally get rid of the evil time we made an empty `OutputSpec::Names()`.
2023-01-11Make it hard to construct an empty `OutputsSpec::Names`John Ericson
This should be a non-empty set, and so we don't want people doing this by accident. We remove the zero-0 constructor with a little inheritance trickery.
2023-01-11Split `OutputsSpec` and `ExtendedOutputsSpec`, use the former moreJohn Ericson
`DerivedPath::Built` and `DerivationGoal` were previously using a regular set with the convention that the empty set means all outputs. But it is easy to forget about this rule when processing those sets. Using `OutputSpec` forces us to get it right.
2023-01-06Merge pull request #7307 from hercules-ci/derivation-goal-improve-commentThéophane Hufschmitt
libstore/derivation-goal: Elaborate a TODO for performance concern
2022-12-23nix develop: Set personalityEelco Dolstra
This makes 'nix develop' set the Linux personality in the same way that the actual build does, allowing a command like 'nix develop nix#devShells.i686-linux.default' on x86_64-linux to work correctly.
2022-12-12Merge pull request #7421 from edolstra/lazy-trees-trivial-changesEelco Dolstra
Trivial changes from the lazy-trees branch
2022-12-09Merge pull request #7409 from tweag/fix-6383Théophane Hufschmitt
check the store for input before failing (hopefully fix #6383)
2022-12-07Trivial changes from the lazy-trees branchEelco Dolstra
2022-12-07Remove repeat and enforce-determinism optionsLinus Heckemann
These only functioned if a very narrow combination of conditions held: - The result path does not yet exist (--check did not result in repeated builds), AND - The result path is not available from any configured substituters, AND - No remote builders that can build the path are available. If any of these do not hold, a derivation would be built 0 or 1 times regardless of the repeat option. Thus, remove it to avoid confusion.
2022-12-06improve styleTaeer Bar-Yam
2022-12-05check the store for input before failing (hopefully fix #6383)Taeer Bar-Yam
2022-12-05check the store for input before failing (hopefully fix #6700)Taeer Bar-Yam
2022-11-29Merge pull request #3600 from NixOS/auto-uid-allocationEelco Dolstra
Automatic UID allocation
2022-11-21Merge remote-tracking branch 'origin/master' into auto-uid-allocationEelco Dolstra
2022-11-18Get CPU stats from the cgroupEelco Dolstra
2022-11-16Replace src/libutil/json.cc with nlohmann json generationYorick van Pelt
2022-11-15libstore/derivation-goal: Elaborate a TODO for performance concernRobert Hensing
2022-11-14derivation-goal: Fix `requires non-existing output` errorRobert Hensing
It occurred when a output of the dependency was already available, so it didn't need rebuilding and didn't get added to the inputDrvOutputs. This process-related info wasn't suitable for the purpose of finding the actual input paths for the builder. It is better to do this in absolute terms by querying the store.
2022-09-02Don’t readDerivation if impure derivations feature is disabledMatthew Bauer
readDerivation is pretty slow, and while it may not be significant for some use cases, on things like ghc-nix where we have thousands of derivations is really slows things down. So, this just doesn’t do the impure derivation check if the impure derivation experimental feature is disabled. Perhaps we could cache the result of isPure() and keep the check, but this is a quick fix to for the slowdown introduced with impure derivations features in 2.8.0.
2022-08-10Merge pull request #6850 from NinjaTrappeur/nin/build-checkThéophane Hufschmitt
Fix Nix build --check flag
2022-08-03moveFile -> renameFileThéophane Hufschmitt
`move` tends to have this `mv` connotation of “I will copy it for you if needs be”
2022-08-03Create a wrapper around stdlib’s `rename`Théophane Hufschmitt
Directly takes some c++ strings, and gently throws an exception on error (rather than having to inline this logic everywhere)
2022-08-01derivation-goal.cc: remove bmCheck custom return branch on buildDoneFélix Baylac-Jacqué
Once a derivation goal has been completed, we check whether or not this goal was meant to be repeated to check its output. An early return branch was preventing the worker to reach that repeat code branch, hence breaking the --check command (#2619). It seems like this early return branch is an artifact of a passed refactoring. As far as I can tell, buildDone's main branch also cleanup the tmp directory before returning.
2022-05-04Get rid of most `.at` calls (#6393)Alain Zscheile
Use one of `get` or `getOr` instead which will either return a null-pointer (with a nicer error message) or a default value when the key is missing.
2022-04-28Fix passing $OUT_PATHS to the post-build hookEelco Dolstra
Fixes #6446.
2022-04-08Remove duplicate "error:"Eelco Dolstra
2022-03-31needsNetworkAccess() -> isSandboxed()Eelco Dolstra
2022-03-31Support fixed-output derivations depending on impure derivationsEelco Dolstra
2022-03-31Add support for impure derivationsEelco Dolstra
Impure derivations are derivations that can produce a different result every time they're built. Example: stdenv.mkDerivation { name = "impure"; __impure = true; # marks this derivation as impure outputHashAlgo = "sha256"; outputHashMode = "recursive"; buildCommand = "date > $out"; }; Some important characteristics: * This requires the 'impure-derivations' experimental feature. * Impure derivations are not "cached". Thus, running "nix-build" on the example above multiple times will cause a rebuild every time. * They are implemented similar to CA derivations, i.e. the output is moved to a content-addressed path in the store. The difference is that we don't register a realisation in the Nix database. * Pure derivations are not allowed to depend on impure derivations. In the future fixed-output derivations will be allowed to depend on impure derivations, thus forming an "impurity barrier" in the dependency graph. * When sandboxing is enabled, impure derivations can access the network in the same way as fixed-output derivations. In relaxed sandboxing mode, they can access the local filesystem.
2022-03-24Retry substitution after an incomplete closure only onceEelco Dolstra
This avoids an infinite loop in the final test in tests/binary-cache.sh. I think this was only not triggered previously by accident (because we were clearing wantedOutputs in between).
2022-03-24Only return wanted outputsEelco Dolstra
2022-03-18Generalize `DerivationType` in preparation for impure derivationsJohn Ericson
2022-03-09BuildResult: Remove unused drvPath fieldEelco Dolstra
2022-03-09BuildResult: Use DerivedPathEelco Dolstra
2022-03-08Add Store::buildPathsWithResults()Eelco Dolstra
This function is like buildPaths(), except that it returns a vector of BuildResults containing the exact statuses and output paths of each derivation / substitution. This is convenient for functions like Installable::build(), because they then don't need to do another series of calls to get the outputs of CA derivations. It's also a precondition to impure derivations, where we *can't* query the output of those derivations since they're not stored in the Nix database. Note that PathSubstitutionGoal can now also return a BuildStatus.
2022-02-28libstore/build: add a few explanatory comments; simplifyMaximilian Bosch