mirror of
https://github.com/NixOS/nix.git
synced 2025-11-24 03:09:35 +01:00
Merge commit '8388d2c7c6' into progress-bar
This commit is contained in:
commit
e73dcf2cdd
95 changed files with 1215 additions and 717 deletions
|
|
@ -308,16 +308,17 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, Source & narSource
|
|||
}
|
||||
|
||||
StorePath BinaryCacheStore::addToStoreFromDump(Source & dump, const string & name,
|
||||
FileIngestionMethod method, HashType hashAlgo, RepairFlag repair)
|
||||
FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references)
|
||||
{
|
||||
if (method != FileIngestionMethod::Recursive || hashAlgo != htSHA256)
|
||||
unsupported("addToStoreFromDump");
|
||||
return addToStoreCommon(dump, repair, CheckSigs, [&](HashResult nar) {
|
||||
ValidPathInfo info {
|
||||
makeFixedOutputPath(method, nar.first, name),
|
||||
makeFixedOutputPath(method, nar.first, name, references),
|
||||
nar.first,
|
||||
};
|
||||
info.narSize = nar.second;
|
||||
info.references = references;
|
||||
return info;
|
||||
})->path;
|
||||
}
|
||||
|
|
@ -385,7 +386,7 @@ void BinaryCacheStore::queryPathInfoUncached(const StorePath & storePath,
|
|||
}
|
||||
|
||||
StorePath BinaryCacheStore::addToStore(const string & name, const Path & srcPath,
|
||||
FileIngestionMethod method, HashType hashAlgo, PathFilter & filter, RepairFlag repair)
|
||||
FileIngestionMethod method, HashType hashAlgo, PathFilter & filter, RepairFlag repair, const StorePathSet & references)
|
||||
{
|
||||
/* FIXME: Make BinaryCacheStore::addToStoreCommon support
|
||||
non-recursive+sha256 so we can just use the default
|
||||
|
|
@ -404,10 +405,11 @@ StorePath BinaryCacheStore::addToStore(const string & name, const Path & srcPath
|
|||
});
|
||||
return addToStoreCommon(*source, repair, CheckSigs, [&](HashResult nar) {
|
||||
ValidPathInfo info {
|
||||
makeFixedOutputPath(method, h, name),
|
||||
makeFixedOutputPath(method, h, name, references),
|
||||
nar.first,
|
||||
};
|
||||
info.narSize = nar.second;
|
||||
info.references = references;
|
||||
info.ca = FixedOutputHash {
|
||||
.method = method,
|
||||
.hash = h,
|
||||
|
|
|
|||
|
|
@ -97,11 +97,11 @@ public:
|
|||
RepairFlag repair, CheckSigsFlag checkSigs) override;
|
||||
|
||||
StorePath addToStoreFromDump(Source & dump, const string & name,
|
||||
FileIngestionMethod method, HashType hashAlgo, RepairFlag repair) override;
|
||||
FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references ) override;
|
||||
|
||||
StorePath addToStore(const string & name, const Path & srcPath,
|
||||
FileIngestionMethod method, HashType hashAlgo,
|
||||
PathFilter & filter, RepairFlag repair) override;
|
||||
PathFilter & filter, RepairFlag repair, const StorePathSet & references) override;
|
||||
|
||||
StorePath addTextToStore(const string & name, const string & s,
|
||||
const StorePathSet & references, RepairFlag repair) override;
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ void LocalDerivationGoal::cleanupHookFinally()
|
|||
void LocalDerivationGoal::cleanupPreChildKill()
|
||||
{
|
||||
sandboxMountNamespace = -1;
|
||||
sandboxUserNamespace = -1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -342,7 +343,7 @@ int childEntry(void * arg)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if __linux__
|
||||
static void linkOrCopy(const Path & from, const Path & to)
|
||||
{
|
||||
if (link(from.c_str(), to.c_str()) == -1) {
|
||||
|
|
@ -358,6 +359,7 @@ static void linkOrCopy(const Path & from, const Path & to)
|
|||
copyPath(from, to);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void LocalDerivationGoal::startBuilder()
|
||||
|
|
@ -906,11 +908,14 @@ void LocalDerivationGoal::startBuilder()
|
|||
"nobody:x:65534:65534:Nobody:/:/noshell\n",
|
||||
sandboxUid(), sandboxGid(), settings.sandboxBuildDir));
|
||||
|
||||
/* Save the mount namespace of the child. We have to do this
|
||||
/* Save the mount- and user namespace of the child. We have to do this
|
||||
*before* the child does a chroot. */
|
||||
sandboxMountNamespace = open(fmt("/proc/%d/ns/mnt", (pid_t) pid).c_str(), O_RDONLY);
|
||||
if (sandboxMountNamespace.get() == -1)
|
||||
throw SysError("getting sandbox mount namespace");
|
||||
sandboxUserNamespace = open(fmt("/proc/%d/ns/user", (pid_t) pid).c_str(), O_RDONLY);
|
||||
if (sandboxUserNamespace.get() == -1)
|
||||
throw SysError("getting sandbox user namespace");
|
||||
|
||||
/* Signal the builder that we've updated its user namespace. */
|
||||
writeFull(userNamespaceSync.writeSide.get(), "1");
|
||||
|
|
@ -918,7 +923,9 @@ void LocalDerivationGoal::startBuilder()
|
|||
} else
|
||||
#endif
|
||||
{
|
||||
#if __linux__
|
||||
fallback:
|
||||
#endif
|
||||
pid = startProcess([&]() {
|
||||
runChild();
|
||||
});
|
||||
|
|
@ -1180,7 +1187,8 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
|||
|
||||
StorePath addToStore(const string & name, const Path & srcPath,
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256,
|
||||
PathFilter & filter = defaultPathFilter, RepairFlag repair = NoRepair) override
|
||||
PathFilter & filter = defaultPathFilter, RepairFlag repair = NoRepair,
|
||||
const StorePathSet & references = StorePathSet()) override
|
||||
{ throw Error("addToStore"); }
|
||||
|
||||
void addToStore(const ValidPathInfo & info, Source & narSource,
|
||||
|
|
@ -1199,9 +1207,10 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
|||
}
|
||||
|
||||
StorePath addToStoreFromDump(Source & dump, const string & name,
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair) override
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair,
|
||||
const StorePathSet & references = StorePathSet()) override
|
||||
{
|
||||
auto path = next->addToStoreFromDump(dump, name, method, hashAlgo, repair);
|
||||
auto path = next->addToStoreFromDump(dump, name, method, hashAlgo, repair, references);
|
||||
goal.addDependency(path);
|
||||
return path;
|
||||
}
|
||||
|
|
@ -1419,7 +1428,7 @@ void LocalDerivationGoal::addDependency(const StorePath & path)
|
|||
|
||||
Path source = worker.store.Store::toRealPath(path);
|
||||
Path target = chrootRootDir + worker.store.printStorePath(path);
|
||||
debug("bind-mounting %s -> %s", target, source);
|
||||
debug("bind-mounting %s -> %s", source, target);
|
||||
|
||||
if (pathExists(target))
|
||||
throw Error("store path '%s' already exists in the sandbox", worker.store.printStorePath(path));
|
||||
|
|
@ -1434,6 +1443,9 @@ void LocalDerivationGoal::addDependency(const StorePath & path)
|
|||
child process.*/
|
||||
Pid child(startProcess([&]() {
|
||||
|
||||
if (usingUserNamespace && (setns(sandboxUserNamespace.get(), 0) == -1))
|
||||
throw SysError("entering sandbox user namespace");
|
||||
|
||||
if (setns(sandboxMountNamespace.get(), 0) == -1)
|
||||
throw SysError("entering sandbox mount namespace");
|
||||
|
||||
|
|
@ -1993,7 +2005,7 @@ void LocalDerivationGoal::runChild()
|
|||
else if (drv->builder == "builtin:unpack-channel")
|
||||
builtinUnpackChannel(drv2);
|
||||
else
|
||||
throw Error("unsupported builtin function '%1%'", string(drv->builder, 8));
|
||||
throw Error("unsupported builtin builder '%1%'", string(drv->builder, 8));
|
||||
_exit(0);
|
||||
} catch (std::exception & e) {
|
||||
writeFull(STDERR_FILENO, e.what() + std::string("\n"));
|
||||
|
|
|
|||
|
|
@ -27,9 +27,10 @@ struct LocalDerivationGoal : public DerivationGoal
|
|||
/* Pipe for synchronising updates to the builder namespaces. */
|
||||
Pipe userNamespaceSync;
|
||||
|
||||
/* The mount namespace of the builder, used to add additional
|
||||
/* The mount namespace and user namespace of the builder, used to add additional
|
||||
paths to the sandbox as a result of recursive Nix calls. */
|
||||
AutoCloseFD sandboxMountNamespace;
|
||||
AutoCloseFD sandboxUserNamespace;
|
||||
|
||||
/* On Linux, whether we're doing the build in its own user
|
||||
namespace. */
|
||||
|
|
|
|||
|
|
@ -120,8 +120,10 @@ ContentAddress parseContentAddress(std::string_view rawCa) {
|
|||
|
||||
ContentAddressMethod parseContentAddressMethod(std::string_view caMethod)
|
||||
{
|
||||
std::string_view asPrefix {std::string{caMethod} + ":"};
|
||||
return parseContentAddressMethodPrefix(asPrefix);
|
||||
std::string asPrefix = std::string{caMethod} + ":";
|
||||
// parseContentAddressMethodPrefix takes its argument by reference
|
||||
std::string_view asPrefixView = asPrefix;
|
||||
return parseContentAddressMethodPrefix(asPrefixView);
|
||||
}
|
||||
|
||||
std::optional<ContentAddress> parseContentAddressOpt(std::string_view rawCaOpt)
|
||||
|
|
|
|||
|
|
@ -403,9 +403,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
|||
return store->queryPathInfo(path);
|
||||
},
|
||||
[&](FixedOutputHashMethod & fohm) {
|
||||
if (!refs.empty())
|
||||
throw UnimplementedError("cannot yet have refs with flat or nar-hashed data");
|
||||
auto path = store->addToStoreFromDump(source, name, fohm.fileIngestionMethod, fohm.hashType, repair);
|
||||
auto path = store->addToStoreFromDump(source, name, fohm.fileIngestionMethod, fohm.hashType, repair, refs);
|
||||
return store->queryPathInfo(path);
|
||||
},
|
||||
}, contentAddressMethod);
|
||||
|
|
|
|||
|
|
@ -544,6 +544,14 @@ struct curlFileTransfer : public FileTransfer
|
|||
stopWorkerThread();
|
||||
});
|
||||
|
||||
#ifdef __linux__
|
||||
/* Cause this thread to not share any FS attributes with the main thread,
|
||||
because this causes setns() in restoreMountNamespace() to fail.
|
||||
Ideally, this would happen in the std::thread() constructor. */
|
||||
if (unshare(CLONE_FS) != 0)
|
||||
throw SysError("unsharing filesystem state in download thread");
|
||||
#endif
|
||||
|
||||
std::map<CURL *, std::shared_ptr<TransferItem>> items;
|
||||
|
||||
bool quit = false;
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ static string quoteRegexChars(const string & raw)
|
|||
return std::regex_replace(raw, specialRegex, R"(\$&)");
|
||||
}
|
||||
|
||||
#if __linux__
|
||||
static void readFileRoots(const char * path, UncheckedRoots & roots)
|
||||
{
|
||||
try {
|
||||
|
|
@ -333,6 +334,7 @@ static void readFileRoots(const char * path, UncheckedRoots & roots)
|
|||
throw;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
|
||||
{
|
||||
|
|
@ -414,7 +416,7 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
#if __linux__
|
||||
readFileRoots("/proc/sys/kernel/modprobe", unchecked);
|
||||
readFileRoots("/proc/sys/kernel/fbsplash", unchecked);
|
||||
readFileRoots("/proc/sys/kernel/poweroff_cmd", unchecked);
|
||||
|
|
|
|||
|
|
@ -951,6 +951,9 @@ public:
|
|||
|
||||
Setting<bool> useRegistries{this, true, "use-registries",
|
||||
"Whether to use flake registries to resolve flake references."};
|
||||
|
||||
Setting<bool> acceptFlakeConfig{this, false, "accept-flake-config",
|
||||
"Whether to accept nix configuration from a flake without prompting."};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor
|
|||
|
||||
StorePath addToStore(const string & name, const Path & srcPath,
|
||||
FileIngestionMethod method, HashType hashAlgo,
|
||||
PathFilter & filter, RepairFlag repair) override
|
||||
PathFilter & filter, RepairFlag repair, const StorePathSet & references) override
|
||||
{ unsupported("addToStore"); }
|
||||
|
||||
StorePath addTextToStore(const string & name, const string & s,
|
||||
|
|
|
|||
|
|
@ -504,9 +504,6 @@ void LocalStore::makeStoreWritable()
|
|||
throw SysError("getting info about the Nix store mount point");
|
||||
|
||||
if (stat.f_flag & ST_RDONLY) {
|
||||
if (unshare(CLONE_NEWNS) == -1)
|
||||
throw SysError("setting up a private mount namespace");
|
||||
|
||||
if (mount(0, realStoreDir.get().c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
||||
throw SysError("remounting %1% writable", realStoreDir);
|
||||
}
|
||||
|
|
@ -1311,7 +1308,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source,
|
|||
|
||||
|
||||
StorePath LocalStore::addToStoreFromDump(Source & source0, const string & name,
|
||||
FileIngestionMethod method, HashType hashAlgo, RepairFlag repair)
|
||||
FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references)
|
||||
{
|
||||
/* For computing the store path. */
|
||||
auto hashSink = std::make_unique<HashSink>(hashAlgo);
|
||||
|
|
@ -1367,7 +1364,7 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, const string & name,
|
|||
|
||||
auto [hash, size] = hashSink->finish();
|
||||
|
||||
auto dstPath = makeFixedOutputPath(method, hash, name);
|
||||
auto dstPath = makeFixedOutputPath(method, hash, name, references);
|
||||
|
||||
addTempRoot(dstPath);
|
||||
|
||||
|
|
@ -1414,6 +1411,7 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, const string & name,
|
|||
|
||||
ValidPathInfo info { dstPath, narHash.first };
|
||||
info.narSize = narHash.second;
|
||||
info.references = references;
|
||||
info.ca = FixedOutputHash { .method = method, .hash = hash };
|
||||
registerValidPath(info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ public:
|
|||
RepairFlag repair, CheckSigsFlag checkSigs) override;
|
||||
|
||||
StorePath addToStoreFromDump(Source & dump, const string & name,
|
||||
FileIngestionMethod method, HashType hashAlgo, RepairFlag repair) override;
|
||||
FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const StorePathSet & references) override;
|
||||
|
||||
StorePath addTextToStore(const string & name, const string & s,
|
||||
const StorePathSet & references, RepairFlag repair) override;
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ void RefScanSink::operator () (std::string_view data)
|
|||
fragment, so search in the concatenation of the tail of the
|
||||
previous fragment and the start of the current fragment. */
|
||||
auto s = tail;
|
||||
s.append(data.data(), refLength);
|
||||
auto tailLen = std::min(data.size(), refLength);
|
||||
s.append(data.data(), tailLen);
|
||||
search(s, hashes, seen);
|
||||
|
||||
search(data, hashes, seen);
|
||||
|
||||
auto tailLen = std::min(data.size(), refLength);
|
||||
auto rest = refLength - tailLen;
|
||||
if (rest < tail.size())
|
||||
tail = tail.substr(tail.size() - rest);
|
||||
|
|
|
|||
|
|
@ -290,6 +290,10 @@ ConnectionHandle RemoteStore::getConnection()
|
|||
return ConnectionHandle(connections->get());
|
||||
}
|
||||
|
||||
void RemoteStore::setOptions()
|
||||
{
|
||||
setOptions(*(getConnection().handle));
|
||||
}
|
||||
|
||||
bool RemoteStore::isValidPathUncached(const StorePath & path)
|
||||
{
|
||||
|
|
@ -578,9 +582,8 @@ ref<const ValidPathInfo> RemoteStore::addCAToStore(
|
|||
|
||||
|
||||
StorePath RemoteStore::addToStoreFromDump(Source & dump, const string & name,
|
||||
FileIngestionMethod method, HashType hashType, RepairFlag repair)
|
||||
FileIngestionMethod method, HashType hashType, RepairFlag repair, const StorePathSet & references)
|
||||
{
|
||||
StorePathSet references;
|
||||
return addCAToStore(dump, name, FixedOutputHashMethod{ .fileIngestionMethod = method, .hashType = hashType }, references, repair)->path;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ public:
|
|||
|
||||
/* Add a content-addressable store path. Does not support references. `dump` will be drained. */
|
||||
StorePath addToStoreFromDump(Source & dump, const string & name,
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair) override;
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair, const StorePathSet & references = StorePathSet()) override;
|
||||
|
||||
void addToStore(const ValidPathInfo & info, Source & nar,
|
||||
RepairFlag repair, CheckSigsFlag checkSigs) override;
|
||||
|
|
@ -148,6 +148,8 @@ protected:
|
|||
|
||||
virtual void setOptions(Connection & conn);
|
||||
|
||||
void setOptions() override;
|
||||
|
||||
ConnectionHandle getConnection();
|
||||
|
||||
friend struct ConnectionHandle;
|
||||
|
|
|
|||
|
|
@ -100,4 +100,5 @@
|
|||
|
||||
; Allow Rosetta 2 to run x86_64 binaries on aarch64-darwin.
|
||||
(allow file-read*
|
||||
(subpath "/Library/Apple/usr/libexec/oah"))
|
||||
(subpath "/Library/Apple/usr/libexec/oah")
|
||||
(subpath "/System/Library/Apple/usr/libexec/oah"))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "sqlite.hh"
|
||||
#include "globals.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
|
@ -27,8 +28,12 @@ namespace nix {
|
|||
|
||||
SQLite::SQLite(const Path & path, bool create)
|
||||
{
|
||||
// useSQLiteWAL also indicates what virtual file system we need. Using
|
||||
// `unix-dotfile` is needed on NFS file systems and on Windows' Subsystem
|
||||
// for Linux (WSL) where useSQLiteWAL should be false by default.
|
||||
const char *vfs = settings.useSQLiteWAL ? 0 : "unix-dotfile";
|
||||
if (sqlite3_open_v2(path.c_str(), &db,
|
||||
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
|
||||
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), vfs) != SQLITE_OK)
|
||||
throw Error("cannot open SQLite database '%s'", path);
|
||||
|
||||
if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ StorePath Store::computeStorePathForText(const string & name, const string & s,
|
|||
|
||||
|
||||
StorePath Store::addToStore(const string & name, const Path & _srcPath,
|
||||
FileIngestionMethod method, HashType hashAlgo, PathFilter & filter, RepairFlag repair)
|
||||
FileIngestionMethod method, HashType hashAlgo, PathFilter & filter, RepairFlag repair, const StorePathSet & references)
|
||||
{
|
||||
Path srcPath(absPath(_srcPath));
|
||||
auto source = sinkToSource([&](Sink & sink) {
|
||||
|
|
@ -246,7 +246,7 @@ StorePath Store::addToStore(const string & name, const Path & _srcPath,
|
|||
else
|
||||
readFile(srcPath, sink);
|
||||
});
|
||||
return addToStoreFromDump(*source, name, method, hashAlgo, repair);
|
||||
return addToStoreFromDump(*source, name, method, hashAlgo, repair, references);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -460,7 +460,7 @@ public:
|
|||
libutil/archive.hh). */
|
||||
virtual StorePath addToStore(const string & name, const Path & srcPath,
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256,
|
||||
PathFilter & filter = defaultPathFilter, RepairFlag repair = NoRepair);
|
||||
PathFilter & filter = defaultPathFilter, RepairFlag repair = NoRepair, const StorePathSet & references = StorePathSet());
|
||||
|
||||
/* Copy the contents of a path to the store and register the
|
||||
validity the resulting path, using a constant amount of
|
||||
|
|
@ -476,7 +476,8 @@ public:
|
|||
`dump` may be drained */
|
||||
// FIXME: remove?
|
||||
virtual StorePath addToStoreFromDump(Source & dump, const string & name,
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair)
|
||||
FileIngestionMethod method = FileIngestionMethod::Recursive, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair,
|
||||
const StorePathSet & references = StorePathSet())
|
||||
{ unsupported("addToStoreFromDump"); }
|
||||
|
||||
/* Like addToStore, but the contents written to the output path is
|
||||
|
|
@ -732,6 +733,11 @@ public:
|
|||
virtual void createUser(const std::string & userName, uid_t userId)
|
||||
{ }
|
||||
|
||||
/*
|
||||
* Synchronises the options of the client with those of the daemon
|
||||
* (a no-op when there’s no daemon)
|
||||
*/
|
||||
virtual void setOptions() { }
|
||||
protected:
|
||||
|
||||
Stats stats;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue