120 lines
5.5 KiB
Markdown
120 lines
5.5 KiB
Markdown
|
|
# Dynix — WIP modular dynamicism for NixOS systems
|
||
|
|
|
||
|
|
Dynix is a prototype for modifying an append-only NixOS configuration, and dynamically
|
||
|
|
|
||
|
|
## Running the tests
|
||
|
|
|
||
|
|
There are currently 3 implemented dynamicism modules: `gotosocial`, `harmonia`, and `distccd`.
|
||
|
|
Each test uses the [NixOS test infrastructure](https://nixos.org/manual/nixos/unstable/#sec-nixos-tests) to:
|
||
|
|
|
||
|
|
1. Setup a virtual machine running NixOS
|
||
|
|
2. Configure the VM's NixOS to run a given service, with certain settings
|
||
|
|
3. Verify that the running service is using those settings
|
||
|
|
4. Use Dynix to change a setting for that service
|
||
|
|
5. Verify that the running service is now using the new setting
|
||
|
|
|
||
|
|
The tests themselves can be run with Nix.
|
||
|
|
To run the test for, e.g., Gotosocial, you can run:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
$ nix --experimental-features "nix-command flakes pipe-operator pipe-operators" build .#default.tests.gotosocial
|
||
|
|
```
|
||
|
|
|
||
|
|
The experimental [piping operator](https://github.com/NixOS/rfcs/pull/148) is currently used in Dynix, so you must enable the experimental feature `pipe-operator` for Lix or `pipe-operators` for CppNix (you can add both to cover both Nix implementations); flakes are used for locked inputs.
|
||
|
|
|
||
|
|
|
||
|
|
To run a test with fewer experimental features, and without locked inputs, you can use the old CLI:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
$ nix-build --experimental-features "pipe-operator pipe-operators" -A tests.gotosocial
|
||
|
|
```
|
||
|
|
|
||
|
|
All the tests at once can be run with:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
$ nix build --experimental-features "nix-command flakes pipe-operator pipe-operators" .#default.allTests
|
||
|
|
```
|
||
|
|
|
||
|
|
## Gotosocial
|
||
|
|
|
||
|
|
This example, implemented in [./modules/dynamicism/gotosocial.nix](./modules/dynamicism/gotosocial.nix), is tested in [./tests/gotosocial](./tests/gotosocial).
|
||
|
|
The test sets up a VM using NixOS's `services.gotosocial` module with the following *static* [configuration](./tests/gotosocial/configuration.nix):
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{
|
||
|
|
services.gotosocial = {
|
||
|
|
enable = true;
|
||
|
|
setupPostgresqlDB = true;
|
||
|
|
settings = {
|
||
|
|
application-name = "gotosocial-for-machine";
|
||
|
|
host = "gotosocial-machine.local";
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
The automated [test script](./tests/gotosocial/test-script.py):
|
||
|
|
|
||
|
|
1. Asserts that that the above *static* configuration is in effect (by extracting the configuration from the running Gotosocial process)
|
||
|
|
2. Runs `dynix append "services.gotosocial.settings.application-name" "yay!"`, which modifies the append-only configuration file `/etc/nixos/dynamic.nix` in the VM filesystem
|
||
|
|
3. Runs the dynamic activation script built by `(import <nixpkgs/nixos>).config.dynamicism.applyDynamicConfiguration { }`, which *applies* the dynamic configuration
|
||
|
|
4. Asserts that the dynamically configured `application-name` is in effect
|
||
|
|
5. Runs `nixos-rebuild switch` to re-apply the *static* configuration
|
||
|
|
6. Asserts that the dynamic configuration is *no longer* in effect, and we are back to the static configuration
|
||
|
|
|
||
|
|
## Harmonia
|
||
|
|
|
||
|
|
This example, implemented in [./modules/dynamicism/harmonia.nix](./modules/dynamicism/harmonia.nix), is tested in [./tests/harmonia](./tests/harmonia).
|
||
|
|
The test sets up a VM using NixOS's `services.harmonia` module with the following *static* [configuration](./tests/harmonia/configuration.nix)
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{
|
||
|
|
services.harmonia = {
|
||
|
|
enable = true;
|
||
|
|
settings = {
|
||
|
|
workers = 4;
|
||
|
|
max_connection_rate = 256;
|
||
|
|
};
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
The VM [test script](./tests/harmonia/test-script.py):
|
||
|
|
|
||
|
|
1. Asserts that the above *static* configuration is in effect (by extracting the configuration from the running Harmonia process)
|
||
|
|
2. Runs `dynix append "services.harmonia.settings.workers" 20`, to modify the append-only configuration file `/etc/nixos/dynamic.nix` in the VM filesystem
|
||
|
|
3. Runs the dynamic activation script built by `(import <nixpkgs/nixos>).config.dynamicism.applyDynamicConfiguration { }`, to *apply* the dynamic configuration
|
||
|
|
4. Asserts that the dynamically configured `workers` is in effect
|
||
|
|
5. Runs `dynix append "services.harmonia.settings.max_connection_rate" 100`
|
||
|
|
6. Runs the dynamic activation script
|
||
|
|
7. Asserts that *both* `max_connection_rate` and `workers` dynamic values are in effect
|
||
|
|
8. Runs `nixos-rebuild switch` to re-apply the *static* configuration
|
||
|
|
9. Asserts that the dynamic configuration is *no longer* in effect, and we are back to the static configuration
|
||
|
|
|
||
|
|
## Distccd
|
||
|
|
|
||
|
|
This example, implemented in [./modules/dynamicism/distccd.nix](./modules/dynamicism/distccd.nix), is tested in [./tests/distccd](./tests/distccd).
|
||
|
|
The test sets up a VM using NixOS's `services.distccd` module with the following *static* [configuration](./tests/distccd/configuration.nix):
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{
|
||
|
|
services.distccd = {
|
||
|
|
jobTimeout = 900;
|
||
|
|
maxJobs = 12;
|
||
|
|
logLevel = "warning";
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
The VM [test script](./tests/distccd/test-script.py):
|
||
|
|
|
||
|
|
1. Asserts that the above *static* configuration is in effect (by extracting the configuration from the running Distccd process)
|
||
|
|
2. Runs `dynix append "services.distccd.maxJobs" 4`, to modify the append-only configuration file `/etc/nixos/dynamic.nix` in the VM filesystem
|
||
|
|
3. Runs the dynamic activation script built by `(import <nixpkgs/nixos>).config.dynamicism.applyDynamicConfiguration { }`, to *apply* the dynamic configuration
|
||
|
|
4. Asserts that the dynamically configured `maxJobs` is in effect
|
||
|
|
5. Runs `dynix append "services.distccd.logLevel" "error"`
|
||
|
|
6. Runs the dynamic activation script
|
||
|
|
7. Asserts that *both* `maxJobs` and `logLevel` dynamic values are in effect
|
||
|
|
8. Runs `nixos-rebuild switch` to re-apply the *static* configuration
|
||
|
|
9. Asserts that the dynamic configuration is *no longer* in effect, and we are back to the static configuration.
|