mirror of
https://github.com/NixOS/nix
synced 2025-06-27 21:01:16 +02:00
Merge remote-tracking branch 'upstream/master' into ca-floating-upstream
This commit is contained in:
commit
c5ccebae00
19 changed files with 118 additions and 69 deletions
|
@ -87,6 +87,7 @@ static void printValue(std::ostream & str, std::set<const Value *> & active, con
|
|||
else if (*i == '\n') str << "\\n";
|
||||
else if (*i == '\r') str << "\\r";
|
||||
else if (*i == '\t') str << "\\t";
|
||||
else if (*i == '$' && *(i+1) == '{') str << "\\" << *i;
|
||||
else str << *i;
|
||||
str << "\"";
|
||||
break;
|
||||
|
@ -1348,7 +1349,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
|||
}
|
||||
|
||||
Value * actualArgs = allocValue();
|
||||
mkAttrs(*actualArgs, fun.lambda.fun->formals->formals.size());
|
||||
mkAttrs(*actualArgs, std::max(static_cast<uint32_t>(fun.lambda.fun->formals->formals.size()), args.size()));
|
||||
|
||||
if (fun.lambda.fun->formals->ellipsis) {
|
||||
// If the formals have an ellipsis (eg the function accepts extra args) pass
|
||||
|
|
|
@ -40,7 +40,7 @@ DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPat
|
|||
throw Error("derivation '%s' does not have output '%s'", store->printStorePath(drvPath), outputName);
|
||||
auto & [outputName, output] = *i;
|
||||
|
||||
auto optStorePath = output.pathOpt(*store, drv.name, outputName);
|
||||
auto optStorePath = output.path(*store, drv.name, outputName);
|
||||
if (optStorePath)
|
||||
outPath = store->printStorePath(*optStorePath);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ static void mkOutputString(EvalState & state, Value & v,
|
|||
const StorePath & drvPath, const BasicDerivation & drv,
|
||||
std::pair<string, DerivationOutput> o)
|
||||
{
|
||||
auto optOutputPath = o.second.pathOpt(*state.store, drv.name, o.first);
|
||||
auto optOutputPath = o.second.path(*state.store, drv.name, o.first);
|
||||
mkString(
|
||||
*state.allocAttr(v, state.symbols.create(o.first)),
|
||||
optOutputPath
|
||||
|
|
|
@ -718,16 +718,25 @@ typedef enum {rpAccept, rpDecline, rpPostpone} HookReply;
|
|||
|
||||
class SubstitutionGoal;
|
||||
|
||||
/* Unless we are repairing, we don't both to test validity and just assume it,
|
||||
so the choices are `Absent` or `Valid`. */
|
||||
enum struct PathStatus {
|
||||
Corrupt,
|
||||
Absent,
|
||||
Valid,
|
||||
};
|
||||
|
||||
struct InitialOutputStatus {
|
||||
StorePath path;
|
||||
/* The output optional indicates whether it's already valid; i.e. exists
|
||||
and is registered. If we're repairing, inner bool indicates whether the
|
||||
valid path is in fact not corrupt. Otherwise, the inner bool is always
|
||||
true (assumed no corruption). */
|
||||
std::optional<bool> valid;
|
||||
PathStatus status;
|
||||
/* Valid in the store, and additionally non-corrupt if we are repairing */
|
||||
bool isValid() const {
|
||||
return valid && *valid;
|
||||
return status == PathStatus::Valid;
|
||||
}
|
||||
/* Merely present, allowed to be corrupt */
|
||||
bool isPresent() const {
|
||||
return status == PathStatus::Corrupt
|
||||
|| status == PathStatus::Valid;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2186,10 +2195,10 @@ void DerivationGoal::startBuilder()
|
|||
: !needsHashRewrite()
|
||||
/* Can always use original path in sandbox */
|
||||
? status.known->path
|
||||
: !status.known->valid
|
||||
: !status.known->isPresent()
|
||||
/* If path doesn't yet exist can just use it */
|
||||
? status.known->path
|
||||
: buildMode != bmRepair && !*status.known->valid
|
||||
: buildMode != bmRepair && !status.known->isValid()
|
||||
/* If we aren't repairing we'll delete a corrupted path, so we
|
||||
can use original path */
|
||||
? status.known->path
|
||||
|
@ -2199,7 +2208,7 @@ void DerivationGoal::startBuilder()
|
|||
scratchOutputs.insert_or_assign(outputName, scratchPath);
|
||||
|
||||
/* A non-removed corrupted path needs to be stored here, too */
|
||||
if (buildMode == bmRepair && !*status.known->valid)
|
||||
if (buildMode == bmRepair && !status.known->isValid())
|
||||
redirectedBadOutputs.insert(status.known->path);
|
||||
|
||||
/* Substitute output placeholders with the scratch output paths.
|
||||
|
@ -4110,7 +4119,7 @@ void DerivationGoal::registerOutputs()
|
|||
floating CA derivations and hash-mismatching fixed-output
|
||||
derivations. */
|
||||
PathLocks dynamicOutputLock;
|
||||
auto optFixedPath = output.pathOpt(worker.store, drv->name, outputName);
|
||||
auto optFixedPath = output.path(worker.store, drv->name, outputName);
|
||||
if (!optFixedPath ||
|
||||
worker.store.printStorePath(*optFixedPath) != finalDestPath)
|
||||
{
|
||||
|
@ -4289,26 +4298,32 @@ void DerivationGoal::registerOutputs()
|
|||
/* Register each output path as valid, and register the sets of
|
||||
paths referenced by each of them. If there are cycles in the
|
||||
outputs, this will fail. */
|
||||
{
|
||||
ValidPathInfos infos2;
|
||||
for (auto & [outputName, newInfo] : infos) {
|
||||
if (useDerivation)
|
||||
worker.store.linkDeriverToPath(drvPath, outputName, newInfo.path);
|
||||
else {
|
||||
/* Once a floating CA derivations reaches this point, it must
|
||||
already be resolved, drvPath the basic derivation path, and
|
||||
a file existsing at that path for sake of the DB's foreign key. */
|
||||
assert(drv->type() != DerivationType::CAFloating);
|
||||
}
|
||||
infos2.push_back(newInfo);
|
||||
}
|
||||
worker.store.registerValidPaths(infos2);
|
||||
ValidPathInfos infos2;
|
||||
for (auto & [outputName, newInfo] : infos) {
|
||||
infos2.push_back(newInfo);
|
||||
}
|
||||
worker.store.registerValidPaths(infos2);
|
||||
|
||||
/* In case of a fixed-output derivation hash mismatch, throw an
|
||||
exception now that we have registered the output as valid. */
|
||||
if (delayedException)
|
||||
std::rethrow_exception(delayedException);
|
||||
|
||||
/* If we made it this far, we are sure the output matches the derivation
|
||||
(since the delayedException would be a fixed output CA mismatch). That
|
||||
means it's safe to link the derivation to the output hash. We must do
|
||||
that for floating CA derivations, which otherwise couldn't be cached,
|
||||
but it's fine to do in all cases. */
|
||||
for (auto & [outputName, newInfo] : infos) {
|
||||
if (useDerivation)
|
||||
worker.store.linkDeriverToPath(drvPath, outputName, newInfo.path);
|
||||
else {
|
||||
/* Once a floating CA derivations reaches this point, it must
|
||||
already be resolved, drvPath the basic derivation path, and
|
||||
a file existsing at that path for sake of the DB's foreign key. */
|
||||
assert(drv->type() != DerivationType::CAFloating);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4601,7 +4616,7 @@ std::map<std::string, std::optional<StorePath>> DerivationGoal::queryPartialDeri
|
|||
if (drv->type() != DerivationType::CAFloating) {
|
||||
std::map<std::string, std::optional<StorePath>> res;
|
||||
for (auto & [name, output] : drv->outputs)
|
||||
res.insert_or_assign(name, output.pathOpt(worker.store, drv->name, name));
|
||||
res.insert_or_assign(name, output.path(worker.store, drv->name, name));
|
||||
return res;
|
||||
} else {
|
||||
return worker.store.queryPartialDerivationOutputMap(drvPath);
|
||||
|
@ -4632,9 +4647,11 @@ void DerivationGoal::checkPathValidity()
|
|||
auto outputPath = *i.second;
|
||||
info.known = {
|
||||
.path = outputPath,
|
||||
.valid = !worker.store.isValidPath(outputPath)
|
||||
? std::optional<bool> {}
|
||||
: !checkHash || worker.pathContentsGood(outputPath),
|
||||
.status = !worker.store.isValidPath(outputPath)
|
||||
? PathStatus::Absent
|
||||
: !checkHash || worker.pathContentsGood(outputPath)
|
||||
? PathStatus::Valid
|
||||
: PathStatus::Corrupt,
|
||||
};
|
||||
}
|
||||
initialOutputs.insert_or_assign(i.first, info);
|
||||
|
|
|
@ -232,7 +232,7 @@ struct ClientSettings
|
|||
else if (setSubstituters(settings.extraSubstituters))
|
||||
;
|
||||
else
|
||||
warn("ignoring the user-specified setting '%s', because it is a restricted setting and you are not a trusted user", name);
|
||||
debug("ignoring the client-specified setting '%s', because it is a restricted setting and you are not a trusted user", name);
|
||||
} catch (UsageError & e) {
|
||||
warn(e.what());
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
std::optional<StorePath> DerivationOutput::pathOpt(const Store & store, std::string_view drvName, std::string_view outputName) const
|
||||
std::optional<StorePath> DerivationOutput::path(const Store & store, std::string_view drvName, std::string_view outputName) const
|
||||
{
|
||||
return std::visit(overloaded {
|
||||
[](DerivationOutputInputAddressed doi) -> std::optional<StorePath> {
|
||||
|
@ -557,7 +557,7 @@ DerivationOutputsAndOptPaths BasicDerivation::outputsAndOptPaths(const Store & s
|
|||
for (auto output : outputs)
|
||||
outsAndOptPaths.insert(std::make_pair(
|
||||
output.first,
|
||||
std::make_pair(output.second, output.second.pathOpt(store, name, output.first))
|
||||
std::make_pair(output.second, output.second.path(store, name, output.first))
|
||||
)
|
||||
);
|
||||
return outsAndOptPaths;
|
||||
|
|
|
@ -52,7 +52,7 @@ struct DerivationOutput
|
|||
/* Note, when you use this function you should make sure that you're passing
|
||||
the right derivation name. When in doubt, you should use the safer
|
||||
interface provided by BasicDerivation::outputsAndOptPaths */
|
||||
std::optional<StorePath> pathOpt(const Store & store, std::string_view drvName, std::string_view outputName) const;
|
||||
std::optional<StorePath> path(const Store & store, std::string_view drvName, std::string_view outputName) const;
|
||||
};
|
||||
|
||||
typedef std::map<string, DerivationOutput> DerivationOutputs;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "serialise.hh"
|
||||
#include "util.hh"
|
||||
#include "remote-fs-accessor.hh"
|
||||
#include "remote-store.hh"
|
||||
#include "worker-protocol.hh"
|
||||
#include "archive.hh"
|
||||
|
@ -43,8 +44,11 @@ StorePathCAMap readStorePathCAMap(const Store & store, Source & from)
|
|||
{
|
||||
StorePathCAMap paths;
|
||||
auto count = readNum<size_t>(from);
|
||||
while (count--)
|
||||
paths.insert_or_assign(store.parseStorePath(readString(from)), parseContentAddressOpt(readString(from)));
|
||||
while (count--) {
|
||||
auto path = store.parseStorePath(readString(from));
|
||||
auto ca = parseContentAddressOpt(readString(from));
|
||||
paths.insert_or_assign(path, ca);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
|
@ -476,10 +480,26 @@ StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path)
|
|||
|
||||
std::map<std::string, std::optional<StorePath>> RemoteStore::queryPartialDerivationOutputMap(const StorePath & path)
|
||||
{
|
||||
auto conn(getConnection());
|
||||
conn->to << wopQueryDerivationOutputMap << printStorePath(path);
|
||||
conn.processStderr();
|
||||
return worker_proto::read(*this, conn->from, Phantom<std::map<std::string, std::optional<StorePath>>> {});
|
||||
if (GET_PROTOCOL_MINOR(getProtocol()) >= 0x16) {
|
||||
auto conn(getConnection());
|
||||
conn->to << wopQueryDerivationOutputMap << printStorePath(path);
|
||||
conn.processStderr();
|
||||
return worker_proto::read(*this, conn->from, Phantom<std::map<std::string, std::optional<StorePath>>> {});
|
||||
} else {
|
||||
// Fallback for old daemon versions.
|
||||
// For floating-CA derivations (and their co-dependencies) this is an
|
||||
// under-approximation as it only returns the paths that can be inferred
|
||||
// from the derivation itself (and not the ones that are known because
|
||||
// the have been built), but as old stores don't handle floating-CA
|
||||
// derivations this shouldn't matter
|
||||
auto derivation = readDerivation(path);
|
||||
auto outputsWithOptPaths = derivation.outputsAndOptPaths(*this);
|
||||
std::map<std::string, std::optional<StorePath>> ret;
|
||||
for (auto & [outputName, outputAndPath] : outputsWithOptPaths) {
|
||||
ret.emplace(outputName, outputAndPath.second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -868,6 +888,18 @@ RemoteStore::Connection::~Connection()
|
|||
}
|
||||
}
|
||||
|
||||
void RemoteStore::narFromPath(const StorePath & path, Sink & sink)
|
||||
{
|
||||
auto conn(connections->get());
|
||||
conn->to << wopNarFromPath << printStorePath(path);
|
||||
conn->processStderr();
|
||||
copyNAR(conn->from, sink);
|
||||
}
|
||||
|
||||
ref<FSAccessor> RemoteStore::getFSAccessor()
|
||||
{
|
||||
return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()));
|
||||
}
|
||||
|
||||
static Logger::Fields readFields(Source & from)
|
||||
{
|
||||
|
|
|
@ -131,6 +131,10 @@ protected:
|
|||
|
||||
friend struct ConnectionHandle;
|
||||
|
||||
virtual ref<FSAccessor> getFSAccessor() override;
|
||||
|
||||
virtual void narFromPath(const StorePath & path, Sink & sink) override;
|
||||
|
||||
private:
|
||||
|
||||
std::atomic_bool failed{false};
|
||||
|
@ -149,6 +153,12 @@ public:
|
|||
bool sameMachine() override
|
||||
{ return true; }
|
||||
|
||||
ref<FSAccessor> getFSAccessor() override
|
||||
{ return LocalFSStore::getFSAccessor(); }
|
||||
|
||||
void narFromPath(const StorePath & path, Sink & sink) override
|
||||
{ LocalFSStore::narFromPath(path, sink); }
|
||||
|
||||
private:
|
||||
|
||||
ref<RemoteStore::Connection> openConnection() override;
|
||||
|
|
|
@ -40,10 +40,6 @@ public:
|
|||
bool sameMachine() override
|
||||
{ return false; }
|
||||
|
||||
void narFromPath(const StorePath & path, Sink & sink) override;
|
||||
|
||||
ref<FSAccessor> getFSAccessor() override;
|
||||
|
||||
private:
|
||||
|
||||
struct Connection : RemoteStore::Connection
|
||||
|
@ -68,19 +64,6 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
void SSHStore::narFromPath(const StorePath & path, Sink & sink)
|
||||
{
|
||||
auto conn(connections->get());
|
||||
conn->to << wopNarFromPath << printStorePath(path);
|
||||
conn->processStderr();
|
||||
copyNAR(conn->from, sink);
|
||||
}
|
||||
|
||||
ref<FSAccessor> SSHStore::getFSAccessor()
|
||||
{
|
||||
return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()));
|
||||
}
|
||||
|
||||
ref<RemoteStore::Connection> SSHStore::openConnection()
|
||||
{
|
||||
auto conn = make_ref<Connection>();
|
||||
|
|
|
@ -98,8 +98,8 @@ static void _main(int argc, char * * argv)
|
|||
|
||||
// List of environment variables kept for --pure
|
||||
std::set<string> keepVars{
|
||||
"HOME", "USER", "LOGNAME", "DISPLAY", "PATH", "TERM",
|
||||
"IN_NIX_SHELL", "TZ", "PAGER", "NIX_BUILD_SHELL", "SHLVL",
|
||||
"HOME", "USER", "LOGNAME", "DISPLAY", "PATH", "TERM", "IN_NIX_SHELL",
|
||||
"NIX_SHELL_PRESERVE_PROMPT", "TZ", "PAGER", "NIX_BUILD_SHELL", "SHLVL",
|
||||
"http_proxy", "https_proxy", "ftp_proxy", "all_proxy", "no_proxy"
|
||||
};
|
||||
|
||||
|
@ -446,7 +446,7 @@ static void _main(int argc, char * * argv)
|
|||
"PATH=%4%:\"$PATH\"; "
|
||||
"SHELL=%5%; "
|
||||
"set +e; "
|
||||
R"s([ -n "$PS1" ] && PS1='\n\[\033[1;32m\][nix-shell:\w]\$\[\033[0m\] '; )s"
|
||||
R"s([ -n "$PS1" -a -z "$NIX_SHELL_PRESERVE_PROMPT" ] && PS1='\n\[\033[1;32m\][nix-shell:\w]\$\[\033[0m\] '; )s"
|
||||
"if [ \"$(type -t runHook)\" = function ]; then runHook shellHook; fi; "
|
||||
"unset NIX_ENFORCE_PURITY; "
|
||||
"shopt -u nullglob; "
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue