Skip to content

Commit

Permalink
Try to realise CA derivations during queryMissing
Browse files Browse the repository at this point in the history
This enables nix to correctly report what will be fetched in the case
that everything is a cache hit.

Note however that if an intermediate build of something which is not
cached could still cause products to end up being substituted if the
intermediate build results in a CA path which is in the cache.

Fixes #8615.

Signed-off-by: Peter Waller <p@pwaller.net>
  • Loading branch information
pwaller committed Jul 7, 2023
1 parent a0c6173 commit 5bbad56
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 7 deletions.
30 changes: 30 additions & 0 deletions src/libstore/misc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,36 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
auto drv = make_ref<Derivation>(derivationFromPath(bfd.drvPath));
ParsedDerivation parsedDrv(StorePath(bfd.drvPath), *drv);

if (!knownOutputPaths && settings.useSubstitutes && parsedDrv.substitutesAllowed()) {
experimentalFeatureSettings.require(Xp::CaDerivations);

// If there are unknown output paths, attempt to find if the
// paths are known to substituters through a realisation.
auto outputHashes = staticOutputHashes(*this, *drv);
knownOutputPaths = true;

for (auto [outputName, hash] : outputHashes) {
if (!bfd.outputs.contains(outputName))
continue;

bool found = false;
for (auto &sub : getDefaultSubstituters()) {
auto realisation = sub->queryRealisation({hash, outputName});
if (!realisation)
continue;
found = true;
if (!isValidPath(realisation->outPath))
invalid.insert(realisation->outPath);
break;
}
if (!found) {
// Some paths did not have a realisation, this must be built.
knownOutputPaths = false;
break;
}
}
}

if (knownOutputPaths && settings.useSubstitutes && parsedDrv.substitutesAllowed()) {
auto drvState = make_ref<Sync<DrvState>>(DrvState(invalid.size()));
for (auto & output : invalid)
Expand Down
35 changes: 28 additions & 7 deletions tests/ca/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

source common.sh

drv=$(nix-instantiate ./content-addressed.nix -A rootCA --arg seed 1)
drv=$(nix-instantiate ./content-addressed.nix -A rootCA --arg seed 1)^out
nix derivation show "$drv" --arg seed 1

buildAttr () {
Expand All @@ -14,12 +14,34 @@ buildAttr () {
nix-build "${args[@]}"
}

testRemoteCache () {
copyAttr () {
local derivationPath=$1
local seedValue=$2
shift; shift
local args=("-f" "./content-addressed.nix" "$derivationPath" --arg seed "$seedValue")
args+=("$@")
# Note: to copy CA derivations, we need to copy the realisations, which
# currently requires naming the installables, not just the derivation output
# path.
nix copy --to file://$cacheDir "${args[@]}"
}

testRemoteCacheFor () {
local derivationPath=$1
clearCache
local outPath=$(buildAttr dependentNonCA 1)
nix copy --to file://$cacheDir $outPath
copyAttr "$derivationPath" 1
clearStore
buildAttr dependentNonCA 1 --option substituters file://$cacheDir --no-require-sigs |& grepQuietInverse "building dependent-non-ca"
# Check nothing gets built.
buildAttr "$derivationPath" 1 --option substituters file://$cacheDir --no-require-sigs |& grepQuietInverse " will be built:"
}

testRemoteCache () {
testRemoteCacheFor rootCA
testRemoteCacheFor dependentCA
testRemoteCacheFor dependentNonCA
testRemoteCacheFor dependentFixedOutput
testRemoteCacheFor dependentForBuildCA
testRemoteCacheFor dependentForBuildNonCA
}

testDeterministicCA () {
Expand Down Expand Up @@ -66,8 +88,7 @@ testNormalization () {
test "$(stat -c %Y $outPath)" -eq 1
}

# Disabled until we have it properly working
# testRemoteCache
testRemoteCache
clearStore
testNormalization
testDeterministicCA
Expand Down
18 changes: 18 additions & 0 deletions tests/ca/content-addressed.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ rec {
echo ${rootCA}/non-ca-hello > $out/dep
'';
};
dependentForBuildCA = mkCADerivation {
name = "dependent-for-build-ca";
buildCommand = ''
echo "Depends on rootCA for building only"
mkdir -p $out
echo ${rootCA}
touch $out
'';
};
dependentForBuildNonCA = mkDerivation {
name = "dependent-for-build-non-ca";
buildCommand = ''
echo "Depends on rootCA for building only"
mkdir -p $out
echo ${rootCA}
touch $out
'';
};
dependentFixedOutput = mkDerivation {
name = "dependent-fixed-output";
outputHashMode = "recursive";
Expand Down

0 comments on commit 5bbad56

Please sign in to comment.