Introducing bento, a NixOS deployment framework

Is this asking for help?

Anyways, just in case it’s (tangentially) useful: https://github.com/input-output-hk/bitte/blob/f452ea2c392a4a301c1feb20955c7d0a4ad38130/modules/terraform.nix#L191-L194

1 Like

I added the feature to compare the expected NixOS version and the last reported NixOS version

   machine   local version   remote version              state                                     time
   -------       ---------      -----------      -------------                                     ----
  kikimora        996vw3r6      996vw3r6 💚    sync pending 🚩       (build 5m 53s) (new config 2m 48s)
       nas        r7ips2c6      lvbajpc5 🛑 rebuild pending 🚩       (build 5m 49s) (new config 1m 45s)
      t470        ih7vxijm      ih7vxijm 💚      up to date 💚                           (build 2m 24s)
        x1        fcz1s2yp      fcz1s2yp 💚      up to date 💚                           (build 2m 37s)

The state “sync pending” means we updated the files used by Bento (mostly 2 shell scripts to download and run nixos-rebuild), and “rebuild pending” when the hash differs, this one implies a rebuild will be done on the remote NixOS.

It’s not perfect, but I finally found how to use systemd sockets to run something, there are two methods, one with a socket and a .service with the same name that should listen on network. The other is using a socket and a template ending with a @ in the name, and using Accept=yes in the socket. I needed the latter.

  systemd.sockets.listen-update = {
    enable = true;
    wantedBy = ["sockets.target"];
    requires = ["network.target"];
    listenStreams = ["51337"];
    socketConfig.Accept = "yes";
  };

  systemd.services."listen-update@" = {
    path = with pkgs; [systemd];
    enable = true;
    serviceConfig.StandardInput = "socket";
    serviceConfig.ExecStart = "${pkgs.systemd.out}/bin/systemctl start bento-upgrade.service";
    serviceConfig.ExecStartPost = "${pkgs.systemd.out}/bin/journalctl -f -n 10 --no-pager -u bento-upgrade.service";
  };

if you open http://localhost:51337 in the web browser, it starts the update process and shows the journal log of the update service :smiley:

2 Likes

Bento :bento: now supports rollback! The fleet display shows the rollback status, so you can easily be aware that something went wrong.

It’s also getting closer to work as a self containing script that doesn’t need to be store in the top level of repo. It’s still shell script only (not even bash), like 400 lines. I may rewrite it into somewhere else at some point.

Also, I’d like it to be able to use a single flakes with many hosts in it, instead of putting a flake per host directory. Ideally, it should support both.

2 Likes

A while ago, I started GitHub - divnix/hive: The secretly open NixOS-Society which deals with a certain folder layout for organizing users and their hosts.

It would be nice if bento would have only a weak opinion on the flake layout.

The flake layout is prime screen assets and in order to limit boilerplate bloat, I enjoy if a vertical framework considers horizontal integration points (i.e. integration points that aren’t anchored to a particular vertical schema).

I’d then like to try an integration upon reviving that project (for workstations :stuck_out_tongue_winking_eye: ).

The next step is to handle flakes with multiple machines.

The current layout is to have the configuration file of each host in its own directory. In the future, for directories with a flakes.nix files, bento will look for machines with a configuration file, and will iterate over the hosts list, instead of using the directory name for the machine.

This doesn’t break setups with non-flakes (it’s still experimental!), we can still use separate directories with their own flakes / non flakes, and we can have a single directory with a flake and many hosts, and handle that.

I need to hack a bit now :rainbow:

2 Likes

I’m just writing a pattern piece for Standard about CD. And after some discussion with a friend and colleague, I realize, there is one very huge advantage of pull-based approaches:

They don’t require you to punch security holes into your target infrastructure, since the target infrastructure never needs to listen.

The ideal would be therefore pull-based approaches (like bento) that aren’t also choreography (unlike bento).

Eureka! bento-server as a “clearance” state machine that can be interacted with through a well-defined API. Sounds like something? :grinning_face_with_smiling_eyes:

I’m not interested to go into this.

But as you said, with a pub/sub or polling agent on each machine, you schedule and order systems upgrades to match your needs. Each server could always get the latest build ASAP, but wait for green light to switch their configuration.

If you need to update a pool, you could group servers in a pool, and just give the green light to them one by one.

The project is now hosted on GitHub GitHub - rapenne-s/bento: A KISS deployment tool to keep your NixOS fleet (servers & workstations) up to date.
It seem nixers enjoy GitHub, I wouldn’t prevent them from contributing :+1:t3:

I think you are. :grinning_face_with_smiling_eyes:

Isn’t that topic to which servers would subscribe the very same “clearance” authority that I describe?

I still and sometimes wonder what part of an answer in the lines of Solenes above let’s one think of something different than what is written there in these exact lines.

8 Likes

I’m very happy to announce Bento 1.0.0 :partying_face: :partying_face:

  • the hosts directory can contain directories with flakes in it, that may contain many hosts, it’s now handled, if there is no flake in it then the machine is named after the directory
  • bento is now a single script, easy to package and add to $PATH, before that it was a set of scripts with a shared shell files with functions in it, not very practical…
3 Likes

Bento 1.0.2 is out already :sweat_smile:

  • bento init allows you to easily create the layout and files to get started
  • flakes! nix shell github:rapenne-s/bento :exploding_head:

it starts to stabilize, it’s mostly finished. I’ll revamp the documentation and the screen recording that are totally outdated now.

1 Like

Getting bored today, I added support for auto update per-host.

This mean, if you don’t update the flakes locally, you can add a SELF_UPDATE file in the same directory where the flakes files are, when the remote system looks for update, if there is no update to do and SELF_UPDATE exists, it runs nix flakes update and run a rebuild, and report as an auto aupdate.

   machine   local version   remote version              state                       elapsed time since
   -------       ---------      -----------      -------------                            -------------
       ams        xb358dkb      xb358dkb 💚      up to date 💚                       (build 1h 15m 45s)
  kikimora        jp54rrj1      w6l04ch4 🛑     autoupdated 🤖                           (build 1m 36s)
       nas        18kd9id6      18kd9id6 💚      up to date 💚                       (build 1h 15m 58s)
      t470        rb4g4wnc      rb4g4wnc 💚      up to date 💚                       (build 1h 16m 31s)
        x1        r2hkkcwq      l57wmax3 🛑 rebuild pending 🚩 (build 2d 2h 16m 25s) (new config 1h 17m 3s)
2 Likes

New asciinema recording showing how to add a new host to Bento, using the new shiny commands :star_struck:

I solved a major pain point. As bento is running on remote hosts through a systemd service started by a timer or a socket, when the update had a change in bento-upgrade.service, this was restarting the service and abruptly stopping bento.

I added restartIfChanged = false; to the service and it prevents that situation, and as it’s a one shot service, we can do it as the next time it will be run, the new version will be used.

I also added bento flake-update to recursively update all flakes because it was painful to do.

The self update code may require more tests, I’m not happy with the current logic because it’s highly inefficient. I’l going to make a state diagram of Bento, this will be nice in the documentation.

1 Like

I added BENTO_DIR environment variable support, so you can run bento status or bento deploy from anywhere instead of having to cd into the directory first. That’s a huge QoL improvement for me :grin:

And bento flake-update now supports an optional parameter to only update some input (still recursively), for example bento flake-update peerix will only update peerix input.

1 Like

It’s now possible to know what the local builds are doing (the nixos-rebuild output) by setting VERBOSE environment variable to any value. I have super slow internet, it was frustrating to have to wait indefinitely until a new host is built after a nixpkgs update.

Display is compact with flakes <3 but not with channels.

1 Like

Bento 1.1.0 :partying_face:

  • remote systems automatically reboot if their configuration directory contains a REBOOT file in it and a kernel/module/initrd changed after a rebuild

this will be improved later to support the same mechanism found in autoUpgrade using a time window. I don’t want my home router to reboot immediately after I push a new kernel on it, I prefer it to reboot when I sleep.

  • The SELF_UPDATE mechanism is still not advertised as finished in the README’s Todo list because I’m not very happy of it right now. If you push a new config, it will be used to switch, then at next bento tick, the lock file will be upgraded if possible and a rebuild will be done, but if you push again the old lock, it will be reused, and after next tick it will be updated. This can create a dancer of version discrepancy that I don’t like. Maybe bento should refuse to update from the sftp sources until you update the lock file or something like that :woman_shrugging:t3:

I’m happily managing 6 systems with Bento :slight_smile:

  • 2 servers
  • 1 router
  • 3 workstations
4 Likes

I reworked the documentation by following https://diataxis.fr/

It feels a huge improvement compared to the previous gigantic readme :star_struck: and I realized there is no tutorial for learning how to use Bento safely.

2 Likes