Merge pull request #5057 from edolstra/nix-develop-chroot

nix develop: Support chroot stores
This commit is contained in:
Eelco Dolstra 2021-07-28 12:30:38 +02:00 committed by GitHub
commit 64a07d3d18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 41 deletions

View file

@ -7,6 +7,7 @@
#include "derivations.hh"
#include "affinity.hh"
#include "progress-bar.hh"
#include "run.hh"
#include <nlohmann/json.hpp>
@ -472,8 +473,6 @@ struct CmdDevelop : Common, MixEnvironment
writeFull(rcFileFd.get(), script);
stopProgressBar();
setEnviron();
// prevent garbage collection until shell exits
setenv("NIX_GCROOT", gcroot.data(), 1);
@ -506,11 +505,7 @@ struct CmdDevelop : Common, MixEnvironment
auto args = phase || !command.empty() ? Strings{std::string(baseNameOf(shell)), rcFilePath}
: Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath};
restoreProcessContext();
execvp(shell.c_str(), stringsToCharPtrs(args).data());
throw SysError("executing shell '%s'", shell);
runProgramInStore(store, shell, args);
}
};

View file

@ -1,3 +1,4 @@
#include "run.hh"
#include "command.hh"
#include "common-args.hh"
#include "shared.hh"
@ -20,15 +21,12 @@ using namespace nix;
std::string chrootHelperName = "__run_in_chroot";
struct RunCommon : virtual Command
{
namespace nix {
using Command::run;
void runProgram(ref<Store> store,
void runProgramInStore(ref<Store> store,
const std::string & program,
const Strings & args)
{
{
stopProgressBar();
restoreProcessContext();
@ -38,9 +36,9 @@ struct RunCommon : virtual Command
(e.g. /home/eelco/nix/store), then run the command in a
chroot. For non-root users, this requires running it in new
mount and user namespaces. Unfortunately,
unshare(CLONE_NEWUSER) doesn't work in a multithreaded
program (which "nix" is), so we exec() a single-threaded
helper program (chrootHelper() below) to do the work. */
unshare(CLONE_NEWUSER) doesn't work in a multithreaded program
(which "nix" is), so we exec() a single-threaded helper program
(chrootHelper() below) to do the work. */
auto store2 = store.dynamic_pointer_cast<LocalStore>();
if (store2 && store->storeDir != store2->getRealStoreDir()) {
@ -55,10 +53,11 @@ struct RunCommon : virtual Command
execvp(program.c_str(), stringsToCharPtrs(args).data());
throw SysError("unable to execute '%s'", program);
}
};
}
struct CmdShell : InstallablesCommand, RunCommon, MixEnvironment
}
struct CmdShell : InstallablesCommand, MixEnvironment
{
using InstallablesCommand::run;
@ -125,13 +124,13 @@ struct CmdShell : InstallablesCommand, RunCommon, MixEnvironment
Strings args;
for (auto & arg : command) args.push_back(arg);
runProgram(store, *command.begin(), args);
runProgramInStore(store, *command.begin(), args);
}
};
static auto rCmdShell = registerCommand<CmdShell>("shell");
struct CmdRun : InstallableCommand, RunCommon
struct CmdRun : InstallableCommand
{
using InstallableCommand::run;
@ -183,7 +182,7 @@ struct CmdRun : InstallableCommand, RunCommon
Strings allArgs{app.program};
for (auto & i : args) allArgs.push_back(i);
runProgram(store, app.program, allArgs);
runProgramInStore(store, app.program, allArgs);
}
};

11
src/nix/run.hh Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#include "store-api.hh"
namespace nix {
void runProgramInStore(ref<Store> store,
const std::string & program,
const Strings & args);
}