forked from lix-project/lix
Remove trailing whitespace / tabs
This commit is contained in:
parent
7f8e805c8e
commit
b4ea83249b
|
@ -35,7 +35,7 @@ my $caBundle = $ENV{"CURL_CA_BUNDLE"} // $ENV{"OPENSSL_X509_CERT_FILE"};
|
|||
|
||||
sub addRequest {
|
||||
my ($storePath, $url, $head) = @_;
|
||||
|
||||
|
||||
my $curl = WWW::Curl::Easy->new;
|
||||
my $curlId = $curlIdCount++;
|
||||
$requests{$curlId} = { storePath => $storePath, url => $url, handle => $curl, content => "", type => $head ? "HEAD" : "GET" };
|
||||
|
@ -69,7 +69,7 @@ sub processRequests {
|
|||
if (scalar @{$rfds} + scalar @{$wfds} + scalar @{$efds} > 0) {
|
||||
IO::Select->select(IO::Select->new(@{$rfds}), IO::Select->new(@{$wfds}), IO::Select->new(@{$efds}), 0.1);
|
||||
}
|
||||
|
||||
|
||||
if ($curlm->perform() != $activeRequests) {
|
||||
while (my ($id, $result) = $curlm->info_read) {
|
||||
if ($id) {
|
||||
|
@ -77,9 +77,9 @@ sub processRequests {
|
|||
my $handle = $request->{handle};
|
||||
$request->{result} = $result;
|
||||
$request->{httpStatus} = $handle->getinfo(CURLINFO_RESPONSE_CODE);
|
||||
|
||||
|
||||
print STDERR "$request->{type} on $request->{url} [$request->{result}, $request->{httpStatus}]\n" if $debug;
|
||||
|
||||
|
||||
$activeRequests--;
|
||||
delete $request->{handle};
|
||||
|
||||
|
@ -115,7 +115,7 @@ sub initCache {
|
|||
url text unique not null
|
||||
);
|
||||
EOF
|
||||
|
||||
|
||||
$dbh->do(<<EOF);
|
||||
create table if not exists NARs (
|
||||
cache integer not null,
|
||||
|
@ -179,7 +179,7 @@ sub positiveHit {
|
|||
|
||||
sub processNARInfo {
|
||||
my ($storePath, $binaryCacheUrl, $request) = @_;
|
||||
|
||||
|
||||
my $cacheId = getCacheId($binaryCacheUrl);
|
||||
|
||||
if ($request->{result} != 0) {
|
||||
|
@ -192,7 +192,7 @@ sub processNARInfo {
|
|||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
my ($storePath2, $url, $fileHash, $fileSize, $narHash, $narSize, $deriver, $system);
|
||||
my $compression = "bzip2";
|
||||
my @refs;
|
||||
|
@ -219,13 +219,13 @@ sub processNARInfo {
|
|||
}
|
||||
|
||||
# FIXME: validate $url etc. for security.
|
||||
|
||||
|
||||
# Cache the result.
|
||||
$insertNAR->execute(
|
||||
$cacheId, basename($storePath), $url, $compression, $fileHash, $fileSize,
|
||||
$narHash, $narSize, join(" ", @refs), $deriver, $system, time())
|
||||
unless $request->{url} =~ /^file:/;
|
||||
|
||||
|
||||
return
|
||||
{ url => $url
|
||||
, compression => $compression
|
||||
|
@ -242,10 +242,10 @@ sub processNARInfo {
|
|||
|
||||
sub getCacheId {
|
||||
my ($binaryCacheUrl) = @_;
|
||||
|
||||
|
||||
my $cacheId = $cacheIds{$binaryCacheUrl};
|
||||
return $cacheId if defined $cacheId;
|
||||
|
||||
|
||||
# FIXME: not atomic.
|
||||
my @res = @{$dbh->selectcol_arrayref("select id from BinaryCaches where url = ?", {}, $binaryCacheUrl)};
|
||||
if (scalar @res == 1) {
|
||||
|
@ -267,8 +267,8 @@ sub getCachedInfoFrom {
|
|||
$queryNAR->execute(getCacheId($binaryCacheUrl), basename($storePath));
|
||||
my $res = $queryNAR->fetchrow_hashref();
|
||||
return undef unless defined $res;
|
||||
|
||||
return
|
||||
|
||||
return
|
||||
{ url => $res->{url}
|
||||
, compression => $res->{compression}
|
||||
, fileHash => $res->{fileHash}
|
||||
|
@ -379,7 +379,7 @@ sub printSubstitutablePaths {
|
|||
}
|
||||
addRequest($storePath, infoUrl($binaryCacheUrl, $storePath), 1);
|
||||
}
|
||||
|
||||
|
||||
processRequests;
|
||||
|
||||
foreach my $request (values %requests) {
|
||||
|
@ -406,7 +406,7 @@ sub printSubstitutablePaths {
|
|||
|
||||
sub downloadBinary {
|
||||
my ($storePath) = @_;
|
||||
|
||||
|
||||
foreach my $binaryCacheUrl (@binaryCacheUrls) {
|
||||
my $info = getCachedInfoFrom($storePath, $binaryCacheUrl);
|
||||
|
||||
|
@ -418,7 +418,7 @@ sub downloadBinary {
|
|||
}
|
||||
|
||||
next unless defined $info;
|
||||
|
||||
|
||||
my $decompressor;
|
||||
if ($info->{compression} eq "bzip2") { $decompressor = "$Nix::Config::bzip2 -d"; }
|
||||
elsif ($info->{compression} eq "xz") { $decompressor = "$Nix::Config::xz -d"; }
|
||||
|
@ -455,7 +455,7 @@ if ($ARGV[0] eq "--query") {
|
|||
while (<STDIN>) {
|
||||
chomp;
|
||||
my ($cmd, @args) = split " ", $_;
|
||||
|
||||
|
||||
if ($cmd eq "have") {
|
||||
printSubstitutablePaths(@args);
|
||||
print "\n";
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
namespace nix {
|
||||
|
||||
using std::map;
|
||||
|
||||
|
||||
|
||||
static string pathNullDevice = "/dev/null";
|
||||
|
||||
|
@ -95,9 +95,9 @@ class Goal : public boost::enable_shared_from_this<Goal>
|
|||
{
|
||||
public:
|
||||
typedef enum {ecBusy, ecSuccess, ecFailed, ecNoSubstituters} ExitCode;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/* Backlink to the worker. */
|
||||
Worker & worker;
|
||||
|
||||
|
@ -155,7 +155,7 @@ public:
|
|||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
ExitCode getExitCode()
|
||||
{
|
||||
return exitCode;
|
||||
|
@ -217,7 +217,7 @@ private:
|
|||
|
||||
/* Goals waiting for busy paths to be unlocked. */
|
||||
WeakGoals waitingForAnyGoal;
|
||||
|
||||
|
||||
/* Goals sleeping for a few seconds (polling a lock). */
|
||||
WeakGoals waitingForAWhile;
|
||||
|
||||
|
@ -238,7 +238,7 @@ public:
|
|||
LocalStore & store;
|
||||
|
||||
boost::shared_ptr<HookInstance> hook;
|
||||
|
||||
|
||||
Worker(LocalStore & store);
|
||||
~Worker();
|
||||
|
||||
|
@ -275,13 +275,13 @@ public:
|
|||
/* Wait for any goal to finish. Pretty indiscriminate way to
|
||||
wait for some resource that some other goal is holding. */
|
||||
void waitForAnyGoal(GoalPtr goal);
|
||||
|
||||
|
||||
/* Wait for a few seconds and then retry this goal. Used when
|
||||
waiting for a lock held by another process. This kind of
|
||||
polling is inefficient, but POSIX doesn't really provide a way
|
||||
to wait for multiple locks in the main select() loop. */
|
||||
void waitForAWhile(GoalPtr goal);
|
||||
|
||||
|
||||
/* Loop until the specified top-level goals have finished. */
|
||||
void run(const Goals & topGoals);
|
||||
|
||||
|
@ -309,11 +309,11 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
|
|||
|
||||
trace(format("waitee `%1%' done; %2% left") %
|
||||
waitee->name % waitees.size());
|
||||
|
||||
|
||||
if (result == ecFailed || result == ecNoSubstituters) ++nrFailed;
|
||||
|
||||
if (result == ecNoSubstituters) ++nrNoSubstituters;
|
||||
|
||||
|
||||
if (waitees.empty() || (result == ecFailed && !keepGoing)) {
|
||||
|
||||
/* If we failed and keepGoing is not set, we remove all
|
||||
|
@ -366,12 +366,12 @@ void commonChildInit(Pipe & logPipe)
|
|||
terminal signals. */
|
||||
if (setsid() == -1)
|
||||
throw SysError(format("creating a new session"));
|
||||
|
||||
|
||||
/* Dup the write side of the logger pipe into stderr. */
|
||||
if (dup2(logPipe.writeSide, STDERR_FILENO) == -1)
|
||||
throw SysError("cannot pipe standard error into log file");
|
||||
logPipe.readSide.close();
|
||||
|
||||
|
||||
/* Dup stderr to stdout. */
|
||||
if (dup2(STDERR_FILENO, STDOUT_FILENO) == -1)
|
||||
throw SysError("cannot dup stderr into stdout");
|
||||
|
@ -400,7 +400,7 @@ const char * * strings2CharPtrs(const Strings & ss)
|
|||
|
||||
/* Restore default handling of SIGPIPE, otherwise some programs will
|
||||
randomly say "Broken pipe". */
|
||||
static void restoreSIGPIPE()
|
||||
static void restoreSIGPIPE()
|
||||
{
|
||||
struct sigaction act, oact;
|
||||
act.sa_handler = SIG_DFL;
|
||||
|
@ -427,7 +427,7 @@ private:
|
|||
string user;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
|
||||
|
||||
public:
|
||||
UserLock();
|
||||
~UserLock();
|
||||
|
@ -442,7 +442,7 @@ public:
|
|||
uid_t getGID() { return gid; }
|
||||
|
||||
bool enabled() { return uid != 0; }
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -497,13 +497,13 @@ void UserLock::acquire()
|
|||
% *i % buildUsersGroup);
|
||||
|
||||
createDirs(nixStateDir + "/userpool");
|
||||
|
||||
|
||||
fnUserLock = (format("%1%/userpool/%2%") % nixStateDir % pw->pw_uid).str();
|
||||
|
||||
if (lockedPaths.find(fnUserLock) != lockedPaths.end())
|
||||
/* We already have a lock on this one. */
|
||||
continue;
|
||||
|
||||
|
||||
AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT, 0600);
|
||||
if (fd == -1)
|
||||
throw SysError(format("opening user lock `%1%'") % fnUserLock);
|
||||
|
@ -519,7 +519,7 @@ void UserLock::acquire()
|
|||
if (uid == getuid() || uid == geteuid())
|
||||
throw Error(format("the Nix user should not be a member of `%1%'")
|
||||
% buildUsersGroup);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -546,7 +546,7 @@ static void runSetuidHelper(const string & command,
|
|||
{
|
||||
Path program = getEnv("NIX_SETUID_HELPER",
|
||||
nixLibexecDir + "/nix-setuid-helper");
|
||||
|
||||
|
||||
/* Fork. */
|
||||
Pid pid;
|
||||
pid = fork();
|
||||
|
@ -564,7 +564,7 @@ static void runSetuidHelper(const string & command,
|
|||
args.push_back(0);
|
||||
|
||||
restoreSIGPIPE();
|
||||
|
||||
|
||||
execve(program.c_str(), (char * *) &args[0], 0);
|
||||
throw SysError(format("executing `%1%'") % program);
|
||||
}
|
||||
|
@ -650,7 +650,7 @@ struct HookInstance
|
|||
|
||||
/* Pipe for the builder's standard output/error. */
|
||||
Pipe builderOut;
|
||||
|
||||
|
||||
/* The process ID of the hook. */
|
||||
Pid pid;
|
||||
|
||||
|
@ -663,12 +663,12 @@ struct HookInstance
|
|||
HookInstance::HookInstance()
|
||||
{
|
||||
debug("starting build hook");
|
||||
|
||||
|
||||
Path buildHook = absPath(getEnv("NIX_BUILD_HOOK"));
|
||||
|
||||
|
||||
/* Create a pipe to get the output of the child. */
|
||||
fromHook.create();
|
||||
|
||||
|
||||
/* Create the communication pipes. */
|
||||
toHook.create();
|
||||
|
||||
|
@ -678,7 +678,7 @@ HookInstance::HookInstance()
|
|||
/* Fork the hook. */
|
||||
pid = fork();
|
||||
switch (pid) {
|
||||
|
||||
|
||||
case -1:
|
||||
throw SysError("unable to fork");
|
||||
|
||||
|
@ -688,7 +688,7 @@ HookInstance::HookInstance()
|
|||
commonChildInit(fromHook);
|
||||
|
||||
if (chdir("/") == -1) throw SysError("changing into `/");
|
||||
|
||||
|
||||
/* Dup the communication pipes. */
|
||||
toHook.writeSide.close();
|
||||
if (dup2(toHook.readSide, STDIN_FILENO) == -1)
|
||||
|
@ -699,20 +699,20 @@ HookInstance::HookInstance()
|
|||
if (dup2(builderOut.writeSide, 4) == -1)
|
||||
throw SysError("dupping builder's stdout/stderr");
|
||||
|
||||
/* XXX: Pass `buildTimeout' to the hook? */
|
||||
/* XXX: Pass `buildTimeout' to the hook? */
|
||||
execl(buildHook.c_str(), buildHook.c_str(), thisSystem.c_str(),
|
||||
(format("%1%") % maxSilentTime).str().c_str(),
|
||||
(format("%1%") % printBuildTrace).str().c_str(),
|
||||
NULL);
|
||||
|
||||
|
||||
throw SysError(format("executing `%1%'") % buildHook);
|
||||
|
||||
|
||||
} catch (std::exception & e) {
|
||||
std::cerr << format("build hook error: %1%") % e.what() << std::endl;
|
||||
}
|
||||
quickExit(1);
|
||||
}
|
||||
|
||||
|
||||
/* parent */
|
||||
pid.setSeparatePG(true);
|
||||
pid.setKillSignal(SIGTERM);
|
||||
|
@ -752,7 +752,7 @@ private:
|
|||
|
||||
/* The derivation stored at drvPath. */
|
||||
Derivation drv;
|
||||
|
||||
|
||||
/* The remainder is state held during the build. */
|
||||
|
||||
/* Locks on the output paths. */
|
||||
|
@ -760,7 +760,7 @@ private:
|
|||
|
||||
/* All input paths (that is, the union of FS closures of the
|
||||
immediate input paths). */
|
||||
PathSet inputPaths;
|
||||
PathSet inputPaths;
|
||||
|
||||
/* Referenceable paths (i.e., input and output paths). */
|
||||
PathSet allPaths;
|
||||
|
@ -784,10 +784,10 @@ private:
|
|||
|
||||
/* The build hook. */
|
||||
boost::shared_ptr<HookInstance> hook;
|
||||
|
||||
|
||||
/* Whether we're currently doing a chroot build. */
|
||||
bool useChroot;
|
||||
|
||||
|
||||
Path chrootRootDir;
|
||||
|
||||
/* RAII object to delete the chroot directory. */
|
||||
|
@ -798,10 +798,10 @@ private:
|
|||
|
||||
/* Whether this is a fixed-output derivation. */
|
||||
bool fixedOutput;
|
||||
|
||||
|
||||
typedef void (DerivationGoal::*GoalState)();
|
||||
GoalState state;
|
||||
|
||||
|
||||
/* Stuff we need to pass to initChild(). */
|
||||
PathSet dirsInChroot;
|
||||
typedef map<string, string> Environment;
|
||||
|
@ -812,7 +812,7 @@ public:
|
|||
~DerivationGoal();
|
||||
|
||||
void cancel();
|
||||
|
||||
|
||||
void work();
|
||||
|
||||
Path getDrvPath()
|
||||
|
@ -917,7 +917,7 @@ void DerivationGoal::killChild()
|
|||
pid.wait(true);
|
||||
} else
|
||||
pid.kill();
|
||||
|
||||
|
||||
assert(pid == -1);
|
||||
}
|
||||
|
||||
|
@ -968,7 +968,7 @@ void DerivationGoal::haveDerivation()
|
|||
side: if the user forgot to make it a root, we wouldn't want
|
||||
things being garbage collected while we're busy. */
|
||||
worker.store.addTempRoot(drvPath);
|
||||
|
||||
|
||||
assert(worker.store.isValidPath(drvPath));
|
||||
|
||||
/* Get the derivation. */
|
||||
|
@ -990,14 +990,14 @@ void DerivationGoal::haveDerivation()
|
|||
don't bother. */
|
||||
foreach (PathSet::iterator, i, invalidOutputs)
|
||||
if (pathFailed(*i)) return;
|
||||
|
||||
|
||||
/* We are first going to try to create the invalid output paths
|
||||
through substitutes. If that doesn't work, we'll build
|
||||
them. */
|
||||
if (queryBoolSetting("build-use-substitutes", true))
|
||||
foreach (PathSet::iterator, i, invalidOutputs)
|
||||
addWaitee(worker.makeSubstitutionGoal(*i));
|
||||
|
||||
|
||||
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
||||
outputsSubstituted();
|
||||
else
|
||||
|
@ -1051,7 +1051,7 @@ void DerivationGoal::inputsRealised()
|
|||
|
||||
/* Gather information necessary for computing the closure and/or
|
||||
running the build hook. */
|
||||
|
||||
|
||||
/* The outputs are referenceable paths. */
|
||||
foreach (DerivationOutputs::iterator, i, drv.outputs) {
|
||||
debug(format("building path `%1%'") % i->second.path);
|
||||
|
@ -1088,7 +1088,7 @@ void DerivationGoal::inputsRealised()
|
|||
fixedOutput = true;
|
||||
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
||||
if (i->second.hash == "") fixedOutput = false;
|
||||
|
||||
|
||||
/* Okay, try to build. Note that here we don't wait for a build
|
||||
slot to become available, since we don't need one if there is a
|
||||
build hook. */
|
||||
|
@ -1108,7 +1108,7 @@ PathSet outputPaths(const DerivationOutputs & outputs)
|
|||
|
||||
static bool canBuildLocally(const string & platform)
|
||||
{
|
||||
return platform == thisSystem
|
||||
return platform == thisSystem
|
||||
#ifdef CAN_DO_LINUX32_BUILDS
|
||||
|| (platform == "i686-linux" && thisSystem == "x86_64-linux")
|
||||
#endif
|
||||
|
@ -1132,7 +1132,7 @@ void DerivationGoal::tryToBuild()
|
|||
worker.waitForAnyGoal(shared_from_this());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Obtain locks on all output paths. The locks are automatically
|
||||
released when we exit this function or Nix crashes. If we
|
||||
can't acquire the lock, then continue; hopefully some other
|
||||
|
@ -1207,7 +1207,7 @@ void DerivationGoal::tryToBuild()
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Make sure that we are allowed to start a build. If this
|
||||
derivation prefers to be done locally, do it even if
|
||||
maxBuildJobs is 0. */
|
||||
|
@ -1217,7 +1217,7 @@ void DerivationGoal::tryToBuild()
|
|||
outputLocks.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
|
||||
/* Okay, we have to build. */
|
||||
|
@ -1265,7 +1265,7 @@ void DerivationGoal::buildDone()
|
|||
|
||||
/* So the child is gone now. */
|
||||
worker.childTerminated(savedPid);
|
||||
|
||||
|
||||
/* Close the read side of the logger pipe. */
|
||||
if (hook) {
|
||||
hook->builderOut.readSide.close();
|
||||
|
@ -1295,13 +1295,13 @@ void DerivationGoal::buildDone()
|
|||
if (rename((chrootRootDir + path).c_str(), path.c_str()) == -1)
|
||||
throw SysError(format("moving build output `%1%' from the chroot to the Nix store") % path);
|
||||
}
|
||||
|
||||
|
||||
if (!pathExists(path)) continue;
|
||||
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st) == -1)
|
||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
/* Check that the output is not group or world writable,
|
||||
as that means that someone else can have interfered
|
||||
|
@ -1319,14 +1319,14 @@ void DerivationGoal::buildDone()
|
|||
if (buildUser.enabled() && !amPrivileged())
|
||||
getOwnership(path);
|
||||
}
|
||||
|
||||
|
||||
/* Check the exit status. */
|
||||
if (!statusOk(status)) {
|
||||
deleteTmpDir(false);
|
||||
throw BuildError(format("builder for `%1%' %2%")
|
||||
% drvPath % statusToString(status));
|
||||
}
|
||||
|
||||
|
||||
deleteTmpDir(true);
|
||||
|
||||
/* Delete the chroot (if we were using one). */
|
||||
|
@ -1336,7 +1336,7 @@ void DerivationGoal::buildDone()
|
|||
hard-linked inputs to be cleared. So set them again. */
|
||||
foreach (PathSet::iterator, i, regularInputPaths)
|
||||
makeImmutable(*i);
|
||||
|
||||
|
||||
/* Compute the FS closure of the outputs and register them as
|
||||
being valid. */
|
||||
computeClosure();
|
||||
|
@ -1358,7 +1358,7 @@ void DerivationGoal::buildDone()
|
|||
problem. */
|
||||
bool hookError = hook &&
|
||||
(!WIFEXITED(status) || WEXITSTATUS(status) != 100);
|
||||
|
||||
|
||||
if (printBuildTrace) {
|
||||
if (hook && hookError)
|
||||
printMsg(lvlError, format("@ hook-failed %1% %2% %3% %4%")
|
||||
|
@ -1378,7 +1378,7 @@ void DerivationGoal::buildDone()
|
|||
if (worker.cacheFailure && !hookError && !fixedOutput)
|
||||
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
||||
worker.store.registerFailedPath(i->second.path);
|
||||
|
||||
|
||||
worker.permanentFailure = !hookError && !fixedOutput;
|
||||
amDone(ecFailed);
|
||||
return;
|
||||
|
@ -1391,7 +1391,7 @@ void DerivationGoal::buildDone()
|
|||
printMsg(lvlError, format("@ build-succeeded %1% %2%")
|
||||
% drvPath % drv.outputs["out"].path);
|
||||
}
|
||||
|
||||
|
||||
amDone(ecSuccess);
|
||||
}
|
||||
|
||||
|
@ -1439,7 +1439,7 @@ HookReply DerivationGoal::tryBuildHook()
|
|||
|
||||
hook = worker.hook;
|
||||
worker.hook.reset();
|
||||
|
||||
|
||||
/* Tell the hook all the inputs that have to be copied to the
|
||||
remote system. This unfortunately has to contain the entire
|
||||
derivation closure to ensure that the validity invariant holds
|
||||
|
@ -1448,18 +1448,18 @@ HookReply DerivationGoal::tryBuildHook()
|
|||
PathSet allInputs;
|
||||
allInputs.insert(inputPaths.begin(), inputPaths.end());
|
||||
computeFSClosure(worker.store, drvPath, allInputs);
|
||||
|
||||
|
||||
string s;
|
||||
foreach (PathSet::iterator, i, allInputs) s += *i + " ";
|
||||
writeLine(hook->toHook.writeSide, s);
|
||||
|
||||
|
||||
/* Tell the hooks the outputs that have to be copied back from the
|
||||
remote system. */
|
||||
s = "";
|
||||
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
||||
s += i->second.path + " ";
|
||||
writeLine(hook->toHook.writeSide, s);
|
||||
|
||||
|
||||
hook->toHook.writeSide.close();
|
||||
|
||||
/* Create the log file and pipe. */
|
||||
|
@ -1469,12 +1469,12 @@ HookReply DerivationGoal::tryBuildHook()
|
|||
fds.insert(hook->fromHook.readSide);
|
||||
fds.insert(hook->builderOut.readSide);
|
||||
worker.childStarted(shared_from_this(), hook->pid, fds, false, false);
|
||||
|
||||
|
||||
if (printBuildTrace)
|
||||
printMsg(lvlError, format("@ build-started %1% %2% %3% %4%")
|
||||
% drvPath % drv.outputs["out"].path % drv.platform % logFile);
|
||||
|
||||
return rpAccept;
|
||||
|
||||
return rpAccept;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1496,7 +1496,7 @@ void DerivationGoal::startBuilder()
|
|||
{
|
||||
startNest(nest, lvlInfo,
|
||||
format("building path(s) %1%") % showPaths(outputPaths(drv.outputs)))
|
||||
|
||||
|
||||
/* Right platform? */
|
||||
if (!canBuildLocally(drv.platform))
|
||||
throw Error(
|
||||
|
@ -1504,7 +1504,7 @@ void DerivationGoal::startBuilder()
|
|||
% drv.platform % thisSystem % drvPath);
|
||||
|
||||
/* Construct the environment passed to the builder. */
|
||||
|
||||
|
||||
/* Most shells initialise PATH to some default (/bin:/usr/bin:...) when
|
||||
PATH is not set. We don't want this, so we fill it in with some dummy
|
||||
value. */
|
||||
|
@ -1614,7 +1614,7 @@ void DerivationGoal::startBuilder()
|
|||
worker.store.makeValidityRegistration(paths, false, false));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* If `build-users-group' is not empty, then we have to build as
|
||||
one of the members of that group. */
|
||||
if (haveBuildUsers()) {
|
||||
|
@ -1625,7 +1625,7 @@ void DerivationGoal::startBuilder()
|
|||
/* Make sure that no other processes are executing under this
|
||||
uid. */
|
||||
buildUser.kill();
|
||||
|
||||
|
||||
/* Change ownership of the temporary build directory, if we're
|
||||
root. If we're not root, then the setuid helper will do it
|
||||
just before it starts the builder. */
|
||||
|
@ -1674,7 +1674,7 @@ void DerivationGoal::startBuilder()
|
|||
|
||||
/* Clean up the chroot directory automatically. */
|
||||
autoDelChroot = boost::shared_ptr<AutoDelete>(new AutoDelete(chrootRootDir));
|
||||
|
||||
|
||||
printMsg(lvlChatty, format("setting up chroot environment in `%1%'") % chrootRootDir);
|
||||
|
||||
/* Create a writable /tmp in the chroot. Many builders need
|
||||
|
@ -1696,8 +1696,8 @@ void DerivationGoal::startBuilder()
|
|||
% (buildUser.enabled() ? buildUser.getUID() : getuid())
|
||||
% (buildUser.enabled() ? buildUser.getGID() : getgid())).str());
|
||||
|
||||
/* Declare the build user's group so that programs get a consistent
|
||||
view of the system (e.g., "id -gn"). */
|
||||
/* Declare the build user's group so that programs get a consistent
|
||||
view of the system (e.g., "id -gn"). */
|
||||
writeFile(chrootRootDir + "/etc/group",
|
||||
(format("nixbld:!:%1%:\n")
|
||||
% (buildUser.enabled() ? buildUser.getGID() : getgid())).str());
|
||||
|
@ -1738,7 +1738,7 @@ void DerivationGoal::startBuilder()
|
|||
/* Creating a hard link to *i is impossible if its
|
||||
immutable bit is set. So clear it first. */
|
||||
makeMutable(*i);
|
||||
|
||||
|
||||
Path p = chrootRootDir + *i;
|
||||
if (link(i->c_str(), p.c_str()) == -1) {
|
||||
/* Hard-linking fails if we exceed the maximum
|
||||
|
@ -1755,25 +1755,25 @@ void DerivationGoal::startBuilder()
|
|||
StringSource source(sink.s);
|
||||
restorePath(p, source);
|
||||
}
|
||||
|
||||
|
||||
makeImmutable(*i);
|
||||
regularInputPaths.insert(*i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
throw Error("chroot builds are not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Run the builder. */
|
||||
printMsg(lvlChatty, format("executing builder `%1%'") %
|
||||
drv.builder);
|
||||
|
||||
/* Create the log file. */
|
||||
Path logFile = openLogFile();
|
||||
|
||||
|
||||
/* Create a pipe to get the output of the builder. */
|
||||
builderOut.create();
|
||||
|
||||
|
@ -1793,7 +1793,7 @@ void DerivationGoal::startBuilder()
|
|||
- The private mount namespace ensures that all the bind mounts
|
||||
we do will only show up in this process and its children, and
|
||||
will disappear automatically when we're done.
|
||||
|
||||
|
||||
- The private network namespace ensures that the builder cannot
|
||||
talk to the outside world (or vice versa). It only has a
|
||||
private loopback interface.
|
||||
|
@ -1845,7 +1845,7 @@ void DerivationGoal::initChild()
|
|||
/* Initialise the loopback interface. */
|
||||
AutoCloseFD fd(socket(PF_INET, SOCK_DGRAM, IPPROTO_IP));
|
||||
if (fd == -1) throw SysError("cannot open IP socket");
|
||||
|
||||
|
||||
struct ifreq ifr;
|
||||
strcpy(ifr.ifr_name, "lo");
|
||||
ifr.ifr_flags = IFF_UP | IFF_LOOPBACK | IFF_RUNNING;
|
||||
|
@ -1867,9 +1867,9 @@ void DerivationGoal::initChild()
|
|||
Path source = *i;
|
||||
Path target = chrootRootDir + source;
|
||||
debug(format("bind mounting `%1%' to `%2%'") % source % target);
|
||||
|
||||
|
||||
createDirs(target);
|
||||
|
||||
|
||||
if (mount(source.c_str(), target.c_str(), "", MS_BIND, 0) == -1)
|
||||
throw SysError(format("bind mount from `%1%' to `%2%' failed") % source % target);
|
||||
}
|
||||
|
@ -1884,7 +1884,7 @@ void DerivationGoal::initChild()
|
|||
if (pathExists("/dev/shm"))
|
||||
if (mount("none", (chrootRootDir + "/dev/shm").c_str(), "tmpfs", 0, 0) == -1)
|
||||
throw SysError("mounting /dev/shm");
|
||||
|
||||
|
||||
/* Do the chroot(). Below we do a chdir() to the
|
||||
temporary build directory to make sure the current
|
||||
directory is in the chroot. (Actually the order
|
||||
|
@ -1894,9 +1894,9 @@ void DerivationGoal::initChild()
|
|||
throw SysError(format("cannot change root directory to `%1%'") % chrootRootDir);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
commonChildInit(builderOut);
|
||||
|
||||
|
||||
if (chdir(tmpDir.c_str()) == -1)
|
||||
throw SysError(format("changing into `%1%'") % tmpDir);
|
||||
|
||||
|
@ -1930,7 +1930,7 @@ void DerivationGoal::initChild()
|
|||
Path program = drv.builder.c_str();
|
||||
std::vector<const char *> args; /* careful with c_str()! */
|
||||
string user; /* must be here for its c_str()! */
|
||||
|
||||
|
||||
/* If we are running in `build-users' mode, then switch to the
|
||||
user we allocated above. Make sure that we drop all root
|
||||
privileges. Note that above we have closed all file
|
||||
|
@ -1941,10 +1941,10 @@ void DerivationGoal::initChild()
|
|||
printMsg(lvlChatty, format("switching to user `%1%'") % buildUser.getUser());
|
||||
|
||||
if (amPrivileged()) {
|
||||
|
||||
|
||||
if (setgroups(0, 0) == -1)
|
||||
throw SysError("cannot clear the set of supplementary groups");
|
||||
|
||||
|
||||
if (setgid(buildUser.getGID()) == -1 ||
|
||||
getgid() != buildUser.getGID() ||
|
||||
getegid() != buildUser.getGID())
|
||||
|
@ -1954,7 +1954,7 @@ void DerivationGoal::initChild()
|
|||
getuid() != buildUser.getUID() ||
|
||||
geteuid() != buildUser.getUID())
|
||||
throw SysError("setuid failed");
|
||||
|
||||
|
||||
} else {
|
||||
/* Let the setuid helper take care of it. */
|
||||
program = nixLibexecDir + "/nix-setuid-helper";
|
||||
|
@ -1965,7 +1965,7 @@ void DerivationGoal::initChild()
|
|||
args.push_back(drv.builder.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Fill in the arguments. */
|
||||
string builderBasename = baseNameOf(drv.builder);
|
||||
args.push_back(builderBasename.c_str());
|
||||
|
@ -1980,7 +1980,7 @@ void DerivationGoal::initChild()
|
|||
|
||||
throw SysError(format("executing `%1%'")
|
||||
% drv.builder);
|
||||
|
||||
|
||||
} catch (std::exception & e) {
|
||||
std::cerr << format("build error: %1%") % e.what() << std::endl;
|
||||
}
|
||||
|
@ -2022,7 +2022,7 @@ void DerivationGoal::computeClosure()
|
|||
if (!worker.store.isValidPath(i->second.path)) allValid = false;
|
||||
if (allValid) return;
|
||||
}
|
||||
|
||||
|
||||
/* Check whether the output paths were created, and grep each
|
||||
output path to determine what other paths it references. Also make all
|
||||
output paths read-only. */
|
||||
|
@ -2037,18 +2037,18 @@ void DerivationGoal::computeClosure()
|
|||
struct stat st;
|
||||
if (lstat(path.c_str(), &st) == -1)
|
||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||
|
||||
|
||||
startNest(nest, lvlTalkative,
|
||||
format("scanning for references inside `%1%'") % path);
|
||||
|
||||
/* Check that fixed-output derivations produced the right
|
||||
outputs (i.e., the content hash should match the specified
|
||||
hash). */
|
||||
hash). */
|
||||
if (i->second.hash != "") {
|
||||
|
||||
bool recursive; HashType ht; Hash h;
|
||||
i->second.parseHashInfo(recursive, ht, h);
|
||||
|
||||
|
||||
if (!recursive) {
|
||||
/* The output path should be a regular file without
|
||||
execute permission. */
|
||||
|
@ -2067,12 +2067,12 @@ void DerivationGoal::computeClosure()
|
|||
}
|
||||
|
||||
/* Get rid of all weird permissions. */
|
||||
canonicalisePathMetaData(path);
|
||||
canonicalisePathMetaData(path);
|
||||
|
||||
/* For this output path, find the references to other paths
|
||||
contained in it. Compute the SHA-256 NAR hash at the same
|
||||
time. The hash is stored in the database so that we can
|
||||
verify later on whether nobody has messed with the store. */
|
||||
/* For this output path, find the references to other paths
|
||||
contained in it. Compute the SHA-256 NAR hash at the same
|
||||
time. The hash is stored in the database so that we can
|
||||
verify later on whether nobody has messed with the store. */
|
||||
HashResult hash;
|
||||
PathSet references = scanForReferences(path, allPaths, hash);
|
||||
contentHashes[path] = hash;
|
||||
|
@ -2126,7 +2126,7 @@ string drvsLogDir = "drvs";
|
|||
Path DerivationGoal::openLogFile()
|
||||
{
|
||||
if (!queryBoolSetting("build-keep-log", true)) return "";
|
||||
|
||||
|
||||
/* Create a log file. */
|
||||
Path dir = (format("%1%/%2%") % nixLogDir % drvsLogDir).str();
|
||||
createDirs(dir);
|
||||
|
@ -2179,7 +2179,7 @@ void DerivationGoal::deleteTmpDir(bool force)
|
|||
{
|
||||
if (tmpDir != "") {
|
||||
if (keepFailed && !force) {
|
||||
printMsg(lvlError,
|
||||
printMsg(lvlError,
|
||||
format("builder for `%1%' failed; keeping build directory `%2%'")
|
||||
% drvPath % tmpDir);
|
||||
if (buildUser.enabled() && !amPrivileged())
|
||||
|
@ -2235,14 +2235,14 @@ PathSet DerivationGoal::checkPathValidity(bool returnValid)
|
|||
bool DerivationGoal::pathFailed(const Path & path)
|
||||
{
|
||||
if (!worker.cacheFailure) return false;
|
||||
|
||||
|
||||
if (!worker.store.hasPathFailed(path)) return false;
|
||||
|
||||
printMsg(lvlError, format("builder for `%1%' failed previously (cached)") % path);
|
||||
|
||||
|
||||
if (printBuildTrace)
|
||||
printMsg(lvlError, format("@ build-failed %1% %2% cached") % drvPath % path);
|
||||
|
||||
|
||||
worker.permanentFailure = true;
|
||||
amDone(ecFailed);
|
||||
|
||||
|
@ -2256,7 +2256,7 @@ bool DerivationGoal::pathFailed(const Path & path)
|
|||
class SubstitutionGoal : public Goal
|
||||
{
|
||||
friend class Worker;
|
||||
|
||||
|
||||
private:
|
||||
/* The store path that should be realised through a substitute. */
|
||||
Path storePath;
|
||||
|
@ -2281,7 +2281,7 @@ private:
|
|||
|
||||
/* Lock on the store path. */
|
||||
boost::shared_ptr<PathLocks> outputLock;
|
||||
|
||||
|
||||
typedef void (SubstitutionGoal::*GoalState)();
|
||||
GoalState state;
|
||||
|
||||
|
@ -2290,7 +2290,7 @@ public:
|
|||
~SubstitutionGoal();
|
||||
|
||||
void cancel();
|
||||
|
||||
|
||||
void work();
|
||||
|
||||
/* The states. */
|
||||
|
@ -2351,7 +2351,7 @@ void SubstitutionGoal::init()
|
|||
trace("init");
|
||||
|
||||
worker.store.addTempRoot(storePath);
|
||||
|
||||
|
||||
/* If the path already exists we're done. */
|
||||
if (worker.store.isValidPath(storePath)) {
|
||||
amDone(ecSuccess);
|
||||
|
@ -2362,7 +2362,7 @@ void SubstitutionGoal::init()
|
|||
throw Error(format("cannot substitute path `%1%' - no write access to the Nix store") % storePath);
|
||||
|
||||
subs = substituters;
|
||||
|
||||
|
||||
tryNext();
|
||||
}
|
||||
|
||||
|
@ -2448,7 +2448,7 @@ void SubstitutionGoal::tryToRun()
|
|||
worker.waitForAnyGoal(shared_from_this());
|
||||
return; /* restart in the tryToRun() state when another goal finishes */
|
||||
}
|
||||
|
||||
|
||||
/* Acquire a lock on the output path. */
|
||||
outputLock = boost::shared_ptr<PathLocks>(new PathLocks);
|
||||
if (!outputLock->lockPaths(singleton<PathSet>(storePath), "", false)) {
|
||||
|
@ -2465,7 +2465,7 @@ void SubstitutionGoal::tryToRun()
|
|||
}
|
||||
|
||||
printMsg(lvlInfo, format("fetching path `%1%'...") % storePath);
|
||||
|
||||
|
||||
logPipe.create();
|
||||
|
||||
/* Remove the (stale) output path if it exists. */
|
||||
|
@ -2475,7 +2475,7 @@ void SubstitutionGoal::tryToRun()
|
|||
/* Fork the substitute program. */
|
||||
pid = fork();
|
||||
switch (pid) {
|
||||
|
||||
|
||||
case -1:
|
||||
throw SysError("unable to fork");
|
||||
|
||||
|
@ -2494,15 +2494,15 @@ void SubstitutionGoal::tryToRun()
|
|||
const char * * argArr = strings2CharPtrs(args);
|
||||
|
||||
execv(sub.c_str(), (char * *) argArr);
|
||||
|
||||
|
||||
throw SysError(format("executing `%1%'") % sub);
|
||||
|
||||
|
||||
} catch (std::exception & e) {
|
||||
std::cerr << format("substitute error: %1%") % e.what() << std::endl;
|
||||
}
|
||||
quickExit(1);
|
||||
}
|
||||
|
||||
|
||||
/* parent */
|
||||
pid.setSeparatePG(true);
|
||||
pid.setKillSignal(SIGTERM);
|
||||
|
@ -2538,23 +2538,23 @@ void SubstitutionGoal::finished()
|
|||
|
||||
/* Check the exit status and the build result. */
|
||||
try {
|
||||
|
||||
|
||||
if (!statusOk(status))
|
||||
throw SubstError(format("fetching path `%1%' %2%")
|
||||
% storePath % statusToString(status));
|
||||
|
||||
if (!pathExists(storePath))
|
||||
throw SubstError(format("substitute did not produce path `%1%'") % storePath);
|
||||
|
||||
|
||||
} catch (SubstError & e) {
|
||||
|
||||
printMsg(lvlInfo, e.msg());
|
||||
|
||||
|
||||
if (printBuildTrace) {
|
||||
printMsg(lvlError, format("@ substituter-failed %1% %2% %3%")
|
||||
% storePath % status % e.msg());
|
||||
}
|
||||
|
||||
|
||||
/* Try the next substitute. */
|
||||
state = &SubstitutionGoal::tryNext;
|
||||
worker.wakeUp(shared_from_this());
|
||||
|
@ -2564,9 +2564,9 @@ void SubstitutionGoal::finished()
|
|||
canonicalisePathMetaData(storePath);
|
||||
|
||||
HashResult hash = hashPath(htSHA256, storePath);
|
||||
|
||||
|
||||
worker.store.optimisePath(storePath); // FIXME: combine with hashPath()
|
||||
|
||||
|
||||
ValidPathInfo info2;
|
||||
info2.path = storePath;
|
||||
info2.hash = hash.first;
|
||||
|
@ -2576,14 +2576,14 @@ void SubstitutionGoal::finished()
|
|||
worker.store.registerValidPath(info2);
|
||||
|
||||
outputLock->setDeletion(true);
|
||||
|
||||
|
||||
printMsg(lvlChatty,
|
||||
format("substitution of path `%1%' succeeded") % storePath);
|
||||
|
||||
if (printBuildTrace) {
|
||||
printMsg(lvlError, format("@ substituter-succeeded %1%") % storePath);
|
||||
}
|
||||
|
||||
|
||||
amDone(ecSuccess);
|
||||
}
|
||||
|
||||
|
@ -2614,7 +2614,7 @@ static bool working = false;
|
|||
Worker::Worker(LocalStore & store)
|
||||
: store(store)
|
||||
{
|
||||
/* Debugging: prevent recursive workers. */
|
||||
/* Debugging: prevent recursive workers. */
|
||||
if (working) abort();
|
||||
working = true;
|
||||
nrLocalBuilds = 0;
|
||||
|
@ -2729,7 +2729,7 @@ void Worker::childStarted(GoalPtr goal,
|
|||
void Worker::childTerminated(pid_t pid, bool wakeSleepers)
|
||||
{
|
||||
assert(pid != -1); /* common mistake */
|
||||
|
||||
|
||||
Children::iterator i = children.find(pid);
|
||||
assert(i != children.end());
|
||||
|
||||
|
@ -2741,7 +2741,7 @@ void Worker::childTerminated(pid_t pid, bool wakeSleepers)
|
|||
children.erase(pid);
|
||||
|
||||
if (wakeSleepers) {
|
||||
|
||||
|
||||
/* Wake up goals waiting for a build slot. */
|
||||
foreach (WeakGoals::iterator, i, wantingToBuild) {
|
||||
GoalPtr goal = i->lock();
|
||||
|
@ -2780,7 +2780,7 @@ void Worker::waitForAWhile(GoalPtr goal)
|
|||
void Worker::run(const Goals & _topGoals)
|
||||
{
|
||||
foreach (Goals::iterator, i, _topGoals) topGoals.insert(*i);
|
||||
|
||||
|
||||
startNest(nest, lvlDebug, format("entered goal loop"));
|
||||
|
||||
while (1) {
|
||||
|
@ -2866,7 +2866,7 @@ void Worker::waitForInput()
|
|||
/* If we are polling goals that are waiting for a lock, then wake
|
||||
up after a few seconds at most. */
|
||||
int wakeUpInterval = queryIntSetting("build-poll-interval", 5);
|
||||
|
||||
|
||||
if (!waitingForAWhile.empty()) {
|
||||
useTimeout = true;
|
||||
if (lastWokenUp == 0)
|
||||
|
@ -2907,7 +2907,7 @@ void Worker::waitForInput()
|
|||
cancel(). */
|
||||
set<pid_t> pids;
|
||||
foreach (Children::iterator, i, children) pids.insert(i->first);
|
||||
|
||||
|
||||
foreach (set<pid_t>::iterator, i, pids) {
|
||||
checkInterrupt();
|
||||
Children::iterator j = children.find(*i);
|
||||
|
@ -3001,7 +3001,7 @@ void LocalStore::buildPaths(const PathSet & drvPaths)
|
|||
if (i2) failed.insert(i2->getDrvPath());
|
||||
else failed.insert(dynamic_cast<SubstitutionGoal *>(i->get())->getStorePath());
|
||||
}
|
||||
|
||||
|
||||
if (!failed.empty())
|
||||
throw Error(format("build of %1% failed") % showPaths(failed), worker.exitStatus());
|
||||
}
|
||||
|
@ -3022,5 +3022,5 @@ void LocalStore::ensurePath(const Path & path)
|
|||
throw Error(format("path `%1%' does not exist and cannot be created") % path, worker.exitStatus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue