Merge remote-tracking branch 'origin/master' into flakes

This commit is contained in:
Eelco Dolstra 2019-11-06 10:44:21 +01:00
commit 88c452d160
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
17 changed files with 155 additions and 83 deletions

View file

@ -256,8 +256,8 @@ fi
# Whether to use the Boehm garbage collector. # Whether to use the Boehm garbage collector.
AC_ARG_ENABLE(gc, AC_HELP_STRING([--enable-gc], AC_ARG_ENABLE(gc, AC_HELP_STRING([--enable-gc],
[enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=no]]), [enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=yes]]),
gc=$enableval, gc=no) gc=$enableval, gc=yes)
if test "$gc" = yes; then if test "$gc" = yes; then
PKG_CHECK_MODULES([BDW_GC], [bdw-gc]) PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
CXXFLAGS="$BDW_GC_CFLAGS $CXXFLAGS" CXXFLAGS="$BDW_GC_CFLAGS $CXXFLAGS"

View file

@ -36,8 +36,8 @@ to <xref linkend="conf-cores" />, unless <xref linkend="conf-cores" />
equals <literal>0</literal>, in which case <envar>NIX_BUILD_CORES</envar> equals <literal>0</literal>, in which case <envar>NIX_BUILD_CORES</envar>
will be the total number of cores in the system.</para> will be the total number of cores in the system.</para>
<para>The total number of consumed cores is a simple multiplication, <para>The maximum number of consumed cores is a simple multiplication,
<xref linkend="conf-cores" /> * <envar>NIX_BUILD_CORES</envar>.</para> <xref linkend="conf-max-jobs" /> * <envar>NIX_BUILD_CORES</envar>.</para>
<para>The balance on how to set these two independent variables depends <para>The balance on how to set these two independent variables depends
upon each builder's workload and hardware. Here are a few example upon each builder's workload and hardware. Here are a few example

View file

@ -5,7 +5,7 @@
version="5.0" version="5.0"
> >
<title>Using the <xref linkend="conf-post-build-hook" /></title> <title>Using the <option linkend="conf-post-build-hook">post-build-hook</option></title>
<subtitle>Uploading to an S3-compatible binary cache after each build</subtitle> <subtitle>Uploading to an S3-compatible binary cache after each build</subtitle>

View file

@ -122,7 +122,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
<varlistentry><term><envar>NIX_LOG_DIR</envar></term> <varlistentry><term><envar>NIX_LOG_DIR</envar></term>
<listitem><para>Overrides the location of the Nix log directory <listitem><para>Overrides the location of the Nix log directory
(default <filename><replaceable>prefix</replaceable>/log/nix</filename>).</para></listitem> (default <filename><replaceable>prefix</replaceable>/var/log/nix</filename>).</para></listitem>
</varlistentry> </varlistentry>

View file

@ -243,9 +243,10 @@
<varlistentry><term><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></term> <varlistentry><term><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></term>
<listitem><para>This option is accepted by <listitem><para>This option is accepted by
<command>nix-env</command>, <command>nix-instantiate</command> and <command>nix-env</command>, <command>nix-instantiate</command>,
<command>nix-build</command>. When evaluating Nix expressions, the <command>nix-shell</command> and <command>nix-build</command>.
expression evaluator will automatically try to call functions that When evaluating Nix expressions, the expression evaluator will
automatically try to call functions that
it encounters. It can automatically call functions for which every it encounters. It can automatically call functions for which every
argument has a <link linkend='ss-functions'>default value</link> argument has a <link linkend='ss-functions'>default value</link>
(e.g., <literal>{ <replaceable>argName</replaceable> ? (e.g., <literal>{ <replaceable>argName</replaceable> ?

View file

@ -51,9 +51,7 @@
}); });
configureFlags = configureFlags =
[ lib.optionals stdenv.isLinux [
"--enable-gc"
] ++ lib.optionals stdenv.isLinux [
"--with-sandbox-shell=${sh}/bin/busybox" "--with-sandbox-shell=${sh}/bin/busybox"
]; ];
@ -173,8 +171,6 @@
buildInputs = tarballDeps ++ buildDeps; buildInputs = tarballDeps ++ buildDeps;
configureFlags = "--enable-gc";
postUnpack = '' postUnpack = ''
(cd $sourceRoot && find . -type f) | cut -c3- > $sourceRoot/.dist-files (cd $sourceRoot && find . -type f) | cut -c3- > $sourceRoot/.dist-files
cat $sourceRoot/.dist-files cat $sourceRoot/.dist-files
@ -219,7 +215,7 @@
in in
runCommand "nix-binary-tarball-${version}" runCommand "nix-binary-tarball-${version}"
{ nativeBuildInputs = lib.optional (system != "aarch64-linux") shellcheck; { #nativeBuildInputs = lib.optional (system != "aarch64-linux") shellcheck;
meta.description = "Distribution-independent Nix bootstrap binaries for ${system}"; meta.description = "Distribution-independent Nix bootstrap binaries for ${system}";
} }
'' ''
@ -372,7 +368,7 @@
x86_64-linux = "${self.hydraJobs.build.x86_64-linux}"; x86_64-linux = "${self.hydraJobs.build.x86_64-linux}";
} }
EOF EOF
su - alice -c 'nix upgrade-nix -vvv --nix-store-paths-url file:///tmp/paths.nix' su - alice -c 'nix --experimental-features nix-command upgrade-nix -vvv --nix-store-paths-url file:///tmp/paths.nix'
(! [ -L /home/alice/.profile-1-link ]) (! [ -L /home/alice/.profile-1-link ])
su - alice -c 'PAGER= nix-store -qR ${self.hydraJobs.build.x86_64-linux}' su - alice -c 'PAGER= nix-store -qR ${self.hydraJobs.build.x86_64-linux}'
@ -381,6 +377,7 @@
umount /nix umount /nix
''); '');
/*
# Check whether we can still evaluate all of Nixpkgs. # Check whether we can still evaluate all of Nixpkgs.
tests.evalNixpkgs = tests.evalNixpkgs =
import (nixpkgs + "/pkgs/top-level/make-tarball.nix") { import (nixpkgs + "/pkgs/top-level/make-tarball.nix") {
@ -389,6 +386,7 @@
pkgs = nixpkgsFor.x86_64-linux; pkgs = nixpkgsFor.x86_64-linux;
officialRelease = false; officialRelease = false;
}; };
*/
# Check whether we can still evaluate NixOS. # Check whether we can still evaluate NixOS.
tests.evalNixOS = tests.evalNixOS =
@ -422,7 +420,7 @@
tests.remoteBuilds tests.remoteBuilds
tests.nix-copy-closure tests.nix-copy-closure
tests.binaryTarball tests.binaryTarball
tests.evalNixpkgs #tests.evalNixpkgs
tests.evalNixOS tests.evalNixOS
installerScript installerScript
]; ];

View file

@ -93,4 +93,36 @@ Value * findAlongAttrPath(EvalState & state, const string & attrPath,
} }
Pos findDerivationFilename(EvalState & state, Value & v, std::string what)
{
Value * v2;
try {
auto dummyArgs = state.allocBindings(0);
v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v);
} catch (Error &) {
throw Error("package '%s' has no source location information", what);
}
// FIXME: is it possible to extract the Pos object instead of doing this
// toString + parsing?
auto pos = state.forceString(*v2);
auto colon = pos.rfind(':');
if (colon == std::string::npos)
throw Error("cannot parse meta.position attribute '%s'", pos);
std::string filename(pos, 0, colon);
unsigned int lineno;
try {
lineno = std::stoi(std::string(pos, colon + 1));
} catch (std::invalid_argument & e) {
throw Error("cannot parse line number '%s'", pos);
}
Symbol file = state.symbols.create(filename);
return { file, lineno, 0 };
}
} }

View file

@ -12,4 +12,7 @@ MakeError(AttrPathNotFound, Error);
Value * findAlongAttrPath(EvalState & state, const string & attrPath, Value * findAlongAttrPath(EvalState & state, const string & attrPath,
Bindings & autoArgs, Value & vIn); Bindings & autoArgs, Value & vIn);
/* Heuristic to find the filename and lineno or a nix value. */
Pos findDerivationFilename(EvalState & state, Value & v, std::string what);
} }

View file

@ -178,6 +178,19 @@ Strings argvToStrings(int argc, char * * argv)
return args; return args;
} }
Strings editorFor(Pos pos)
{
auto editor = getEnv("EDITOR", "cat");
auto args = tokenizeString<Strings>(editor);
if (pos.line > 0 && (
editor.find("emacs") != std::string::npos ||
editor.find("nano") != std::string::npos ||
editor.find("vim") != std::string::npos))
args.push_back(fmt("+%d", pos.line));
args.push_back(pos.file);
return args;
}
std::string renderLabels(const Strings & labels) std::string renderLabels(const Strings & labels)
{ {
std::string res; std::string res;

View file

@ -5,6 +5,7 @@
#include <memory> #include <memory>
#include "util.hh" #include "util.hh"
#include "nixexpr.hh"
namespace nix { namespace nix {
@ -241,6 +242,9 @@ public:
Strings argvToStrings(int argc, char * * argv); Strings argvToStrings(int argc, char * * argv);
/* Helper function to generate args that invoke $EDITOR on filename:lineno */
Strings editorFor(Pos pos);
/* Helper function for rendering argument labels. */ /* Helper function for rendering argument labels. */
std::string renderLabels(const Strings & labels); std::string renderLabels(const Strings & labels);

View file

@ -1572,7 +1572,11 @@ std::unique_ptr<InterruptCallback> createInterruptCallback(std::function<void()>
AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode) AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode)
{ {
AutoCloseFD fdSocket = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); AutoCloseFD fdSocket = socket(PF_UNIX, SOCK_STREAM
#ifdef SOCK_CLOEXEC
| SOCK_CLOEXEC
#endif
, 0);
if (!fdSocket) if (!fdSocket)
throw SysError("cannot create Unix domain socket"); throw SysError("cannot create Unix domain socket");

View file

@ -1,11 +1,17 @@
#include <sstream>
#include "command.hh" #include "command.hh"
#include "logging.hh"
#include "serve-protocol.hh" #include "serve-protocol.hh"
#include "shared.hh" #include "shared.hh"
#include "store-api.hh" #include "store-api.hh"
#include "util.hh"
#include "worker-protocol.hh" #include "worker-protocol.hh"
using namespace nix; using namespace nix;
namespace {
std::string formatProtocol(unsigned int proto) std::string formatProtocol(unsigned int proto)
{ {
if (proto) { if (proto) {
@ -16,19 +22,30 @@ std::string formatProtocol(unsigned int proto)
return "unknown"; return "unknown";
} }
bool checkPass(const std::string & msg) {
logger->log(ANSI_GREEN "[PASS] " ANSI_NORMAL + msg);
return true;
}
bool checkFail(const std::string & msg) {
logger->log(ANSI_RED "[FAIL] " ANSI_NORMAL + msg);
return false;
}
}
struct CmdDoctor : StoreCommand struct CmdDoctor : StoreCommand
{ {
bool success = true; bool success = true;
std::string description() override std::string description() override
{ {
return "check your system for potential problems"; return "check your system for potential problems and print a PASS or FAIL for each check.";
} }
void run(ref<Store> store) override void run(ref<Store> store) override
{ {
std::cout << "Store uri: " << store->getUri() << std::endl; logger->log("Running checks against store uri: " + store->getUri());
std::cout << std::endl;
auto type = getStoreType(); auto type = getStoreType();
@ -51,15 +68,14 @@ struct CmdDoctor : StoreCommand
dirs.insert(dirOf(canonPath(dir + "/nix-env", true))); dirs.insert(dirOf(canonPath(dir + "/nix-env", true)));
if (dirs.size() != 1) { if (dirs.size() != 1) {
std::cout << "Warning: multiple versions of nix found in PATH." << std::endl; std::stringstream ss;
std::cout << std::endl; ss << "Multiple versions of nix found in PATH:\n";
for (auto & dir : dirs) for (auto & dir : dirs)
std::cout << " " << dir << std::endl; ss << " " << dir << "\n";
std::cout << std::endl; return checkFail(ss.str());
return false;
} }
return true; return checkPass("PATH contains only one nix version.");
} }
bool checkProfileRoots(ref<Store> store) bool checkProfileRoots(ref<Store> store)
@ -82,17 +98,17 @@ struct CmdDoctor : StoreCommand
} }
if (!dirs.empty()) { if (!dirs.empty()) {
std::cout << "Warning: found profiles outside of " << settings.nixStateDir << "/profiles." << std::endl; std::stringstream ss;
std::cout << "The generation this profile points to might not have a gcroot and could be" << std::endl; ss << "Found profiles outside of " << settings.nixStateDir << "/profiles.\n"
std::cout << "garbage collected, resulting in broken symlinks." << std::endl; << "The generation this profile points to might not have a gcroot and could be\n"
std::cout << std::endl; << "garbage collected, resulting in broken symlinks.\n\n";
for (auto & dir : dirs) for (auto & dir : dirs)
std::cout << " " << dir << std::endl; ss << " " << dir << "\n";
std::cout << std::endl; ss << "\n";
return false; return checkFail(ss.str());
} }
return true; return checkPass("All profiles are gcroots.");
} }
bool checkStoreProtocol(unsigned int storeProto) bool checkStoreProtocol(unsigned int storeProto)
@ -102,17 +118,16 @@ struct CmdDoctor : StoreCommand
: PROTOCOL_VERSION; : PROTOCOL_VERSION;
if (clientProto != storeProto) { if (clientProto != storeProto) {
std::cout << "Warning: protocol version of this client does not match the store." << std::endl; std::stringstream ss;
std::cout << "While this is not necessarily a problem it's recommended to keep the client in" << std::endl; ss << "Warning: protocol version of this client does not match the store.\n"
std::cout << "sync with the daemon." << std::endl; << "While this is not necessarily a problem it's recommended to keep the client in\n"
std::cout << std::endl; << "sync with the daemon.\n\n"
std::cout << "Client protocol: " << formatProtocol(clientProto) << std::endl; << "Client protocol: " << formatProtocol(clientProto) << "\n"
std::cout << "Store protocol: " << formatProtocol(storeProto) << std::endl; << "Store protocol: " << formatProtocol(storeProto) << "\n\n";
std::cout << std::endl; return checkFail(ss.str());
return false;
} }
return true; return checkPass("Client protocol matches store protocol.");
} }
}; };

View file

@ -31,45 +31,17 @@ struct CmdEdit : InstallableCommand
auto v = installable->toValue(*state); auto v = installable->toValue(*state);
Value * v2; Pos pos = findDerivationFilename(*state, *v, installable->what());
try {
auto dummyArgs = state->allocBindings(0);
v2 = findAlongAttrPath(*state, "meta.position", *dummyArgs, *v);
} catch (Error &) {
throw Error("package '%s' has no source location information", installable->what());
}
auto pos = state->forceString(*v2);
debug("position is %s", pos);
auto colon = pos.rfind(':');
if (colon == std::string::npos)
throw Error("cannot parse meta.position attribute '%s'", pos);
std::string filename(pos, 0, colon);
int lineno;
try {
lineno = std::stoi(std::string(pos, colon + 1));
} catch (std::invalid_argument & e) {
throw Error("cannot parse line number '%s'", pos);
}
auto editor = getEnv("EDITOR", "cat");
auto args = tokenizeString<Strings>(editor);
if (editor.find("emacs") != std::string::npos ||
editor.find("nano") != std::string::npos ||
editor.find("vim") != std::string::npos)
args.push_back(fmt("+%d", lineno));
args.push_back(filename);
stopProgressBar(); stopProgressBar();
auto args = editorFor(pos);
execvp(args.front().c_str(), stringsToCharPtrs(args).data()); execvp(args.front().c_str(), stringsToCharPtrs(args).data());
throw SysError("cannot run editor '%s'", editor); std::string command;
for (const auto &arg : args) command += " '" + arg + "'";
throw SysError("cannot run command%s", command);
} }
}; };

View file

@ -22,6 +22,7 @@ extern "C" {
#include "shared.hh" #include "shared.hh"
#include "eval.hh" #include "eval.hh"
#include "eval-inline.hh" #include "eval-inline.hh"
#include "attr-path.hh"
#include "store-api.hh" #include "store-api.hh"
#include "common-eval-args.hh" #include "common-eval-args.hh"
#include "get-drvs.hh" #include "get-drvs.hh"
@ -440,6 +441,7 @@ bool NixRepl::processLine(string line)
<< " <x> = <expr> Bind expression to variable\n" << " <x> = <expr> Bind expression to variable\n"
<< " :a <expr> Add attributes from resulting set to scope\n" << " :a <expr> Add attributes from resulting set to scope\n"
<< " :b <expr> Build derivation\n" << " :b <expr> Build derivation\n"
<< " :e <expr> Open the derivation in $EDITOR\n"
<< " :i <expr> Build derivation, then install result into current profile\n" << " :i <expr> Build derivation, then install result into current profile\n"
<< " :l <path> Load Nix expression and add it to scope\n" << " :l <path> Load Nix expression and add it to scope\n"
<< " :p <expr> Evaluate and print expression recursively\n" << " :p <expr> Evaluate and print expression recursively\n"
@ -466,6 +468,34 @@ bool NixRepl::processLine(string line)
reloadFiles(); reloadFiles();
} }
else if (command == ":e" || command == ":edit") {
Value v;
evalString(arg, v);
Pos pos;
if (v.type == tPath || v.type == tString) {
PathSet context;
auto filename = state.coerceToString(noPos, v, context);
pos.file = state.symbols.create(filename);
} else if (v.type == tLambda) {
pos = v.lambda.fun->pos;
} else {
// assume it's a derivation
pos = findDerivationFilename(state, v, arg);
}
// Open in EDITOR
auto args = editorFor(pos);
auto editor = args.front();
args.pop_front();
runProgram(editor, args);
// Reload right after exiting the editor
state.resetFileCache();
reloadFiles();
}
else if (command == ":t") { else if (command == ":t") {
Value v; Value v;
evalString(arg, v); evalString(arg, v);

View file

@ -11,10 +11,10 @@ makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; in {
nodes = nodes =
{ client = { client =
{ config, pkgs, ... }: { config, lib, pkgs, ... }:
{ virtualisation.writableStore = true; { virtualisation.writableStore = true;
virtualisation.pathsInNixDB = [ pkgA ]; virtualisation.pathsInNixDB = [ pkgA ];
nix.binaryCaches = [ ]; nix.binaryCaches = lib.mkForce [ ];
}; };
server = server =

View file

@ -42,7 +42,7 @@ in
builder2 = builder; builder2 = builder;
client = client =
{ config, pkgs, ... }: { config, lib, pkgs, ... }:
{ nix.maxJobs = 0; # force remote building { nix.maxJobs = 0; # force remote building
nix.distributedBuilds = true; nix.distributedBuilds = true;
nix.buildMachines = nix.buildMachines =
@ -61,7 +61,7 @@ in
]; ];
virtualisation.writableStore = true; virtualisation.writableStore = true;
virtualisation.pathsInNixDB = [ config.system.build.extraUtils ]; virtualisation.pathsInNixDB = [ config.system.build.extraUtils ];
nix.binaryCaches = [ ]; nix.binaryCaches = lib.mkForce [ ];
programs.ssh.extraConfig = "ConnectTimeout 30"; programs.ssh.extraConfig = "ConnectTimeout 30";
}; };
}; };

View file

@ -12,7 +12,7 @@ makeTest {
machine = machine =
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
{ virtualisation.writableStore = true; { virtualisation.writableStore = true;
nix.binaryCaches = [ ]; nix.binaryCaches = lib.mkForce [ ];
nix.nixPath = [ "nixpkgs=${lib.cleanSource pkgs.path}" ]; nix.nixPath = [ "nixpkgs=${lib.cleanSource pkgs.path}" ];
virtualisation.pathsInNixDB = [ pkgs.stdenv pkgs.pkgsi686Linux.stdenv ]; virtualisation.pathsInNixDB = [ pkgs.stdenv pkgs.pkgsi686Linux.stdenv ];
}; };