turn the documentation into a more diataxis style

This commit is contained in:
Solene Rapenne 2022-09-26 23:40:00 +02:00
parent 6de41994bf
commit a7b4f7dae7
3 changed files with 154 additions and 149 deletions

165
README.md
View File

@ -6,21 +6,30 @@ This name was chosen because Bento are good, and comes with the idea of "ready t
Use with flakes: `nix shell github:rapenne-s/bento`
# Why?
# Documentation
- [Reference documentation](doc/reference.md): contains environment variable, command line parameters
- [How-to](doc/how-to.md): contains examples and how-to guides
# About Bento
## Explanation
There is currently no tool to manage a bunch of NixOS systems that could be workstations anywhere in the world, or servers in a datacenter, using flakes or not.
# Features
Most NixOS deployment tools are working on a "push" model, in which a system is connecting to a remote NixOS to push its new version.
- secure 🛡️: each client can only access its own configuration files (ssh authentication + sftp chroot)
Bento has a different approach with a "pull" model:
- privacy first 🛡️: each client can only access its own configuration files (using ssh authentication to reach a SFTP chroot)
- insightful 📒: you can check the remote systems are running the same NixOS built locally with their configuration files, thanks to reproducibility
- efficient 🏂🏾: configurations can be built on the central management server to serve binary packages if it is used as a substituters by the clients
- organized 💼: system administrators have all configurations files in one repository to easy management
- peace of mind 🧘🏿: configurations validity can be verified locally by system administrators
- organized 💼: system administrators have all configurations files in one repository to ease management
- peace of mind 🧘🏿: configurations can be validated locally by system administrators
- smart 💡: secrets (arbitrary files) can (soon) be deployed without storing them in the nix store
- robustness in mind 🦾: clients just need to connect to a remote ssh, there are many ways to bypass firewalls (corkscrew, VPN, Tor hidden service, I2P, ...)
- robustness in mind 🦾: clients ony need to connect to a remote ssh server, there are many ways to bypass firewalls (corkscrew, VPN, Tor hidden service, I2P, ...)
- extensible 🧰 🪡: you can change every component, if you prefer using GitHub repositories to fetch configuration files instead of a remote sftp server, you can change it
- for all NixOS 💻🏭📱: it can be used for remote workstations, smartphones running NixoS, servers in a datacenter
- for all NixOS 💻🏭📱: it can be used for anything running NixOS: remote workstations, smartphones or servers in a datacenter
# Prerequisites
@ -45,148 +54,6 @@ There is a diagram showing the design pattern of **bento**:
![diagram](https://dataswamp.org/~solene/static/nixos-fleet-pattern.png)
# Layout
Here is the typical directory layout for using **bento** for the non-flakes system `router`, a single flake my-laptop for the system `t470`, and a flake with multiples configuration in `all-flakes-systems`:
```
├── hosts
│   ├── router
│   │   ├── configuration.nix
│   │   ├── hardware-configuration.nix
│   │   └── utils -> ../../utils/
│   ├── all-flakes-systems
│   │   ├── configuration.nix
│   │   ├── flake.lock
│   │   ├── flake.nix
│   │   ├── hardware-configuration.nix
│   │   └── utils -> ../../utils/
│   └── my-laptop
│   ├── configuration.nix
│   ├── default-spec.nix
│   ├── flake.lock
│   ├── flake.nix
│   ├── hardware-configuration.nix
│   ├── home.nix
│   ├── minecraft.nix
│   ├── nfs.nix
│   ├── nvidia.nix
│   └── utils -> ../../utils/
├── README.md
└── utils
└── bento.nix
└── common-stuff.nix
└── fleet.nix
```
# Environment variables
`bento` is using the following environment variables as configuration:
- `BENTO_DIR`: contains the path of a bento directory, so you can run `bento` commands from anywhere
- `NAME`: contains machine names (flake config or directory in `hosts/`) to restrict commands `deploy` and `build` to this machine only
- `VERBOSE`: if defined to anything, display `nixos-rebuild` output for local builds done with `bento build` or `bento deploy`
# Workflow
1. make configuration changes per host in `hosts/` or a global include file in `utils` (you can rename it as you wish)
2. run `sudo bento deploy` to verify, build every system, and publish the configuration files on the SFTP server
3. hosts will pickup changes and run a rebuild
# Track each host state
As each host is sending a log upon rebuild to tell if it failed or succeeded, we can use this file to check what happened since the sftp file `last_time_changed` was created.
Using `bento status` you can track the current state of each hosts (time since last update, current NixOS version, status report)
[![asciicast](https://asciinema.org/a/520504.svg)](https://asciinema.org/a/520504)
# Self update mode
You can create a file named `SELF_UPDATE` in a host directory using flakes. When that host will look for updates on the sftp server, if there is no changes to rebuild, if `SELF_UPDATE` exists along with a `flake.nix` file, it will try to update the inputs, if an input is updated, then the usual rebuild is happening.
This is useful if you want to let remote hosts to be autonomous and pick up new nixpkgs version as soon as possible.
Systems will be reported as "auto upgraded" in the `bento status` command if they rebuild after a local flake update.
This adds at least 8 kB of inbound bandwidth for each input when checking for changes.
# Auto reboot
You can create a file named `REBOOT` in a host directory. When that host will rebuild the system, it will look at the new kernel, kernel modules and initrd, if they changed, a reboot will occur immediately after reporting a successful upgrade. A kexec is used for UEFI systems for a faster reboot (this avoids BIOS and bootloader steps).
# Examples
## Get started with bento
1. `bento init`
2. copy the configuration file of the server in a subdirectory of `hosts`, add `fleet.nix` to it
3. add keys to `fleet.nix`
4. run `bento deploy` as root
5. follow deployment with `bento status`
6. add new hosts keys to `fleet.nix` and their configuration in your `hosts` directory
## Adding a new host
Here are the steps to add a server named `kikimora` to bento:
[![asciicast](https://asciinema.org/a/520498.svg)](https://asciinema.org/a/520498)
1. generate a ssh-key on `kikimora` for root user
2. add kikimora's public key to bento `fleet.nix` file
3. reconfigure the ssh host to allow kikimora's key (it should include the `fleet.nix` file)
4. copy kikimora's config (usually `/etc/nixos/` in bento `hosts/kikimora/` directory
5. add utils/bento.nix to its config (in `hosts/kikimora` run `ln -s ../../utils .` and add `./utils/bento.nix` in `imports` list)
6. check kikimora's config locally with `bento build dry-build`, you can check only `kikimora` with `env NAME=kikimora bento build dry-build`
7. populate the chroot with `sudo bento deploy` to copy the files in `/home/chroot/kikimora/config/`
8. run bootstrap script on kikimora to switch to the new configuration from sftp and enable the timer to poll for upgrades
9. you can get bento's log with `journalctl -u bento-upgrade.service` and see next timer information with `systemctl status bento-upgrade.timer`
## Deploying changes
Here are the steps to deploy a change in a host managed with **bento**
1. edit its configuration file to make the changes in `hosts/the_host_name/something.nix`
2. run `sudo bento deploy` to build and publish configuration files
3. wait for the timer of that system to trigger the update, or ask the user to open http://localhost:51337/ to force the update
If you don't want to wait for the timer, you can ssh into the machine to run `systemctl start bento-upgrade.service`
## Status report of the fleet
Using `bento status`, you instantly get a report of your fleet, all information are extracted from the logs files deposited after each update:
- what is the version they should have (built locally) against the version they are currently running
- their state:
- **sync pending**: no configuration file changed, only files specific to **Bento**
- **rebuild pending**: the local version has been updated and the remote must run `nixos-rebuild`
- **up to date**: everything is fine
- **extra logs**: the update process has been run more than necessary, this shouldn't happen. The most common case is to run the update service manually.
- **failing**: the update process failed
- **rollbacked**: the update process failed and a rollback has been done to previous version. **Bento** won't try until a new configuration is available.
- the time elapsed since last rebuild
- the time elapsed since the new onfiguration has been made available
Non-flakes systems aren't reproducible (without efforts), so we can't compare the remote version with the local one, but we can report this information.
Example of output:
```
machine local version remote version state time
------- --------- ----------- ------------- ----
interbus non-flakes 1dyc4lgr 📌 up to date 💚 (build 11s)
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 b2ovrtjy ih7vxijm 🛑 rollbacked 🔃 (build 2m 24s)
x1 fcz1s2yp fcz1s2yp 💚 up to date 💚 (build 2m 37s)
```
## Update all flakes
With `bento flake-update` you can easily update your flakes recursively to the latest version.
A parameter can be added to only update a given source with, i.e to update all nixpkgs in the flakes `bento flake-update nixpkgs`.
# CAVEATS
- if you propagate a new version while a host is updating, it may be incorrectly seen as "up to date" because the log file deposited will be newer than the `last_time_changed` file

110
doc/how-to.md Normal file
View File

@ -0,0 +1,110 @@
# Layout
Here is the typical directory layout for using **bento** for the non-flakes system `router`, a single flake my-laptop for the system `t470`, and a flake with multiples configuration in `all-flakes-systems`:
```
├── hosts
│   ├── router
│   │   ├── configuration.nix
│   │   ├── hardware-configuration.nix
│   │   └── utils -> ../../utils/
│   ├── all-flakes-systems
│   │   ├── configuration.nix
│   │   ├── flake.lock
│   │   ├── flake.nix
│   │   ├── hardware-configuration.nix
│   │   └── utils -> ../../utils/
│   └── my-laptop
│   ├── configuration.nix
│   ├── default-spec.nix
│   ├── flake.lock
│   ├── flake.nix
│   ├── hardware-configuration.nix
│   ├── home.nix
│   ├── minecraft.nix
│   ├── nfs.nix
│   ├── nvidia.nix
│   └── utils -> ../../utils/
├── README.md
└── utils
└── bento.nix
└── common-stuff.nix
└── fleet.nix
```
# Workflow
1. make configuration changes per host in `hosts/` or a global include file in `utils` (you can rename it as you wish)
2. run `sudo bento deploy` to verify, build every system, and publish the configuration files on the SFTP server
3. hosts will pickup changes and run a rebuild
# Get started with bento
1. `bento init`
2. copy the configuration file of the server in a subdirectory of `hosts`, add `fleet.nix` to it
3. add keys to `fleet.nix`
4. run `bento deploy` as root
5. follow deployment with `bento status`
6. add new hosts keys to `fleet.nix` and their configuration in your `hosts` directory
# Adding a new host
Here are the steps to add a server named `kikimora` to bento:
[![asciicast](https://asciinema.org/a/520498.svg)](https://asciinema.org/a/520498)
1. generate a ssh-key on `kikimora` for root user
2. add kikimora's public key to bento `fleet.nix` file
3. reconfigure the ssh host to allow kikimora's key (it should include the `fleet.nix` file)
4. copy kikimora's config (usually `/etc/nixos/` in bento `hosts/kikimora/` directory
5. add utils/bento.nix to its config (in `hosts/kikimora` run `ln -s ../../utils .` and add `./utils/bento.nix` in `imports` list)
6. check kikimora's config locally with `bento build dry-build`, you can check only `kikimora` with `env NAME=kikimora bento build dry-build`
7. populate the chroot with `sudo bento deploy` to copy the files in `/home/chroot/kikimora/config/`
8. run bootstrap script on kikimora to switch to the new configuration from sftp and enable the timer to poll for upgrades
9. you can get bento's log with `journalctl -u bento-upgrade.service` and see next timer information with `systemctl status bento-upgrade.timer`
# Deploying changes
Here are the steps to deploy a change in a host managed with **bento**
1. edit its configuration file to make the changes in `hosts/the_host_name/something.nix`
2. run `sudo bento deploy` to build and publish configuration files
3. wait for the timer of that system to trigger the update, or ask the user to open http://localhost:51337/ to force the update
If you don't want to wait for the timer, you can ssh into the machine to run `systemctl start bento-upgrade.service`
# Status report of the fleet
Using `bento status`, you instantly get a report of your fleet, all information are extracted from the logs files deposited after each update:
- what is the version they should have (built locally) against the version they are currently running
- their state:
- **sync pending**: no configuration file changed, only files specific to **Bento**
- **rebuild pending**: the local version has been updated and the remote must run `nixos-rebuild`
- **up to date**: everything is fine
- **extra logs**: the update process has been run more than necessary, this shouldn't happen. The most common case is to run the update service manually.
- **failing**: the update process failed
- **rollbacked**: the update process failed and a rollback has been done to previous version. **Bento** won't try until a new configuration is available.
- the time elapsed since last rebuild
- the time elapsed since the new onfiguration has been made available
Non-flakes systems aren't reproducible (without efforts), so we can't compare the remote version with the local one, but we can report this information.
Example of output:
```
machine local version remote version state time
------- --------- ----------- ------------- ----
interbus non-flakes 1dyc4lgr 📌 up to date 💚 (build 11s)
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 b2ovrtjy ih7vxijm 🛑 rollbacked 🔃 (build 2m 24s)
x1 fcz1s2yp fcz1s2yp 💚 up to date 💚 (build 2m 37s)
```
# Update all flakes
With `bento flake-update` you can easily update your flakes recursively to the latest version.
A parameter can be added to only update a given source with, i.e to update all nixpkgs in the flakes `bento flake-update nixpkgs`.

28
doc/reference.md Normal file
View File

@ -0,0 +1,28 @@
# Environment variables
`bento` is using the following environment variables as configuration:
- `BENTO_DIR`: contains the path of a bento directory, so you can run `bento` commands from anywhere
- `NAME`: contains machine names (flake config or directory in `hosts/`) to restrict commands `deploy` and `build` to this machine only
- `VERBOSE`: if defined to anything, display `nixos-rebuild` output for local builds done with `bento build` or `bento deploy`
# Self update mode
You can create a file named `SELF_UPDATE` in a host directory using flakes. When that host will look for updates on the sftp server, if there is no changes to rebuild, if `SELF_UPDATE` exists along with a `flake.nix` file, it will try to update the inputs, if an input is updated, then the usual rebuild is happening.
This is useful if you want to let remote hosts to be autonomous and pick up new nixpkgs version as soon as possible.
Systems will be reported as "auto upgraded" in the `bento status` command if they rebuild after a local flake update.
This adds at least 8 kB of inbound bandwidth for each input when checking for changes.
# Auto reboot
You can create a file named `REBOOT` in a host directory. When that host will rebuild the system, it will look at the new kernel, kernel modules and initrd, if they changed, a reboot will occur immediately after reporting a successful upgrade. A kexec is used for UEFI systems for a faster reboot (this avoids BIOS and bootloader steps).
# Track each host state
As each host is sending a log upon rebuild to tell if it failed or succeeded, we can use this file to check what happened since the sftp file `last_time_changed` was created.
Using `bento status` you can track the current state of each hosts (time since last update, current NixOS version, status report)
[![asciicast](https://asciinema.org/a/520504.svg)](https://asciinema.org/a/520504)