nix profile: Support CA derivations
This commit is contained in:
parent
54888b92de
commit
161f798aa1
|
@ -470,7 +470,6 @@ std::vector<InstallableValue::DerivationInfo> InstallableAttrPath::toDerivations
|
||||||
for (auto & drvInfo : drvInfos) {
|
for (auto & drvInfo : drvInfos) {
|
||||||
res.push_back({
|
res.push_back({
|
||||||
state->store->parseStorePath(drvInfo.queryDrvPath()),
|
state->store->parseStorePath(drvInfo.queryDrvPath()),
|
||||||
state->store->maybeParseStorePath(drvInfo.queryOutPath()),
|
|
||||||
drvInfo.queryOutputName()
|
drvInfo.queryOutputName()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -584,9 +583,8 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF
|
||||||
|
|
||||||
auto drvPath = attr->forceDerivation();
|
auto drvPath = attr->forceDerivation();
|
||||||
|
|
||||||
auto drvInfo = DerivationInfo{
|
auto drvInfo = DerivationInfo {
|
||||||
std::move(drvPath),
|
std::move(drvPath),
|
||||||
state->store->maybeParseStorePath(attr->getAttr(state->sOutPath)->getString()),
|
|
||||||
attr->getAttr(state->sOutputName)->getString()
|
attr->getAttr(state->sOutputName)->getString()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,6 @@ struct InstallableValue : Installable
|
||||||
struct DerivationInfo
|
struct DerivationInfo
|
||||||
{
|
{
|
||||||
StorePath drvPath;
|
StorePath drvPath;
|
||||||
std::optional<StorePath> outPath;
|
|
||||||
std::string outputName;
|
std::string outputName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,27 @@ struct ProfileElement
|
||||||
{
|
{
|
||||||
return std::tuple(describe(), storePaths) < std::tuple(other.describe(), other.storePaths);
|
return std::tuple(describe(), storePaths) < std::tuple(other.describe(), other.storePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateStorePaths(ref<Store> evalStore, ref<Store> store, Installable & installable)
|
||||||
|
{
|
||||||
|
// FIXME: respect meta.outputsToInstall
|
||||||
|
storePaths.clear();
|
||||||
|
for (auto & buildable : getBuiltPaths(evalStore, store, installable.toDerivedPaths())) {
|
||||||
|
std::visit(overloaded {
|
||||||
|
[&](const BuiltPath::Opaque & bo) {
|
||||||
|
storePaths.insert(bo.path);
|
||||||
|
},
|
||||||
|
[&](const BuiltPath::Built & bfd) {
|
||||||
|
// TODO: Why are we querying if we know the output
|
||||||
|
// names already? Is it just to figure out what the
|
||||||
|
// default one is?
|
||||||
|
for (auto & output : store->queryDerivationOutputMap(bfd.drvPath)) {
|
||||||
|
storePaths.insert(output.second);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, buildable.raw());
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProfileManifest
|
struct ProfileManifest
|
||||||
|
@ -232,53 +253,25 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
|
||||||
{
|
{
|
||||||
ProfileManifest manifest(*getEvalState(), *profile);
|
ProfileManifest manifest(*getEvalState(), *profile);
|
||||||
|
|
||||||
std::vector<DerivedPath> pathsToBuild;
|
auto builtPaths = Installable::build(getEvalStore(), store, Realise::Outputs, installables, bmNormal);
|
||||||
|
|
||||||
for (auto & installable : installables) {
|
for (auto & installable : installables) {
|
||||||
if (auto installable2 = std::dynamic_pointer_cast<InstallableFlake>(installable)) {
|
ProfileElement element;
|
||||||
auto [attrPath, resolvedRef, drv] = installable2->toDerivation();
|
|
||||||
|
|
||||||
ProfileElement element;
|
if (auto installable2 = std::dynamic_pointer_cast<InstallableFlake>(installable)) {
|
||||||
if (!drv.outPath)
|
// FIXME: make build() return this?
|
||||||
throw UnimplementedError("CA derivations are not yet supported by 'nix profile'");
|
auto [attrPath, resolvedRef, drv] = installable2->toDerivation();
|
||||||
element.storePaths = {*drv.outPath}; // FIXME
|
|
||||||
element.source = ProfileElementSource{
|
element.source = ProfileElementSource{
|
||||||
installable2->flakeRef,
|
installable2->flakeRef,
|
||||||
resolvedRef,
|
resolvedRef,
|
||||||
attrPath,
|
attrPath,
|
||||||
};
|
};
|
||||||
|
|
||||||
pathsToBuild.push_back(DerivedPath::Built{drv.drvPath, StringSet{drv.outputName}});
|
|
||||||
|
|
||||||
manifest.elements.emplace_back(std::move(element));
|
|
||||||
} else {
|
|
||||||
auto buildables = Installable::build(getEvalStore(), store, Realise::Outputs, {installable}, bmNormal);
|
|
||||||
|
|
||||||
for (auto & buildable : buildables) {
|
|
||||||
ProfileElement element;
|
|
||||||
|
|
||||||
std::visit(overloaded {
|
|
||||||
[&](const BuiltPath::Opaque & bo) {
|
|
||||||
pathsToBuild.push_back(bo);
|
|
||||||
element.storePaths.insert(bo.path);
|
|
||||||
},
|
|
||||||
[&](const BuiltPath::Built & bfd) {
|
|
||||||
// TODO: Why are we querying if we know the output
|
|
||||||
// names already? Is it just to figure out what the
|
|
||||||
// default one is?
|
|
||||||
for (auto & output : store->queryDerivationOutputMap(bfd.drvPath)) {
|
|
||||||
pathsToBuild.push_back(DerivedPath::Built{bfd.drvPath, {output.first}});
|
|
||||||
element.storePaths.insert(output.second);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}, buildable.raw());
|
|
||||||
|
|
||||||
manifest.elements.emplace_back(std::move(element));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
store->buildPaths(pathsToBuild);
|
element.updateStorePaths(getEvalStore(), store, *installable);
|
||||||
|
|
||||||
|
manifest.elements.push_back(std::move(element));
|
||||||
|
}
|
||||||
|
|
||||||
updateProfile(manifest.build(store));
|
updateProfile(manifest.build(store));
|
||||||
}
|
}
|
||||||
|
@ -407,8 +400,8 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
|
||||||
|
|
||||||
auto matchers = getMatchers(store);
|
auto matchers = getMatchers(store);
|
||||||
|
|
||||||
// FIXME: code duplication
|
std::vector<std::shared_ptr<Installable>> installables;
|
||||||
std::vector<DerivedPath> pathsToBuild;
|
std::vector<size_t> indices;
|
||||||
|
|
||||||
auto upgradedCount = 0;
|
auto upgradedCount = 0;
|
||||||
|
|
||||||
|
@ -423,32 +416,30 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
|
||||||
Activity act(*logger, lvlChatty, actUnknown,
|
Activity act(*logger, lvlChatty, actUnknown,
|
||||||
fmt("checking '%s' for updates", element.source->attrPath));
|
fmt("checking '%s' for updates", element.source->attrPath));
|
||||||
|
|
||||||
InstallableFlake installable(
|
auto installable = std::make_shared<InstallableFlake>(
|
||||||
this,
|
this,
|
||||||
getEvalState(),
|
getEvalState(),
|
||||||
FlakeRef(element.source->originalRef),
|
FlakeRef(element.source->originalRef),
|
||||||
"",
|
"",
|
||||||
{element.source->attrPath},
|
Strings{element.source->attrPath},
|
||||||
{},
|
Strings{},
|
||||||
lockFlags);
|
lockFlags);
|
||||||
|
|
||||||
auto [attrPath, resolvedRef, drv] = installable.toDerivation();
|
auto [attrPath, resolvedRef, drv] = installable->toDerivation();
|
||||||
|
|
||||||
if (element.source->resolvedRef == resolvedRef) continue;
|
if (element.source->resolvedRef == resolvedRef) continue;
|
||||||
|
|
||||||
printInfo("upgrading '%s' from flake '%s' to '%s'",
|
printInfo("upgrading '%s' from flake '%s' to '%s'",
|
||||||
element.source->attrPath, element.source->resolvedRef, resolvedRef);
|
element.source->attrPath, element.source->resolvedRef, resolvedRef);
|
||||||
|
|
||||||
if (!drv.outPath)
|
|
||||||
throw UnimplementedError("CA derivations are not yet supported by 'nix profile'");
|
|
||||||
element.storePaths = {*drv.outPath}; // FIXME
|
|
||||||
element.source = ProfileElementSource{
|
element.source = ProfileElementSource{
|
||||||
installable.flakeRef,
|
installable->flakeRef,
|
||||||
resolvedRef,
|
resolvedRef,
|
||||||
attrPath,
|
attrPath,
|
||||||
};
|
};
|
||||||
|
|
||||||
pathsToBuild.push_back(DerivedPath::Built{drv.drvPath, {drv.outputName}});
|
installables.push_back(installable);
|
||||||
|
indices.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +456,13 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
|
||||||
warn ("Use 'nix profile list' to see the current profile.");
|
warn ("Use 'nix profile list' to see the current profile.");
|
||||||
}
|
}
|
||||||
|
|
||||||
store->buildPaths(pathsToBuild);
|
auto builtPaths = Installable::build(getEvalStore(), store, Realise::Outputs, installables, bmNormal);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < installables.size(); ++i) {
|
||||||
|
auto & installable = installables.at(i);
|
||||||
|
auto & element = manifest.elements[indices.at(i)];
|
||||||
|
element.updateStorePaths(getEvalStore(), store, *installable);
|
||||||
|
}
|
||||||
|
|
||||||
updateProfile(manifest.build(store));
|
updateProfile(manifest.build(store));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,11 @@ cat > $flake1Dir/flake.nix <<EOF
|
||||||
echo Hello \${builtins.readFile ./who}
|
echo Hello \${builtins.readFile ./who}
|
||||||
EOF
|
EOF
|
||||||
chmod +x \$out/bin/hello
|
chmod +x \$out/bin/hello
|
||||||
|
echo DONE
|
||||||
'';
|
'';
|
||||||
|
__contentAddressed = import ./ca.nix;
|
||||||
|
outputHashMode = "recursive";
|
||||||
|
outputHashAlgo = "sha256";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -30,6 +34,7 @@ EOF
|
||||||
|
|
||||||
printf World > $flake1Dir/who
|
printf World > $flake1Dir/who
|
||||||
printf 1.0 > $flake1Dir/version
|
printf 1.0 > $flake1Dir/version
|
||||||
|
printf false > $flake1Dir/ca.nix
|
||||||
|
|
||||||
cp ./config.nix $flake1Dir/
|
cp ./config.nix $flake1Dir/
|
||||||
|
|
||||||
|
@ -66,3 +71,17 @@ nix profile diff-closures | grep 'Version 3 -> 4'
|
||||||
# Test wipe-history.
|
# Test wipe-history.
|
||||||
nix profile wipe-history
|
nix profile wipe-history
|
||||||
[[ $(nix profile history | grep Version | wc -l) -eq 1 ]]
|
[[ $(nix profile history | grep Version | wc -l) -eq 1 ]]
|
||||||
|
|
||||||
|
# Test upgrade to CA package.
|
||||||
|
printf true > $flake1Dir/ca.nix
|
||||||
|
printf 3.0 > $flake1Dir/version
|
||||||
|
nix profile upgrade --extra-experimental-features ca-derivations 0
|
||||||
|
nix profile history | grep "packages.$system.default: 1.0 -> 3.0"
|
||||||
|
|
||||||
|
# Test new install of CA package.
|
||||||
|
nix profile remove 0
|
||||||
|
printf 4.0 > $flake1Dir/version
|
||||||
|
printf Utrecht > $flake1Dir/who
|
||||||
|
nix profile install --extra-experimental-features ca-derivations $flake1Dir
|
||||||
|
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello Utrecht" ]]
|
||||||
|
[[ $(nix path-info --json $(realpath $TEST_HOME/.nix-profile/bin/hello) | jq -r .[].ca) =~ fixed:r:sha256: ]]
|
||||||
|
|
Loading…
Reference in a new issue