forked from lix-project/lix
Check requiredSystemFeatures for local builds
For example, this prevents a "kvm" build on machines that don't have KVM. Fixes #2012.
This commit is contained in:
parent
7ae7a38c9a
commit
1e7b8deea7
|
@ -757,6 +757,33 @@ password <replaceable>my-password</replaceable>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
|
<varlistentry xml:id="conf-system-features"><term><literal>system-features</literal></term>
|
||||||
|
|
||||||
|
<listitem><para>A set of system “features” supported by this
|
||||||
|
machine, e.g. <literal>kvm</literal>. Derivations can express a
|
||||||
|
dependency on such features through the derivation attribute
|
||||||
|
<varname>requiredSystemFeatures</varname>. For example, the
|
||||||
|
attribute
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
requiredSystemFeatures = [ "kvm" ];
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
ensures that the derivation can only be built on a machine with
|
||||||
|
the <literal>kvm</literal> feature.</para>
|
||||||
|
|
||||||
|
<para>This setting by default includes <literal>kvm</literal> if
|
||||||
|
<filename>/dev/kvm</filename> is accessible, and the
|
||||||
|
pseudo-features <literal>nixos-test</literal>,
|
||||||
|
<literal>benchmark</literal> and <literal>big-parallel</literal>
|
||||||
|
that are used in Nixpkgs to route builds to specific
|
||||||
|
machines.</para>
|
||||||
|
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
<varlistentry xml:id="conf-timeout"><term><literal>timeout</literal></term>
|
<varlistentry xml:id="conf-timeout"><term><literal>timeout</literal></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
</partintro>
|
</partintro>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<xi:include href="rl-2.2.xml" />
|
||||||
<xi:include href="rl-2.1.xml" />
|
<xi:include href="rl-2.1.xml" />
|
||||||
<xi:include href="rl-2.0.xml" />
|
<xi:include href="rl-2.0.xml" />
|
||||||
<xi:include href="rl-1.11.10.xml" />
|
<xi:include href="rl-1.11.10.xml" />
|
||||||
|
|
|
@ -1646,18 +1646,13 @@ HookReply DerivationGoal::tryBuildHook()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
/* Tell the hook about system features (beyond the system type)
|
|
||||||
required from the build machine. (The hook could parse the
|
|
||||||
drv file itself, but this is easier.) */
|
|
||||||
auto features = parsedDrv->getStringsAttr("requiredSystemFeatures").value_or(Strings());
|
|
||||||
|
|
||||||
/* Send the request to the hook. */
|
/* Send the request to the hook. */
|
||||||
worker.hook->sink
|
worker.hook->sink
|
||||||
<< "try"
|
<< "try"
|
||||||
<< (worker.getNrLocalBuilds() < settings.maxBuildJobs ? 1 : 0)
|
<< (worker.getNrLocalBuilds() < settings.maxBuildJobs ? 1 : 0)
|
||||||
<< drv->platform
|
<< drv->platform
|
||||||
<< drvPath
|
<< drvPath
|
||||||
<< features;
|
<< parsedDrv->getRequiredSystemFeatures();
|
||||||
worker.hook->sink.flush();
|
worker.hook->sink.flush();
|
||||||
|
|
||||||
/* Read the first line of input, which should be a word indicating
|
/* Read the first line of input, which should be a word indicating
|
||||||
|
@ -1797,11 +1792,13 @@ static void preloadNSS() {
|
||||||
void DerivationGoal::startBuilder()
|
void DerivationGoal::startBuilder()
|
||||||
{
|
{
|
||||||
/* Right platform? */
|
/* Right platform? */
|
||||||
if (!parsedDrv->canBuildLocally()) {
|
if (!parsedDrv->canBuildLocally())
|
||||||
throw Error(
|
throw Error("a '%s' with features {%s} is required to build '%s', but I am a '%s' with features {%s}",
|
||||||
format("a '%1%' is required to build '%3%', but I am a '%2%'")
|
drv->platform,
|
||||||
% drv->platform % settings.thisSystem % drvPath);
|
concatStringsSep(", ", parsedDrv->getRequiredSystemFeatures()),
|
||||||
}
|
drvPath,
|
||||||
|
settings.thisSystem,
|
||||||
|
concatStringsSep(", ", settings.systemFeatures));
|
||||||
|
|
||||||
if (drv->isBuiltin())
|
if (drv->isBuiltin())
|
||||||
preloadNSS();
|
preloadNSS();
|
||||||
|
@ -2625,7 +2622,7 @@ void DerivationGoal::runChild()
|
||||||
createDirs(chrootRootDir + "/dev/shm");
|
createDirs(chrootRootDir + "/dev/shm");
|
||||||
createDirs(chrootRootDir + "/dev/pts");
|
createDirs(chrootRootDir + "/dev/pts");
|
||||||
ss.push_back("/dev/full");
|
ss.push_back("/dev/full");
|
||||||
if (pathExists("/dev/kvm"))
|
if (settings.systemFeatures.get().count("kvm") && pathExists("/dev/kvm"))
|
||||||
ss.push_back("/dev/kvm");
|
ss.push_back("/dev/kvm");
|
||||||
ss.push_back("/dev/null");
|
ss.push_back("/dev/null");
|
||||||
ss.push_back("/dev/random");
|
ss.push_back("/dev/random");
|
||||||
|
|
|
@ -86,6 +86,21 @@ unsigned int Settings::getDefaultCores()
|
||||||
return std::max(1U, std::thread::hardware_concurrency());
|
return std::max(1U, std::thread::hardware_concurrency());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringSet Settings::getDefaultSystemFeatures()
|
||||||
|
{
|
||||||
|
/* For backwards compatibility, accept some "features" that are
|
||||||
|
used in Nixpkgs to route builds to certain machines but don't
|
||||||
|
actually require anything special on the machines. */
|
||||||
|
StringSet features{"nixos-test", "benchmark", "big-parallel"};
|
||||||
|
|
||||||
|
#if __linux__
|
||||||
|
if (access("/dev/kvm", R_OK | W_OK) == 0)
|
||||||
|
features.insert("kvm");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
const string nixVersion = PACKAGE_VERSION;
|
const string nixVersion = PACKAGE_VERSION;
|
||||||
|
|
||||||
template<> void BaseSetting<SandboxMode>::set(const std::string & str)
|
template<> void BaseSetting<SandboxMode>::set(const std::string & str)
|
||||||
|
|
|
@ -32,6 +32,8 @@ class Settings : public Config {
|
||||||
|
|
||||||
unsigned int getDefaultCores();
|
unsigned int getDefaultCores();
|
||||||
|
|
||||||
|
StringSet getDefaultSystemFeatures();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Settings();
|
Settings();
|
||||||
|
@ -261,6 +263,10 @@ public:
|
||||||
"These may be supported natively (e.g. armv7 on some aarch64 CPUs "
|
"These may be supported natively (e.g. armv7 on some aarch64 CPUs "
|
||||||
"or using hacks like qemu-user."};
|
"or using hacks like qemu-user."};
|
||||||
|
|
||||||
|
Setting<StringSet> systemFeatures{this, getDefaultSystemFeatures(),
|
||||||
|
"system-features",
|
||||||
|
"Optional features that this system implements (like \"kvm\")."};
|
||||||
|
|
||||||
Setting<Strings> substituters{this,
|
Setting<Strings> substituters{this,
|
||||||
nixStore == "/nix/store" ? Strings{"https://cache.nixos.org/"} : Strings(),
|
nixStore == "/nix/store" ? Strings{"https://cache.nixos.org/"} : Strings(),
|
||||||
"substituters",
|
"substituters",
|
||||||
|
|
|
@ -82,11 +82,25 @@ std::experimental::optional<Strings> ParsedDerivation::getStringsAttr(const std:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringSet ParsedDerivation::getRequiredSystemFeatures() const
|
||||||
|
{
|
||||||
|
StringSet res;
|
||||||
|
for (auto & i : getStringsAttr("requiredSystemFeatures").value_or(Strings()))
|
||||||
|
res.insert(i);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
bool ParsedDerivation::canBuildLocally() const
|
bool ParsedDerivation::canBuildLocally() const
|
||||||
{
|
{
|
||||||
return drv.platform == settings.thisSystem
|
if (drv.platform != settings.thisSystem.get()
|
||||||
|| settings.extraPlatforms.get().count(drv.platform) > 0
|
&& !settings.extraPlatforms.get().count(drv.platform)
|
||||||
|| drv.isBuiltin();
|
&& !drv.isBuiltin())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto & feature : getRequiredSystemFeatures())
|
||||||
|
if (!settings.systemFeatures.get().count(feature)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParsedDerivation::willBuildLocally() const
|
bool ParsedDerivation::willBuildLocally() const
|
||||||
|
|
|
@ -25,6 +25,8 @@ public:
|
||||||
|
|
||||||
std::experimental::optional<Strings> getStringsAttr(const std::string & name) const;
|
std::experimental::optional<Strings> getStringsAttr(const std::string & name) const;
|
||||||
|
|
||||||
|
StringSet getRequiredSystemFeatures() const;
|
||||||
|
|
||||||
bool canBuildLocally() const;
|
bool canBuildLocally() const;
|
||||||
|
|
||||||
bool willBuildLocally() const;
|
bool willBuildLocally() const;
|
||||||
|
|
|
@ -11,7 +11,8 @@ rm -rf $TEST_ROOT/store0 $TEST_ROOT/store1
|
||||||
|
|
||||||
nix build -f build-hook.nix -o $TEST_ROOT/result --max-jobs 0 \
|
nix build -f build-hook.nix -o $TEST_ROOT/result --max-jobs 0 \
|
||||||
--sandbox-paths /nix/store --sandbox-build-dir /build-tmp \
|
--sandbox-paths /nix/store --sandbox-build-dir /build-tmp \
|
||||||
--builders "$TEST_ROOT/store0; $TEST_ROOT/store1 - - 1 1 foo"
|
--builders "$TEST_ROOT/store0; $TEST_ROOT/store1 - - 1 1 foo" \
|
||||||
|
--system-features foo
|
||||||
|
|
||||||
outPath=$TEST_ROOT/result
|
outPath=$TEST_ROOT/result
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue