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? |
ghost
left a comment
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
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:
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 |
roberth
left a comment
There was a problem hiding this comment.
- 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! |
roberth
left a comment
There was a problem hiding this comment.
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 buildSuggestion 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. |
fricklerhandwerk
left a comment
There was a problem hiding this comment.
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.
| 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.
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.
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
mkBinaryCachewhich 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 theclosureInfofunction and uses the same techniques to construct.narinfofiles.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/storeto 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 copyinside a derivation but that didn't work well, so I came up with this function.Things done
sandbox = trueset 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.shto update generated release notes