forked from lix-project/lix
Merge remote-tracking branch 'origin/master' into flakes
This commit is contained in:
commit
e302ba0e65
|
@ -4,7 +4,7 @@
|
||||||
version="5.0"
|
version="5.0"
|
||||||
xml:id="ssec-relnotes-2.3">
|
xml:id="ssec-relnotes-2.3">
|
||||||
|
|
||||||
<title>Release 2.3 (2019-08-??)</title>
|
<title>Release 2.3 (2019-09-04)</title>
|
||||||
|
|
||||||
<para>This is primarily a bug fix release. However, it makes some
|
<para>This is primarily a bug fix release. However, it makes some
|
||||||
incompatible changes:</para>
|
incompatible changes:</para>
|
||||||
|
|
|
@ -13,8 +13,12 @@
|
||||||
<true/>
|
<true/>
|
||||||
<key>RunAtLoad</key>
|
<key>RunAtLoad</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>Program</key>
|
<key>ProgramArguments</key>
|
||||||
<string>@bindir@/nix-daemon</string>
|
<array>
|
||||||
|
<string>/bin/sh</string>
|
||||||
|
<string>-c</string>
|
||||||
|
<string>/bin/wait4path @bindir@/nix-daemon && @bindir@/nix-daemon</string>
|
||||||
|
</array>
|
||||||
<key>StandardErrorPath</key>
|
<key>StandardErrorPath</key>
|
||||||
<string>/var/log/nix-daemon.log</string>
|
<string>/var/log/nix-daemon.log</string>
|
||||||
<key>StandardOutPath</key>
|
<key>StandardOutPath</key>
|
||||||
|
|
|
@ -55,7 +55,7 @@ void BinaryCacheStore::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinaryCacheStore::getFile(const std::string & path,
|
void BinaryCacheStore::getFile(const std::string & path,
|
||||||
Callback<std::shared_ptr<std::string>> callback)
|
Callback<std::shared_ptr<std::string>> callback) noexcept
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
callback(getFile(path));
|
callback(getFile(path));
|
||||||
|
@ -240,7 +240,7 @@ void BinaryCacheStore::narFromPath(const Path & storePath, Sink & sink)
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinaryCacheStore::queryPathInfoUncached(const Path & storePath,
|
void BinaryCacheStore::queryPathInfoUncached(const Path & storePath,
|
||||||
Callback<std::shared_ptr<ValidPathInfo>> callback)
|
Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept
|
||||||
{
|
{
|
||||||
auto uri = getUri();
|
auto uri = getUri();
|
||||||
auto act = std::make_shared<Activity>(*logger, lvlTalkative, actQueryPathInfo,
|
auto act = std::make_shared<Activity>(*logger, lvlTalkative, actQueryPathInfo,
|
||||||
|
@ -249,21 +249,23 @@ void BinaryCacheStore::queryPathInfoUncached(const Path & storePath,
|
||||||
|
|
||||||
auto narInfoFile = narInfoFileFor(storePath);
|
auto narInfoFile = narInfoFileFor(storePath);
|
||||||
|
|
||||||
|
auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
|
||||||
|
|
||||||
getFile(narInfoFile,
|
getFile(narInfoFile,
|
||||||
{[=](std::future<std::shared_ptr<std::string>> fut) {
|
{[=](std::future<std::shared_ptr<std::string>> fut) {
|
||||||
try {
|
try {
|
||||||
auto data = fut.get();
|
auto data = fut.get();
|
||||||
|
|
||||||
if (!data) return callback(nullptr);
|
if (!data) return (*callbackPtr)(nullptr);
|
||||||
|
|
||||||
stats.narInfoRead++;
|
stats.narInfoRead++;
|
||||||
|
|
||||||
callback((std::shared_ptr<ValidPathInfo>)
|
(*callbackPtr)((std::shared_ptr<ValidPathInfo>)
|
||||||
std::make_shared<NarInfo>(*this, *data, narInfoFile));
|
std::make_shared<NarInfo>(*this, *data, narInfoFile));
|
||||||
|
|
||||||
(void) act; // force Activity into this lambda to ensure it stays alive
|
(void) act; // force Activity into this lambda to ensure it stays alive
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
callback.rethrow();
|
callbackPtr->rethrow();
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
/* Fetch the specified file and call the specified callback with
|
/* Fetch the specified file and call the specified callback with
|
||||||
the result. A subclass may implement this asynchronously. */
|
the result. A subclass may implement this asynchronously. */
|
||||||
virtual void getFile(const std::string & path,
|
virtual void getFile(const std::string & path,
|
||||||
Callback<std::shared_ptr<std::string>> callback);
|
Callback<std::shared_ptr<std::string>> callback) noexcept;
|
||||||
|
|
||||||
std::shared_ptr<std::string> getFile(const std::string & path);
|
std::shared_ptr<std::string> getFile(const std::string & path);
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
bool isValidPathUncached(const Path & path) override;
|
bool isValidPathUncached(const Path & path) override;
|
||||||
|
|
||||||
void queryPathInfoUncached(const Path & path,
|
void queryPathInfoUncached(const Path & path,
|
||||||
Callback<std::shared_ptr<ValidPathInfo>> callback) override;
|
Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept override;
|
||||||
|
|
||||||
Path queryPathFromHashPart(const string & hashPart) override
|
Path queryPathFromHashPart(const string & hashPart) override
|
||||||
{ unsupported("queryPathFromHashPart"); }
|
{ unsupported("queryPathFromHashPart"); }
|
||||||
|
|
|
@ -1197,7 +1197,7 @@ void DerivationGoal::haveDerivation()
|
||||||
/* We are first going to try to create the invalid output paths
|
/* We are first going to try to create the invalid output paths
|
||||||
through substitutes. If that doesn't work, we'll build
|
through substitutes. If that doesn't work, we'll build
|
||||||
them. */
|
them. */
|
||||||
if (settings.useSubstitutes && drv->substitutesAllowed())
|
if (settings.useSubstitutes && parsedDrv->substitutesAllowed())
|
||||||
for (auto & i : invalidOutputs)
|
for (auto & i : invalidOutputs)
|
||||||
addWaitee(worker.makeSubstitutionGoal(i, buildMode == bmRepair ? Repair : NoRepair));
|
addWaitee(worker.makeSubstitutionGoal(i, buildMode == bmRepair ? Repair : NoRepair));
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,6 @@ Path BasicDerivation::findOutput(const string & id) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BasicDerivation::substitutesAllowed() const
|
|
||||||
{
|
|
||||||
return get(env, "allowSubstitutes", "1") == "1";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool BasicDerivation::isBuiltin() const
|
bool BasicDerivation::isBuiltin() const
|
||||||
{
|
{
|
||||||
return string(builder, 0, 8) == "builtin:";
|
return string(builder, 0, 8) == "builtin:";
|
||||||
|
|
|
@ -56,8 +56,6 @@ struct BasicDerivation
|
||||||
the given derivation. */
|
the given derivation. */
|
||||||
Path findOutput(const string & id) const;
|
Path findOutput(const string & id) const;
|
||||||
|
|
||||||
bool substitutesAllowed() const;
|
|
||||||
|
|
||||||
bool isBuiltin() const;
|
bool isBuiltin() const;
|
||||||
|
|
||||||
/* Return true iff this is a fixed-output derivation. */
|
/* Return true iff this is a fixed-output derivation. */
|
||||||
|
|
|
@ -77,13 +77,13 @@ struct CurlDownloader : public Downloader
|
||||||
|
|
||||||
DownloadItem(CurlDownloader & downloader,
|
DownloadItem(CurlDownloader & downloader,
|
||||||
const DownloadRequest & request,
|
const DownloadRequest & request,
|
||||||
Callback<DownloadResult> callback)
|
Callback<DownloadResult> && callback)
|
||||||
: downloader(downloader)
|
: downloader(downloader)
|
||||||
, request(request)
|
, request(request)
|
||||||
, act(*logger, lvlTalkative, actDownload,
|
, act(*logger, lvlTalkative, actDownload,
|
||||||
fmt(request.data ? "uploading '%s'" : "downloading '%s'", request.uri),
|
fmt(request.data ? "uploading '%s'" : "downloading '%s'", request.uri),
|
||||||
{request.uri}, request.parentAct)
|
{request.uri}, request.parentAct)
|
||||||
, callback(callback)
|
, callback(std::move(callback))
|
||||||
, finalSink([this](const unsigned char * data, size_t len) {
|
, finalSink([this](const unsigned char * data, size_t len) {
|
||||||
if (this->request.dataCallback) {
|
if (this->request.dataCallback) {
|
||||||
writtenToSink += len;
|
writtenToSink += len;
|
||||||
|
@ -342,15 +342,9 @@ struct CurlDownloader : public Downloader
|
||||||
(httpStatus == 200 || httpStatus == 201 || httpStatus == 204 || httpStatus == 206 || httpStatus == 304 || httpStatus == 226 /* FTP */ || httpStatus == 0 /* other protocol */))
|
(httpStatus == 200 || httpStatus == 201 || httpStatus == 204 || httpStatus == 206 || httpStatus == 304 || httpStatus == 226 /* FTP */ || httpStatus == 0 /* other protocol */))
|
||||||
{
|
{
|
||||||
result.cached = httpStatus == 304;
|
result.cached = httpStatus == 304;
|
||||||
|
act.progress(result.bodySize, result.bodySize);
|
||||||
done = true;
|
done = true;
|
||||||
|
callback(std::move(result));
|
||||||
try {
|
|
||||||
act.progress(result.bodySize, result.bodySize);
|
|
||||||
callback(std::move(result));
|
|
||||||
} catch (...) {
|
|
||||||
done = true;
|
|
||||||
callback.rethrow();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
@ -671,7 +665,7 @@ struct CurlDownloader : public Downloader
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
enqueueItem(std::make_shared<DownloadItem>(*this, request, callback));
|
enqueueItem(std::make_shared<DownloadItem>(*this, request, std::move(callback)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -131,23 +131,25 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void getFile(const std::string & path,
|
void getFile(const std::string & path,
|
||||||
Callback<std::shared_ptr<std::string>> callback) override
|
Callback<std::shared_ptr<std::string>> callback) noexcept override
|
||||||
{
|
{
|
||||||
checkEnabled();
|
checkEnabled();
|
||||||
|
|
||||||
auto request(makeRequest(path));
|
auto request(makeRequest(path));
|
||||||
|
|
||||||
|
auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
|
||||||
|
|
||||||
getDownloader()->enqueueDownload(request,
|
getDownloader()->enqueueDownload(request,
|
||||||
{[callback, this](std::future<DownloadResult> result) {
|
{[callbackPtr, this](std::future<DownloadResult> result) {
|
||||||
try {
|
try {
|
||||||
callback(result.get().data);
|
(*callbackPtr)(result.get().data);
|
||||||
} catch (DownloadError & e) {
|
} catch (DownloadError & e) {
|
||||||
if (e.error == Downloader::NotFound || e.error == Downloader::Forbidden)
|
if (e.error == Downloader::NotFound || e.error == Downloader::Forbidden)
|
||||||
return callback(std::shared_ptr<std::string>());
|
return (*callbackPtr)(std::shared_ptr<std::string>());
|
||||||
maybeDisable();
|
maybeDisable();
|
||||||
callback.rethrow();
|
callbackPtr->rethrow();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
callback.rethrow();
|
callbackPtr->rethrow();
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ struct LegacySSHStore : public Store
|
||||||
}
|
}
|
||||||
|
|
||||||
void queryPathInfoUncached(const Path & path,
|
void queryPathInfoUncached(const Path & path,
|
||||||
Callback<std::shared_ptr<ValidPathInfo>> callback) override
|
Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept override
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto conn(connections->get());
|
auto conn(connections->get());
|
||||||
|
|
|
@ -622,7 +622,7 @@ uint64_t LocalStore::addValidPath(State & state,
|
||||||
|
|
||||||
|
|
||||||
void LocalStore::queryPathInfoUncached(const Path & path,
|
void LocalStore::queryPathInfoUncached(const Path & path,
|
||||||
Callback<std::shared_ptr<ValidPathInfo>> callback)
|
Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto info = std::make_shared<ValidPathInfo>();
|
auto info = std::make_shared<ValidPathInfo>();
|
||||||
|
|
|
@ -127,7 +127,7 @@ public:
|
||||||
PathSet queryAllValidPaths() override;
|
PathSet queryAllValidPaths() override;
|
||||||
|
|
||||||
void queryPathInfoUncached(const Path & path,
|
void queryPathInfoUncached(const Path & path,
|
||||||
Callback<std::shared_ptr<ValidPathInfo>> callback) override;
|
Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept override;
|
||||||
|
|
||||||
void queryReferrers(const Path & path, PathSet & referrers) override;
|
void queryReferrers(const Path & path, PathSet & referrers) override;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
|
#include "parsed-derivations.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "local-store.hh"
|
#include "local-store.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
@ -189,6 +190,7 @@ void Store::queryMissing(const PathSet & targets,
|
||||||
}
|
}
|
||||||
|
|
||||||
Derivation drv = derivationFromPath(i2.first);
|
Derivation drv = derivationFromPath(i2.first);
|
||||||
|
ParsedDerivation parsedDrv(i2.first, drv);
|
||||||
|
|
||||||
PathSet invalid;
|
PathSet invalid;
|
||||||
for (auto & j : drv.outputs)
|
for (auto & j : drv.outputs)
|
||||||
|
@ -197,7 +199,7 @@ void Store::queryMissing(const PathSet & targets,
|
||||||
invalid.insert(j.second.path);
|
invalid.insert(j.second.path);
|
||||||
if (invalid.empty()) return;
|
if (invalid.empty()) return;
|
||||||
|
|
||||||
if (settings.useSubstitutes && drv.substitutesAllowed()) {
|
if (settings.useSubstitutes && parsedDrv.substitutesAllowed()) {
|
||||||
auto drvState = make_ref<Sync<DrvState>>(DrvState(invalid.size()));
|
auto drvState = make_ref<Sync<DrvState>>(DrvState(invalid.size()));
|
||||||
for (auto & output : invalid)
|
for (auto & output : invalid)
|
||||||
pool.enqueue(std::bind(checkOutput, i2.first, make_ref<Derivation>(drv), output, drvState));
|
pool.enqueue(std::bind(checkOutput, i2.first, make_ref<Derivation>(drv), output, drvState));
|
||||||
|
|
|
@ -108,4 +108,9 @@ bool ParsedDerivation::willBuildLocally() const
|
||||||
return getBoolAttr("preferLocalBuild") && canBuildLocally();
|
return getBoolAttr("preferLocalBuild") && canBuildLocally();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ParsedDerivation::substitutesAllowed() const
|
||||||
|
{
|
||||||
|
return getBoolAttr("allowSubstitutes", true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ public:
|
||||||
bool canBuildLocally() const;
|
bool canBuildLocally() const;
|
||||||
|
|
||||||
bool willBuildLocally() const;
|
bool willBuildLocally() const;
|
||||||
|
|
||||||
|
bool substitutesAllowed() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,7 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths,
|
||||||
|
|
||||||
|
|
||||||
void RemoteStore::queryPathInfoUncached(const Path & path,
|
void RemoteStore::queryPathInfoUncached(const Path & path,
|
||||||
Callback<std::shared_ptr<ValidPathInfo>> callback)
|
Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
std::shared_ptr<ValidPathInfo> info;
|
std::shared_ptr<ValidPathInfo> info;
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
PathSet queryAllValidPaths() override;
|
PathSet queryAllValidPaths() override;
|
||||||
|
|
||||||
void queryPathInfoUncached(const Path & path,
|
void queryPathInfoUncached(const Path & path,
|
||||||
Callback<std::shared_ptr<ValidPathInfo>> callback) override;
|
Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept override;
|
||||||
|
|
||||||
void queryReferrers(const Path & path, PathSet & referrers) override;
|
void queryReferrers(const Path & path, PathSet & referrers) override;
|
||||||
|
|
||||||
|
|
|
@ -329,13 +329,14 @@ ref<const ValidPathInfo> Store::queryPathInfo(const Path & storePath)
|
||||||
|
|
||||||
|
|
||||||
void Store::queryPathInfo(const Path & storePath,
|
void Store::queryPathInfo(const Path & storePath,
|
||||||
Callback<ref<ValidPathInfo>> callback)
|
Callback<ref<ValidPathInfo>> callback) noexcept
|
||||||
{
|
{
|
||||||
assertStorePath(storePath);
|
std::string hashPart;
|
||||||
|
|
||||||
auto hashPart = storePathToHash(storePath);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
assertStorePath(storePath);
|
||||||
|
|
||||||
|
hashPart = storePathToHash(storePath);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = state.lock()->pathInfoCache.get(hashPart);
|
auto res = state.lock()->pathInfoCache.get(hashPart);
|
||||||
|
@ -365,8 +366,10 @@ void Store::queryPathInfo(const Path & storePath,
|
||||||
|
|
||||||
} catch (...) { return callback.rethrow(); }
|
} catch (...) { return callback.rethrow(); }
|
||||||
|
|
||||||
|
auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
|
||||||
|
|
||||||
queryPathInfoUncached(storePath,
|
queryPathInfoUncached(storePath,
|
||||||
{[this, storePath, hashPart, callback](std::future<std::shared_ptr<ValidPathInfo>> fut) {
|
{[this, storePath, hashPart, callbackPtr](std::future<std::shared_ptr<ValidPathInfo>> fut) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto info = fut.get();
|
auto info = fut.get();
|
||||||
|
@ -386,8 +389,8 @@ void Store::queryPathInfo(const Path & storePath,
|
||||||
throw InvalidPath("path '%s' is not valid", storePath);
|
throw InvalidPath("path '%s' is not valid", storePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(ref<ValidPathInfo>(info));
|
(*callbackPtr)(ref<ValidPathInfo>(info));
|
||||||
} catch (...) { callback.rethrow(); }
|
} catch (...) { callbackPtr->rethrow(); }
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -361,12 +361,12 @@ public:
|
||||||
|
|
||||||
/* Asynchronous version of queryPathInfo(). */
|
/* Asynchronous version of queryPathInfo(). */
|
||||||
void queryPathInfo(const Path & path,
|
void queryPathInfo(const Path & path,
|
||||||
Callback<ref<ValidPathInfo>> callback);
|
Callback<ref<ValidPathInfo>> callback) noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void queryPathInfoUncached(const Path & path,
|
virtual void queryPathInfoUncached(const Path & path,
|
||||||
Callback<std::shared_ptr<ValidPathInfo>> callback) = 0;
|
Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -469,21 +469,34 @@ string get(const T & map, const string & key, const string & def = "")
|
||||||
type T or an exception. (We abuse std::future<T> to pass the value or
|
type T or an exception. (We abuse std::future<T> to pass the value or
|
||||||
exception.) */
|
exception.) */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Callback
|
class Callback
|
||||||
{
|
{
|
||||||
std::function<void(std::future<T>)> fun;
|
std::function<void(std::future<T>)> fun;
|
||||||
|
std::atomic_flag done = ATOMIC_FLAG_INIT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
Callback(std::function<void(std::future<T>)> fun) : fun(fun) { }
|
Callback(std::function<void(std::future<T>)> fun) : fun(fun) { }
|
||||||
|
|
||||||
void operator()(T && t) const
|
Callback(Callback && callback) : fun(std::move(callback.fun))
|
||||||
{
|
{
|
||||||
|
auto prev = callback.done.test_and_set();
|
||||||
|
if (prev) done.test_and_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(T && t) noexcept
|
||||||
|
{
|
||||||
|
auto prev = done.test_and_set();
|
||||||
|
assert(!prev);
|
||||||
std::promise<T> promise;
|
std::promise<T> promise;
|
||||||
promise.set_value(std::move(t));
|
promise.set_value(std::move(t));
|
||||||
fun(promise.get_future());
|
fun(promise.get_future());
|
||||||
}
|
}
|
||||||
|
|
||||||
void rethrow(const std::exception_ptr & exc = std::current_exception()) const
|
void rethrow(const std::exception_ptr & exc = std::current_exception()) noexcept
|
||||||
{
|
{
|
||||||
|
auto prev = done.test_and_set();
|
||||||
|
assert(!prev);
|
||||||
std::promise<T> promise;
|
std::promise<T> promise;
|
||||||
promise.set_exception(exc);
|
promise.set_exception(exc);
|
||||||
fun(promise.get_future());
|
fun(promise.get_future());
|
||||||
|
|
|
@ -17,42 +17,50 @@ expr=$(cat <<EOF
|
||||||
with import ./config.nix; mkDerivation {
|
with import ./config.nix; mkDerivation {
|
||||||
name = "gc-A";
|
name = "gc-A";
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
|
set -x
|
||||||
[[ \$(ls \$NIX_STORE/*-garbage? | wc -l) = 3 ]]
|
[[ \$(ls \$NIX_STORE/*-garbage? | wc -l) = 3 ]]
|
||||||
mkdir \$out
|
mkdir \$out
|
||||||
echo foo > \$out/bar
|
echo foo > \$out/bar
|
||||||
echo 1...
|
echo 1...
|
||||||
sleep 2
|
sleep 2
|
||||||
echo 200 > $fake_free
|
echo 200 > ${fake_free}.tmp1
|
||||||
|
mv ${fake_free}.tmp1 $fake_free
|
||||||
echo 2...
|
echo 2...
|
||||||
sleep 2
|
sleep 2
|
||||||
echo 3...
|
echo 3...
|
||||||
|
sleep 2
|
||||||
|
echo 4...
|
||||||
[[ \$(ls \$NIX_STORE/*-garbage? | wc -l) = 1 ]]
|
[[ \$(ls \$NIX_STORE/*-garbage? | wc -l) = 1 ]]
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expr2=$(cat <<EOF
|
||||||
|
with import ./config.nix; mkDerivation {
|
||||||
|
name = "gc-B";
|
||||||
|
buildCommand = ''
|
||||||
|
set -x
|
||||||
|
mkdir \$out
|
||||||
|
echo foo > \$out/bar
|
||||||
|
echo 1...
|
||||||
|
sleep 2
|
||||||
|
echo 200 > ${fake_free}.tmp2
|
||||||
|
mv ${fake_free}.tmp2 $fake_free
|
||||||
|
echo 2...
|
||||||
|
sleep 2
|
||||||
|
echo 3...
|
||||||
|
sleep 2
|
||||||
|
echo 4...
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
nix build --impure -v -o $TEST_ROOT/result-A -L "($expr)" \
|
nix build --impure -v -o $TEST_ROOT/result-A -L "($expr)" \
|
||||||
--min-free 1000 --max-free 2000 --min-free-check-interval 1 &
|
--min-free 1000 --max-free 2000 --min-free-check-interval 1 &
|
||||||
pid=$!
|
pid=$!
|
||||||
|
|
||||||
expr2=$(cat <<EOF
|
|
||||||
with import ./config.nix; mkDerivation {
|
|
||||||
name = "gc-B";
|
|
||||||
buildCommand = ''
|
|
||||||
mkdir \$out
|
|
||||||
echo foo > \$out/bar
|
|
||||||
echo 1...
|
|
||||||
sleep 2
|
|
||||||
echo 200 > $fake_free
|
|
||||||
echo 2...
|
|
||||||
sleep 2
|
|
||||||
echo 3...
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
nix build --impure -v -o $TEST_ROOT/result-B -L "($expr2)" \
|
nix build --impure -v -o $TEST_ROOT/result-B -L "($expr2)" \
|
||||||
--min-free 1000 --max-free 2000 --min-free-check-interval 1
|
--min-free 1000 --max-free 2000 --min-free-check-interval 1
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue