mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Merge pull request #10915 from NixOS/dummy-memory
Use `MemorySourceAccessor` in `DummyStore` so writes work
This commit is contained in:
commit
3eb223f4bb
6 changed files with 117 additions and 49 deletions
|
|
@ -1,5 +1,6 @@
|
|||
#include "nix/store/store-open.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
#include "nix/store/dummy-store.hh"
|
||||
#include "nix/fetchers/fetch-settings.hh"
|
||||
#include "nix/fetchers/fetchers.hh"
|
||||
#include "nix/fetchers/git-utils.hh"
|
||||
|
|
@ -179,10 +180,11 @@ TEST_F(GitTest, submodulePeriodSupport)
|
|||
// 6) Commit the addition in super
|
||||
commitAll(super.get(), "Add submodule with branch='.'");
|
||||
|
||||
// TODO: Use dummy:// store with MemorySourceAccessor.
|
||||
Path storeTmpDir = createTempDir();
|
||||
auto storeTmpDirAutoDelete = AutoDelete(storeTmpDir, true);
|
||||
ref<Store> store = openStore(storeTmpDir);
|
||||
auto store = [] {
|
||||
auto cfg = make_ref<DummyStoreConfig>(StoreReference::Params{});
|
||||
cfg->readOnly = false;
|
||||
return cfg->openStore();
|
||||
}();
|
||||
|
||||
auto settings = fetchers::Settings{};
|
||||
auto input = fetchers::Input::fromAttrs(
|
||||
|
|
|
|||
|
|
@ -1,48 +1,17 @@
|
|||
#include "nix/store/store-registration.hh"
|
||||
#include "nix/util/archive.hh"
|
||||
#include "nix/util/callback.hh"
|
||||
#include "nix/util/memory-source-accessor.hh"
|
||||
#include "nix/store/dummy-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct DummyStoreConfig : public std::enable_shared_from_this<DummyStoreConfig>, virtual StoreConfig
|
||||
std::string DummyStoreConfig::doc()
|
||||
{
|
||||
using StoreConfig::StoreConfig;
|
||||
|
||||
DummyStoreConfig(std::string_view scheme, std::string_view authority, const Params & params)
|
||||
: StoreConfig(params)
|
||||
{
|
||||
if (!authority.empty())
|
||||
throw UsageError("`%s` store URIs must not contain an authority part %s", scheme, authority);
|
||||
}
|
||||
|
||||
static const std::string name()
|
||||
{
|
||||
return "Dummy Store";
|
||||
}
|
||||
|
||||
static std::string doc()
|
||||
{
|
||||
return
|
||||
return
|
||||
#include "dummy-store.md"
|
||||
;
|
||||
}
|
||||
|
||||
static StringSet uriSchemes()
|
||||
{
|
||||
return {"dummy"};
|
||||
}
|
||||
|
||||
ref<Store> openStore() const override;
|
||||
|
||||
StoreReference getReference() const override
|
||||
{
|
||||
return {
|
||||
.variant =
|
||||
StoreReference::Specified{
|
||||
.scheme = *uriSchemes().begin(),
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
;
|
||||
}
|
||||
|
||||
struct DummyStore : virtual Store
|
||||
{
|
||||
|
|
@ -50,9 +19,12 @@ struct DummyStore : virtual Store
|
|||
|
||||
ref<const Config> config;
|
||||
|
||||
ref<MemorySourceAccessor> contents;
|
||||
|
||||
DummyStore(ref<const Config> config)
|
||||
: Store{*config}
|
||||
, config(config)
|
||||
, contents(make_ref<MemorySourceAccessor>())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -80,8 +52,8 @@ struct DummyStore : virtual Store
|
|||
unsupported("addToStore");
|
||||
}
|
||||
|
||||
virtual StorePath addToStoreFromDump(
|
||||
Source & dump,
|
||||
StorePath addToStoreFromDump(
|
||||
Source & source,
|
||||
std::string_view name,
|
||||
FileSerialisationMethod dumpMethod = FileSerialisationMethod::NixArchive,
|
||||
ContentAddressMethod hashMethod = FileIngestionMethod::NixArchive,
|
||||
|
|
@ -89,7 +61,45 @@ struct DummyStore : virtual Store
|
|||
const StorePathSet & references = StorePathSet(),
|
||||
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
|
||||
|
|
@ -105,7 +115,7 @@ struct DummyStore : virtual Store
|
|||
|
||||
virtual ref<SourceAccessor> getFSAccessor(bool requireValidPath) override
|
||||
{
|
||||
return makeEmptySourceAccessor();
|
||||
return this->contents;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ R"(
|
|||
|
||||
**Store URL format**: `dummy://`
|
||||
|
||||
This store type represents a store that contains no store paths and
|
||||
cannot be written to. It's useful when you want to use the Nix
|
||||
evaluator when no actual Nix store exists, e.g.
|
||||
This store type represents a store in memory.
|
||||
Store objects can be read and written, but only so long as the store is open.
|
||||
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
|
||||
# nix eval --store dummy:// --expr '1 + 2'
|
||||
|
|
|
|||
50
src/libstore/include/nix/store/dummy-store.hh
Normal file
50
src/libstore/include/nix/store/dummy-store.hh
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#include "nix/store/store-api.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct DummyStoreConfig : public std::enable_shared_from_this<DummyStoreConfig>, virtual StoreConfig
|
||||
{
|
||||
using StoreConfig::StoreConfig;
|
||||
|
||||
DummyStoreConfig(std::string_view scheme, std::string_view authority, const Params & params)
|
||||
: StoreConfig(params)
|
||||
{
|
||||
if (!authority.empty())
|
||||
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()
|
||||
{
|
||||
return "Dummy Store";
|
||||
}
|
||||
|
||||
static std::string doc();
|
||||
|
||||
static StringSet uriSchemes()
|
||||
{
|
||||
return {"dummy"};
|
||||
}
|
||||
|
||||
ref<Store> openStore() const override;
|
||||
|
||||
StoreReference getReference() const override
|
||||
{
|
||||
return {
|
||||
.variant =
|
||||
StoreReference::Specified{
|
||||
.scheme = *uriSchemes().begin(),
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace nix
|
||||
|
|
@ -34,6 +34,7 @@ headers = [ config_pub_h ] + files(
|
|||
'derived-path-map.hh',
|
||||
'derived-path.hh',
|
||||
'downstream-placeholder.hh',
|
||||
'dummy-store.hh',
|
||||
'export-import.hh',
|
||||
'filetransfer.hh',
|
||||
'gc-store.hh',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include "nix/util/source-path.hh"
|
||||
#include "nix/util/fs-sink.hh"
|
||||
#include "nix/util/variant-wrapper.hh"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue