1 #pragma once 2 3 #include "hash.hh" 4 #include "serialise.hh" 5 #include "crypto.hh" 6 #include "lru-cache.hh" 7 #include "sync.hh" 8 #include "globals.hh" 9 #include "config.hh" 10 11 #include <atomic> 12 #include <limits> 13 #include <map> 14 #include <unordered_map> 15 #include <unordered_set> 16 #include <memory> 17 #include <string> 18 #include <chrono> 19 20 21 namespace nix { 22 23 24 MakeError(SubstError, Error) 25 MakeError(BuildError, Error) /* denotes a permanent build failure */ 26 MakeError(InvalidPath, Error) 27 MakeError(Unsupported, Error) 28 MakeError(SubstituteGone, Error) 29 MakeError(SubstituterDisabled, Error) 30 31 32 struct BasicDerivation; 33 struct Derivation; 34 class FSAccessor; 35 class NarInfoDiskCache; 36 class Store; 37 class JSONPlaceholder; 38 39 40 enum RepairFlag : bool { NoRepair = false, Repair = true }; 41 enum CheckSigsFlag : bool { NoCheckSigs = false, CheckSigs = true }; 42 enum SubstituteFlag : bool { NoSubstitute = false, Substitute = true }; 43 enum AllowInvalidFlag : bool { DisallowInvalid = false, AllowInvalid = true }; 44 45 46 /* Size of the hash part of store paths, in base-32 characters. */ 47 const size_t storePathHashLen = 32; // i.e. 160 bits 48 49 /* Magic header of exportPath() output (obsolete). */ 50 const uint32_t exportMagic = 0x4558494e; 51 52 53 typedef std::unordered_map<Path, std::unordered_set<std::string>> Roots; 54 55 56 struct GCOptions 57 { 58 /* Garbage collector operation: 59 60 - `gcReturnLive': return the set of paths reachable from 61 (i.e. in the closure of) the roots. 62 63 - `gcReturnDead': return the set of paths not reachable from 64 the roots. 65 66 - `gcDeleteDead': actually delete the latter set. 67 68 - `gcDeleteSpecific': delete the paths listed in 69 `pathsToDelete', insofar as they are not reachable. 70 */ 71 typedef enum { 72 gcReturnLive, 73 gcReturnDead, 74 gcDeleteDead, 75 gcDeleteSpecific, 76 } GCAction; 77 78 GCAction action{gcDeleteDead}; 79 80 /* If `ignoreLiveness' is set, then reachability from the roots is 81 ignored (dangerous!). However, the paths must still be 82 unreferenced *within* the store (i.e., there can be no other 83 store paths that depend on them). */ 84 bool ignoreLiveness{false}; 85 86 /* For `gcDeleteSpecific', the paths to delete. */ 87 PathSet pathsToDelete; 88 89 /* Stop after at least `maxFreed' bytes have been freed. */ 90 unsigned long long maxFreed{std::numeric_limits<unsigned long long>::max()}; 91 }; 92 93 94 struct GCResults 95 { 96 /* Depending on the action, the GC roots, or the paths that would 97 be or have been deleted. */ 98 PathSet paths; 99 100 /* For `gcReturnDead', `gcDeleteDead' and `gcDeleteSpecific', the 101 number of bytes that would be or was freed. */ 102 unsigned long long bytesFreed = 0; 103 }; 104 105 106 struct SubstitutablePathInfo 107 { 108 Path deriver; 109 PathSet references; 110 unsigned long long downloadSize; /* 0 = unknown or inapplicable */ 111 unsigned long long narSize; /* 0 = unknown */ 112 }; 113 114 typedef std::map<Path, SubstitutablePathInfo> SubstitutablePathInfos; 115 116 117 struct ValidPathInfo 118 { 119 Path path; 120 Path deriver; 121 Hash narHash; 122 PathSet references; 123 time_t registrationTime = 0; 124 uint64_t narSize = 0; // 0 = unknown 125 uint64_t id; // internal use only 126 127 /* Whether the path is ultimately trusted, that is, it's a 128 derivation output that was built locally. */ 129 bool ultimate = false; 130 131 StringSet sigs; // note: not necessarily verified 132 133 /* If non-empty, an assertion that the path is content-addressed, 134 i.e., that the store path is computed from a cryptographic hash 135 of the contents of the path, plus some other bits of data like 136 the "name" part of the path. Such a path doesn't need 137 signatures, since we don't have to trust anybody's claim that 138 the path is the output of a particular derivation. (In the 139 extensional store model, we have to trust that the *contents* 140 of an output path of a derivation were actually produced by 141 that derivation. In the intensional model, we have to trust 142 that a particular output path was produced by a derivation; the 143 path then implies the contents.) 144 145 Ideally, the content-addressability assertion would just be a 146 Boolean, and the store path would be computed from 147 ‘storePathToName(path)’, ‘narHash’ and ‘references’. However, 148 1) we've accumulated several types of content-addressed paths 149 over the years; and 2) fixed-output derivations support 150 multiple hash algorithms and serialisation methods (flat file 151 vs NAR). Thus, ‘ca’ has one of the following forms: 152 153 * ‘text:sha256:<sha256 hash of file contents>’: For paths 154 computed by makeTextPath() / addTextToStore(). 155 156 * ‘fixed:<r?>:<ht>:<h>’: For paths computed by 157 makeFixedOutputPath() / addToStore(). 158 */ 159 std::string ca; 160 operator ==nix::ValidPathInfo161 bool operator == (const ValidPathInfo & i) const 162 { 163 return 164 path == i.path 165 && narHash == i.narHash 166 && references == i.references; 167 } 168 169 /* Return a fingerprint of the store path to be used in binary 170 cache signatures. It contains the store path, the base-32 171 SHA-256 hash of the NAR serialisation of the path, the size of 172 the NAR, and the sorted references. The size field is strictly 173 speaking superfluous, but might prevent endless/excessive data 174 attacks. */ 175 std::string fingerprint() const; 176 177 void sign(const SecretKey & secretKey); 178 179 /* Return true iff the path is verifiably content-addressed. */ 180 bool isContentAddressed(const Store & store) const; 181 182 static const size_t maxSigs = std::numeric_limits<size_t>::max(); 183 184 /* Return the number of signatures on this .narinfo that were 185 produced by one of the specified keys, or maxSigs if the path 186 is content-addressed. */ 187 size_t checkSignatures(const Store & store, const PublicKeys & publicKeys) const; 188 189 /* Verify a single signature. */ 190 bool checkSignature(const PublicKeys & publicKeys, const std::string & sig) const; 191 192 Strings shortRefs() const; 193 ~ValidPathInfonix::ValidPathInfo194 virtual ~ValidPathInfo() { } 195 }; 196 197 typedef list<ValidPathInfo> ValidPathInfos; 198 199 200 enum BuildMode { bmNormal, bmRepair, bmCheck }; 201 202 203 struct BuildResult 204 { 205 /* Note: don't remove status codes, and only add new status codes 206 at the end of the list, to prevent client/server 207 incompatibilities in the nix-store --serve protocol. */ 208 enum Status { 209 Built = 0, 210 Substituted, 211 AlreadyValid, 212 PermanentFailure, 213 InputRejected, 214 OutputRejected, 215 TransientFailure, // possibly transient 216 CachedFailure, // no longer used 217 TimedOut, 218 MiscFailure, 219 DependencyFailed, 220 LogLimitExceeded, 221 NotDeterministic, 222 } status = MiscFailure; 223 std::string errorMsg; 224 225 /* How many times this build was performed. */ 226 unsigned int timesBuilt = 0; 227 228 /* If timesBuilt > 1, whether some builds did not produce the same 229 result. (Note that 'isNonDeterministic = false' does not mean 230 the build is deterministic, just that we don't have evidence of 231 non-determinism.) */ 232 bool isNonDeterministic = false; 233 234 /* The start/stop times of the build (or one of the rounds, if it 235 was repeated). */ 236 time_t startTime = 0, stopTime = 0; 237 successnix::BuildResult238 bool success() { 239 return status == Built || status == Substituted || status == AlreadyValid; 240 } 241 }; 242 243 244 class Store : public std::enable_shared_from_this<Store>, public Config 245 { 246 public: 247 248 typedef std::map<std::string, std::string> Params; 249 250 const PathSetting storeDir_{this, false, settings.nixStore, 251 "store", "path to the Nix store"}; 252 const Path storeDir = storeDir_; 253 254 const Setting<int> pathInfoCacheSize{this, 65536, "path-info-cache-size", "size of the in-memory store path information cache"}; 255 256 const Setting<bool> isTrusted{this, false, "trusted", "whether paths from this store can be used as substitutes even when they lack trusted signatures"}; 257 258 protected: 259 260 struct PathInfoCacheValue { 261 PathInfoCacheValuenix::Store::PathInfoCacheValue262 PathInfoCacheValue(std::shared_ptr<ValidPathInfo> value) : 263 time_point(std::chrono::steady_clock::now()), 264 value(value) {} 265 266 // Convenience constructor copying from reference PathInfoCacheValuenix::Store::PathInfoCacheValue267 PathInfoCacheValue(const ValidPathInfo& value) : 268 PathInfoCacheValue(std::make_shared<ValidPathInfo>(value)) {} 269 270 // Record a missing path PathInfoCacheValuenix::Store::PathInfoCacheValue271 PathInfoCacheValue(std::nullptr_t nil) : 272 PathInfoCacheValue(std::shared_ptr<ValidPathInfo>()) {} 273 274 // Time of cache entry creation or update(?) 275 std::chrono::time_point<std::chrono::steady_clock> time_point; 276 277 // Null if missing 278 std::shared_ptr<ValidPathInfo> value; 279 280 // Whether the value is valid as a cache entry. The path may not exist. 281 bool isKnownNow(); 282 283 // Past tense, because a path can only be assumed to exists when 284 // isKnownNow() && didExist() didExistnix::Store::PathInfoCacheValue285 inline bool didExist() { 286 return value != 0; 287 } 288 }; 289 290 struct State 291 { 292 LRUCache<std::string, PathInfoCacheValue> pathInfoCache; 293 }; 294 295 Sync<State> state; 296 297 std::shared_ptr<NarInfoDiskCache> diskCache; 298 299 Store(const Params & params); 300 301 public: 302 ~Store()303 virtual ~Store() { } 304 305 virtual std::string getUri() = 0; 306 307 /* Return true if ‘path’ is in the Nix store (but not the Nix 308 store itself). */ 309 bool isInStore(const Path & path) const; 310 311 /* Return true if ‘path’ is a store path, i.e. a direct child of 312 the Nix store. */ 313 bool isStorePath(const Path & path) const; 314 315 /* Throw an exception if ‘path’ is not a store path. */ 316 void assertStorePath(const Path & path) const; 317 318 /* Chop off the parts after the top-level store name, e.g., 319 /nix/store/abcd-foo/bar => /nix/store/abcd-foo. */ 320 Path toStorePath(const Path & path) const; 321 322 /* Follow symlinks until we end up with a path in the Nix store. */ 323 Path followLinksToStore(const Path & path) const; 324 325 /* Same as followLinksToStore(), but apply toStorePath() to the 326 result. */ 327 Path followLinksToStorePath(const Path & path) const; 328 329 /* Constructs a unique store path name. */ 330 Path makeStorePath(const string & type, 331 const Hash & hash, const string & name) const; 332 333 Path makeOutputPath(const string & id, 334 const Hash & hash, const string & name) const; 335 336 Path makeFixedOutputPath(bool recursive, 337 const Hash & hash, const string & name) const; 338 339 Path makeTextPath(const string & name, const Hash & hash, 340 const PathSet & references) const; 341 342 /* This is the preparatory part of addToStore(); it computes the 343 store path to which srcPath is to be copied. Returns the store 344 path and the cryptographic hash of the contents of srcPath. */ 345 std::pair<Path, Hash> computeStorePathForPath(const string & name, 346 const Path & srcPath, bool recursive = true, 347 HashType hashAlgo = htSHA256, PathFilter & filter = defaultPathFilter) const; 348 349 /* Preparatory part of addTextToStore(). 350 351 !!! Computation of the path should take the references given to 352 addTextToStore() into account, otherwise we have a (relatively 353 minor) security hole: a caller can register a source file with 354 bogus references. If there are too many references, the path may 355 not be garbage collected when it has to be (not really a problem, 356 the caller could create a root anyway), or it may be garbage 357 collected when it shouldn't be (more serious). 358 359 Hashing the references would solve this (bogus references would 360 simply yield a different store path, so other users wouldn't be 361 affected), but it has some backwards compatibility issues (the 362 hashing scheme changes), so I'm not doing that for now. */ 363 Path computeStorePathForText(const string & name, const string & s, 364 const PathSet & references) const; 365 366 /* Check whether a path is valid. */ 367 bool isValidPath(const Path & path); 368 369 protected: 370 371 virtual bool isValidPathUncached(const Path & path); 372 373 public: 374 375 /* Query which of the given paths is valid. Optionally, try to 376 substitute missing paths. */ 377 virtual PathSet queryValidPaths(const PathSet & paths, 378 SubstituteFlag maybeSubstitute = NoSubstitute); 379 380 /* Query the set of all valid paths. Note that for some store 381 backends, the name part of store paths may be omitted 382 (i.e. you'll get /nix/store/<hash> rather than 383 /nix/store/<hash>-<name>). Use queryPathInfo() to obtain the 384 full store path. */ queryAllValidPaths()385 virtual PathSet queryAllValidPaths() 386 { unsupported("queryAllValidPaths"); } 387 388 /* Query information about a valid path. It is permitted to omit 389 the name part of the store path. */ 390 ref<const ValidPathInfo> queryPathInfo(const Path & path); 391 392 /* Asynchronous version of queryPathInfo(). */ 393 void queryPathInfo(const Path & path, 394 Callback<ref<ValidPathInfo>> callback) noexcept; 395 396 protected: 397 398 virtual void queryPathInfoUncached(const Path & path, 399 Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept = 0; 400 401 public: 402 403 /* Queries the set of incoming FS references for a store path. 404 The result is not cleared. */ queryReferrers(const Path & path,PathSet & referrers)405 virtual void queryReferrers(const Path & path, PathSet & referrers) 406 { unsupported("queryReferrers"); } 407 408 /* Return all currently valid derivations that have `path' as an 409 output. (Note that the result of `queryDeriver()' is the 410 derivation that was actually used to produce `path', which may 411 not exist anymore.) */ queryValidDerivers(const Path & path)412 virtual PathSet queryValidDerivers(const Path & path) { return {}; }; 413 414 /* Query the outputs of the derivation denoted by `path'. */ queryDerivationOutputs(const Path & path)415 virtual PathSet queryDerivationOutputs(const Path & path) 416 { unsupported("queryDerivationOutputs"); } 417 418 /* Query the output names of the derivation denoted by `path'. */ queryDerivationOutputNames(const Path & path)419 virtual StringSet queryDerivationOutputNames(const Path & path) 420 { unsupported("queryDerivationOutputNames"); } 421 422 /* Query the full store path given the hash part of a valid store 423 path, or "" if the path doesn't exist. */ 424 virtual Path queryPathFromHashPart(const string & hashPart) = 0; 425 426 /* Query which of the given paths have substitutes. */ querySubstitutablePaths(const PathSet & paths)427 virtual PathSet querySubstitutablePaths(const PathSet & paths) { return {}; }; 428 429 /* Query substitute info (i.e. references, derivers and download 430 sizes) of a set of paths. If a path does not have substitute 431 info, it's omitted from the resulting ‘infos’ map. */ querySubstitutablePathInfos(const PathSet & paths,SubstitutablePathInfos & infos)432 virtual void querySubstitutablePathInfos(const PathSet & paths, 433 SubstitutablePathInfos & infos) { return; }; 434 wantMassQuery()435 virtual bool wantMassQuery() { return false; } 436 437 /* Import a path into the store. */ 438 virtual void addToStore(const ValidPathInfo & info, Source & narSource, 439 RepairFlag repair = NoRepair, CheckSigsFlag checkSigs = CheckSigs, 440 std::shared_ptr<FSAccessor> accessor = 0); 441 442 // FIXME: remove 443 virtual void addToStore(const ValidPathInfo & info, const ref<std::string> & nar, 444 RepairFlag repair = NoRepair, CheckSigsFlag checkSigs = CheckSigs, 445 std::shared_ptr<FSAccessor> accessor = 0); 446 447 /* Copy the contents of a path to the store and register the 448 validity the resulting path. The resulting path is returned. 449 The function object `filter' can be used to exclude files (see 450 libutil/archive.hh). */ 451 virtual Path addToStore(const string & name, const Path & srcPath, 452 bool recursive = true, HashType hashAlgo = htSHA256, 453 PathFilter & filter = defaultPathFilter, RepairFlag repair = NoRepair) = 0; 454 455 /* Like addToStore, but the contents written to the output path is 456 a regular file containing the given string. */ 457 virtual Path addTextToStore(const string & name, const string & s, 458 const PathSet & references, RepairFlag repair = NoRepair) = 0; 459 460 /* Write a NAR dump of a store path. */ 461 virtual void narFromPath(const Path & path, Sink & sink) = 0; 462 463 /* For each path, if it's a derivation, build it. Building a 464 derivation means ensuring that the output paths are valid. If 465 they are already valid, this is a no-op. Otherwise, validity 466 can be reached in two ways. First, if the output paths is 467 substitutable, then build the path that way. Second, the 468 output paths can be created by running the builder, after 469 recursively building any sub-derivations. For inputs that are 470 not derivations, substitute them. */ 471 virtual void buildPaths(const PathSet & paths, BuildMode buildMode = bmNormal); 472 473 /* Build a single non-materialized derivation (i.e. not from an 474 on-disk .drv file). Note that ‘drvPath’ is only used for 475 informational purposes. */ 476 virtual BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv, 477 BuildMode buildMode = bmNormal) = 0; 478 479 /* Ensure that a path is valid. If it is not currently valid, it 480 may be made valid by running a substitute (if defined for the 481 path). */ 482 virtual void ensurePath(const Path & path) = 0; 483 484 /* Add a store path as a temporary root of the garbage collector. 485 The root disappears as soon as we exit. */ addTempRoot(const Path & path)486 virtual void addTempRoot(const Path & path) 487 { unsupported("addTempRoot"); } 488 489 /* Add an indirect root, which is merely a symlink to `path' from 490 /nix/var/nix/gcroots/auto/<hash of `path'>. `path' is supposed 491 to be a symlink to a store path. The garbage collector will 492 automatically remove the indirect root when it finds that 493 `path' has disappeared. */ addIndirectRoot(const Path & path)494 virtual void addIndirectRoot(const Path & path) 495 { unsupported("addIndirectRoot"); } 496 497 /* Acquire the global GC lock, then immediately release it. This 498 function must be called after registering a new permanent root, 499 but before exiting. Otherwise, it is possible that a running 500 garbage collector doesn't see the new root and deletes the 501 stuff we've just built. By acquiring the lock briefly, we 502 ensure that either: 503 504 - The collector is already running, and so we block until the 505 collector is finished. The collector will know about our 506 *temporary* locks, which should include whatever it is we 507 want to register as a permanent lock. 508 509 - The collector isn't running, or it's just started but hasn't 510 acquired the GC lock yet. In that case we get and release 511 the lock right away, then exit. The collector scans the 512 permanent root and sees our's. 513 514 In either case the permanent root is seen by the collector. */ syncWithGC()515 virtual void syncWithGC() { }; 516 517 /* Find the roots of the garbage collector. Each root is a pair 518 (link, storepath) where `link' is the path of the symlink 519 outside of the Nix store that point to `storePath'. If 520 'censor' is true, privacy-sensitive information about roots 521 found in /proc is censored. */ findRoots(bool censor)522 virtual Roots findRoots(bool censor) 523 { unsupported("findRoots"); } 524 525 /* Perform a garbage collection. */ collectGarbage(const GCOptions & options,GCResults & results)526 virtual void collectGarbage(const GCOptions & options, GCResults & results) 527 { unsupported("collectGarbage"); } 528 529 /* Return a string representing information about the path that 530 can be loaded into the database using `nix-store --load-db' or 531 `nix-store --register-validity'. */ 532 string makeValidityRegistration(const PathSet & paths, 533 bool showDerivers, bool showHash); 534 535 /* Write a JSON representation of store path metadata, such as the 536 hash and the references. If ‘includeImpureInfo’ is true, 537 variable elements such as the registration time are 538 included. If ‘showClosureSize’ is true, the closure size of 539 each path is included. */ 540 void pathInfoToJSON(JSONPlaceholder & jsonOut, const PathSet & storePaths, 541 bool includeImpureInfo, bool showClosureSize, 542 AllowInvalidFlag allowInvalid = DisallowInvalid); 543 544 /* Return the size of the closure of the specified path, that is, 545 the sum of the size of the NAR serialisation of each path in 546 the closure. */ 547 std::pair<uint64_t, uint64_t> getClosureSize(const Path & storePath); 548 549 /* Optimise the disk space usage of the Nix store by hard-linking files 550 with the same contents. */ optimiseStore()551 virtual void optimiseStore() { }; 552 553 /* Check the integrity of the Nix store. Returns true if errors 554 remain. */ verifyStore(bool checkContents,RepairFlag repair=NoRepair)555 virtual bool verifyStore(bool checkContents, RepairFlag repair = NoRepair) { return false; }; 556 557 /* Return an object to access files in the Nix store. */ getFSAccessor()558 virtual ref<FSAccessor> getFSAccessor() 559 { unsupported("getFSAccessor"); } 560 561 /* Add signatures to the specified store path. The signatures are 562 not verified. */ addSignatures(const Path & storePath,const StringSet & sigs)563 virtual void addSignatures(const Path & storePath, const StringSet & sigs) 564 { unsupported("addSignatures"); } 565 566 /* Utility functions. */ 567 568 /* Read a derivation, after ensuring its existence through 569 ensurePath(). */ 570 Derivation derivationFromPath(const Path & drvPath); 571 572 /* Place in `out' the set of all store paths in the file system 573 closure of `storePath'; that is, all paths than can be directly 574 or indirectly reached from it. `out' is not cleared. If 575 `flipDirection' is true, the set of paths that can reach 576 `storePath' is returned; that is, the closures under the 577 `referrers' relation instead of the `references' relation is 578 returned. */ 579 virtual void computeFSClosure(const PathSet & paths, 580 PathSet & out, bool flipDirection = false, 581 bool includeOutputs = false, bool includeDerivers = false); 582 583 void computeFSClosure(const Path & path, 584 PathSet & out, bool flipDirection = false, 585 bool includeOutputs = false, bool includeDerivers = false); 586 587 /* Given a set of paths that are to be built, return the set of 588 derivations that will be built, and the set of output paths 589 that will be substituted. */ 590 virtual void queryMissing(const PathSet & targets, 591 PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown, 592 unsigned long long & downloadSize, unsigned long long & narSize); 593 594 /* Sort a set of paths topologically under the references 595 relation. If p refers to q, then p precedes q in this list. */ 596 Paths topoSortPaths(const PathSet & paths); 597 598 /* Export multiple paths in the format expected by ‘nix-store 599 --import’. */ 600 void exportPaths(const Paths & paths, Sink & sink); 601 602 void exportPath(const Path & path, Sink & sink); 603 604 /* Import a sequence of NAR dumps created by exportPaths() into 605 the Nix store. Optionally, the contents of the NARs are 606 preloaded into the specified FS accessor to speed up subsequent 607 access. */ 608 Paths importPaths(Source & source, std::shared_ptr<FSAccessor> accessor, 609 CheckSigsFlag checkSigs = CheckSigs); 610 611 struct Stats 612 { 613 std::atomic<uint64_t> narInfoRead{0}; 614 std::atomic<uint64_t> narInfoReadAverted{0}; 615 std::atomic<uint64_t> narInfoMissing{0}; 616 std::atomic<uint64_t> narInfoWrite{0}; 617 std::atomic<uint64_t> pathInfoCacheSize{0}; 618 std::atomic<uint64_t> narRead{0}; 619 std::atomic<uint64_t> narReadBytes{0}; 620 std::atomic<uint64_t> narReadCompressedBytes{0}; 621 std::atomic<uint64_t> narWrite{0}; 622 std::atomic<uint64_t> narWriteAverted{0}; 623 std::atomic<uint64_t> narWriteBytes{0}; 624 std::atomic<uint64_t> narWriteCompressedBytes{0}; 625 std::atomic<uint64_t> narWriteCompressionTimeMs{0}; 626 }; 627 628 const Stats & getStats(); 629 630 /* Return the build log of the specified store path, if available, 631 or null otherwise. */ getBuildLog(const Path & path)632 virtual std::shared_ptr<std::string> getBuildLog(const Path & path) 633 { return nullptr; } 634 635 /* Hack to allow long-running processes like hydra-queue-runner to 636 occasionally flush their path info cache. */ clearPathInfoCache()637 void clearPathInfoCache() 638 { 639 state.lock()->pathInfoCache.clear(); 640 } 641 642 /* Establish a connection to the store, for store types that have 643 a notion of connection. Otherwise this is a no-op. */ connect()644 virtual void connect() { }; 645 646 /* Get the protocol version of this store or it's connection. */ getProtocol()647 virtual unsigned int getProtocol() 648 { 649 return 0; 650 }; 651 652 /* Get the priority of the store, used to order substituters. In 653 particular, binary caches can specify a priority field in their 654 "nix-cache-info" file. Lower value means higher priority. */ getPriority()655 virtual int getPriority() { return 0; } 656 toRealPath(const Path & storePath)657 virtual Path toRealPath(const Path & storePath) 658 { 659 return storePath; 660 } 661 createUser(const std::string & userName,uid_t userId)662 virtual void createUser(const std::string & userName, uid_t userId) 663 { } 664 665 protected: 666 667 Stats stats; 668 669 /* Unsupported methods. */ unsupported(const std::string & op)670 [[noreturn]] void unsupported(const std::string & op) 671 { 672 throw Unsupported("operation '%s' is not supported by store '%s'", op, getUri()); 673 } 674 675 }; 676 677 678 class LocalFSStore : public virtual Store 679 { 680 public: 681 682 // FIXME: the (Store*) cast works around a bug in gcc that causes 683 // it to emit the call to the Option constructor. Clang works fine 684 // either way. 685 const PathSetting rootDir{(Store*) this, true, "", 686 "root", "directory prefixed to all other paths"}; 687 const PathSetting stateDir{(Store*) this, false, 688 rootDir != "" ? rootDir + "/nix/var/nix" : settings.nixStateDir, 689 "state", "directory where Nix will store state"}; 690 const PathSetting logDir{(Store*) this, false, 691 rootDir != "" ? rootDir + "/nix/var/log/nix" : settings.nixLogDir, 692 "log", "directory where Nix will store state"}; 693 694 const static string drvsLogDir; 695 696 LocalFSStore(const Params & params); 697 698 void narFromPath(const Path & path, Sink & sink) override; 699 ref<FSAccessor> getFSAccessor() override; 700 701 /* Register a permanent GC root. */ 702 Path addPermRoot(const Path & storePath, 703 const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false); 704 getRealStoreDir()705 virtual Path getRealStoreDir() { return storeDir; } 706 toRealPath(const Path & storePath)707 Path toRealPath(const Path & storePath) override 708 { 709 assert(isInStore(storePath)); 710 return getRealStoreDir() + "/" + std::string(storePath, storeDir.size() + 1); 711 } 712 713 std::shared_ptr<std::string> getBuildLog(const Path & path) override; 714 }; 715 716 717 /* Extract the name part of the given store path. */ 718 string storePathToName(const Path & path); 719 720 /* Extract the hash part of the given store path. */ 721 string storePathToHash(const Path & path); 722 723 /* Check whether ‘name’ is a valid store path name part, i.e. contains 724 only the characters [a-zA-Z0-9\+\-\.\_\?\=] and doesn't start with 725 a dot. */ 726 void checkStoreName(const string & name); 727 728 729 /* Copy a path from one store to another. */ 730 void copyStorePath(ref<Store> srcStore, ref<Store> dstStore, 731 const Path & storePath, RepairFlag repair = NoRepair, CheckSigsFlag checkSigs = CheckSigs); 732 733 734 /* Copy store paths from one store to another. The paths may be copied 735 in parallel. They are copied in a topologically sorted order 736 (i.e. if A is a reference of B, then A is copied before B), but 737 the set of store paths is not automatically closed; use 738 copyClosure() for that. */ 739 void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const PathSet & storePaths, 740 RepairFlag repair = NoRepair, 741 CheckSigsFlag checkSigs = CheckSigs, 742 SubstituteFlag substitute = NoSubstitute); 743 744 745 /* Copy the closure of the specified paths from one store to another. */ 746 void copyClosure(ref<Store> srcStore, ref<Store> dstStore, 747 const PathSet & storePaths, 748 RepairFlag repair = NoRepair, 749 CheckSigsFlag checkSigs = CheckSigs, 750 SubstituteFlag substitute = NoSubstitute); 751 752 753 /* Remove the temporary roots file for this process. Any temporary 754 root becomes garbage after this point unless it has been registered 755 as a (permanent) root. */ 756 void removeTempRoots(); 757 758 759 /* Return a Store object to access the Nix store denoted by 760 ‘uri’ (slight misnomer...). Supported values are: 761 762 * ‘local’: The Nix store in /nix/store and database in 763 /nix/var/nix/db, accessed directly. 764 765 * ‘daemon’: The Nix store accessed via a Unix domain socket 766 connection to nix-daemon. 767 768 * ‘unix://<path>’: The Nix store accessed via a Unix domain socket 769 connection to nix-daemon, with the socket located at <path>. 770 771 * ‘auto’ or ‘’: Equivalent to ‘local’ or ‘daemon’ depending on 772 whether the user has write access to the local Nix 773 store/database. 774 775 * ‘file://<path>’: A binary cache stored in <path>. 776 777 * ‘https://<path>’: A binary cache accessed via HTTP. 778 779 * ‘s3://<path>’: A writable binary cache stored on Amazon's Simple 780 Storage Service. 781 782 * ‘ssh://[user@]<host>’: A remote Nix store accessed by running 783 ‘nix-store --serve’ via SSH. 784 785 You can pass parameters to the store implementation by appending 786 ‘?key=value&key=value&...’ to the URI. 787 */ 788 ref<Store> openStore(const std::string & uri = settings.storeUri.get(), 789 const Store::Params & extraParams = Store::Params()); 790 791 792 enum StoreType { 793 tDaemon, 794 tLocal, 795 tOther 796 }; 797 798 799 StoreType getStoreType(const std::string & uri = settings.storeUri.get(), 800 const std::string & stateDir = settings.nixStateDir); 801 802 /* Return the default substituter stores, defined by the 803 ‘substituters’ option and various legacy options. */ 804 std::list<ref<Store>> getDefaultSubstituters(); 805 806 807 /* Store implementation registration. */ 808 typedef std::function<std::shared_ptr<Store>( 809 const std::string & uri, const Store::Params & params)> OpenStore; 810 811 struct RegisterStoreImplementation 812 { 813 typedef std::vector<OpenStore> Implementations; 814 static Implementations * implementations; 815 RegisterStoreImplementationnix::RegisterStoreImplementation816 RegisterStoreImplementation(OpenStore fun) 817 { 818 if (!implementations) implementations = new Implementations; 819 implementations->push_back(fun); 820 } 821 }; 822 823 824 825 /* Display a set of paths in human-readable form (i.e., between quotes 826 and separated by commas). */ 827 string showPaths(const PathSet & paths); 828 829 830 ValidPathInfo decodeValidPathInfo(std::istream & str, 831 bool hashGiven = false); 832 833 834 /* Compute the content-addressability assertion (ValidPathInfo::ca) 835 for paths created by makeFixedOutputPath() / addToStore(). */ 836 std::string makeFixedOutputCA(bool recursive, const Hash & hash); 837 838 839 /* Split URI into protocol+hierarchy part and its parameter set. */ 840 std::pair<std::string, Store::Params> splitUriAndParams(const std::string & uri); 841 842 } 843