TLDR: push a commit to the testing-<hostname> branch (rebased on the
main branch) to deploy a change to the machine named <hostname>.
By default, each machine pulls configuration from the branch
testing-<hostname>. 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:
- Create a
testing-<hostname>branch in your configuration repository on top of themainbranch - Add new commits to this branch and push it
- comin runs
switch-to-configuration teston 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.
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:
services.comin = {
enable = true;
remotes = [
{
name = "local";
url = "/your/local/infra/repository";
poller.period = 2;
}
];
}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-<hostname> branch in order to only deploy this
configuration to the new machine.
The option services.comin.gpgPublicKeyPaths allows to declare a list
of GPG public keys. If services.comin.gpgPublicKeyPaths != [], comin only evaluates commits signed
by one of these GPG keys. Note only the last commit needs to be signed.
The file containing a GPG public key has to be created with gpg --armor --export [email protected].
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.
comin supports deploying configuration from a repository that doesn't use Nix flake. Here is a configuration example:
services.comin = {
repositoryType = "nix";
systemAttr = "your.nixos.configuration.attribute";
...
...
}Please note this is currently not supported by for nix-darwin configurations.
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
- The most recent successful deployments generating a boot entry
(deployment with the operation
bootorswitch). 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
- The size of this list is controlled with the option
- The most recent successful deployments
- The size of this list is controlled with the option
retention.deployment_successful_capacity
- The size of this list is controlled with the option
- The most recent deployments of any type
- The size of this list is controlled with the option
retention.deployment_capacity
- The size of this list is controlled with the option
A deployment can appear in several lists, when it satisfies several criteria.
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/comindirectory, the current booted entry would still be present in the boot menu.