mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +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/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(
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,17 @@
|
||||||
#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"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
struct DummyStoreConfig : public std::enable_shared_from_this<DummyStoreConfig>, virtual StoreConfig
|
std::string DummyStoreConfig::doc()
|
||||||
{
|
{
|
||||||
using StoreConfig::StoreConfig;
|
return
|
||||||
|
|
||||||
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
|
|
||||||
#include "dummy-store.md"
|
#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
|
struct DummyStore : virtual Store
|
||||||
{
|
{
|
||||||
|
|
@ -50,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>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,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,
|
||||||
|
|
@ -89,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
|
||||||
|
|
@ -105,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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
|
||||||
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-map.hh',
|
||||||
'derived-path.hh',
|
'derived-path.hh',
|
||||||
'downstream-placeholder.hh',
|
'downstream-placeholder.hh',
|
||||||
|
'dummy-store.hh',
|
||||||
'export-import.hh',
|
'export-import.hh',
|
||||||
'filetransfer.hh',
|
'filetransfer.hh',
|
||||||
'gc-store.hh',
|
'gc-store.hh',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
///@file
|
||||||
|
|
||||||
#include "nix/util/source-path.hh"
|
#include "nix/util/source-path.hh"
|
||||||
#include "nix/util/fs-sink.hh"
|
#include "nix/util/fs-sink.hh"
|
||||||
#include "nix/util/variant-wrapper.hh"
|
#include "nix/util/variant-wrapper.hh"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue