zhaofengli / colmena

A simple, stateless NixOS deployment tool
https://colmena.cli.rs
MIT License
1.23k stars 66 forks source link

Add plan/diff command #64

Open scvalex opened 2 years ago

scvalex commented 2 years ago

A plan or diff-current-to-next command would be useful to have.

We can get something pretty close already by combining colmena and nix-diff:

$ colmena build --on laptop
[INFO ] Using configuration: ./deployment.nix
[INFO ] Enumerating nodes...
[INFO ] Selected 1 out of 5 hosts.
       ✅ 11s All done!
laptop ✅ 10s Evaluated laptop
laptop ✅ 1s Built "/nix/store/r829pyjngqxmn7k1j9j39w3rcaarg2d1-nixos-system-laptop-21.11pre-git"

$ nix-diff --color always --character-oriented /var/run/current-system /nix/store/r829pyjngqxmn7k1j9j39w3rcaarg2d1-nixos-system-laptop-21.11pre-git | less -R

Screenshot_20220311_110918

There are a few problems with the above:

If you're interested in a feature like this, I'd be up for rewriting nix-diff as a rust library and trying to integrate it into colmena.

bjornfor commented 2 years ago

Nix itself has a related command: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-profile-diff-closures.html

scvalex commented 2 years ago

That is a very neat command.

On my system, I get something like this:

$ nix profile diff-closures --profile /nix/var/nix/profiles/system
...
Version 123 -> 124:

Version 124 -> 125:

Version 125 -> 126:
  chromium: 98.0.4758.102 → 99.0.4844.51
  chromium-unwrapped: 98.0.4758.102 → 99.0.4844.51, -2113.2 KiB
  cpupower: 5.10.102 → 5.10.103
  firefox: 97.0.1 → 97.0.2
  firefox-unwrapped: 97.0.1 → 97.0.2, -1489.6 KiB
  initrd-linux: 5.10.102 → 5.10.103
  linux: 5.10.102, 5.10.102-modules → 5.10.103, 5.10.103-modules, +18.4 KiB
  nix-diff: ∅ → 1.0.16, +2257.7 KiB
  signal-desktop: 5.31.1 → 5.33.0, +12308.2 KiB
  thunderbird: 91.6.1 → 91.6.2
  thunderbird-unwrapped: 91.6.1 → 91.6.2, +8.5 KiB
  zfs-kernel: 2.1.2-5.10.102 → 2.1.2-5.10.103

That's very user-friendly, but it doesn't show some changes. The 124 -> 125 update was a change to networking.hosts, but it shows up as empty in the diff-closures output.

For my tastes, I think nix-diff shows too much output, but nix profile dif-closures shows too little output.

blaggacao commented 2 years ago

nix-diff would benefit greatly from a semantic differ, not only on the nix level, but also on the major config language levels, with json & xml as a minimum.

When using nix-diff that was the biggest pain point.

In terms of evaluation, maybe https://github.com//kamadorueda/nixel is useful.

In terms of semantic differ, for json I only know nixpkgs#jd-diff, which iirc is written on Go. On the xml side maybe there are a couple of libraries laying around.

For semantic diffing, we'd also need to peak at the data at hand, which doesn't sound great for performance, but also the only option since config strings aren't typed in nixpkgs (why?).

All in all, I'd be very interested in this feature / library.

I might have good use for the planned rust cli for divnix/std.

https://github.com/josephburnett/jd/tree/master/lib

vincentbernat commented 1 year ago

With NixOps, I was using:

  system.activationScripts.diff = ''
    PATH=$PATH:${config.nix.package}/bin \
      ${pkgs.nvd}/bin/nvd diff /run/current-system "$systemConfig"
  '';

However, the activation output is hidden by Colmena.

justinas commented 1 year ago

With NixOps, I was using:

However, the activation output is hidden by Colmena.

I am using an equivalent snippet. You must run Colmena with the -v flag to get activation output, e.g. colmena apply --on foobar -v. Although a flag to make it verbose during activation but not build would be cool I guess!