## How to test a NixOS configuration change TLDR: push a commit to the `testing-` branch (rebased on the `main` branch) to deploy a change to the machine named ``. By default, each machine pulls configuration from the branch `testing-`. When this branch is on top of the `main` branch, comin deploys this configuration by running `switch-to-configuration test`: the bootloader configuration is not modified. To test a configuration: 1. Create a `testing-` branch in your configuration repository on top of the `main` branch 2. Add new commits to this branch and push it 3. comin runs `switch-to-configuration test` on the configuration: the bootload is not updated Contrary to the main branch, this branch can be hard reset but always has to be on top of the `main` branch. To `nixos-rebuild switch` to this configuration, the `main` branch has to be rebased on the `testing` branch. ## Iterate faster with local repository By default, comin polls remotes every 60 seconds. You could however add a local repository as a comin remote: comin could then poll this branch every second. When you commit to this repository, comin is starting to deploy the new configuration immediately. However, be careful because this repository could then be used by an attacker to update your machine. Example of a configuration with a local repository: ```nix services.comin = { enable = true; remotes = [ { name = "local"; url = "/your/local/infra/repository"; poller.period = 2; } ]; } ``` ## How to migrate a configuration from a machine to another one Suppose you have a running NixOS machine and you want to move this configuration to another machine while preserving the same hostname. If you use a testing branch, both of these machines will be updated when changes are pushed to the testing branch. To avoid such situation, we could set the option `services.comin.machineId`. If the machine where comin is running doesn't have this expected `machine-id` (compared to the content of the `/etc/machine-id` file), comin won't deploy the configuration. So, to migrate to another machine, you have to update this option in the `testing-` branch in order to only deploy this configuration to the new machine. ## Check Git commit signatures The option `services.comin.gpgPublicKeyPaths` allows to declare a list of GPG public keys. If `services.comin.gpgPublicKeyPaths != []` or `services.comin.sshAllowedSignersPath` is set, comin only evaluates commits signed by a configured commit-signing trust source. Note only the last commit needs to be signed. The file containing a GPG public key has to be created with `gpg --armor --export alice@cyb.org`. The option `services.comin.sshAllowedSignersPath` can also be used to verify SSH-signed commits with an OpenSSH allowed signers file. For example: ```text alice@example.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... bob@example.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5BBBB... ``` comin supports public key entries and the optional `namespaces=` restriction; other allowed signers options are rejected. ## How to deploy a nix-darwin configuration When comin is running on a Darwin system, it automatically builds and deploys a configuration found in the flake output `darwinConfigurations.hostname`. So, you only need to set this flake output and run comin on the target machine. ## How to use comin without Nix flake comin supports deploying configuration from a repository that doesn't use Nix flake. Here is a configuration example: ```nix services.comin = { repositoryType = "nix"; systemAttr = "your.nixos.configuration.attribute"; ... ... } ``` Please note this is currently not supported by for nix-darwin configurations. ## Deployments and profiles retention policy comin tracks deployments in its persisent storage. It uses these deployment entries to add and remove system profiles which are consumed by bootloaders to install boot menu entries. First of all, comin always keep the current switched deployment and the current booted deployment. Then, comin maintains 3 lists of deployments. These lists are updated when a deployment is created or updated. In the comin configuration, you can specify the capacity for each of these lists. These three lists are 1. The most recent successful deployments generating a boot entry (deployment with the operation `boot` or `switch`). It also deduplicates storepaths in order to keep a minimum number of distinct deployments. - The size of this list is controlled with the option `retention.deployment_boot_entry_capacity` 2. The most recent successful deployments - The size of this list is controlled with the option `retention.deployment_successful_capacity` 3. The most recent deployments of any type - The size of this list is controlled with the option `retention.deployment_capacity` A deployment can appear in several lists, when it satisfies several criteria. ## What happen on /var/lib/comin deletion comin store a state file in the `/var/lib/comin` directory. Here are the consequencies: - comin no longer knows the last deployed commit ID. It would then be possible for an attacker to hard reset the remote repository main branch. If you signed your commits, an attacker could then rollback the repository to a previous signed commit, which could contains CVEs. - comin no longer knows the deployment history. On the next deployment, it would then no longer able to generate boot entries for previous deployments. However, if you delete the `/var/lib/comin` directory, the current booted entry would still be present in the boot menu.