Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/libcmd/include/nix/cmd/installable-attr-path.hh
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
#include <regex>
#include <queue>

#include <nlohmann/json.hpp>

namespace nix {

class InstallableAttrPath : public InstallableValue
Expand Down
16 changes: 16 additions & 0 deletions src/libstore/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,22 @@ std::string BaseSetting<Settings::ExternalBuilders>::to_string() const
return nlohmann::json(value).dump();
}

template<>
std::map<std::string, std::string> BaseSetting<std::map<std::string, std::string>>::parse(const std::string & str) const
{
try {
return nlohmann::json::parse(str).template get<std::map<std::string, std::string>>();
} catch (std::exception & e) {
throw UsageError("parsing setting '%s': %s", name, e.what());
}
}

template<>
std::string BaseSetting<std::map<std::string, std::string>>::to_string() const
{
return nlohmann::json(value).dump();
}

template<>
void BaseSetting<PathsInChroot>::appendOrSet(PathsInChroot newValue, bool append)
{
Expand Down
9 changes: 9 additions & 0 deletions src/libstore/include/nix/store/globals.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,15 @@ public:
)"};

std::optional<std::string> getHostName();

Setting<std::map<std::string, std::string>> buildProvenanceTags{
this,
{},
"build-provenance-tags",
R"(
Arbitrary name/value pairs that are recorded in the build provenance of store paths built by this machine.
This can be used to tag builds with metadata such as the CI job URL, build cluster name, etc.
)"};
};

// FIXME: don't use a global variable.
Expand Down
7 changes: 7 additions & 0 deletions src/libstore/include/nix/store/provenance.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ struct BuildProvenance : Provenance
*/
std::optional<std::string> buildHost;

/**
* User-defined tags from the build host.
*/
std::map<std::string, std::string> tags;

/**
* The system type of the derivation.
*/
Expand All @@ -39,11 +44,13 @@ struct BuildProvenance : Provenance
const StorePath & drvPath,
const OutputName & output,
std::optional<std::string> buildHost,
std::map<std::string, std::string> tags,
std::string system,
std::shared_ptr<const Provenance> next)
: drvPath(drvPath)
, output(output)
, buildHost(std::move(buildHost))
, tags(std::move(tags))
, system(std::move(system))
, next(std::move(next))
{
Expand Down
7 changes: 6 additions & 1 deletion src/libstore/provenance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ nlohmann::json BuildProvenance::to_json() const
{"buildHost", buildHost},
{"system", system},
{"next", next ? next->to_json() : nlohmann::json(nullptr)},
{"tags", tags},
};
}

Expand All @@ -23,10 +24,14 @@ Provenance::Register registerBuildProvenance("build", [](nlohmann::json json) {
std::optional<std::string> buildHost;
if (auto p = optionalValueAt(obj, "buildHost"))
buildHost = p->get<std::optional<std::string>>();
std::map<std::string, std::string> tags;
if (auto p = optionalValueAt(obj, "tags"); p && !p->is_null())
tags = p->get<std::map<std::string, std::string>>();
auto buildProv = make_ref<BuildProvenance>(
StorePath(getString(valueAt(obj, "drv"))),
getString(valueAt(obj, "output")),
buildHost,
std::move(buildHost),
std::move(tags),
getString(valueAt(obj, "system")),
next);
return buildProv;
Expand Down
7 changes: 6 additions & 1 deletion src/libstore/unix/build/derivation-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1873,7 +1873,12 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
newInfo.ultimate = true;
if (experimentalFeatureSettings.isEnabled(Xp::Provenance))
newInfo.provenance = std::make_shared<const BuildProvenance>(
drvPath, outputName, settings.getHostName(), drv.platform, drvProvenance);
drvPath,
outputName,
settings.getHostName(),
settings.buildProvenanceTags.get(),
drv.platform,
drvProvenance);
store.signPathInfo(newInfo);

finish(newInfo.path);
Expand Down
2 changes: 2 additions & 0 deletions src/nix/provenance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ struct CmdProvenanceShow : StorePathsCommand
build->output,
build->buildHost.value_or("unknown host").c_str(),
build->system);
for (auto & [tagName, tagValue] : build->tags)
logger->cout(" tag " ANSI_BOLD "%s" ANSI_NORMAL ": %s", tagName, tagValue);
provenance = build->next;
}

Expand Down
1 change: 1 addition & 0 deletions tests/functional/common/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ substituters =
flake-registry = $TEST_ROOT/registry.json
show-trace = true
host-name = test-host
build-provenance-tags = {"pr": "1234", "branch": "main"}
include nix.conf.extra
trusted-users = $(whoami)
${_NIX_TEST_EXTRA_CONFIG:-}
Expand Down
12 changes: 12 additions & 0 deletions tests/functional/flakes/provenance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ builder=$(nix eval --raw "$flake1Dir#packages.$system.default._builder")
},
"output": "out",
"system": "$system",
"tags": {
"branch": "main",
"pr": "1234"
},
"type": "build"
}
EOF
Expand Down Expand Up @@ -172,6 +176,10 @@ nix copy --from "file://$binaryCache" "$outPath" --no-check-sigs
},
"output": "out",
"system": "$system",
"tags": {
"branch": "main",
"pr": "1234"
},
"type": "build"
},
"type": "copied"
Expand All @@ -186,6 +194,8 @@ unset _NIX_FORCE_HTTP
$outPath
← copied from file://$binaryCache
← built from derivation $drvPath (output out) on test-host for $system
tag branch: main
tag pr: 1234
← with derivation metadata
{
"license": [
Expand Down Expand Up @@ -258,6 +268,8 @@ nix build --impure --print-out-paths --no-link "$flake1Dir#packages.$system.defa
[[ "$(nix provenance show "$outPath")" = "$(cat <<EOF
$outPath
← built from derivation $drvPath (output out) on test-host for $system
tag branch: main
tag pr: 1234
← with derivation metadata
{
"license": [
Expand Down