Merge branch 'master' into read-only-local-store

This commit is contained in:
Ben Radford 2023-05-25 10:06:24 +01:00
commit 8e4b15e6a0
No known key found for this signature in database
GPG key ID: 9DF5D4640AB888D5
6 changed files with 142 additions and 43 deletions

View file

@ -1777,7 +1777,8 @@ void LocalDerivationGoal::runChild()
if (pathExists(path))
ss.push_back(path);
dirsInChroot.emplace(settings.caFile, "/etc/ssl/certs/ca-certificates.crt");
if (settings.caFile != "")
dirsInChroot.try_emplace("/etc/ssl/certs/ca-certificates.crt", settings.caFile, true);
}
for (auto & i : ss) dirsInChroot.emplace(i, i);

View file

@ -9,8 +9,8 @@ static void checkName(std::string_view path, std::string_view name)
if (name.empty())
throw BadStorePath("store path '%s' has an empty name", path);
if (name.size() > StorePath::MaxPathLen)
throw BadStorePath("store path '%s' has a name longer than '%d characters",
StorePath::MaxPathLen, path);
throw BadStorePath("store path '%s' has a name longer than %d characters",
path, StorePath::MaxPathLen);
// See nameRegexStr for the definition
for (auto c : name)
if (!((c >= '0' && c <= '9')

View file

@ -259,6 +259,7 @@ struct CmdFlakeInfo : CmdFlakeMetadata
struct CmdFlakeCheck : FlakeCommand
{
bool build = true;
bool checkAllSystems = false;
CmdFlakeCheck()
{
@ -267,6 +268,11 @@ struct CmdFlakeCheck : FlakeCommand
.description = "Do not build checks.",
.handler = {&build, false}
});
addFlag({
.longName = "all-systems",
.description = "Check the outputs for all systems.",
.handler = {&checkAllSystems, true}
});
}
std::string description() override
@ -292,6 +298,7 @@ struct CmdFlakeCheck : FlakeCommand
lockFlags.applyNixConfig = true;
auto flake = lockFlake();
auto localSystem = std::string(settings.thisSystem.get());
bool hasErrors = false;
auto reportError = [&](const Error & e) {
@ -307,6 +314,8 @@ struct CmdFlakeCheck : FlakeCommand
}
};
std::set<std::string> omittedSystems;
// FIXME: rewrite to use EvalCache.
auto resolve = [&] (PosIdx p) {
@ -327,6 +336,15 @@ struct CmdFlakeCheck : FlakeCommand
reportError(Error("'%s' is not a valid system type, at %s", system, resolve(pos)));
};
auto checkSystemType = [&](const std::string & system, const PosIdx pos) {
if (!checkAllSystems && system != localSystem) {
omittedSystems.insert(system);
return false;
} else {
return true;
}
};
auto checkDerivation = [&](const std::string & attrPath, Value & v, const PosIdx pos) -> std::optional<StorePath> {
try {
auto drvInfo = getDerivation(*state, v, false);
@ -509,16 +527,18 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs) {
auto drvPath = checkDerivation(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
if (drvPath && attr_name == settings.thisSystem.get()) {
drvPaths.push_back(DerivedPath::Built {
.drvPath = *drvPath,
.outputs = OutputsSpec::All { },
});
if (checkSystemType(attr_name, attr.pos)) {
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs) {
auto drvPath = checkDerivation(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
if (drvPath && attr_name == settings.thisSystem.get()) {
drvPaths.push_back(DerivedPath::Built {
.drvPath = *drvPath,
.outputs = OutputsSpec::All { },
});
}
}
}
}
@ -529,9 +549,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
checkApp(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
if (checkSystemType(attr_name, attr.pos)) {
checkApp(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
}
}
@ -540,11 +562,13 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs)
checkDerivation(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
if (checkSystemType(attr_name, attr.pos)) {
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs)
checkDerivation(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
};
}
}
@ -553,11 +577,13 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs)
checkApp(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
if (checkSystemType(attr_name, attr.pos)) {
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs)
checkApp(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
};
}
}
@ -566,9 +592,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
checkDerivation(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
if (checkSystemType(attr_name, attr.pos)) {
checkDerivation(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
}
}
@ -577,9 +605,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
checkApp(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
if (checkSystemType(attr_name, attr.pos) ) {
checkApp(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
}
}
@ -587,6 +617,7 @@ struct CmdFlakeCheck : FlakeCommand
state->forceAttrs(vOutput, pos, "");
for (auto & attr : *vOutput.attrs) {
checkSystemName(state->symbols[attr.name], attr.pos);
checkSystemType(state->symbols[attr.name], attr.pos);
// FIXME: do getDerivations?
}
}
@ -636,9 +667,11 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
checkBundler(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
if (checkSystemType(attr_name, attr.pos)) {
checkBundler(
fmt("%s.%s", name, attr_name),
*attr.value, attr.pos);
};
}
}
@ -647,12 +680,14 @@ struct CmdFlakeCheck : FlakeCommand
for (auto & attr : *vOutput.attrs) {
const auto & attr_name = state->symbols[attr.name];
checkSystemName(attr_name, attr.pos);
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs) {
checkBundler(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
}
if (checkSystemType(attr_name, attr.pos)) {
state->forceAttrs(*attr.value, attr.pos, "");
for (auto & attr2 : *attr.value->attrs) {
checkBundler(
fmt("%s.%s.%s", name, attr_name, state->symbols[attr2.name]),
*attr2.value, attr2.pos);
}
};
}
}
@ -685,7 +720,15 @@ struct CmdFlakeCheck : FlakeCommand
}
if (hasErrors)
throw Error("some errors were encountered during the evaluation");
}
if (!omittedSystems.empty()) {
warn(
"The check omitted these incompatible systems: %s\n"
"Use '--all-systems' to check all.",
concatStringsSep(", ", omittedSystems)
);
};
};
};
static Strings defaultTemplateAttrPathsPrefixes{"templates."};

View file

@ -72,6 +72,8 @@ cat > $flakeDir/flake.nix <<EOF
}
EOF
checkRes=$(nix flake check --keep-going $flakeDir 2>&1 && fail "nix flake check should have failed" || true)
nix flake check $flakeDir
checkRes=$(nix flake check --all-systems --keep-going $flakeDir 2>&1 && fail "nix flake check --all-systems should have failed" || true)
echo "$checkRes" | grepQuiet "packages.system-1.default"
echo "$checkRes" | grepQuiet "packages.system-2.default"

View file

@ -0,0 +1,29 @@
{ fixed-output }:
with import ./config.nix;
mkDerivation ({
name = "ssl-export";
buildCommand = ''
# Add some indirection, otherwise grepping into the debug output finds the string.
report () { echo CERT_$1_IN_SANDBOX; }
if [ -f /etc/ssl/certs/ca-certificates.crt ]; then
content=$(</etc/ssl/certs/ca-certificates.crt)
if [ "$content" == CERT_CONTENT ]; then
report present
fi
else
report missing
fi
# Always fail, because we do not want to bother with fixed-output
# derivations being cached, and do not want to compute the right hash.
false;
'';
} // (
if fixed-output == "fixed-output"
then { outputHash = "sha256:0000000000000000000000000000000000000000000000000000000000000000"; }
else { }
))

View file

@ -40,3 +40,27 @@ grepQuiet 'may not be deterministic' $TEST_ROOT/log
# Test that sandboxed builds cannot write to /etc easily
(! nix-build -E 'with import ./config.nix; mkDerivation { name = "etc-write"; buildCommand = "echo > /etc/test"; }' --no-out-link --sandbox-paths /nix/store)
## Test mounting of SSL certificates into the sandbox
testCert () {
(! nix-build linux-sandbox-cert-test.nix --argstr fixed-output "$2" --no-out-link --sandbox-paths /nix/store --option ssl-cert-file "$3" 2> $TEST_ROOT/log)
cat $TEST_ROOT/log
grepQuiet "CERT_${1}_IN_SANDBOX" $TEST_ROOT/log
}
nocert=$TEST_ROOT/no-cert-file.pem
cert=$TEST_ROOT/some-cert-file.pem
echo -n "CERT_CONTENT" > $cert
# No cert in sandbox when not a fixed-output derivation
testCert missing normal "$cert"
# No cert in sandbox when ssl-cert-file is empty
testCert missing fixed-output ""
# No cert in sandbox when ssl-cert-file is a nonexistent file
testCert missing fixed-output "$nocert"
# Cert in sandbox when ssl-cert-file is set to an existing file
testCert present fixed-output "$cert"