-
-
Notifications
You must be signed in to change notification settings - Fork 14.5k
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
Introduce mkBinaryCache function #194345
Introduce mkBinaryCache function #194345
Conversation
What was the reasoning there? I've used sqlite on readonly-mounted devices before. You might have to disable locking, which means promising that nothing else has read-write access to the same database. |
You're right that SQLite can operate in that mode, but it's not really viable when you're talking about mounting the main store of the CI machine which is busily building other things. FWIW, I did come up with one (fragile and intricate) solution where you manually create a writable overlay filesystem on There is probably also the possibility for weirdness because IIRC Nix sometimes creates store paths while performing apparently side-effect-free operations, which would not work on the read-only mount--I'm not sure if this is a possibility when the store is being used as a substituter. Lastly I forgot to mention, but there were also other problems with read-only mounts, like the one I described in the linked issue. I spent a while trying to hack Nix to operate in a read-only mode where it wouldn't try to do things like |
I tried that too at one point and got pretty much the same results. It is pretty weird how insistent Nix is about being able to write to |
Indeed haha our beautiful pure functional abstraction is built on a thing that loves to randomly Any chance you'd be willing to review this? |
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.
Overall I guess I'm a bit unclear on the use case for this being in nixpkgs... you've put it into build-support
, but nothing in nixpkgs uses it in order to build any packages. Is there some future package, to be in nixpkgs, which needs this in order to support its build? The use case mentioned at the top of the PR talks about a CI system, but presumably that is site-specific to your organization, right?
I'm also a bit unsure about the use of recursive nix (although it is not IFD/EBEB) and the assumptions about the (AFAICT undocumented/unspecified) structure of narinfo files.
pkgs/build-support/binary-cache.nix
Outdated
finalXzFile = "nar/" + fileHash + ".nar.xz" | ||
os.rename(xzFile, finalXzFile) | ||
|
||
with open(narInfoHash + ".narinfo", "w") as f: |
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.
Isn't there some way to get nix to create the narinfo?
AFAICT the file format isn't specified anywhere, so if it changes this won't get updated...
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.
Not that I'm aware of, but I'd love to find one. It seems pretty ad-hoc, look at this CGI script in nix-binary-cache
:
echo "StorePath: $path" |
What was the failure? If |
The argument is just that this is a useful function, for working with a "core" Nix functionality, which ought to be generally available.
I wouldn't call it recursive nix -- it uses
I found |
But is it useful to nixpkgs? Nixpkgs is (a) a collection of expressions for building software and (b) Nix subroutines needed by (a). If there is some software you want to package within nixpkgs that needs this subroutine, it would be a great idea to include it with the PR which adds that software package. |
I would say definitely! A Nix binary cache is a perfectly valid kind of software that I might want to build. It is an end goal in itself, if you're trying to work with Nix substituters. For a close analogy of something already in Nixpkgs, consider Since Nix binary caches are a native part of the Nix ecosystem, Nixpkgs seems like a very natural place to add support. |
Without having read the whole thread: this has the same issues as |
I don't think so. This PR doesn't involve This PR doesn't try to separate the DB from the store paths and then restore the store paths using substituters. As you noted in #123943, that's what caused the problems. |
In fact, this PR does exactly what @roberth said all uses of
That's what this PR does. And it is packaged in a way that makes it impossible to not do this. So it does appear as if this is less footgun-prone than |
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.
- Needs a test; perhaps a NixOS VM test?
- Needs documentation in the Nixpkgs manual.
Okay, I've taken a stab at documentation. I'm having a little trouble adding a NixOS test, because the VM environment seems not to having a working However, I'm finding that |
A channel can be set up by importing Suppose you want to build |
That helped, thanks! I'm having trouble with the |
You could use |
Okay, got a working VM test! |
d8302c8
to
1b13d9a
Compare
Friendly ping @roberth, I think this is ready to go! |
@roberth just checking in again, think we can merge this? Thanks! |
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.
Sorry for the delay. Could you try the suggestions? Otherwise lgtm!
|
Oh, no, no, no, no, no. That's not right. You do need to update your system
|
Sure -- would that be I'm having some trouble applying your suggestions above. Both cause the tests to fail in slightly different ways. Error messages are below. I have no idea why these cause failures, maybe the code this is based on has to be just so. Help? Suggestion 1: Use nativeBuildInputs/buildCommand instead of PATH/buildermachine # building '/nix/store/x30m3rvz7j39imcm6i25mf444kiavlbp-acl-2.3.1.tar.gz.drv'...
machine # warning: error: unable to download 'https://mirror.easyname.at/nongnu/acl/acl-2.3.1.tar.gz': Couldn't resolve host name (6); retrying in 288 ms
machine # warning: error: unable to download 'https://mirror.easyname.at/nongnu/acl/acl-2.3.1.tar.gz': Couldn't resolve host name (6); retrying in 603 ms
machine # warning: error: unable to download 'https://mirror.easyname.at/nongnu/acl/acl-2.3.1.tar.gz': Couldn't resolve host name (6); retrying in 1412 ms
machine # warning: error: unable to download 'https://mirror.easyname.at/nongnu/acl/acl-2.3.1.tar.gz': Couldn't resolve host name (6); retrying in 2016 ms
machine # error: unable to download 'https://mirror.easyname.at/nongnu/acl/acl-2.3.1.tar.gz': Couldn't resolve host name (6)
machine # error: builder for '/nix/store/x30m3rvz7j39imcm6i25mf444kiavlbp-acl-2.3.1.tar.gz.drv' failed with exit code 1
machine # error: 1 dependencies of derivation '/nix/store/1aq767kvk0v8s7z7rvbc6ymlnxrpf85f-acl-2.3.1.drv' failed to build
machine # building '/nix/store/c99ihlhb2lh875spzsl6rnc4058grxvn-autoconf-2.71.tar.xz.drv'...
machine # error: 1 dependencies of derivation '/nix/store/5b0mvjy9yqhphn6jf7hz2lrxqrdcfgb9-libarchive-3.6.1.drv' failed to build Suggestion 2: stdenv -> stdenvNoCCmachine # warning: error: unable to download 'http://tarballs.nixos.org/stdenv-linux/x86_64/c5aabb0d603e2c1ea05f5a93b3be82437f5ebf31/bootstrap-tools.tar.xz': Couldn't resolve host name (6); retrying in 337 ms
machine # warning: error: unable to download 'http://tarballs.nixos.org/stdenv-linux/x86_64/c5aabb0d603e2c1ea05f5a93b3be82437f5ebf31/bootstrap-tools.tar.xz': Couldn't resolve host name (6); retrying in 648 ms
machine # warning: error: unable to download 'http://tarballs.nixos.org/stdenv-linux/x86_64/c5aabb0d603e2c1ea05f5a93b3be82437f5ebf31/bootstrap-tools.tar.xz': Couldn't resolve host name (6); retrying in 1407 ms
machine # [ 37.506805] systemd[1]: Started Logrotate Service.
machine # [ 37.531086] systemd[1]: logrotate.service: Deactivated successfully.
machine # warning: error: unable to download 'http://tarballs.nixos.org/stdenv-linux/x86_64/c5aabb0d603e2c1ea05f5a93b3be82437f5ebf31/bootstrap-tools.tar.xz': Couldn't resolve host name (6); retrying in 2556 ms
machine # error: unable to download 'http://tarballs.nixos.org/stdenv-linux/x86_64/c5aabb0d603e2c1ea05f5a93b3be82437f5ebf31/bootstrap-tools.tar.xz': Couldn't resolve host name (6)
machine # error: builder for '/nix/store/bzq60ip2z5xgi7jk6jgdw8cngfiwjrcm-bootstrap-tools.tar.xz.drv' failed with exit code 1 |
4599370
to
7d33f88
Compare
I just rebased everything on master and force pushed, including your two suggestions @roberth. So on the current branch the tests fail on |
Ok, back from a deep rabbit hole that included improving the |
7d33f88
to
1c4768e
Compare
1c4768e
to
d1a2a16
Compare
Okay, squashed and rebased again. Sorry for the noise all. |
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.
Docs look very good! As always, only cosmetic comments. :)
|
||
Nix packages are most commonly shared between machines using [HTTP, SSH, or S3](https://nixos.org/manual/nix/stable/package-management/sharing-packages.html), but a flat-file binary cache can still be useful in some situations. For example, you can copy it directly to another machine, or make it available on a network file system. It can also be a convenient way to make some Nix packages available inside a container via bind-mounting. | ||
|
||
Note that this function is meant for advanced use-cases. The more idiomatic way to work with flat-file binary caches is via the [nix-copy-closure](https://nixos.org/manual/nix/stable/command-ref/nix-copy-closure.html) command. You may also want to consider [dockerTools](#sec-pkgs-dockerTools) for your containerization needs. |
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.
Note that this function is meant for advanced use-cases. The more idiomatic way to work with flat-file binary caches is via the [nix-copy-closure](https://nixos.org/manual/nix/stable/command-ref/nix-copy-closure.html) command. You may also want to consider [dockerTools](#sec-pkgs-dockerTools) for your containerization needs. | |
Note that this function is meant for advanced use-cases. The more idiomatic way to work with flat-file binary caches is via the [`nix-copy-closure`](https://nixos.org/manual/nix/stable/command-ref/nix-copy-closure.html) command. You may also want to consider [`dockerTools`](#sec-pkgs-dockerTools) for your containerization needs. |
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 actually looks worse when rendered because the links no longer render as blue, so you can't easily tell it's a link.
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.
That's a problem to be solved in CSS. The source should have rich semantics regardless of the representation du jour. Making things inline code tells the reader it's a code token and not some weird jargon term or other proper name.
Has the time come at last @roberth? 😃 I know we discussed using the new self-contained outputs thing here, but at this point the PR has been open for so long I'd love to get it merged and pursue future improvements in a subsequent PR. |
Description of changes
This introduces a new function
mkBinaryCache
which can be used to construct a flat-file binary cache (i.e. one you can use with thefile://
prefix) from a derivation. It's inspired by theclosureInfo
function and uses the same techniques to construct.narinfo
files.My use-case that I'd like to test Nix builds in a containerized CI environment, without downloading a bunch of stuff on every pipeline run. Thus, I want to make a binary cache of some kind available inside the container. The most efficient way to do this is with a bind-mount.
Initially I tried just mounting
/nix/store
to a path on the container, but I soon ran into a problem: you can either mount read/write, in which case the container might potentially mess with the integrity of the store, especially when run as root. Or, you can mount read-only, in which case you run into NixOS/nix#6835. Some discussion on the Nix hackers Matrix channel showed that mounting the store read-only is unlikely to be solvable because of how the Sqlite DB works.So, making a flat-file binary cache and then bind-mounting it seemed like the best approach. I initially tried just running
nix copy
inside a derivation but that didn't work well, so I came up with this function.Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)nixos/doc/manual/md-to-db.sh
to update generated release notes