-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add nix store import
and nix store export
commands
#9474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 00
indicates end of stream - uint64
01 00 00 00 00 00 00 00
indicates 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #9361 (review)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 tobinary
by 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. ↩