forked from lix-project/lix
UDSRemoteStore: Support the 'root' store parameter
Useful when we're using a daemon with a chroot store, e.g. $ NIX_DAEMON_SOCKET_PATH=/tmp/chroot/nix/var/nix/daemon-socket/socket nix-daemon --store /tmp/chroot Then the client can now connect with $ nix build --store unix:///tmp/chroot/nix/var/nix/daemon-socket/socket?root=/tmp/chroot nixpkgs#hello
This commit is contained in:
parent
e6150de90d
commit
4202a3bc4e
|
@ -292,7 +292,7 @@ bool LocalDerivationGoal::cleanupDecideWhetherDiskFull()
|
||||||
auto & localStore = getLocalStore();
|
auto & localStore = getLocalStore();
|
||||||
uint64_t required = 8ULL * 1024 * 1024; // FIXME: make configurable
|
uint64_t required = 8ULL * 1024 * 1024; // FIXME: make configurable
|
||||||
struct statvfs st;
|
struct statvfs st;
|
||||||
if (statvfs(localStore.realStoreDir.c_str(), &st) == 0 &&
|
if (statvfs(localStore.realStoreDir.get().c_str(), &st) == 0 &&
|
||||||
(uint64_t) st.f_bavail * st.f_bsize < required)
|
(uint64_t) st.f_bavail * st.f_bsize < required)
|
||||||
diskFull = true;
|
diskFull = true;
|
||||||
if (statvfs(tmpDir.c_str(), &st) == 0 &&
|
if (statvfs(tmpDir.c_str(), &st) == 0 &&
|
||||||
|
@ -417,7 +417,7 @@ void LocalDerivationGoal::startBuilder()
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & localStore = getLocalStore();
|
auto & localStore = getLocalStore();
|
||||||
if (localStore.storeDir != localStore.realStoreDir) {
|
if (localStore.storeDir != localStore.realStoreDir.get()) {
|
||||||
#if __linux__
|
#if __linux__
|
||||||
useChroot = true;
|
useChroot = true;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -775,7 +775,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
AutoCloseDir dir(opendir(realStoreDir.c_str()));
|
AutoCloseDir dir(opendir(realStoreDir.get().c_str()));
|
||||||
if (!dir) throw SysError("opening directory '%1%'", realStoreDir);
|
if (!dir) throw SysError("opening directory '%1%'", realStoreDir);
|
||||||
|
|
||||||
/* Read the store and immediately delete all paths that
|
/* Read the store and immediately delete all paths that
|
||||||
|
@ -856,7 +856,7 @@ void LocalStore::autoGC(bool sync)
|
||||||
return std::stoll(readFile(*fakeFreeSpaceFile));
|
return std::stoll(readFile(*fakeFreeSpaceFile));
|
||||||
|
|
||||||
struct statvfs st;
|
struct statvfs st;
|
||||||
if (statvfs(realStoreDir.c_str(), &st))
|
if (statvfs(realStoreDir.get().c_str(), &st))
|
||||||
throw SysError("getting filesystem info about '%s'", realStoreDir);
|
throw SysError("getting filesystem info about '%s'", realStoreDir);
|
||||||
|
|
||||||
return (uint64_t) st.f_bavail * st.f_frsize;
|
return (uint64_t) st.f_bavail * st.f_frsize;
|
||||||
|
|
|
@ -18,6 +18,9 @@ struct LocalFSStoreConfig : virtual StoreConfig
|
||||||
const PathSetting logDir{(StoreConfig*) this, false,
|
const PathSetting logDir{(StoreConfig*) this, false,
|
||||||
rootDir != "" ? rootDir + "/nix/var/log/nix" : settings.nixLogDir,
|
rootDir != "" ? rootDir + "/nix/var/log/nix" : settings.nixLogDir,
|
||||||
"log", "directory where Nix will store state"};
|
"log", "directory where Nix will store state"};
|
||||||
|
const PathSetting realStoreDir{(StoreConfig*) this, false,
|
||||||
|
rootDir != "" ? rootDir + "/nix/store" : storeDir, "real",
|
||||||
|
"physical path to the Nix store"};
|
||||||
};
|
};
|
||||||
|
|
||||||
class LocalFSStore : public virtual LocalFSStoreConfig, public virtual Store
|
class LocalFSStore : public virtual LocalFSStoreConfig, public virtual Store
|
||||||
|
@ -34,7 +37,7 @@ public:
|
||||||
/* Register a permanent GC root. */
|
/* Register a permanent GC root. */
|
||||||
Path addPermRoot(const StorePath & storePath, const Path & gcRoot);
|
Path addPermRoot(const StorePath & storePath, const Path & gcRoot);
|
||||||
|
|
||||||
virtual Path getRealStoreDir() { return storeDir; }
|
virtual Path getRealStoreDir() { return realStoreDir; }
|
||||||
|
|
||||||
Path toRealPath(const Path & storePath) override
|
Path toRealPath(const Path & storePath) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -106,9 +106,6 @@ LocalStore::LocalStore(const Params & params)
|
||||||
, LocalStoreConfig(params)
|
, LocalStoreConfig(params)
|
||||||
, Store(params)
|
, Store(params)
|
||||||
, LocalFSStore(params)
|
, LocalFSStore(params)
|
||||||
, realStoreDir_{this, false, rootDir != "" ? rootDir + "/nix/store" : storeDir, "real",
|
|
||||||
"physical path to the Nix store"}
|
|
||||||
, realStoreDir(realStoreDir_)
|
|
||||||
, dbDir(stateDir + "/db")
|
, dbDir(stateDir + "/db")
|
||||||
, linksDir(realStoreDir + "/.links")
|
, linksDir(realStoreDir + "/.links")
|
||||||
, reservedPath(dbDir + "/reserved")
|
, reservedPath(dbDir + "/reserved")
|
||||||
|
@ -153,13 +150,13 @@ LocalStore::LocalStore(const Params & params)
|
||||||
printError("warning: the group '%1%' specified in 'build-users-group' does not exist", settings.buildUsersGroup);
|
printError("warning: the group '%1%' specified in 'build-users-group' does not exist", settings.buildUsersGroup);
|
||||||
else {
|
else {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(realStoreDir.c_str(), &st))
|
if (stat(realStoreDir.get().c_str(), &st))
|
||||||
throw SysError("getting attributes of path '%1%'", realStoreDir);
|
throw SysError("getting attributes of path '%1%'", realStoreDir);
|
||||||
|
|
||||||
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
||||||
if (chown(realStoreDir.c_str(), 0, gr->gr_gid) == -1)
|
if (chown(realStoreDir.get().c_str(), 0, gr->gr_gid) == -1)
|
||||||
throw SysError("changing ownership of path '%1%'", realStoreDir);
|
throw SysError("changing ownership of path '%1%'", realStoreDir);
|
||||||
if (chmod(realStoreDir.c_str(), perm) == -1)
|
if (chmod(realStoreDir.get().c_str(), perm) == -1)
|
||||||
throw SysError("changing permissions on path '%1%'", realStoreDir);
|
throw SysError("changing permissions on path '%1%'", realStoreDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,14 +434,14 @@ void LocalStore::makeStoreWritable()
|
||||||
if (getuid() != 0) return;
|
if (getuid() != 0) return;
|
||||||
/* Check if /nix/store is on a read-only mount. */
|
/* Check if /nix/store is on a read-only mount. */
|
||||||
struct statvfs stat;
|
struct statvfs stat;
|
||||||
if (statvfs(realStoreDir.c_str(), &stat) != 0)
|
if (statvfs(realStoreDir.get().c_str(), &stat) != 0)
|
||||||
throw SysError("getting info about the Nix store mount point");
|
throw SysError("getting info about the Nix store mount point");
|
||||||
|
|
||||||
if (stat.f_flag & ST_RDONLY) {
|
if (stat.f_flag & ST_RDONLY) {
|
||||||
if (unshare(CLONE_NEWNS) == -1)
|
if (unshare(CLONE_NEWNS) == -1)
|
||||||
throw SysError("setting up a private mount namespace");
|
throw SysError("setting up a private mount namespace");
|
||||||
|
|
||||||
if (mount(0, realStoreDir.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
if (mount(0, realStoreDir.get().c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
||||||
throw SysError("remounting %1% writable", realStoreDir);
|
throw SysError("remounting %1% writable", realStoreDir);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -83,9 +83,6 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PathSetting realStoreDir_;
|
|
||||||
|
|
||||||
const Path realStoreDir;
|
|
||||||
const Path dbDir;
|
const Path dbDir;
|
||||||
const Path linksDir;
|
const Path linksDir;
|
||||||
const Path reservedPath;
|
const Path reservedPath;
|
||||||
|
@ -279,8 +276,6 @@ private:
|
||||||
void signPathInfo(ValidPathInfo & info);
|
void signPathInfo(ValidPathInfo & info);
|
||||||
void signRealisation(Realisation &);
|
void signRealisation(Realisation &);
|
||||||
|
|
||||||
Path getRealStoreDir() override { return realStoreDir; }
|
|
||||||
|
|
||||||
void createUser(const std::string & userName, uid_t userId) override;
|
void createUser(const std::string & userName, uid_t userId) override;
|
||||||
|
|
||||||
// XXX: Make a generic `Store` method
|
// XXX: Make a generic `Store` method
|
||||||
|
|
|
@ -198,7 +198,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats,
|
||||||
/* Make the containing directory writable, but only if it's not
|
/* Make the containing directory writable, but only if it's not
|
||||||
the store itself (we don't want or need to mess with its
|
the store itself (we don't want or need to mess with its
|
||||||
permissions). */
|
permissions). */
|
||||||
bool mustToggle = dirOf(path) != realStoreDir;
|
bool mustToggle = dirOf(path) != realStoreDir.get();
|
||||||
if (mustToggle) makeWritable(dirOf(path));
|
if (mustToggle) makeWritable(dirOf(path));
|
||||||
|
|
||||||
/* When we're done, make the directory read-only again and reset
|
/* When we're done, make the directory read-only again and reset
|
||||||
|
|
|
@ -43,8 +43,8 @@ struct RunCommon : virtual Command
|
||||||
helper program (chrootHelper() below) to do the work. */
|
helper program (chrootHelper() below) to do the work. */
|
||||||
auto store2 = store.dynamic_pointer_cast<LocalStore>();
|
auto store2 = store.dynamic_pointer_cast<LocalStore>();
|
||||||
|
|
||||||
if (store2 && store->storeDir != store2->realStoreDir) {
|
if (store2 && store->storeDir != store2->getRealStoreDir()) {
|
||||||
Strings helperArgs = { chrootHelperName, store->storeDir, store2->realStoreDir, program };
|
Strings helperArgs = { chrootHelperName, store->storeDir, store2->getRealStoreDir(), program };
|
||||||
for (auto & arg : args) helperArgs.push_back(arg);
|
for (auto & arg : args) helperArgs.push_back(arg);
|
||||||
|
|
||||||
execv(readLink("/proc/self/exe").c_str(), stringsToCharPtrs(helperArgs).data());
|
execv(readLink("/proc/self/exe").c_str(), stringsToCharPtrs(helperArgs).data());
|
||||||
|
|
Loading…
Reference in a new issue