Add nix store import and nix store export commands#9474
Add nix store import and nix store export commands#9474thufschmitt wants to merge 2 commits intoNixOS:masterfrom
nix store import and nix store export commands#9474Conversation
Fix NixOS#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.
f53a23c to
1a3c322
Compare
nix store import and nix store export commandsnix store import and nix store export commands
roberth
left a comment
There was a problem hiding this comment.
Did a bit of digging to help with naming and documentation.
This should have a page in the protocols section of the manual. Basic info:
Framing protocol
A binary protocol for a stream of store objects. It has framing which does not allow trivial concatenation of streams - the end of stream marker would have to be stripped from the input streams.
Contents:
- no magic bytes in
- unit64
00 00 00 00 00 00 00 00indicates end of stream - uint64
01 00 00 00 00 00 00 00indicates that a store object follows
Store object
Can not be differentiated from a NAR, except by checking whether the stream ends after the NAR has been parsed.
- no magic bytes
- a NAR
- other fields (details tbd)
NAR
NAR has magic bytes. Currently only the nix-archive-1 format exists.
src/nix/store-import.cc
Outdated
|
|
||
| StorePathSet pathsAsSet; | ||
| pathsAsSet.insert(storePaths.begin(), storePaths.end()); | ||
| FdSink sink(STDOUT_FILENO); |
There was a problem hiding this comment.
I think that in that case we don't really care about the progress bar as it's not expected that the thing will be printed on the terminal (because it's a binary blob).
However, we should probably not print anything if stdout is a tty. I'll see to that
There was a problem hiding this comment.
I've made it barf when trying to write to a tty, unless explicitly requested
| )", | ||
| .labels = {"format"}, | ||
| .handler = {[&](std::string_view arg) { | ||
| if (arg == "binary") |
There was a problem hiding this comment.
Ideally the format identifier is usable out of context, because it's more recognizable and searchable that way.
E.g.
| if (arg == "binary") | |
| if (arg == "nix-store-object-stream-0") |
thought: For version 1 it would be wise to add magic bytes. That would bring it up to NAR level, which has nix-archive-1 for magic.
There was a problem hiding this comment.
Erk, I really wouldn't want to have to write nix store export --format nix-store-object-stream-0 😬 (at least not if there's no alternative)
There was a problem hiding this comment.
Maybe binary should be an alias for this format name, at which point we're almost full circle. I think that's good?
There was a problem hiding this comment.
We could lay groundwork to be able to say in the future something like --format binary --format-version 1 (default to latest). But I agree with @roberth that there should be a "fancy" or fully-qualified, distinctive name that is easy to find when one needs to figure things out.
There was a problem hiding this comment.
Well, we can add that, but isn't that vastly overkill and confusing for something that we most likely won't want to evolve? We might add new formats, which is why we settled on having this --format parameter, but if we ever add another one, that'll most likely be something totally different. And I really don't see anyone willing to pass --format nix-store-object-stream-0
There was a problem hiding this comment.
I can imagine this, but actually we can add the behavior I proposed exactly when needed. Therefore nevermind.
| StorePathSet pathsAsSet; | ||
| pathsAsSet.insert(storePaths.begin(), storePaths.end()); | ||
| FdSink sink(STDOUT_FILENO); | ||
| store->exportPaths(pathsAsSet, sink); |
There was a problem hiding this comment.
Now that we've named the protocol, we can mention it in the exportPaths method's header, and link to the manual.
Allow specifying a file in `nix store export` and `nix store import`. Also refuse to write binary things to the terminal unless explicitly asked to.
|
IMHO we should not have the import/export format in the new CLI at all. It's poorly designed (see #3183 (comment)), not extensible, currently broken (in that it doesn't forward CA fields and signatures), and AFAIK nobody uses it anymore. This to me is a great example of historical cruft in the old CLI that we should not carry forward into the new CLI. |
| * 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 |
There was a problem hiding this comment.
This suggests that the output is a tarball, which is not the case.
I would be totally fine with it. This leaves us with two options:
I'd be in favour of 1., and only do 2. lazily if people ask for it (or even just let people implement it if they feel like it) |
|
Is it possible (from CLI) to export/import a single pair of |
I suppose the functionality is the format being a simple byte stream, which can be handled more freely than
The zip header is a blessing and a curse. It's only at the end, so you have to first store the whole thing in a non-final way before you have the necessary info to put it into a store properly. Not great for importing. A tar of individually compressed files would be pretty good. Actually a tar of a binary cache directory would give you that. There's your version 2 binary format ;)
If we're going to do new format, we'd better start from the bottom.
|
Not in one go, but |
|
If it cannot be reimported, it doesn't provide the valuable part of |
|
@thufschmitt I agree with lazily doing option 2. We can (eventually) add these commands when somebody comes up with a better closure serialization format. |
This is a loss of functionality; for a closure one can tar/dat/whatever a |
|
Another protocol that solves the extensibility problem is half a version handshake and then The quality of this solution exist in a superposition of pretty ok and absolutely terrible. Not sure. |
|
Hey! Just spoke w/ @tomberek about the lack of Our use-case is leveraging a OCI (read: OCI container image registry) to upload NAR files (ref: oras.land), and thus sharing/distributing/caching builds. @Reasonable-Solutions can perhaps expand a bit more on this/explain why this is a route that we're following (I cannot) =) |
Motivation
The only thing that the issue didn't precise is how we should call the
current (
nix-store --export) format1. I've settled tobinaryby lackof something better.
Context
Fix #9038
Priorities
Add 👍 to pull requests you find important.
Footnotes
The issue mentions
--format tar, but this is whishful thinkingfor the future, the current format isn't
tar-based at all. ↩