Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/nix
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: af7ffe882f2e^
Choose a base ref
...
head repository: NixOS/nix
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e2e6a4651a73
Choose a head ref
  • 8 commits
  • 13 files changed
  • 1 contributor

Commits on May 17, 2021

  1. Always send the realisations as JSON

    Align all the worker protocol with `buildDerivation` which inlines the
    realisations as one opaque json blob.
    That way we don’t have to bother changing the remote store protocol
    when the definition of `Realisation` changes, as long as we keep the
    json backwards-compatible
    thufschmitt committed May 17, 2021
    Copy the full SHA
    af7ffe8 View commit details
  2. Add a dependencies field to DrvOutputInfo

    Currently never used, nor set but will be useful shortly
    thufschmitt committed May 17, 2021
    Copy the full SHA
    ce41fce View commit details
  3. Copy the full SHA
    0c1d9d4 View commit details

Commits on May 19, 2021

  1. Extract a generic computeClosure function

    Move the `closure` logic of `computeFSClosure` to its own (templated)
    function.
    That way we can reuse it for the realisations too
    thufschmitt committed May 19, 2021
    Copy the full SHA
    af83ce9 View commit details
  2. Copy the full SHA
    51704fe View commit details
  3. Add a method to compute the closure of a realisation

    Only considers the closure in term of `Realisation`, ignores all the
    opaque inputs.
    
    Dunno whether that’s the nicest solution, need to think it through a bit
    thufschmitt committed May 19, 2021
    Copy the full SHA
    9ebdcc4 View commit details
  4. Copy the full SHA
    e6b6982 View commit details
  5. Make copyPaths copy the whole realisations closure

    Otherwise registering the realisations on the remote side might fail as
    it now expects a complete closure
    thufschmitt committed May 19, 2021
    Copy the full SHA
    e2e6a46 View commit details
1 change: 1 addition & 0 deletions src/libstore/build/derivation-goal.cc
Original file line number Diff line number Diff line change
@@ -927,6 +927,7 @@ void DerivationGoal::resolvedFinished() {
auto newRealisation = *realisation;
newRealisation.id = DrvOutput{initialOutputs.at(wantedOutput).outputHash, wantedOutput};
newRealisation.signatures.clear();
newRealisation.drvOutputDeps = drvOutputReferences(worker.store, *drv, realisation->outPath);
signRealisation(newRealisation);
worker.store.registerDrvOutput(newRealisation);
} else {
15 changes: 14 additions & 1 deletion src/libstore/ca-specific-schema.sql
Original file line number Diff line number Diff line change
@@ -3,10 +3,23 @@
-- is enabled

create table if not exists Realisations (
id integer primary key autoincrement not null,
drvPath text not null,
outputName text not null, -- symbolic output id, usually "out"
outputPath integer not null,
signatures text, -- space-separated list
primary key (drvPath, outputName),
foreign key (outputPath) references ValidPaths(id) on delete cascade
);

create index if not exists IndexRealisations on Realisations(drvPath, outputName);

create table if not exists RealisationsRefs (
referrer integer not null,
realisationReference integer,
opaquePathReference integer,
foreign key (referrer) references Realisations(id) on delete cascade,
foreign key (realisationReference) references Realisations(id) on delete restrict,
foreign key (opaquePathReference) references ValidPaths(id) on delete restrict,
CHECK ((realisationReference is null AND opaquePathReference is not null)
OR (opaquePathReference is null AND realisationReference is not null))
);
25 changes: 18 additions & 7 deletions src/libstore/daemon.cc
Original file line number Diff line number Diff line change
@@ -885,10 +885,15 @@ static void performOp(TunnelLogger * logger, ref<Store> store,

case wopRegisterDrvOutput: {
logger->startWork();
auto outputId = DrvOutput::parse(readString(from));
auto outputPath = StorePath(readString(from));
store->registerDrvOutput(Realisation{
.id = outputId, .outPath = outputPath});
if (GET_PROTOCOL_MINOR(clientVersion) < 31) {
auto outputId = DrvOutput::parse(readString(from));
auto outputPath = StorePath(readString(from));
store->registerDrvOutput(Realisation{
.id = outputId, .outPath = outputPath});
} else {
auto realisation = worker_proto::read(*store, from, Phantom<Realisation>());
store->registerDrvOutput(realisation);
}
logger->stopWork();
break;
}
@@ -898,9 +903,15 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
auto outputId = DrvOutput::parse(readString(from));
auto info = store->queryRealisation(outputId);
logger->stopWork();
std::set<StorePath> outPaths;
if (info) outPaths.insert(info->outPath);
worker_proto::write(*store, to, outPaths);
if (GET_PROTOCOL_MINOR(clientVersion) < 31) {
std::set<StorePath> outPaths;
if (info) outPaths.insert(info->outPath);
worker_proto::write(*store, to, outPaths);
} else {
std::set<Realisation> realisations;
if (info) realisations.insert(*info);
worker_proto::write(*store, to, realisations);
}
break;
}

88 changes: 76 additions & 12 deletions src/libstore/local-store.cc
Original file line number Diff line number Diff line change
@@ -59,6 +59,10 @@ struct LocalStore::State::Stmts {
SQLiteStmt QueryAllRealisedOutputs;
SQLiteStmt QueryPathFromHashPart;
SQLiteStmt QueryValidPaths;
SQLiteStmt QueryRealisationPathReferences;
SQLiteStmt QueryRealisationRealisationReferences;
SQLiteStmt AddRealisationPathReference;
SQLiteStmt AddRealisationRealisationReference;
};

int getSchema(Path schemaPath)
@@ -316,7 +320,7 @@ LocalStore::LocalStore(const Params & params)
)");
state->stmts->QueryRealisedOutput.create(state->db,
R"(
select Output.path, Realisations.signatures from Realisations
select Realisations.id, Output.path, Realisations.signatures from Realisations
inner join ValidPaths as Output on Output.id = Realisations.outputPath
where drvPath = ? and outputName = ?
;
@@ -328,6 +332,32 @@ LocalStore::LocalStore(const Params & params)
where drvPath = ?
;
)");
state->stmts->QueryRealisationPathReferences.create(state->db,
R"(
select path from ValidPaths
join RealisationsRefs on opaquePathReference = ValidPaths.id
where referrer = ?;
)");
state->stmts->QueryRealisationRealisationReferences.create(state->db,
R"(
select drvPath, outputName from Realisations
join RealisationsRefs on realisationReference = Realisations.id
where referrer = ?;
)");
state->stmts->AddRealisationPathReference.create(state->db,
R"(
insert or replace into RealisationsRefs (referrer, opaquePathReference)
values (
?,
(select id from ValidPaths where path = ?));
)");
state->stmts->AddRealisationRealisationReference.create(state->db,
R"(
insert or replace into RealisationsRefs (referrer, realisationReference)
values (
?,
(select id from Realisations where drvPath = ? and outputName = ?));
)");
}
}

@@ -666,13 +696,22 @@ void LocalStore::registerDrvOutput(const Realisation & info)
settings.requireExperimentalFeature("ca-derivations");
auto state(_state.lock());
retrySQLite<void>([&]() {
state->stmts->RegisterRealisedOutput.use()
(info.id.strHash())
(info.id.outputName)
(printStorePath(info.outPath))
(concatStringsSep(" ", info.signatures))
state->stmts->RegisterRealisedOutput
.use()(info.id.strHash())(info.id.outputName)(printStorePath(
info.outPath))(concatStringsSep(" ", info.signatures))
.exec();
});
uint64_t myId = state->db.getLastInsertedRowId();
for (auto& path : info.opaqueDeps) {
state->stmts->AddRealisationPathReference
.use()(myId)(printStorePath(path))
.exec();
}
for (auto& outputId : info.drvOutputDeps) {
state->stmts->AddRealisationRealisationReference
.use()(myId)(outputId.strHash())(outputId.outputName)
.exec();
}
}

void LocalStore::cacheDrvOutputMapping(State & state, const uint64_t deriver, const string & outputName, const StorePath & output)
@@ -1670,14 +1709,39 @@ std::optional<const Realisation> LocalStore::queryRealisation(
typedef std::optional<const Realisation> Ret;
return retrySQLite<Ret>([&]() -> Ret {
auto state(_state.lock());
auto use(state->stmts->QueryRealisedOutput.use()(id.strHash())(
id.outputName));
if (!use.next())
auto useQueryRealisedOutput(state->stmts->QueryRealisedOutput.use()(
id.strHash())(id.outputName));
if (!useQueryRealisedOutput.next())
return std::nullopt;
auto outputPath = parseStorePath(use.getStr(0));
auto signatures = tokenizeString<StringSet>(use.getStr(1));
auto realisationDbId = useQueryRealisedOutput.getInt(0);
auto outputPath = parseStorePath(useQueryRealisedOutput.getStr(1));
auto signatures =
tokenizeString<StringSet>(useQueryRealisedOutput.getStr(2));

std::set<StorePath> opaqueDeps;
auto usePathRefs(state->stmts->QueryRealisationPathReferences.use()(
realisationDbId));
while (usePathRefs.next())
opaqueDeps.insert(parseStorePath(usePathRefs.getStr(0)));

std::set<DrvOutput> drvOutputDeps;
auto useRealisationRefs(
state->stmts->QueryRealisationRealisationReferences.use()(
realisationDbId));
while (useRealisationRefs.next())
drvOutputDeps.insert(DrvOutput{
Hash::parseAnyPrefixed(useRealisationRefs.getStr(0)),
useRealisationRefs.getStr(1),
}
);

return Ret{Realisation{
.id = id, .outPath = outputPath, .signatures = signatures}};
.id = id,
.outPath = outputPath,
.signatures = signatures,
.opaqueDeps = opaqueDeps,
.drvOutputDeps = drvOutputDeps,
}};
});
}
} // namespace nix
Loading