diff options
author | regnat <rg@regnat.ovh> | 2022-03-08 06:02:25 +0100 |
---|---|---|
committer | Taeer Bar-Yam <taeer.bar-yam@tweag.io> | 2022-12-08 16:03:20 -0500 |
commit | 04b113f6cb5356d44992f98928a595cdf93d561a (patch) | |
tree | e2bfb930f02057394be2714b6968a625677501ad /src/libstore/store-api.cc | |
parent | 1dd7779c7cdca7061e80ebc3b7886a2aa97b0d8a (diff) |
Fix `nix log` with CA derivations
Fix #6209
When trying to run `nix log <installable>`, try first to resolve the derivation pointed to
by `<installable>` as it is the resolved one that holds the build log.
This has a couple of shortcomings:
1. It’s expensive as it requires re-reading the derivation
2. It’s brittle because if the derivation doesn’t exist anymore or can’t
be resolved (which is the case if any one of its build inputs is missing),
then we can’t access the log anymore
However, I don’t think we can do better (at least not right now).
The alternatives I see are:
1. Copy the build log for the un-resolved derivation. But that means a
lot of duplication
2. Store the results of the resolving in the db. Which might be the best
long-term solution, but leads to a whole new class of potential
issues.
Diffstat (limited to 'src/libstore/store-api.cc')
-rw-r--r-- | src/libstore/store-api.cc | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 8811ab578..ebd641aa4 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -1300,6 +1300,34 @@ Derivation readDerivationCommon(Store& store, const StorePath& drvPath, bool req } } +std::optional<StorePath> Store::getBuildDerivationPath(const StorePath & path) +{ + + if (!path.isDerivation()) { + try { + auto info = queryPathInfo(path); + if (!info->deriver) return std::nullopt; + return *info->deriver; + } catch (InvalidPath &) { + return std::nullopt; + } + } + + if (!settings.isExperimentalFeatureEnabled(Xp::CaDerivations) || !isValidPath(path)) + return path; + + auto drv = readDerivation(path); + if (!derivationHasKnownOutputPaths(drv.type())) { + // The build log is actually attached to the corresponding + // resolved derivation, so we need to get it first + auto resolvedDrv = drv.tryResolve(*this); + if (resolvedDrv) + return writeDerivation(*this, *resolvedDrv, NoRepair, true); + } + + return path; +} + Derivation Store::readDerivation(const StorePath & drvPath) { return readDerivationCommon(*this, drvPath, true); } |