forked from lix-project/lix
nix run: Mount the Nix store in a private namespace
This is a convenience command to allow users who are not privileged to create /nix/store to use Nix with regular binary caches. For example, $ NIX_REMOTE="local?state=$HOME/nix/var&real=/$HOME/nix/store" nix run firefox bashInteractive will download Firefox and bash from cache.nixos.org, then start a shell in which $HOME/nix/store is mounted on /nix/store.
This commit is contained in:
parent
6f2d51287c
commit
a24f2c9b84
2 changed files with 25 additions and 1 deletions
|
@ -73,6 +73,8 @@ private:
|
||||||
|
|
||||||
Sync<State, std::recursive_mutex> _state;
|
Sync<State, std::recursive_mutex> _state;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
const Path realStoreDir;
|
const Path realStoreDir;
|
||||||
const Path dbDir;
|
const Path dbDir;
|
||||||
const Path linksDir;
|
const Path linksDir;
|
||||||
|
@ -80,6 +82,8 @@ private:
|
||||||
const Path schemaPath;
|
const Path schemaPath;
|
||||||
const Path trashDir;
|
const Path trashDir;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
bool requireSigs;
|
bool requireSigs;
|
||||||
|
|
||||||
PublicKeys publicKeys;
|
PublicKeys publicKeys;
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
|
#include "local-store.hh"
|
||||||
|
|
||||||
|
#if __linux__
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
|
@ -40,6 +45,20 @@ struct CmdRun : StoreCommand, MixInstallables
|
||||||
|
|
||||||
store->buildPaths(pathsToBuild);
|
store->buildPaths(pathsToBuild);
|
||||||
|
|
||||||
|
auto store2 = store.dynamic_pointer_cast<LocalStore>();
|
||||||
|
|
||||||
|
if (store2 && store->storeDir != store2->realStoreDir) {
|
||||||
|
#if __linux__
|
||||||
|
if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == -1)
|
||||||
|
throw SysError("setting up a private mount namespace");
|
||||||
|
|
||||||
|
if (mount(store2->realStoreDir.c_str(), store->storeDir.c_str(), "", MS_BIND, 0) == -1)
|
||||||
|
throw SysError(format("mounting ‘%s’ on ‘%s’") % store2->realStoreDir % store->storeDir);
|
||||||
|
#else
|
||||||
|
throw Error(format("mounting the Nix store on ‘%s’ is not supported on this platform") % store->storeDir);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
PathSet outPaths;
|
PathSet outPaths;
|
||||||
for (auto & path : pathsToBuild)
|
for (auto & path : pathsToBuild)
|
||||||
if (isDerivation(path)) {
|
if (isDerivation(path)) {
|
||||||
|
@ -55,7 +74,8 @@ struct CmdRun : StoreCommand, MixInstallables
|
||||||
unixPath.push_front(path + "/bin");
|
unixPath.push_front(path + "/bin");
|
||||||
setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
|
setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
|
||||||
|
|
||||||
execlp("bash", "bash", nullptr);
|
if (execlp("bash", "bash", nullptr) == -1)
|
||||||
|
throw SysError("unable to exec ‘bash’");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue