1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2024-09-19 10:50:24 -04:00

Add a nix store import and nix store export commands

Fix https://github.com/NixOS/nix/issues/9038

The only thing that the issue didn't precise is how we should call the
current (`nix-store --export`) format[^1]. I've settled to `binary` by lack
of something better.

[^1]: The issue mentions `--format tar`, but this is whishful thinking
for the future, the current format isn't `tar`-based at all.
This commit is contained in:
Théophane Hufschmitt 2023-11-27 18:03:58 +01:00
parent f0180487a0
commit 1a3c3224d3
6 changed files with 158 additions and 0 deletions

View file

@ -0,0 +1,14 @@
synopsis: Add `nix store import` and `nix store export`
prs: #9474
issues: #9038
description: {
Added a pair of new commands: [`nix store import`] and [`nix store export`].
[`nix store export`]: @docroot@/command-ref/new-cli/nix3-store-export.md
[`nix store import`]: @docroot@/command-ref/new-cli/nix3-store-import.md
}

15
src/nix/store-export.md Normal file
View file

@ -0,0 +1,15 @@
R""(
# Examples
* Export the closure of a given installable and re-import it in another machine
```console
$ nix store export --recursive --format binary nixpkgs#hello > hello-closure.tar
$ ssh user@otherHost nix store import < hello-closure.tar
```
# Description
This command generates an archive containing the serialisation of *installable*, as well as all the metadata required so that it can be imported with [`nix store import`](@docroot@/command-ref/new-cli/nix3-store-import.md).
)""

88
src/nix/store-import.cc Normal file
View file

@ -0,0 +1,88 @@
#include "command.hh"
#include "store-api.hh"
using namespace nix;
struct MixImportExport : virtual Args
{
enum struct ArchiveFormat
{
Binary,
};
std::optional<ArchiveFormat> format = std::nullopt;
MixImportExport()
{
addFlag(
{.longName = "format",
.description = R"(
Format of the archive.
The only supported format is `binary`, which corresponds to the format used by [`nix-store --export`](@docroot@/command-ref/nix-store/export.md).
)",
.labels = {"format"},
.handler = {[&](std::string_view arg) {
if (arg == "binary")
format = ArchiveFormat::Binary;
else
throw Error("Unknown archive format: %s", arg);
}}});
}
};
struct CmdStoreExport : StorePathsCommand, MixImportExport
{
std::string description() override
{
return "Export the given store path(s) in a way that can be imported by `nix store import`.";
}
std::string doc() override
{
return
#include "store-export.md"
;
}
void run(ref<Store> store, StorePaths && storePaths) override
{
// We don't use the format parameter now, but we still want to enforce it
// being specified to not block us on backwards-compatibility.
if (!format)
throw UsageError("`--format` must be specified");
StorePathSet pathsAsSet;
pathsAsSet.insert(storePaths.begin(), storePaths.end());
FdSink sink(STDOUT_FILENO);
store->exportPaths(pathsAsSet, sink);
sink.flush();
}
};
struct CmdStoreImport : StoreCommand, MixImportExport
{
std::string description() override
{
return "Import the given store path(s) from a file created by `nix store export`.";
}
std::string doc() override
{
return
#include "store-import.md"
;
}
void run(ref<Store> store) override
{
FdSource source(STDIN_FILENO);
auto paths = store->importPaths(source, NoCheckSigs);
for (auto & path : paths)
logger->cout("%s", store->printStorePath(path));
}
};
static auto rStoreExport = registerCommand2<CmdStoreExport>({"store", "export"});
static auto rStoreImport = registerCommand2<CmdStoreImport>({"store", "import"});

16
src/nix/store-import.md Normal file
View file

@ -0,0 +1,16 @@
R""(
# Examples
* Import a closure that has been exported from another machine
```console
$ ssh user@otherHost nix store export --recursive --format binary nixpkgs#hello > hello-closure.tar
$ nix store import < hello-closure.tar
```
# Description
This command reads an archive of store paths, as produced by [`nix store export`](@docroot@/command-ref/new-cli/nix3-store-export.md), and adds it to the store.
)""

View file

@ -121,6 +121,7 @@ nix_tests = \
flakes/show.sh \
impure-derivations.sh \
path-from-hash-part.sh \
store-import-export.sh \
path-info.sh \
toString-path.sh \
read-only-store.sh \

View file

@ -0,0 +1,24 @@
source config.sh
clearStore
BUILT_STORE_PATHS=$(nix build -f ./dependencies.nix input1_drv input2_drv --no-link --print-out-paths | sort)
# Make sure that we require the `--format` argument.
expect 1 nix store export --recursive $BUILT_STORE_PATHS > "$TEST_ROOT/store-export" 2> /dev/null || \
fail "nix store export should require the --format argument"
nix store export --format binary --recursive $BUILT_STORE_PATHS > "$TEST_ROOT/store-export"
clearStore
IMPORTED_STORE_PATHS=$(nix store import < "$TEST_ROOT/store-export" | sort)
# Make sure that the paths we built previously are still valid.
for BUILT_STORE_PATH in $BUILT_STORE_PATHS; do
nix path-info "$BUILT_STORE_PATH" || \
fail "path $BUILT_STORE_PATH should have been imported but isn't valid"
done
# Make sure that all the imported paths are valid.
for IMPORTED_STORE_PATH in $IMPORTED_STORE_PATHS; do
nix path-info "$IMPORTED_STORE_PATH" ||
fail "path $BUILT_STORE_PATH should have been imported but isn't valid"
done