1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 03:56:01 +01:00

Use MemorySourceAccessor in DummyStore

Add `read-only` setting to `dummy://` store for back compat.

Test by changing an existing test to use this instead, fixing a TODO.

Co-Authored-By: HaeNoe <git@haenoe.party>
Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
This commit is contained in:
John Ericson 2024-06-14 10:54:34 -04:00
parent 168c24b605
commit d5ce8c3caa
4 changed files with 67 additions and 11 deletions

View file

@ -1,5 +1,6 @@
#include "nix/store/store-open.hh" #include "nix/store/store-open.hh"
#include "nix/store/globals.hh" #include "nix/store/globals.hh"
#include "nix/store/dummy-store.hh"
#include "nix/fetchers/fetch-settings.hh" #include "nix/fetchers/fetch-settings.hh"
#include "nix/fetchers/fetchers.hh" #include "nix/fetchers/fetchers.hh"
#include "nix/fetchers/git-utils.hh" #include "nix/fetchers/git-utils.hh"
@ -179,10 +180,11 @@ TEST_F(GitTest, submodulePeriodSupport)
// 6) Commit the addition in super // 6) Commit the addition in super
commitAll(super.get(), "Add submodule with branch='.'"); commitAll(super.get(), "Add submodule with branch='.'");
// TODO: Use dummy:// store with MemorySourceAccessor. auto store = [] {
Path storeTmpDir = createTempDir(); auto cfg = make_ref<DummyStoreConfig>(StoreReference::Params{});
auto storeTmpDirAutoDelete = AutoDelete(storeTmpDir, true); cfg->readOnly = false;
ref<Store> store = openStore(storeTmpDir); return cfg->openStore();
}();
auto settings = fetchers::Settings{}; auto settings = fetchers::Settings{};
auto input = fetchers::Input::fromAttrs( auto input = fetchers::Input::fromAttrs(

View file

@ -1,5 +1,7 @@
#include "nix/store/store-registration.hh" #include "nix/store/store-registration.hh"
#include "nix/util/archive.hh"
#include "nix/util/callback.hh" #include "nix/util/callback.hh"
#include "nix/util/memory-source-accessor.hh"
#include "nix/store/dummy-store.hh" #include "nix/store/dummy-store.hh"
namespace nix { namespace nix {
@ -17,9 +19,12 @@ struct DummyStore : virtual Store
ref<const Config> config; ref<const Config> config;
ref<MemorySourceAccessor> contents;
DummyStore(ref<const Config> config) DummyStore(ref<const Config> config)
: Store{*config} : Store{*config}
, config(config) , config(config)
, contents(make_ref<MemorySourceAccessor>())
{ {
} }
@ -47,8 +52,8 @@ struct DummyStore : virtual Store
unsupported("addToStore"); unsupported("addToStore");
} }
virtual StorePath addToStoreFromDump( StorePath addToStoreFromDump(
Source & dump, Source & source,
std::string_view name, std::string_view name,
FileSerialisationMethod dumpMethod = FileSerialisationMethod::NixArchive, FileSerialisationMethod dumpMethod = FileSerialisationMethod::NixArchive,
ContentAddressMethod hashMethod = FileIngestionMethod::NixArchive, ContentAddressMethod hashMethod = FileIngestionMethod::NixArchive,
@ -56,7 +61,45 @@ struct DummyStore : virtual Store
const StorePathSet & references = StorePathSet(), const StorePathSet & references = StorePathSet(),
RepairFlag repair = NoRepair) override RepairFlag repair = NoRepair) override
{ {
unsupported("addToStore"); if (config->readOnly)
unsupported("addToStoreFromDump");
auto temp = make_ref<MemorySourceAccessor>();
{
MemorySink tempSink{*temp};
// TODO factor this out into `restorePath`, same todo on it.
switch (dumpMethod) {
case FileSerialisationMethod::NixArchive:
parseDump(tempSink, source);
break;
case FileSerialisationMethod::Flat: {
// Replace root dir with file so next part succeeds.
temp->root = MemorySourceAccessor::File::Regular{};
tempSink.createRegularFile(CanonPath::root, [&](auto & sink) { source.drainInto(sink); });
break;
}
}
}
auto hash = hashPath({temp, CanonPath::root}, hashMethod.getFileIngestionMethod(), hashAlgo).first;
auto desc = ContentAddressWithReferences::fromParts(
hashMethod,
hash,
{
.others = references,
// caller is not capable of creating a self-reference, because
// this is content-addressed without modulus
.self = false,
});
auto dstPath = makeFixedOutputPathFromCA(name, desc);
contents->open(CanonPath(printStorePath(dstPath)), std::move(temp->root));
return dstPath;
} }
void narFromPath(const StorePath & path, Sink & sink) override void narFromPath(const StorePath & path, Sink & sink) override
@ -72,7 +115,7 @@ struct DummyStore : virtual Store
virtual ref<SourceAccessor> getFSAccessor(bool requireValidPath) override virtual ref<SourceAccessor> getFSAccessor(bool requireValidPath) override
{ {
return makeEmptySourceAccessor(); return this->contents;
} }
}; };

View file

@ -2,9 +2,11 @@ R"(
**Store URL format**: `dummy://` **Store URL format**: `dummy://`
This store type represents a store that contains no store paths and This store type represents a store in memory.
cannot be written to. It's useful when you want to use the Nix Store objects can be read and written, but only so long as the store is open.
evaluator when no actual Nix store exists, e.g. Once the store is closed, all data will be forgoton.
It's useful when you want to use the Nix evaluator when no actual Nix store exists, e.g.
```console ```console
# nix eval --store dummy:// --expr '1 + 2' # nix eval --store dummy:// --expr '1 + 2'

View file

@ -13,6 +13,15 @@ struct DummyStoreConfig : public std::enable_shared_from_this<DummyStoreConfig>,
throw UsageError("`%s` store URIs must not contain an authority part %s", scheme, authority); throw UsageError("`%s` store URIs must not contain an authority part %s", scheme, authority);
} }
Setting<bool> readOnly{
this,
true,
"read-only",
R"(
Make any sort of write fail instead of succeeding.
No additional memory will be used, because no information needs to be stored.
)"};
static const std::string name() static const std::string name()
{ {
return "Dummy Store"; return "Dummy Store";