22#include " build/derivation-check.hh"
33#include " nix/store/globals.hh"
44#include " nix/store/local-store.hh"
5+ #include " nix/store/restricted-store.hh"
56#include " nix/store/path-references.hh"
67#include " nix/store/posix-fs-canonicalise.hh"
78#include " nix/util/archive.hh"
@@ -100,7 +101,7 @@ static void replaceValidPath(const std::filesystem::path & storePath, const std:
100101 deletePath (oldPath);
101102}
102103
103- SingleDrvOutputs DerivationBuilderImpl::registerOutputs ()
104+ SingleDrvOutputs DerivationBuilderImpl::registerOutputs (LocalStore & localStore )
104105{
105106 std::map<std::string, ValidPathInfo> infos;
106107
@@ -326,7 +327,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
326327 /* Put the temporary copy in a directory inaccessible to the builder.
327328 actualPath might point inside the build chroot, which is controlled
328329 by the derivation builder. */
329- auto [rewriteTempDir, rewriteTempDirFd] = store .createTempDirInStore ();
330+ auto [rewriteTempDir, rewriteTempDirFd] = localStore .createTempDirInStore ();
330331 AutoDelete delRewriteTempDir (rewriteTempDir);
331332 std::filesystem::path tmpPath = rewriteTempDir / " x" ;
332333 restorePath (tmpPath, *source);
@@ -410,7 +411,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
410411 }();
411412
412413 auto newInfo0 = ValidPathInfo::makeFromCA (
413- store ,
414+ storeDirConfig ,
414415 outputPathName (drv.name , outputName),
415416 ContentAddressWithReferences::fromParts (outputHash.method , std::move (got), rewriteRefs ()),
416417 Hash::dummy);
@@ -438,15 +439,15 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
438439
439440 auto moveOutputToTempDir = [&]() -> void {
440441 std::filesystem::path tempDir;
441- std::tie (tempDir, tempDirFd) = store .createTempDirInStore ();
442+ std::tie (tempDir, tempDirFd) = localStore .createTempDirInStore ();
442443 delTempDir = AutoDelete (tempDir);
443444
444445 auto tmpOutput = tempDir / " x" ;
445446
446447 /* Copy files to break stale file descriptors. copyRecursive below will use
447448 reflinking to optimise the copying overhead. */
448449 auto pathAccessor = makeFSSourceAccessor (actualPath);
449- RestoreSink restoreSink{store. config ->getLocalSettings ().fsyncStorePaths };
450+ RestoreSink restoreSink{store->getLocalSettings ().fsyncStorePaths };
450451 restoreSink.dstPath = tmpOutput;
451452 copyRecursive (*pathAccessor, CanonPath::root, restoreSink, CanonPath::root);
452453 /* This makes it slightly harder to make sense of the control flow. The rule
@@ -471,7 +472,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
471472 {makeFSSourceAccessor (actualPath), CanonPath::root},
472473 FileSerialisationMethod::NixArchive,
473474 HashAlgorithm::SHA256 );
474- ValidPathInfo newInfo0{requiredFinalPath, {store , narHashAndSize.hash }};
475+ ValidPathInfo newInfo0{requiredFinalPath, {storeDirConfig , narHashAndSize.hash }};
475476 newInfo0.narSize = narHashAndSize.numBytesDigested ;
476477 auto refs = rewriteRefs ();
477478 newInfo0.references = std::move (refs.others );
@@ -532,44 +533,44 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
532533 derivations. */
533534 PathLocks dynamicOutputLock;
534535 dynamicOutputLock.setDeletion (true );
535- auto optFixedPath = output->path (store , drv.name , outputName);
536+ auto optFixedPath = output->path (storeDirConfig , drv.name , outputName);
536537 if (!optFixedPath || storeDirConfig.printStorePath (*optFixedPath) != finalDestPath) {
537538 assert (newInfo.ca );
538539
539540 /* Don't wait on lock for the hash-mismatching fixed-output
540541 derivation case, to avoid a deadlock in the case where a build
541542 with the correct hash is in progress. */
542- bool locked = dynamicOutputLock.lockPaths ({store. toRealPath (newInfo.path )}, " " , !optFixedPath);
543+ bool locked = dynamicOutputLock.lockPaths ({store-> toRealPath (newInfo.path )}, " " , !optFixedPath);
543544
544545 /* If we can't lock the correct path, clean up and bail now. */
545546 if (!locked) {
546547 debug (
547548 " failed to lock correct output path of %s, namely %s, not moving output" ,
548549 storeDirConfig.printStorePath (drvPath),
549- PathFmt (store. toRealPath (newInfo.path )));
550+ PathFmt (store-> toRealPath (newInfo.path )));
550551 deletePath (actualPath);
551552 /* Trigger the hash-mismatch error. */
552- checkCAOutput (store , drvPath, *output, newInfo, outputName);
553+ checkCAOutput (storeDirConfig , drvPath, *output, newInfo, outputName);
553554 unreachable ();
554555 }
555556 }
556557
557558 /* Move files, if needed */
558- if (store. toRealPath (newInfo.path ) != actualPath) {
559+ if (store-> toRealPath (newInfo.path ) != actualPath) {
559560 if (buildMode == bmRepair) {
560561 /* Path already exists, need to replace it */
561- replaceValidPath (store. toRealPath (newInfo.path ), actualPath);
562+ replaceValidPath (store-> toRealPath (newInfo.path ), actualPath);
562563 } else if (buildMode == bmCheck) {
563564 /* Path already exists, and we want to compare, so we leave out
564565 new path in place. */
565- } else if (store .isValidPath (newInfo.path )) {
566+ } else if (localStore .isValidPath (newInfo.path )) {
566567 /* Path already exists because CA path produced by something
567568 else. No moving needed. */
568569 assert (newInfo.ca );
569570 /* Can delete our scratch copy now. */
570571 deletePath (actualPath);
571572 } else {
572- auto destPath = store. toRealPath (newInfo.path );
573+ auto destPath = store-> toRealPath (newInfo.path );
573574 deletePath (destPath);
574575 movePath (actualPath, destPath);
575576 }
@@ -578,12 +579,12 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
578579 if (buildMode == bmCheck) {
579580 /* Check against already registered outputs */
580581
581- if (store .isValidPath (newInfo.path )) {
582- ValidPathInfo oldInfo (*store .queryPathInfo (newInfo.path ));
582+ if (localStore .isValidPath (newInfo.path )) {
583+ ValidPathInfo oldInfo (*localStore .queryPathInfo (newInfo.path ));
583584 if (newInfo.narHash != oldInfo.narHash ) {
584585 auto * diffHook = localSettings.getDiffHook ();
585586 if (diffHook || settings.keepFailed ) {
586- auto dst = store. toRealPath (newInfo.path );
587+ auto dst = store-> toRealPath (newInfo.path );
587588 dst += " .check" ;
588589 deletePath (dst);
589590 movePath (actualPath, dst);
@@ -604,20 +605,20 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
604605 throw NotDeterministic (
605606 " derivation '%s' may not be deterministic: output %s differs from %s" ,
606607 storeDirConfig.printStorePath (drvPath),
607- PathFmt (store. toRealPath (newInfo.path )),
608+ PathFmt (store-> toRealPath (newInfo.path )),
608609 PathFmt (dst));
609610 } else
610611 throw NotDeterministic (
611612 " derivation '%s' may not be deterministic: output %s differs" ,
612613 storeDirConfig.printStorePath (drvPath),
613- PathFmt (store. toRealPath (newInfo.path )));
614+ PathFmt (store-> toRealPath (newInfo.path )));
614615 }
615616
616617 /* Since we verified the build, it's now ultimately trusted. */
617618 if (!oldInfo.ultimate ) {
618619 oldInfo.ultimate = true ;
619- store .signPathInfo (oldInfo);
620- store .registerValidPaths ({{oldInfo.path , oldInfo}});
620+ localStore .signPathInfo (oldInfo);
621+ localStore .registerValidPaths ({{oldInfo.path , oldInfo}});
621622 }
622623 }
623624 } else {
@@ -631,12 +632,13 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
631632 debug (" unreferenced input: '%1%'" , storeDirConfig.printStorePath (i));
632633 }
633634
634- if (!store.isValidPath (newInfo.path ))
635- store.optimisePath (store.toRealPath (newInfo.path ), NoRepair); // FIXME: combine with scanForReferences()
635+ if (!localStore.isValidPath (newInfo.path ))
636+ localStore.optimisePath (
637+ store->toRealPath (newInfo.path ), NoRepair); // FIXME: combine with scanForReferences()
636638
637639 newInfo.deriver = drvPath;
638640 newInfo.ultimate = true ;
639- store .signPathInfo (newInfo);
641+ localStore .signPathInfo (newInfo);
640642
641643 finish (newInfo.path );
642644
@@ -651,7 +653,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
651653 possibly quite slow thing it was) doesn't have to be done
652654 again. */
653655 if (newInfo.ca )
654- store .registerValidPaths ({{newInfo.path , newInfo}});
656+ localStore .registerValidPaths ({{newInfo.path , newInfo}});
655657 }
656658
657659 /* Do this in both the check and non-check cases, because we
@@ -662,7 +664,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
662664
663665 /* Apply output checks. This includes checking of the wanted vs got
664666 hash of fixed-outputs. */
665- checkOutputs (store , drvPath, drv, drvOptions.outputChecks , infos);
667+ checkOutputs (localStore , drvPath, drv, drvOptions.outputChecks , infos);
666668
667669 if (buildMode == bmCheck) {
668670 return {};
@@ -676,7 +678,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
676678 for (auto & [outputName, newInfo] : infos) {
677679 infos2.insert_or_assign (newInfo.path , newInfo);
678680 }
679- store .registerValidPaths (infos2);
681+ localStore .registerValidPaths (infos2);
680682 }
681683
682684 /* If we made it this far, we are sure the output matches the
@@ -699,13 +701,64 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
699701 },
700702 };
701703 if (experimentalFeatureSettings.isEnabled (Xp::CaDerivations) && !type (drv).isImpure ()) {
702- store .signRealisation (thisRealisation);
703- store .registerDrvOutput (thisRealisation, NoCheckSigs);
704+ localStore .signRealisation (thisRealisation);
705+ localStore .registerDrvOutput (thisRealisation, NoCheckSigs);
704706 }
705707 builtOutputs.emplace (outputName, thisRealisation);
706708 }
707709
708710 return builtOutputs;
709711}
710712
713+ BuildingStore::~BuildingStore () = default ;
714+
715+ namespace {
716+
717+ struct LocalBuildingStore : BuildingStore
718+ {
719+ LocalStore & localStore;
720+
721+ LocalBuildingStore (LocalStore & localStore)
722+ : BuildingStore{localStore.storeDir }
723+ , localStore{localStore}
724+ {
725+ }
726+
727+ std::filesystem::path getRealStoreDir () const override
728+ {
729+ return localStore.config ->realStoreDir .get ();
730+ }
731+
732+ std::filesystem::path getBuildDir () const override
733+ {
734+ return localStore.config ->getBuildDir ();
735+ }
736+
737+ const LocalSettings & getLocalSettings () const override
738+ {
739+ return localStore.config ->getLocalSettings ();
740+ }
741+
742+ ref<Store> makeRecursiveNixStore (RestrictionContext & ctx) override
743+ {
744+ return makeRestrictedStore (
745+ [&] {
746+ auto config = make_ref<LocalStore::Config>(*localStore.config );
747+ config->pathInfoCacheSize = 0 ;
748+ config->stateDir = " /no-such-path" ;
749+ config->logDir = " /no-such-path" ;
750+ return config;
751+ }(),
752+ ref<LocalStore>(std::dynamic_pointer_cast<LocalStore>(localStore.shared_from_this ())),
753+ ctx);
754+ }
755+ };
756+
757+ } // namespace
758+
759+ std::unique_ptr<BuildingStore> makeBuildingStoreFromLocalStore (LocalStore & localStore)
760+ {
761+ return std::make_unique<LocalBuildingStore>(localStore);
762+ }
763+
711764} // namespace nix
0 commit comments