mirror of
https://github.com/NixOS/nix
synced 2024-10-18 00:16:11 -04:00
Merge 3929d27ea4
into ab0f9f9089
This commit is contained in:
commit
d2db8c0ad4
14
doc/manual/rl-next/nix-store-import-export.md
Normal file
14
doc/manual/rl-next/nix-store-import-export.md
Normal 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
15
src/nix/store-export.md
Normal 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).
|
||||
)""
|
134
src/nix/store-import.cc
Normal file
134
src/nix/store-import.cc
Normal file
|
@ -0,0 +1,134 @@
|
|||
#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"
|
||||
;
|
||||
}
|
||||
|
||||
std::optional<Path> outputFile = std::nullopt;
|
||||
|
||||
CmdStoreExport()
|
||||
{
|
||||
addFlag({
|
||||
.longName = "output-file",
|
||||
.description = "Write the archive to the given file instead of stdout.",
|
||||
.labels = {"file"},
|
||||
.handler = {&outputFile},
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
auto sink = [&]() -> FdSink {
|
||||
if (outputFile) {
|
||||
if (*outputFile == "-") {
|
||||
return FdSink(STDOUT_FILENO);
|
||||
} else {
|
||||
auto fd = open(outputFile->c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
|
||||
return FdSink(fd);
|
||||
}
|
||||
} else if (isatty(STDOUT_FILENO)) {
|
||||
throw Error("Refusing to write binary data to a terminal. Use `--output-file` to specify a file to write to.");
|
||||
} else {
|
||||
return FdSink(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"
|
||||
;
|
||||
}
|
||||
|
||||
std::optional<Path> inputFile = std::nullopt;
|
||||
|
||||
CmdStoreImport() {
|
||||
addFlag({
|
||||
.longName = "input-file",
|
||||
.description = "Read the archive from the given file instead of stdin.",
|
||||
.labels = {"file"},
|
||||
.handler = {&inputFile},
|
||||
});
|
||||
}
|
||||
|
||||
void run(ref<Store> store) override
|
||||
{
|
||||
FdSource source = [&]() -> FdSource {
|
||||
if (inputFile && *inputFile != "-") {
|
||||
auto fd = open(inputFile->c_str(), O_RDONLY);
|
||||
return FdSource(fd);
|
||||
} else {
|
||||
return FdSource(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
16
src/nix/store-import.md
Normal 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.
|
||||
|
||||
)""
|
|
@ -107,6 +107,7 @@ nix_tests = \
|
|||
completions.sh \
|
||||
impure-derivations.sh \
|
||||
path-from-hash-part.sh \
|
||||
store-import-export.sh \
|
||||
path-info.sh \
|
||||
toString-path.sh \
|
||||
read-only-store.sh \
|
||||
|
|
38
tests/functional/store-import-export.sh
Normal file
38
tests/functional/store-import-export.sh
Normal file
|
@ -0,0 +1,38 @@
|
|||
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
|
||||
|
||||
faketty () {
|
||||
# Run a command in a pseudo-terminal.
|
||||
script -qefc "$(printf "%q " "$@")" /dev/null
|
||||
}
|
||||
|
||||
! faketty nix store export --format binary --recursive $BUILT_STORE_PATHS > /dev/null || \
|
||||
fail "nix store export should refuse to write in a tty by default"
|
||||
faketty nix store export --format binary --recursive $BUILT_STORE_PATHS --output-file - > /dev/null || \
|
||||
fail "nix store export should accept to write in a tty if explicitly asked to"
|
||||
|
||||
nix store export --format binary --recursive $BUILT_STORE_PATHS --output-file "$TEST_ROOT/store-export2"
|
||||
diff "$TEST_ROOT/store-export" "$TEST_ROOT/store-export2" || \
|
||||
fail '`nix store export --output-file blah` should be equivalent to `nix store export > blah`'
|
Loading…
Reference in a new issue