nix-store -q -R $( nix-store -q --deriver /nix/store/any5gh2i9yqbsafs0v6mbapa7412a2jw-nixos-system-foobar-23.05.20230723.ac1acba ) |
xargs nix-store --export > d.nar
then
nix-store -q -R $( nix-store -q --deriver /nix/store/any5gh2i9yqbsafs0v6mbapa7412a2jw-nixos-system-foobar-23.05.20230723.ac1acba ) |
xargs nix-store --export > d.nar
then
Yes, thank you! That worked!
I piped it through gzip:
| xargs nix-store --export | gzip >
and
gunzip --stdout /tmp/importme.nar.gz | nix-store --import
and it imported a lot of /nix/store/...drv
paths.
So now just to figure out how to nixos-rebuilt
into that imported derivation.
First step is nix-store -r /nix/store/[…].drv
Then I think it is /nix/store/any5gh2i9yqbsafs0v6mbapa7412a2jw-nixos-system-foobar-23.05.20230723.ac1acba/bin/switch-to-configuration switch
. I haven’t actually run mainline NixOS in a long time, so I might be mixing up things; I hope you have some path to recover the VM if this messes up the boot…
I’ll test it on a new VM in cloud, so if it blows NixOS, not a big deal. Thank you
I’ve just run it. It took really long time to realize all those derivations but it did finish OK. Unfortunately when I run
find /nix/ -name switch-to-configuration
I get only the Nix store path that the current generation (/nix/var/nix/profiles/system
) is pointing to.
What is the path you have built, where it comes from originally, and what is inside this path?
(I think you have obtained updated software builds, so further experiment should go faster)
Apologize for the late answer and thank you very much for putting up with me.
I tried the whole process again:
out=$(nix build --no-link --print-out-paths .#nixosConfigurations.foobar.config.system.build.toplevel)
out
has /nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c
nix-store -q -R $(nix-store -q --deriver "${out}") | xargs nix-store --export | gzip > /tmp/export.nar.gz
ls -lh /tmp/export.nar.gz
-rw-r--r-- 1 root root 8.2M Aug 2 14:23 /tmp/export.nar.gz
nixos-generate-config
(in other words a very basic system)/nix/store/*.drv
gunzip --stdout /tmp/export.nar.gz | nix-store --import
nix-store -r /nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c.drv
don't know how to build these paths:
/nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c.drv
error: cannot build missing derivation '/nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c.drv'
ls -l /nix/store/*foobar*
ls: cannot access '/nix/store/*foobar*': No such file or directory
switch-to-configuration
is the one that created the initial simple configurationfind /nix/ -name switch-to-configuration
/nix/store/g6jzf8hqqpk6b3c6dz7yvzxfncarqs7s-nixos-system-nixos-23.05.997.ddf4688dc7a/bin/switch-to-configuration
And when you ran nix-store --import
, did it print anything? It should print the paths imported (including nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c.drv
)
Also, nix-store -q --deriver "${out}"
— was the shell environment variable out
set? Your commands don’t show this. What this command prints on its own?
/nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c
(the output of nix build --no-link --print-out-paths .#nixosConfigurations.foobar.config.system.build.toplevel
)
Yes, many nix store paths, but not /nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c
Can you check whether /nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c
was missing from the export (e.g. not in the tarball) or just not imported?
Does the number of imported derivations match the number of derivations in the tarball?
I’ll need to try again to build it / export it / import it - which I’m happy to do but…
This process of exporting tens of derivations is miles away from my initial goal which was to somehow serialize/compile/collapse a large repository with many files with configuration for many hosts into a single file/a few files for a single host. The GZIPed export has 8M which is more than my entire uncompressed source…
Yeah, I was already wondering about that. Have you tried the approach I mentioned above?
With this you would only pack up the flake.nix, flake.lock and the relevant subtree. That solves your trust problem.
Regarding complexity of evaluation: You have to decide which side to take in the trade-off. Push a small config to the target and evaluate on the target or pre-evaluate on a bigger machine and push a bigger intermediate result. If you can communicate with the the target machine you might be able to limit the export to missing store paths, potentially reducing the size of your tarball.
The suggestion to copy files, not the whole repo - I do that since beginning. Very early (probably my mistake) I realized that I can just copy files and I don’t need to copy .git/
. Thank you for that suggestion.
I didn’t follow up about the suggestion using Haumea
. When I started with Nix / NixOS I looked at Haumea
, mkFlake
, mkHome
, Snowfall Lib
and couple of others. I like the approach but I firmly decided to create my own naming / file structure. I like the simplicity of Nix language and I like that I can build my own framework-ish structure rather than using someone’s else idea.
I appreciate the suggestion but I really don’t like these framework-ish projects.
I decided that I’m OK if the target host does all the work and it takes a lot of time. I was slightly worried about memory consumption but I don’t have problem with that even on a cheap $5 VPS. The only problem is that it takes a minute or two to finish the evaluation but that’s OK with me even if the time increases in the future.
What I’m not OK is that I have to ship 100 files (and in future probably more) to the host.
Let’s take an example of a configuration that reads JSON (JSON is in the repo or it is in other repo with flake) that has an array with name, IP and a few options. The flake.nix would then map over the array and generate nixosConfigurations.foo
, nixosConfigurations.bar
… for each host with different name, IP and some configuration based on those few options in the JSON. That configuration would be included / excluded simply by mkIf
.
Such solution can be easily implemented in Nix language and by using flakes and when I call nixos-rebuild --flake .#foo
the Nix compiler has to have some intermediate steps where in some point it will work only on that part of code that works with nixosConfigurations.foo
and that has mkIf true
(not mkIf <some function of variable>
).
The only thing I need is to get that code from that specific step of evaluation and save it as a blob of Nix language that doesn’t have JSON (already read by builtins.fromJSON
), doesn’t have comments, doesn’t have packages."aarch64-linux".hello
since I’m not on ARM and I’m not using hello
package anywhere in the configuration…
But if this is not possible - that’s OK. I can’t have everything. I love Nix anyway .
Thank you.
Just so you know, because of all this trouble, I started a PR that will allow you to simply run nix derivation show -r
and nix derivation add
to transfer all the derivations required by the system configuration in one file and actually read it again.
As long as you can embed all info in derivations (meaning they don’t rely on input sources that you have to copy over manually), this will be the single file solution you’re looking for.
I also didn’t see you mention trying nix-copy-closure
. I linked it above, and you can specify a (wrong, only file://
argument in --to
and zip the resulting folder.nix copy
can do that, and it’s not useful here, see Compile NixOS derivations into a single file for a single host - #48 by iFreilicht.
I’m sorry for troubling you but I’m so happy that you actually want to change the core code to enable this feature. Thank you so much!
So I’m assuming I’ll be able to do something like
nix build --no-link --print-out-paths .#nixosConfigurations.foobar.config.system.build.toplevel
derivation show -r \
/nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c.drv \
> something
and then
nix derivation add < /tmp/something
/nix/store/2z6q5mvh95w4r0swq8b856awkyknn2f6-nixos-system-foobar-23.05.20230731.b7cde1c/bin/switch-to-configuration boot
Let me check it.
THANK YOU!
My pleasure! Nix has a lot of corners like this that you would expect to work but that actually don’t, and I really want to fix those. User-facing features like this are a great opportunity for myself to become more familiar with the code-base and should enable me to make more contributions in the future.
Yes, that’s the idea exactly. As you can see in the PR, I also added documentation for this. You can also try it out yourself already:
$ nix shell github:iFreilicht/nix/enable-derivation-show-add-roundtrip
# This will build nix from source off of my branch, it will take a few minutes
$ nix --version # Just to make sure it's using the right version
nix (Nix) 2.18.0pre20230731_57113a6
$ nix derivation show 'nixpkgs#hello' | nix derivation add # Sanity check
/nix/store/8rgfc52k0529kypam0jy5p1a4jsj4dbq-hello-2.12.1.drv
$ nix derivation show -r $system_foobar > something
$ nix derivation add < something
If this works, doesn’t work, or you have feedback on the docs, feel free to comment on the PR in GitHub. Getting feedback and real-life tests from users on changes like this is very valuable!
Signing up for Github account now!
Hmm, I need to figure out how to do it. I’ll try
nix run github:nixos/nixpkgs/nixos-unstable#nix
No, you have to use the exact command that I posted:
nix shell github:iFreilicht/nix/enable-derivation-show-add-roundtrip
You can also use nix run
, but that seems less convenient.
Just tried it, but the tests fail:
ran test tests/derivation-json.sh... [FAIL]
Huh, that’s not good, that means that test is flaky and potentially not reproducible. Could you give me the rest of the output? Ideally like so:
$ nix log github:iFreilicht/nix/enable-derivation-show-add-roundtrip | sed -n '/derivation-json.sh/,$p'
ran test tests/derivation-json.sh... [FAIL]
...