Allow setting the state directory as a store parameter
E.g. "local?store=/tmp/store&state=/tmp/var".
This commit is contained in:
parent
f2682e6e18
commit
812c0dfbe2
13 changed files with 112 additions and 77 deletions
|
@ -29,7 +29,7 @@ static string gcRootsDir = "gcroots";
|
||||||
int LocalStore::openGCLock(LockType lockType)
|
int LocalStore::openGCLock(LockType lockType)
|
||||||
{
|
{
|
||||||
Path fnGCLock = (format("%1%/%2%")
|
Path fnGCLock = (format("%1%/%2%")
|
||||||
% settings.nixStateDir % gcLockName).str();
|
% stateDir % gcLockName).str();
|
||||||
|
|
||||||
debug(format("acquiring global GC lock ‘%1%’") % fnGCLock);
|
debug(format("acquiring global GC lock ‘%1%’") % fnGCLock);
|
||||||
|
|
||||||
|
@ -78,12 +78,12 @@ void LocalStore::addIndirectRoot(const Path & path)
|
||||||
{
|
{
|
||||||
string hash = printHash32(hashString(htSHA1, path));
|
string hash = printHash32(hashString(htSHA1, path));
|
||||||
Path realRoot = canonPath((format("%1%/%2%/auto/%3%")
|
Path realRoot = canonPath((format("%1%/%2%/auto/%3%")
|
||||||
% settings.nixStateDir % gcRootsDir % hash).str());
|
% stateDir % gcRootsDir % hash).str());
|
||||||
makeSymlink(realRoot, path);
|
makeSymlink(realRoot, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path Store::addPermRoot(const Path & _storePath,
|
Path LocalFSStore::addPermRoot(const Path & _storePath,
|
||||||
const Path & _gcRoot, bool indirect, bool allowOutsideRootsDir)
|
const Path & _gcRoot, bool indirect, bool allowOutsideRootsDir)
|
||||||
{
|
{
|
||||||
Path storePath(canonPath(_storePath));
|
Path storePath(canonPath(_storePath));
|
||||||
|
@ -106,7 +106,7 @@ Path Store::addPermRoot(const Path & _storePath,
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (!allowOutsideRootsDir) {
|
if (!allowOutsideRootsDir) {
|
||||||
Path rootsDir = canonPath((format("%1%/%2%") % settings.nixStateDir % gcRootsDir).str());
|
Path rootsDir = canonPath((format("%1%/%2%") % stateDir % gcRootsDir).str());
|
||||||
|
|
||||||
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
|
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
|
||||||
throw Error(format(
|
throw Error(format(
|
||||||
|
@ -153,7 +153,7 @@ void LocalStore::addTempRoot(const Path & path)
|
||||||
if (state->fdTempRoots == -1) {
|
if (state->fdTempRoots == -1) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
Path dir = (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str();
|
Path dir = (format("%1%/%2%") % stateDir % tempRootsDir).str();
|
||||||
createDirs(dir);
|
createDirs(dir);
|
||||||
|
|
||||||
state->fnTempRoots = (format("%1%/%2%") % dir % getpid()).str();
|
state->fnTempRoots = (format("%1%/%2%") % dir % getpid()).str();
|
||||||
|
@ -200,19 +200,15 @@ void LocalStore::addTempRoot(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef std::shared_ptr<AutoCloseFD> FDPtr;
|
void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||||
typedef list<FDPtr> FDs;
|
|
||||||
|
|
||||||
|
|
||||||
static void readTempRoots(Store & store, PathSet & tempRoots, FDs & fds)
|
|
||||||
{
|
{
|
||||||
/* Read the `temproots' directory for per-process temporary root
|
/* Read the `temproots' directory for per-process temporary root
|
||||||
files. */
|
files. */
|
||||||
DirEntries tempRootFiles = readDirectory(
|
DirEntries tempRootFiles = readDirectory(
|
||||||
(format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str());
|
(format("%1%/%2%") % stateDir % tempRootsDir).str());
|
||||||
|
|
||||||
for (auto & i : tempRootFiles) {
|
for (auto & i : tempRootFiles) {
|
||||||
Path path = (format("%1%/%2%/%3%") % settings.nixStateDir % tempRootsDir % i.name).str();
|
Path path = (format("%1%/%2%/%3%") % stateDir % tempRootsDir % i.name).str();
|
||||||
|
|
||||||
debug(format("reading temporary root file ‘%1%’") % path);
|
debug(format("reading temporary root file ‘%1%’") % path);
|
||||||
FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666)));
|
FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666)));
|
||||||
|
@ -251,7 +247,7 @@ static void readTempRoots(Store & store, PathSet & tempRoots, FDs & fds)
|
||||||
while ((end = contents.find((char) 0, pos)) != string::npos) {
|
while ((end = contents.find((char) 0, pos)) != string::npos) {
|
||||||
Path root(contents, pos, end - pos);
|
Path root(contents, pos, end - pos);
|
||||||
debug(format("got temporary root ‘%1%’") % root);
|
debug(format("got temporary root ‘%1%’") % root);
|
||||||
store.assertStorePath(root);
|
assertStorePath(root);
|
||||||
tempRoots.insert(root);
|
tempRoots.insert(root);
|
||||||
pos = end + 1;
|
pos = end + 1;
|
||||||
}
|
}
|
||||||
|
@ -290,7 +286,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
else {
|
else {
|
||||||
target = absPath(target, dirOf(path));
|
target = absPath(target, dirOf(path));
|
||||||
if (!pathExists(target)) {
|
if (!pathExists(target)) {
|
||||||
if (isInDir(path, settings.nixStateDir + "/" + gcRootsDir + "/auto")) {
|
if (isInDir(path, stateDir + "/" + gcRootsDir + "/auto")) {
|
||||||
printMsg(lvlInfo, format("removing stale link from ‘%1%’ to ‘%2%’") % path % target);
|
printMsg(lvlInfo, format("removing stale link from ‘%1%’ to ‘%2%’") % path % target);
|
||||||
unlink(path.c_str());
|
unlink(path.c_str());
|
||||||
}
|
}
|
||||||
|
@ -326,10 +322,10 @@ Roots LocalStore::findRoots()
|
||||||
Roots roots;
|
Roots roots;
|
||||||
|
|
||||||
/* Process direct roots in {gcroots,manifests,profiles}. */
|
/* Process direct roots in {gcroots,manifests,profiles}. */
|
||||||
findRoots(settings.nixStateDir + "/" + gcRootsDir, DT_UNKNOWN, roots);
|
findRoots(stateDir + "/" + gcRootsDir, DT_UNKNOWN, roots);
|
||||||
if (pathExists(settings.nixStateDir + "/manifests"))
|
if (pathExists(stateDir + "/manifests"))
|
||||||
findRoots(settings.nixStateDir + "/manifests", DT_UNKNOWN, roots);
|
findRoots(stateDir + "/manifests", DT_UNKNOWN, roots);
|
||||||
findRoots(settings.nixStateDir + "/profiles", DT_UNKNOWN, roots);
|
findRoots(stateDir + "/profiles", DT_UNKNOWN, roots);
|
||||||
|
|
||||||
return roots;
|
return roots;
|
||||||
}
|
}
|
||||||
|
@ -635,7 +631,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
per-process temporary root files. So after this point no paths
|
per-process temporary root files. So after this point no paths
|
||||||
can be added to the set of temporary roots. */
|
can be added to the set of temporary roots. */
|
||||||
FDs fds;
|
FDs fds;
|
||||||
readTempRoots(*this, state.tempRoots, fds);
|
readTempRoots(state.tempRoots, fds);
|
||||||
state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
|
state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
|
||||||
|
|
||||||
/* After this point the set of roots or temporary roots cannot
|
/* After this point the set of roots or temporary roots cannot
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
#include "fs-accessor.hh"
|
#include "fs-accessor.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "globals.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
LocalFSStore::LocalFSStore(const Params & params)
|
||||||
|
: Store(params)
|
||||||
|
, stateDir(get(params, "state", settings.nixStateDir))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
struct LocalStoreAccessor : public FSAccessor
|
struct LocalStoreAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
ref<Store> store;
|
ref<Store> store;
|
||||||
|
|
|
@ -38,9 +38,10 @@ namespace nix {
|
||||||
|
|
||||||
LocalStore::LocalStore(const Params & params)
|
LocalStore::LocalStore(const Params & params)
|
||||||
: LocalFSStore(params)
|
: LocalFSStore(params)
|
||||||
|
, dbDir(get(params, "state", "") != "" ? get(params, "state", "") + "/db" : settings.nixDBPath)
|
||||||
, linksDir(storeDir + "/.links")
|
, linksDir(storeDir + "/.links")
|
||||||
, reservedPath(settings.nixDBPath + "/reserved")
|
, reservedPath(dbDir + "/reserved")
|
||||||
, schemaPath(settings.nixDBPath + "/schema")
|
, schemaPath(dbDir + "/schema")
|
||||||
, requireSigs(settings.get("signed-binary-caches", std::string("")) != "") // FIXME: rename option
|
, requireSigs(settings.get("signed-binary-caches", std::string("")) != "") // FIXME: rename option
|
||||||
, publicKeys(getDefaultPublicKeys())
|
, publicKeys(getDefaultPublicKeys())
|
||||||
{
|
{
|
||||||
|
@ -55,11 +56,11 @@ LocalStore::LocalStore(const Params & params)
|
||||||
createDirs(storeDir);
|
createDirs(storeDir);
|
||||||
makeStoreWritable();
|
makeStoreWritable();
|
||||||
createDirs(linksDir);
|
createDirs(linksDir);
|
||||||
Path profilesDir = settings.nixStateDir + "/profiles";
|
Path profilesDir = stateDir + "/profiles";
|
||||||
createDirs(profilesDir);
|
createDirs(profilesDir);
|
||||||
createDirs(settings.nixStateDir + "/temproots");
|
createDirs(stateDir + "/temproots");
|
||||||
createDirs(settings.nixDBPath);
|
createDirs(dbDir);
|
||||||
Path gcRootsDir = settings.nixStateDir + "/gcroots";
|
Path gcRootsDir = stateDir + "/gcroots";
|
||||||
if (!pathExists(gcRootsDir)) {
|
if (!pathExists(gcRootsDir)) {
|
||||||
createDirs(gcRootsDir);
|
createDirs(gcRootsDir);
|
||||||
createSymlink(profilesDir, gcRootsDir + "/profiles");
|
createSymlink(profilesDir, gcRootsDir + "/profiles");
|
||||||
|
@ -135,7 +136,7 @@ LocalStore::LocalStore(const Params & params)
|
||||||
/* Acquire the big fat lock in shared mode to make sure that no
|
/* Acquire the big fat lock in shared mode to make sure that no
|
||||||
schema upgrade is in progress. */
|
schema upgrade is in progress. */
|
||||||
try {
|
try {
|
||||||
Path globalLockPath = settings.nixDBPath + "/big-lock";
|
Path globalLockPath = dbDir + "/big-lock";
|
||||||
globalLock = openLockFile(globalLockPath.c_str(), true);
|
globalLock = openLockFile(globalLockPath.c_str(), true);
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
if (e.errNo != EACCES) throw;
|
if (e.errNo != EACCES) throw;
|
||||||
|
@ -246,19 +247,13 @@ int LocalStore::getSchema()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LocalStore::haveWriteAccess()
|
|
||||||
{
|
|
||||||
return access(settings.nixDBPath.c_str(), R_OK | W_OK) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LocalStore::openDB(State & state, bool create)
|
void LocalStore::openDB(State & state, bool create)
|
||||||
{
|
{
|
||||||
if (!haveWriteAccess())
|
if (access(dbDir.c_str(), R_OK | W_OK))
|
||||||
throw SysError(format("Nix database directory ‘%1%’ is not writable") % settings.nixDBPath);
|
throw SysError(format("Nix database directory ‘%1%’ is not writable") % dbDir);
|
||||||
|
|
||||||
/* Open the Nix database. */
|
/* Open the Nix database. */
|
||||||
string dbPath = settings.nixDBPath + "/db.sqlite";
|
string dbPath = dbDir + "/db.sqlite";
|
||||||
auto & db(state.db);
|
auto & db(state.db);
|
||||||
if (sqlite3_open_v2(dbPath.c_str(), &db.db,
|
if (sqlite3_open_v2(dbPath.c_str(), &db.db,
|
||||||
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
|
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
|
||||||
|
|
|
@ -73,6 +73,7 @@ private:
|
||||||
|
|
||||||
Sync<State, std::recursive_mutex> _state;
|
Sync<State, std::recursive_mutex> _state;
|
||||||
|
|
||||||
|
const Path dbDir;
|
||||||
const Path linksDir;
|
const Path linksDir;
|
||||||
const Path reservedPath;
|
const Path reservedPath;
|
||||||
const Path schemaPath;
|
const Path schemaPath;
|
||||||
|
@ -146,6 +147,15 @@ public:
|
||||||
|
|
||||||
void syncWithGC() override;
|
void syncWithGC() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
typedef std::shared_ptr<AutoCloseFD> FDPtr;
|
||||||
|
typedef list<FDPtr> FDs;
|
||||||
|
|
||||||
|
void readTempRoots(PathSet & tempRoots, FDs & fds);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
Roots findRoots() override;
|
Roots findRoots() override;
|
||||||
|
|
||||||
void collectGarbage(const GCOptions & options, GCResults & results) override;
|
void collectGarbage(const GCOptions & options, GCResults & results) override;
|
||||||
|
@ -179,8 +189,6 @@ public:
|
||||||
|
|
||||||
void addSignatures(const Path & storePath, const StringSet & sigs) override;
|
void addSignatures(const Path & storePath, const StringSet & sigs) override;
|
||||||
|
|
||||||
static bool haveWriteAccess();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int getSchema();
|
int getSchema();
|
||||||
|
|
|
@ -74,7 +74,7 @@ static void makeName(const Path & profile, unsigned int num,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path createGeneration(ref<Store> store, Path profile, Path outPath)
|
Path createGeneration(ref<LocalFSStore> store, Path profile, Path outPath)
|
||||||
{
|
{
|
||||||
/* The new generation number should be higher than old the
|
/* The new generation number should be higher than old the
|
||||||
previous ones. */
|
previous ones. */
|
||||||
|
|
|
@ -31,9 +31,9 @@ typedef list<Generation> Generations;
|
||||||
profile, sorted by generation number. */
|
profile, sorted by generation number. */
|
||||||
Generations findGenerations(Path profile, int & curGen);
|
Generations findGenerations(Path profile, int & curGen);
|
||||||
|
|
||||||
class Store;
|
class LocalFSStore;
|
||||||
|
|
||||||
Path createGeneration(ref<Store> store, Path profile, Path outPath);
|
Path createGeneration(ref<LocalFSStore> store, Path profile, Path outPath);
|
||||||
|
|
||||||
void deleteGeneration(const Path & profile, unsigned int gen);
|
void deleteGeneration(const Path & profile, unsigned int gen);
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ Path Store::computeStorePathForText(const string & name, const string & s,
|
||||||
|
|
||||||
|
|
||||||
Store::Store(const Params & params)
|
Store::Store(const Params & params)
|
||||||
: storeDir(settings.nixStore)
|
: storeDir(get(params, "store", settings.nixStore))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +508,8 @@ static RegisterStoreImplementation regStore([](
|
||||||
else return 0;
|
else return 0;
|
||||||
|
|
||||||
if (mode == mAuto) {
|
if (mode == mAuto) {
|
||||||
if (LocalStore::haveWriteAccess())
|
auto stateDir = get(params, "state", settings.nixStateDir);
|
||||||
|
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
|
||||||
mode = mLocal;
|
mode = mLocal;
|
||||||
else if (pathExists(settings.nixDaemonSocketFile))
|
else if (pathExists(settings.nixDaemonSocketFile))
|
||||||
mode = mDaemon;
|
mode = mDaemon;
|
||||||
|
|
|
@ -372,10 +372,6 @@ public:
|
||||||
`path' has disappeared. */
|
`path' has disappeared. */
|
||||||
virtual void addIndirectRoot(const Path & path) = 0;
|
virtual void addIndirectRoot(const Path & path) = 0;
|
||||||
|
|
||||||
/* Register a permanent GC root. */
|
|
||||||
Path addPermRoot(const Path & storePath,
|
|
||||||
const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false);
|
|
||||||
|
|
||||||
/* Acquire the global GC lock, then immediately release it. This
|
/* Acquire the global GC lock, then immediately release it. This
|
||||||
function must be called after registering a new permanent root,
|
function must be called after registering a new permanent root,
|
||||||
but before exiting. Otherwise, it is possible that a running
|
but before exiting. Otherwise, it is possible that a running
|
||||||
|
@ -494,11 +490,17 @@ protected:
|
||||||
|
|
||||||
class LocalFSStore : public Store
|
class LocalFSStore : public Store
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
using Store::Store;
|
|
||||||
public:
|
public:
|
||||||
|
const Path stateDir;
|
||||||
|
|
||||||
|
LocalFSStore(const Params & params);
|
||||||
|
|
||||||
void narFromPath(const Path & path, Sink & sink) override;
|
void narFromPath(const Path & path, Sink & sink) override;
|
||||||
ref<FSAccessor> getFSAccessor() override;
|
ref<FSAccessor> getFSAccessor() override;
|
||||||
|
|
||||||
|
/* Register a permanent GC root. */
|
||||||
|
Path addPermRoot(const Path & storePath,
|
||||||
|
const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,19 +45,30 @@ public:
|
||||||
return *p;
|
return *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator std::shared_ptr<T> ()
|
operator std::shared_ptr<T> () const
|
||||||
|
{
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<T> get_ptr() const
|
||||||
{
|
{
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T2>
|
template<typename T2>
|
||||||
ref<T2> cast()
|
ref<T2> cast() const
|
||||||
{
|
{
|
||||||
return ref<T2>(std::dynamic_pointer_cast<T2>(p));
|
return ref<T2>(std::dynamic_pointer_cast<T2>(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T2>
|
template<typename T2>
|
||||||
operator ref<T2> ()
|
std::shared_ptr<T2> dynamic_pointer_cast() const
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<T2>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T2>
|
||||||
|
operator ref<T2> () const
|
||||||
{
|
{
|
||||||
return ref<T2>((std::shared_ptr<T2>) p);
|
return ref<T2>((std::shared_ptr<T2>) p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -692,6 +692,9 @@ static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
|
auto store2 = globals.state->store.dynamic_pointer_cast<LocalFSStore>();
|
||||||
|
if (!store2) throw Error("--set is not supported for this Nix store");
|
||||||
|
|
||||||
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
|
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
|
||||||
string arg = *i++;
|
string arg = *i++;
|
||||||
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
|
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
|
||||||
|
@ -722,7 +725,7 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(format("switching to new user environment"));
|
debug(format("switching to new user environment"));
|
||||||
Path generation = createGeneration(globals.state->store, globals.profile, drv.queryOutPath());
|
Path generation = createGeneration(ref<LocalFSStore>(store2), globals.profile, drv.queryOutPath());
|
||||||
switchLink(globals.profile, generation);
|
switchLink(globals.profile, generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,19 +131,23 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
state.store->buildPaths({topLevelDrv}, state.repair ? bmRepair : bmNormal);
|
state.store->buildPaths({topLevelDrv}, state.repair ? bmRepair : bmNormal);
|
||||||
|
|
||||||
/* Switch the current user environment to the output path. */
|
/* Switch the current user environment to the output path. */
|
||||||
PathLocks lock;
|
auto store2 = state.store.dynamic_pointer_cast<LocalFSStore>();
|
||||||
lockProfile(lock, profile);
|
|
||||||
|
|
||||||
Path lockTokenCur = optimisticLockProfile(profile);
|
if (store2) {
|
||||||
if (lockToken != lockTokenCur) {
|
PathLocks lock;
|
||||||
printMsg(lvlError, format("profile ‘%1%’ changed while we were busy; restarting") % profile);
|
lockProfile(lock, profile);
|
||||||
return false;
|
|
||||||
|
Path lockTokenCur = optimisticLockProfile(profile);
|
||||||
|
if (lockToken != lockTokenCur) {
|
||||||
|
printMsg(lvlError, format("profile ‘%1%’ changed while we were busy; restarting") % profile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(format("switching to new user environment"));
|
||||||
|
Path generation = createGeneration(ref<LocalFSStore>(store2), profile, topLevelOut);
|
||||||
|
switchLink(profile, generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(format("switching to new user environment"));
|
|
||||||
Path generation = createGeneration(state.store, profile, topLevelOut);
|
|
||||||
switchLink(profile, generation);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,9 @@ void processExpr(EvalState & state, const Strings & attrPaths,
|
||||||
else {
|
else {
|
||||||
Path rootName = gcRoot;
|
Path rootName = gcRoot;
|
||||||
if (++rootNr > 1) rootName += "-" + std::to_string(rootNr);
|
if (++rootNr > 1) rootName += "-" + std::to_string(rootNr);
|
||||||
drvPath = state.store->addPermRoot(drvPath, rootName, indirectRoot);
|
auto store2 = state.store.dynamic_pointer_cast<LocalFSStore>();
|
||||||
|
if (store2)
|
||||||
|
drvPath = store2->addPermRoot(drvPath, rootName, indirectRoot);
|
||||||
}
|
}
|
||||||
std::cout << format("%1%%2%\n") % drvPath % (outputName != "out" ? "!" + outputName : "");
|
std::cout << format("%1%%2%\n") % drvPath % (outputName != "out" ? "!" + outputName : "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ static PathSet realisePath(Path path, bool build = true)
|
||||||
{
|
{
|
||||||
DrvPathWithOutputs p = parseDrvPathWithOutputs(path);
|
DrvPathWithOutputs p = parseDrvPathWithOutputs(path);
|
||||||
|
|
||||||
|
auto store2 = std::dynamic_pointer_cast<LocalFSStore>(store);
|
||||||
|
|
||||||
if (isDerivation(p.first)) {
|
if (isDerivation(p.first)) {
|
||||||
if (build) store->buildPaths({path});
|
if (build) store->buildPaths({path});
|
||||||
Derivation drv = store->derivationFromPath(p.first);
|
Derivation drv = store->derivationFromPath(p.first);
|
||||||
|
@ -77,13 +79,15 @@ static PathSet realisePath(Path path, bool build = true)
|
||||||
if (i == drv.outputs.end())
|
if (i == drv.outputs.end())
|
||||||
throw Error(format("derivation ‘%1%’ does not have an output named ‘%2%’") % p.first % j);
|
throw Error(format("derivation ‘%1%’ does not have an output named ‘%2%’") % p.first % j);
|
||||||
Path outPath = i->second.path;
|
Path outPath = i->second.path;
|
||||||
if (gcRoot == "")
|
if (store2) {
|
||||||
printGCWarning();
|
if (gcRoot == "")
|
||||||
else {
|
printGCWarning();
|
||||||
Path rootName = gcRoot;
|
else {
|
||||||
if (rootNr > 1) rootName += "-" + std::to_string(rootNr);
|
Path rootName = gcRoot;
|
||||||
if (i->first != "out") rootName += "-" + i->first;
|
if (rootNr > 1) rootName += "-" + std::to_string(rootNr);
|
||||||
outPath = store->addPermRoot(outPath, rootName, indirectRoot);
|
if (i->first != "out") rootName += "-" + i->first;
|
||||||
|
outPath = store2->addPermRoot(outPath, rootName, indirectRoot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
outputs.insert(outPath);
|
outputs.insert(outPath);
|
||||||
}
|
}
|
||||||
|
@ -93,13 +97,15 @@ static PathSet realisePath(Path path, bool build = true)
|
||||||
else {
|
else {
|
||||||
if (build) store->ensurePath(path);
|
if (build) store->ensurePath(path);
|
||||||
else if (!store->isValidPath(path)) throw Error(format("path ‘%1%’ does not exist and cannot be created") % path);
|
else if (!store->isValidPath(path)) throw Error(format("path ‘%1%’ does not exist and cannot be created") % path);
|
||||||
if (gcRoot == "")
|
if (store2) {
|
||||||
printGCWarning();
|
if (gcRoot == "")
|
||||||
else {
|
printGCWarning();
|
||||||
Path rootName = gcRoot;
|
else {
|
||||||
rootNr++;
|
Path rootName = gcRoot;
|
||||||
if (rootNr > 1) rootName += "-" + std::to_string(rootNr);
|
rootNr++;
|
||||||
path = store->addPermRoot(path, rootName, indirectRoot);
|
if (rootNr > 1) rootName += "-" + std::to_string(rootNr);
|
||||||
|
path = store2->addPermRoot(path, rootName, indirectRoot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {path};
|
return {path};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue