mirror of
https://github.com/NixOS/nix.git
synced 2024-11-22 06:42:28 +00:00
Merge branch '2.18-maintenance' into mergify/bp/2.18-maintenance/pr-10919
This commit is contained in:
commit
e818523eb1
@ -556,7 +556,7 @@
|
|||||||
# tarball for the user's system and calls the second half of the
|
# tarball for the user's system and calls the second half of the
|
||||||
# installation script.
|
# installation script.
|
||||||
installerScript = installScriptFor [ "x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" "armv6l-linux" "armv7l-linux" ];
|
installerScript = installScriptFor [ "x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" "armv6l-linux" "armv7l-linux" ];
|
||||||
installerScriptForGHA = installScriptFor [ "x86_64-linux" "x86_64-darwin" "armv6l-linux" "armv7l-linux"];
|
installerScriptForGHA = installScriptFor [ "x86_64-linux" "aarch64-darwin" "armv6l-linux" "armv7l-linux"];
|
||||||
|
|
||||||
# docker image with Nix inside
|
# docker image with Nix inside
|
||||||
dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage);
|
dockerImage = lib.genAttrs linux64BitSystems (system: self.packages.${system}.dockerImage);
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
# System specific settings
|
# System specific settings
|
||||||
# Notes:
|
# Notes:
|
||||||
# - up to macOS Big Sur we used the same GID/UIDs as Linux (30000:30001-32)
|
# - up to macOS Big Sur we used the same GID/UIDs as Linux (30000:30001-32)
|
||||||
@ -19,12 +17,10 @@ export NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-351}"
|
|||||||
export NIX_BUILD_GROUP_ID="${NIX_BUILD_GROUP_ID:-350}"
|
export NIX_BUILD_GROUP_ID="${NIX_BUILD_GROUP_ID:-350}"
|
||||||
export NIX_BUILD_USER_NAME_TEMPLATE="_nixbld%d"
|
export NIX_BUILD_USER_NAME_TEMPLATE="_nixbld%d"
|
||||||
|
|
||||||
>>>>>>> df36ff0d1 (install-darwin: fix _nixbld uids for macOS sequoia)
|
|
||||||
readonly NIX_DAEMON_DEST=/Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
readonly NIX_DAEMON_DEST=/Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
||||||
# create by default; set 0 to DIY, use a symlink, etc.
|
# create by default; set 0 to DIY, use a symlink, etc.
|
||||||
readonly NIX_VOLUME_CREATE=${NIX_VOLUME_CREATE:-1} # now default
|
readonly NIX_VOLUME_CREATE=${NIX_VOLUME_CREATE:-1} # now default
|
||||||
NIX_FIRST_BUILD_UID="301"
|
|
||||||
NIX_BUILD_USER_NAME_TEMPLATE="_nixbld%d"
|
|
||||||
|
|
||||||
# caution: may update times on / if not run as normal non-root user
|
# caution: may update times on / if not run as normal non-root user
|
||||||
read_only_root() {
|
read_only_root() {
|
||||||
|
@ -24,16 +24,11 @@ readonly RED='\033[31m'
|
|||||||
# as creating each user takes non-trivial amount of time on macos
|
# as creating each user takes non-trivial amount of time on macos
|
||||||
readonly NIX_USER_COUNT=${NIX_USER_COUNT:-32}
|
readonly NIX_USER_COUNT=${NIX_USER_COUNT:-32}
|
||||||
readonly NIX_BUILD_GROUP_NAME="nixbld"
|
readonly NIX_BUILD_GROUP_NAME="nixbld"
|
||||||
<<<<<<< HEAD
|
|
||||||
# darwin installer needs to override these
|
|
||||||
NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-30001}"
|
|
||||||
NIX_BUILD_USER_NAME_TEMPLATE="nixbld%d"
|
|
||||||
=======
|
|
||||||
# each system specific installer must set these:
|
# each system specific installer must set these:
|
||||||
# NIX_FIRST_BUILD_UID
|
# NIX_FIRST_BUILD_UID
|
||||||
# NIX_BUILD_GROUP_ID
|
# NIX_BUILD_GROUP_ID
|
||||||
# NIX_BUILD_USER_NAME_TEMPLATE
|
# NIX_BUILD_USER_NAME_TEMPLATE
|
||||||
>>>>>>> 75567423f (install-darwin: move nixbld gid to match first UID)
|
|
||||||
# Please don't change this. We don't support it, because the
|
# Please don't change this. We don't support it, because the
|
||||||
# default shell profile that comes with Nix doesn't support it.
|
# default shell profile that comes with Nix doesn't support it.
|
||||||
readonly NIX_ROOT="/nix"
|
readonly NIX_ROOT="/nix"
|
||||||
@ -703,6 +698,12 @@ EOF
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_required_system_specific_settings() {
|
||||||
|
if [ -z "${NIX_FIRST_BUILD_UID+x}" ] || [ -z "${NIX_BUILD_USER_NAME_TEMPLATE+x}" ]; then
|
||||||
|
failure "Internal error: System specific installer for $(uname) ($1) does not export required settings."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
welcome_to_nix() {
|
welcome_to_nix() {
|
||||||
local -r NIX_UID_RANGES="${NIX_FIRST_BUILD_UID}..$((NIX_FIRST_BUILD_UID + NIX_USER_COUNT - 1))"
|
local -r NIX_UID_RANGES="${NIX_FIRST_BUILD_UID}..$((NIX_FIRST_BUILD_UID + NIX_USER_COUNT - 1))"
|
||||||
local -r RANGE_TEXT=$(echo -ne "${BLUE}(uids [${NIX_UID_RANGES}])${ESC}")
|
local -r RANGE_TEXT=$(echo -ne "${BLUE}(uids [${NIX_UID_RANGES}])${ESC}")
|
||||||
@ -722,7 +723,9 @@ manager. This will happen in a few stages:
|
|||||||
if you are ready to continue.
|
if you are ready to continue.
|
||||||
|
|
||||||
3. Create the system users ${RANGE_TEXT} and groups ${GROUP_TEXT}
|
3. Create the system users ${RANGE_TEXT} and groups ${GROUP_TEXT}
|
||||||
that the Nix daemon uses to run builds.
|
that the Nix daemon uses to run builds. To create system users
|
||||||
|
in a different range, exit and run this tool again with
|
||||||
|
NIX_FIRST_BUILD_UID set.
|
||||||
|
|
||||||
4. Perform the basic installation of the Nix files daemon.
|
4. Perform the basic installation of the Nix files daemon.
|
||||||
|
|
||||||
@ -964,13 +967,16 @@ main() {
|
|||||||
if is_os_darwin; then
|
if is_os_darwin; then
|
||||||
# shellcheck source=./install-darwin-multi-user.sh
|
# shellcheck source=./install-darwin-multi-user.sh
|
||||||
. "$EXTRACTED_NIX_PATH/install-darwin-multi-user.sh"
|
. "$EXTRACTED_NIX_PATH/install-darwin-multi-user.sh"
|
||||||
|
check_required_system_specific_settings "install-darwin-multi-user.sh"
|
||||||
elif is_os_linux; then
|
elif is_os_linux; then
|
||||||
# shellcheck source=./install-systemd-multi-user.sh
|
# shellcheck source=./install-systemd-multi-user.sh
|
||||||
. "$EXTRACTED_NIX_PATH/install-systemd-multi-user.sh" # most of this works on non-systemd distros also
|
. "$EXTRACTED_NIX_PATH/install-systemd-multi-user.sh" # most of this works on non-systemd distros also
|
||||||
|
check_required_system_specific_settings "install-systemd-multi-user.sh"
|
||||||
else
|
else
|
||||||
failure "Sorry, I don't know what to do on $(uname)"
|
failure "Sorry, I don't know what to do on $(uname)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
welcome_to_nix
|
welcome_to_nix
|
||||||
|
|
||||||
if ! is_root; then
|
if ! is_root; then
|
||||||
|
@ -3,14 +3,11 @@
|
|||||||
set -eu
|
set -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
# System specific settings
|
# System specific settings
|
||||||
export NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-30001}"
|
export NIX_FIRST_BUILD_UID="${NIX_FIRST_BUILD_UID:-30001}"
|
||||||
export NIX_BUILD_GROUP_ID="${NIX_BUILD_GROUP_ID:-30000}"
|
export NIX_BUILD_GROUP_ID="${NIX_BUILD_GROUP_ID:-30000}"
|
||||||
export NIX_BUILD_USER_NAME_TEMPLATE="nixbld%d"
|
export NIX_BUILD_USER_NAME_TEMPLATE="nixbld%d"
|
||||||
|
|
||||||
>>>>>>> 75567423f (install-darwin: move nixbld gid to match first UID)
|
|
||||||
readonly SERVICE_SRC=/lib/systemd/system/nix-daemon.service
|
readonly SERVICE_SRC=/lib/systemd/system/nix-daemon.service
|
||||||
readonly SERVICE_DEST=/etc/systemd/system/nix-daemon.service
|
readonly SERVICE_DEST=/etc/systemd/system/nix-daemon.service
|
||||||
|
|
||||||
|
@ -6,6 +6,25 @@
|
|||||||
|
|
||||||
namespace nix::eval_cache {
|
namespace nix::eval_cache {
|
||||||
|
|
||||||
|
CachedEvalError::CachedEvalError(ref<EvalState> state, ref<AttrCursor> cursor, Symbol attr)
|
||||||
|
: EvalError("cached failure of attribute '%s'", cursor->getAttrPathStr(attr))
|
||||||
|
, state(state), cursor(cursor), attr(attr)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void CachedEvalError::force()
|
||||||
|
{
|
||||||
|
auto & v = cursor->forceValue();
|
||||||
|
|
||||||
|
if (v.type() == nAttrs) {
|
||||||
|
auto a = v.attrs->get(this->attr);
|
||||||
|
|
||||||
|
state->forceValue(*a->value, a->pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shouldn't happen.
|
||||||
|
throw EvalError("evaluation of cached failed attribute '%s' unexpectedly succeeded", cursor->getAttrPathStr(attr));
|
||||||
|
}
|
||||||
|
|
||||||
static const char * schema = R"sql(
|
static const char * schema = R"sql(
|
||||||
create table if not exists Attributes (
|
create table if not exists Attributes (
|
||||||
parent integer not null,
|
parent integer not null,
|
||||||
@ -469,7 +488,7 @@ Suggestions AttrCursor::getSuggestionsForAttr(Symbol name)
|
|||||||
return Suggestions::bestMatches(strAttrNames, root->state.symbols[name]);
|
return Suggestions::bestMatches(strAttrNames, root->state.symbols[name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name, bool forceErrors)
|
std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
@ -486,12 +505,9 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name, bool forceErro
|
|||||||
if (attr) {
|
if (attr) {
|
||||||
if (std::get_if<missing_t>(&attr->second))
|
if (std::get_if<missing_t>(&attr->second))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else if (std::get_if<failed_t>(&attr->second)) {
|
else if (std::get_if<failed_t>(&attr->second))
|
||||||
if (forceErrors)
|
throw CachedEvalError(ref(root->state.shared_from_this()), ref(shared_from_this()), name);
|
||||||
debug("reevaluating failed cached attribute '%s'", getAttrPathStr(name));
|
else
|
||||||
else
|
|
||||||
throw CachedEvalError("cached failure of attribute '%s'", getAttrPathStr(name));
|
|
||||||
} else
|
|
||||||
return std::make_shared<AttrCursor>(root,
|
return std::make_shared<AttrCursor>(root,
|
||||||
std::make_pair(shared_from_this(), name), nullptr, std::move(attr));
|
std::make_pair(shared_from_this(), name), nullptr, std::move(attr));
|
||||||
}
|
}
|
||||||
@ -536,9 +552,9 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(std::string_view name)
|
|||||||
return maybeGetAttr(root->state.symbols.create(name));
|
return maybeGetAttr(root->state.symbols.create(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<AttrCursor> AttrCursor::getAttr(Symbol name, bool forceErrors)
|
ref<AttrCursor> AttrCursor::getAttr(Symbol name)
|
||||||
{
|
{
|
||||||
auto p = maybeGetAttr(name, forceErrors);
|
auto p = maybeGetAttr(name);
|
||||||
if (!p)
|
if (!p)
|
||||||
throw Error("attribute '%s' does not exist", getAttrPathStr(name));
|
throw Error("attribute '%s' does not exist", getAttrPathStr(name));
|
||||||
return ref(p);
|
return ref(p);
|
||||||
@ -549,11 +565,11 @@ ref<AttrCursor> AttrCursor::getAttr(std::string_view name)
|
|||||||
return getAttr(root->state.symbols.create(name));
|
return getAttr(root->state.symbols.create(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(const std::vector<Symbol> & attrPath, bool force)
|
OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(const std::vector<Symbol> & attrPath)
|
||||||
{
|
{
|
||||||
auto res = shared_from_this();
|
auto res = shared_from_this();
|
||||||
for (auto & attr : attrPath) {
|
for (auto & attr : attrPath) {
|
||||||
auto child = res->maybeGetAttr(attr, force);
|
auto child = res->maybeGetAttr(attr);
|
||||||
if (!child) {
|
if (!child) {
|
||||||
auto suggestions = res->getSuggestionsForAttr(attr);
|
auto suggestions = res->getSuggestionsForAttr(attr);
|
||||||
return OrSuggestions<ref<AttrCursor>>::failed(suggestions);
|
return OrSuggestions<ref<AttrCursor>>::failed(suggestions);
|
||||||
@ -750,7 +766,7 @@ bool AttrCursor::isDerivation()
|
|||||||
|
|
||||||
StorePath AttrCursor::forceDerivation()
|
StorePath AttrCursor::forceDerivation()
|
||||||
{
|
{
|
||||||
auto aDrvPath = getAttr(root->state.sDrvPath, true);
|
auto aDrvPath = getAttr(root->state.sDrvPath);
|
||||||
auto drvPath = root->state.store->parseStorePath(aDrvPath->getString());
|
auto drvPath = root->state.store->parseStorePath(aDrvPath->getString());
|
||||||
if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) {
|
if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) {
|
||||||
/* The eval cache contains 'drvPath', but the actual path has
|
/* The eval cache contains 'drvPath', but the actual path has
|
||||||
|
@ -10,14 +10,29 @@
|
|||||||
|
|
||||||
namespace nix::eval_cache {
|
namespace nix::eval_cache {
|
||||||
|
|
||||||
MakeError(CachedEvalError, EvalError);
|
|
||||||
|
|
||||||
struct AttrDb;
|
struct AttrDb;
|
||||||
class AttrCursor;
|
class AttrCursor;
|
||||||
|
|
||||||
|
struct CachedEvalError : EvalError
|
||||||
|
{
|
||||||
|
const ref<EvalState> state;
|
||||||
|
const ref<AttrCursor> cursor;
|
||||||
|
const Symbol attr;
|
||||||
|
|
||||||
|
CachedEvalError(ref<EvalState>, ref<AttrCursor> cursor, Symbol attr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate this attribute, which should result in a regular
|
||||||
|
* `EvalError` exception being thrown.
|
||||||
|
*/
|
||||||
|
[[noreturn]]
|
||||||
|
void force();
|
||||||
|
};
|
||||||
|
|
||||||
class EvalCache : public std::enable_shared_from_this<EvalCache>
|
class EvalCache : public std::enable_shared_from_this<EvalCache>
|
||||||
{
|
{
|
||||||
friend class AttrCursor;
|
friend class AttrCursor;
|
||||||
|
friend class CachedEvalError;
|
||||||
|
|
||||||
std::shared_ptr<AttrDb> db;
|
std::shared_ptr<AttrDb> db;
|
||||||
EvalState & state;
|
EvalState & state;
|
||||||
@ -73,6 +88,7 @@ typedef std::variant<
|
|||||||
class AttrCursor : public std::enable_shared_from_this<AttrCursor>
|
class AttrCursor : public std::enable_shared_from_this<AttrCursor>
|
||||||
{
|
{
|
||||||
friend class EvalCache;
|
friend class EvalCache;
|
||||||
|
friend class CachedEvalError;
|
||||||
|
|
||||||
ref<EvalCache> root;
|
ref<EvalCache> root;
|
||||||
typedef std::optional<std::pair<std::shared_ptr<AttrCursor>, Symbol>> Parent;
|
typedef std::optional<std::pair<std::shared_ptr<AttrCursor>, Symbol>> Parent;
|
||||||
@ -102,11 +118,11 @@ public:
|
|||||||
|
|
||||||
Suggestions getSuggestionsForAttr(Symbol name);
|
Suggestions getSuggestionsForAttr(Symbol name);
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> maybeGetAttr(Symbol name, bool forceErrors = false);
|
std::shared_ptr<AttrCursor> maybeGetAttr(Symbol name);
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> maybeGetAttr(std::string_view name);
|
std::shared_ptr<AttrCursor> maybeGetAttr(std::string_view name);
|
||||||
|
|
||||||
ref<AttrCursor> getAttr(Symbol name, bool forceErrors = false);
|
ref<AttrCursor> getAttr(Symbol name);
|
||||||
|
|
||||||
ref<AttrCursor> getAttr(std::string_view name);
|
ref<AttrCursor> getAttr(std::string_view name);
|
||||||
|
|
||||||
@ -114,7 +130,7 @@ public:
|
|||||||
* Get an attribute along a chain of attrsets. Note that this does
|
* Get an attribute along a chain of attrsets. Note that this does
|
||||||
* not auto-call functors or functions.
|
* not auto-call functors or functions.
|
||||||
*/
|
*/
|
||||||
OrSuggestions<ref<AttrCursor>> findAlongAttrPath(const std::vector<Symbol> & attrPath, bool force = false);
|
OrSuggestions<ref<AttrCursor>> findAlongAttrPath(const std::vector<Symbol> & attrPath);
|
||||||
|
|
||||||
std::string getString();
|
std::string getString();
|
||||||
|
|
||||||
|
@ -1110,7 +1110,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
|||||||
// If we don't recognize it, it's probably content
|
// If we don't recognize it, it's probably content
|
||||||
return true;
|
return true;
|
||||||
} catch (EvalError & e) {
|
} catch (EvalError & e) {
|
||||||
// Some attrs may contain errors, eg. legacyPackages of
|
// Some attrs may contain errors, e.g. legacyPackages of
|
||||||
// nixpkgs. We still want to recurse into it, instead of
|
// nixpkgs. We still want to recurse into it, instead of
|
||||||
// skipping it at all.
|
// skipping it at all.
|
||||||
return true;
|
return true;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
#include "loggers.hh"
|
#include "loggers.hh"
|
||||||
#include "markdown.hh"
|
#include "markdown.hh"
|
||||||
|
#include "eval-cache.hh"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -480,7 +481,15 @@ void mainWrapped(int argc, char * * argv)
|
|||||||
if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) {
|
if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) {
|
||||||
evalSettings.pureEval = false;
|
evalSettings.pureEval = false;
|
||||||
}
|
}
|
||||||
args.command->second->run();
|
|
||||||
|
try {
|
||||||
|
args.command->second->run();
|
||||||
|
} catch (eval_cache::CachedEvalError & e) {
|
||||||
|
/* Evaluate the original attribute that resulted in this
|
||||||
|
cached error so that we can show the original error to the
|
||||||
|
user. */
|
||||||
|
e.force();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
22
tests/functional/flakes/eval-cache.sh
Normal file
22
tests/functional/flakes/eval-cache.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
source ./common.sh
|
||||||
|
|
||||||
|
requireGit
|
||||||
|
|
||||||
|
flake1Dir="$TEST_ROOT/eval-cache-flake"
|
||||||
|
|
||||||
|
createGitRepo "$flake1Dir" ""
|
||||||
|
|
||||||
|
cat >"$flake1Dir/flake.nix" <<EOF
|
||||||
|
{
|
||||||
|
description = "Fnord";
|
||||||
|
outputs = { self }: {
|
||||||
|
foo.bar = throw "breaks";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
git -C "$flake1Dir" add flake.nix
|
||||||
|
git -C "$flake1Dir" commit -m "Init"
|
||||||
|
|
||||||
|
expect 1 nix build "$flake1Dir#foo.bar" 2>&1 | grepQuiet 'error: breaks'
|
||||||
|
expect 1 nix build "$flake1Dir#foo.bar" 2>&1 | grepQuiet 'error: breaks'
|
@ -14,6 +14,7 @@ nix_tests = \
|
|||||||
flakes/absolute-paths.sh \
|
flakes/absolute-paths.sh \
|
||||||
flakes/build-paths.sh \
|
flakes/build-paths.sh \
|
||||||
flakes/flake-in-submodule.sh \
|
flakes/flake-in-submodule.sh \
|
||||||
|
flakes/eval-cache.sh \
|
||||||
gc.sh \
|
gc.sh \
|
||||||
nix-collect-garbage-d.sh \
|
nix-collect-garbage-d.sh \
|
||||||
remote-store.sh \
|
remote-store.sh \
|
||||||
|
Loading…
Reference in New Issue
Block a user