Remove references from fixed output derivation ab syntax

In other words, use a plain `ContentAddress` not
`ContentAddressWithReferences` for `DerivationOutput::CAFixed`.

Supporting fixed output derivations with (fixed) references would be a
cool feature, but it is out of scope at this moment.
This commit is contained in:
John Ericson 2023-04-19 14:48:53 -04:00
parent aba8a8a83a
commit 7103c6da70
9 changed files with 55 additions and 52 deletions

View file

@ -1303,11 +1303,9 @@ drvName, Bindings * attrs, Value & v)
auto method = ingestionMethod.value_or(FileIngestionMethod::Flat); auto method = ingestionMethod.value_or(FileIngestionMethod::Flat);
DerivationOutput::CAFixed dof { DerivationOutput::CAFixed dof {
.ca = ContentAddressWithReferences::fromParts( .ca = ContentAddress::fromParts(
std::move(method), std::move(method),
std::move(h), std::move(h)),
// FIXME non-trivial fixed refs set
{}),
}; };
drv.env["out"] = state.store->printStorePath(dof.path(*state.store, drvName, "out")); drv.env["out"] = state.store->printStorePath(dof.path(*state.store, drvName, "out"));

View file

@ -274,11 +274,13 @@ void DerivationGoal::haveDerivation()
) )
) )
); );
else else {
auto * cap = getDerivationCA(*drv);
addWaitee(upcast_goal(worker.makePathSubstitutionGoal( addWaitee(upcast_goal(worker.makePathSubstitutionGoal(
status.known->path, status.known->path,
buildMode == bmRepair ? Repair : NoRepair, buildMode == bmRepair ? Repair : NoRepair,
getDerivationCA(*drv)))); cap ? std::optional { *cap } : std::nullopt)));
}
} }
if (waitees.empty()) /* to prevent hang (no wake-up event) */ if (waitees.empty()) /* to prevent hang (no wake-up event) */

View file

@ -196,6 +196,11 @@ const Hash & ContentAddress::getHash() const
}, raw); }, raw);
} }
std::string ContentAddress::printMethodAlgo() const {
return getMethod().renderPrefix()
+ printHashType(getHash().type);
}
bool StoreReferences::empty() const bool StoreReferences::empty() const
{ {
return !self && others.empty(); return !self && others.empty();
@ -271,9 +276,4 @@ Hash ContentAddressWithReferences::getHash() const
}, raw); }, raw);
} }
std::string ContentAddressWithReferences::printMethodAlgo() const {
return getMethod().renderPrefix()
+ printHashType(getHash().type);
}
} }

View file

@ -177,6 +177,8 @@ struct ContentAddress
ContentAddressMethod getMethod() const; ContentAddressMethod getMethod() const;
const Hash & getHash() const; const Hash & getHash() const;
std::string printMethodAlgo() const;
}; };
std::string renderContentAddress(std::optional<ContentAddress> ca); std::string renderContentAddress(std::optional<ContentAddress> ca);
@ -286,8 +288,6 @@ struct ContentAddressWithReferences
ContentAddressMethod getMethod() const; ContentAddressMethod getMethod() const;
Hash getHash() const; Hash getHash() const;
std::string printMethodAlgo() const;
}; };
} }

View file

@ -38,7 +38,7 @@ StorePath DerivationOutput::CAFixed::path(const Store & store, std::string_view
{ {
return store.makeFixedOutputPathFromCA( return store.makeFixedOutputPathFromCA(
outputPathName(drvName, outputName), outputPathName(drvName, outputName),
ca); ContentAddressWithReferences::withoutRefs(ca));
} }
@ -230,11 +230,9 @@ static DerivationOutput parseDerivationOutput(const Store & store,
validatePath(pathS); validatePath(pathS);
auto hash = Hash::parseNonSRIUnprefixed(hashS, hashType); auto hash = Hash::parseNonSRIUnprefixed(hashS, hashType);
return DerivationOutput::CAFixed { return DerivationOutput::CAFixed {
.ca = ContentAddressWithReferences::fromParts( .ca = ContentAddress::fromParts(
std::move(method), std::move(method),
std::move(hash), std::move(hash)),
// FIXME non-trivial fixed refs set
{}),
}; };
} else { } else {
experimentalFeatureSettings.require(Xp::CaDerivations); experimentalFeatureSettings.require(Xp::CaDerivations);
@ -1020,10 +1018,9 @@ DerivationOutput DerivationOutput::fromJSON(
else if (keys == (std::set<std::string_view> { "path", "hashAlgo", "hash" })) { else if (keys == (std::set<std::string_view> { "path", "hashAlgo", "hash" })) {
auto [method, hashType] = methodAlgo(); auto [method, hashType] = methodAlgo();
auto dof = DerivationOutput::CAFixed { auto dof = DerivationOutput::CAFixed {
.ca = ContentAddressWithReferences::fromParts( .ca = ContentAddress::fromParts(
std::move(method), std::move(method),
Hash::parseNonSRIUnprefixed((std::string) json["hash"], hashType), Hash::parseNonSRIUnprefixed((std::string) json["hash"], hashType)),
{}),
}; };
if (dof.path(store, drvName, outputName) != store.parseStorePath((std::string) json["path"])) if (dof.path(store, drvName, outputName) != store.parseStorePath((std::string) json["path"]))
throw Error("Path doesn't match derivation output"); throw Error("Path doesn't match derivation output");

View file

@ -36,9 +36,11 @@ struct DerivationOutputInputAddressed
struct DerivationOutputCAFixed struct DerivationOutputCAFixed
{ {
/** /**
* hash and refs used for expected hash computation * Method and hash used for expected hash computation.
*
* References are not allowed by fiat.
*/ */
ContentAddressWithReferences ca; /* hash and refs used for validating output */ ContentAddress ca;
/** /**
* Return the \ref StorePath "store path" corresponding to this output * Return the \ref StorePath "store path" corresponding to this output

View file

@ -83,26 +83,16 @@ void Store::computeFSClosure(const StorePath & startPath,
} }
std::optional<ContentAddress> getDerivationCA(const BasicDerivation & drv) const ContentAddress * getDerivationCA(const BasicDerivation & drv)
{ {
auto out = drv.outputs.find("out"); auto out = drv.outputs.find("out");
if (out == drv.outputs.end()) if (out == drv.outputs.end())
return std::nullopt; return nullptr;
if (auto dof = std::get_if<DerivationOutput::CAFixed>(&out->second)) { if (auto dof = std::get_if<DerivationOutput::CAFixed>(&out->second)) {
return std::visit(overloaded {
[&](const TextInfo & ti) -> std::optional<ContentAddress> { return &dof->ca;
if (!ti.references.empty())
return std::nullopt;
return ti.hash;
},
[&](const FixedOutputInfo & fi) -> std::optional<ContentAddress> {
if (!fi.references.empty())
return std::nullopt;
return fi.hash;
},
}, dof->ca.raw);
} }
return std::nullopt; return nullptr;
} }
void Store::queryMissing(const std::vector<DerivedPath> & targets, void Store::queryMissing(const std::vector<DerivedPath> & targets,
@ -152,7 +142,13 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
if (drvState_->lock()->done) return; if (drvState_->lock()->done) return;
SubstitutablePathInfos infos; SubstitutablePathInfos infos;
querySubstitutablePathInfos({{outPath, getDerivationCA(*drv)}}, infos); auto * cap = getDerivationCA(*drv);
querySubstitutablePathInfos({
{
outPath,
cap ? std::optional { *cap } : std::nullopt,
},
}, infos);
if (infos.empty()) { if (infos.empty()) {
drvState_->lock()->done = true; drvState_->lock()->done = true;

View file

@ -1022,7 +1022,7 @@ std::optional<ValidPathInfo> decodeValidPathInfo(
*/ */
std::pair<std::string, Store::Params> splitUriAndParams(const std::string & uri); std::pair<std::string, Store::Params> splitUriAndParams(const std::string & uri);
std::optional<ContentAddress> getDerivationCA(const BasicDerivation & drv); const ContentAddress * getDerivationCA(const BasicDerivation & drv);
std::map<DrvOutput, StorePath> drvOutputReferences( std::map<DrvOutput, StorePath> drvOutputReferences(
Store & store, Store & store,

View file

@ -74,19 +74,30 @@ TEST_JSON(DerivationTest, inputAddressed,
}), }),
"drv-name", "output-name") "drv-name", "output-name")
TEST_JSON(DerivationTest, caFixed, TEST_JSON(DerivationTest, caFixedFlat,
R"({
"hashAlgo": "sha256",
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
"path": "/nix/store/rhcg9h16sqvlbpsa6dqm57sbr2al6nzg-drv-name-output-name"
})",
(DerivationOutput::CAFixed {
.ca = FixedOutputHash {
.method = FileIngestionMethod::Flat,
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
},
}),
"drv-name", "output-name")
TEST_JSON(DerivationTest, caFixedNAR,
R"({ R"({
"hashAlgo": "r:sha256", "hashAlgo": "r:sha256",
"hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f", "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
"path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name" "path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"
})", })",
(DerivationOutput::CAFixed { (DerivationOutput::CAFixed {
.ca = FixedOutputInfo { .ca = FixedOutputHash {
.hash = { .method = FileIngestionMethod::Recursive,
.method = FileIngestionMethod::Recursive, .hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
},
.references = {},
}, },
}), }),
"drv-name", "output-name") "drv-name", "output-name")
@ -98,11 +109,8 @@ TEST_JSON(DynDerivationTest, caFixedText,
"path": "/nix/store/6s1zwabh956jvhv4w9xcdb5jiyanyxg1-drv-name-output-name" "path": "/nix/store/6s1zwabh956jvhv4w9xcdb5jiyanyxg1-drv-name-output-name"
})", })",
(DerivationOutput::CAFixed { (DerivationOutput::CAFixed {
.ca = TextInfo { .ca = TextHash {
.hash = { .hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
},
.references = {},
}, },
}), }),
"drv-name", "output-name") "drv-name", "output-name")