Skip to content

Just Commands

The commands below are all executed with just 🡕.

Usage
just <command> <arguments>

Each command is prefixed with an icon indicating its usage context:

  • 💠 Common: available in all contexts.
  • 🔆 Framework: specific to the upstream DNF framework (dnf/).
  • ✳️ Project: specific to the consuming project (my network).
  • 🔗 Co-development: consuming project that contains a clone of the framework.

The recipes live in dnf/just/. The project Justfile imports one bootstrap file, which determines the available commands depending on the context.

ContextJustfile lineCommands
Frameworkimport 'just/dnf.just'💠 🔆
Consumer projectimport? 'dnf/just/project.just'💠 ✳️
Co-developmentimport 'dnf/just/codev.just'💠 ✳️ 🔗

In a consumer project, dnf/ is the symlink to the Nix store created by nix run .#init. The ? in import? lets just start as long as this symlink does not exist.

Co-development replaces this link with a git clone of the framework. The recipes 🔆 unit-tests, check-recipes, simulate, simulate-debug, fixtures and pkg-update can also be run there from the root. Project templates include the codev.just line, commented out.


Common to all contexts, these commands help maintain the code and generate declarative files.

Runs nix develop -c zsh to get a shell with the project tools.

Fenêtre de terminal
just develop

Runs the full chain: statix fix → check-code → generate → format → _fix_fs_permissions.

Fenêtre de terminal
just clean

Runs treefmt on all files using the shared framework config. In co-development, also formats dnf/.

Fenêtre de terminal
just format

Regenerates the default.nix files of module folders and, in a project, the var/generated/*.nix files from etc/config.yaml. It also seeds usr/machines/<host>/ for each host with a disko block (see Machine folder).

Fenêtre de terminal
just generate

Run these checks before deploying to catch regressions.

Runs code verification (check-code), DNF unit tests and flake verification (check-flake). Unit tests only run on a framework clone: a dnf/ symlinked to the store was tested before publication.

Fenêtre de terminal
just check

Static analysis with statix and dead code detection with deadnix, on all *.nix files.

Fenêtre de terminal
just check-code

Runs nix flake check while filtering known warnings from DNF’s non-standard outputs (colmena, colmenaHive, homeManagerModules, libTests, mkNodes, secretsPlan, version).

Fenêtre de terminal
just check-flake

In the framework repository (dnf/). Tests and pkg-update also run from the root of a co-development project.

Runs nix-unit on the framework’s libTests tests.

Fenêtre de terminal
just unit-tests

Verifies that the three bootstraps (dnf, project, codev) load correctly, and that each nested just <recipe> call resolves to a recipe from its own context. just only resolves these calls at runtime: CI runs the same verification.

Fenêtre de terminal
just check-recipes

Runs NixOS test scenarios (NixOS Test Driver).

ArgumentEffect
(empty)Lists available scenarios
allRuns all scenarios (nix flake check)
fullRegenerates fixtures then runs everything
<name>Runs a named scenario
Fenêtre de terminal
just simulate # list
just simulate all # run all
just simulate modules-node-console-git

Runs the interactive driver of a scenario (Python REPL).

Fenêtre de terminal
just simulate-debug modules-node-console-git

Manages test fixtures: generation, drift check, regeneration of disposable keys and secrets.

ActionEffect
generateRegenerates var/generated/ for all test environments
checkChecks for drift without modifying the tree
gen-secretsRegenerates disposable test keys and secrets
Fenêtre de terminal
just fixtures check

Updates a package from dnf/pkgs/ to its latest upstream version, or to version if given, using nix-update 🡕. See Packages outside nixpkgs.

Fenêtre de terminal
just pkg-update rename-simple
just pkg-update fleet-update 0.2.0 # explicit version (release train)

Displays the framework version, its revision, its latest tag, and the generator release it pins.

Fenêtre de terminal
just version

Displays what the next release entry would look like, without writing anything. Requires git-cliff, provided by the devShell (just develop).

Fenêtre de terminal
just changelog

Bumps the version, adds the CHANGELOG entry, commits and tags the framework, without pushing. See Publishing a release.

Fenêtre de terminal
just bump # level inferred from commits

Installing a new host follows a precise sequence.

Formats disks via disko and installs NixOS via nixos-anywhere.

The ip argument defaults to auto: the address is computed the same way as for full-install, no need to look it up.

The recipe also drops on the target, before the system installation, the age key /etc/sops/age/infra.key and, on an encrypted host, the SSH host key of its initrd: sops works from the first activation and the very first boot already listens on port 2222. The volume is formatted with the shared fleet passphrase, so there is nothing to type.

Fenêtre de terminal
just install myserver
just install myserver nixos 10.0.0.5 # custom IP
just install myserver nix auto test # test VM only

✳️ full-install <host> [user] [ip] ⭐

Section titled “✳️ full-install <host> [user] [ip] ⭐”

Full chain: install + wait for reboot + unlock + configure + apply + gc + reboot.

The starting address is calculated automatically: host name in its own zone, reserved pass-through address if plugged in elsewhere. See Machines outside their zone.

After reboot, the machine may not have returned to the same place: the recipe probes all its known addresses, on ports 22 and 2222, and continues on whichever responds. An encrypted host is unlocked along the way by just unlock.

The final reboot is not cosmetic: apply activates user space but not the kernel or initrd, and this reboot is the only automatic proof that the machine restarts on its own. On an encrypted host, it also proves that remote unlock works, while you are still in front of it rather than at the first power outage. unlock is therefore called again right after.

Fenêtre de terminal
just full-install myserver
just full-install myserver nixos 10.0.3.42 # forced address

Formats a USB device with disko and installs NixOS on it. Seals the host like install.

Fenêtre de terminal
just install-key myusbhost

✳️ install-here <hôte> <login> [empreinte] [yes] [passphrase]

Section titled “✳️ install-here <hôte> <login> [empreinte] [yes] [passphrase]”

Installs the machine it runs on, booted from the generic DNF ISO, as the project’s administration workstation: disko wipes its disk, the keys are born on the target (bootstrap-keys), then nixos-install. The project joins /etc/nixos of the new system, owned by login. An encrypted disk requires its passphrase file, which becomes the fleet’s shared passphrase; the initrd SSH key is deposited on the target.

Fenêtre de terminal
just install-here poste alice '<empreinte>'

✳️ backup-admin <périphérique> [passphrase] [racine]

Section titled “✳️ backup-admin <périphérique> [passphrase] [racine]”

Writes to a USB key, without formatting it, an age-encrypted backup of what nothing else replaces: the nix deployment key (which gives the admin age key), the infra age key and the project (git bundle). File dnf-backup-<domaine>.tar.age, with a plain README.txt; a previous backup of the same network is kept, renamed with its date.

  • périphérique: a partition of the key, /dev/disk/by-label/SECOURS for example;
  • passphrase: a file containing it; otherwise, age asks for it;
  • racine: the system holding the keys, /mnt from the installer.

darkone new runs it after installation.

Fenêtre de terminal
just backup-admin /dev/disk/by-label/SECOURS

✳️ backup-check <périphérique> [passphrase] [racine]

Section titled “✳️ backup-check <périphérique> [passphrase] [racine]”

Reads back the backup-admin backup, same arguments, and compares it to the keys and the latest commit of the project.

Chains copy-id → copy-hw → push-key → luks (the last one does nothing on a non-encrypted host).

The address is resolved once and passed to the whole chain. If the host is plugged outside its zone, the SSH redirection is set up in the process, so that the following apply reaches it: just roaming-clear <host> once the machine is back home.

Fenêtre de terminal
just configure myserver

Checks that the nix deployment key can open the target host, and pushes the shared private key to gateways (TLS certificate synchronization from the HCS).

Fenêtre de terminal
just copy-id myserver

Runs nixos-generate-config --show-hardware-config remotely and saves the result in usr/machines/<host>/hardware/hardware-configuration.nix, then chains detect-hw.

Fenêtre de terminal
just copy-hw myserver

Collects on the machine the kernel modules of its wired network cards and writes them to usr/machines/<hôte>/hardware/detected-hardware.nix (generated file, imported automatically). They join the initrd only if it has network, for remote LUKS unlocking. Also detects a virtual machine (systemd-detect-virt): no firmware is loaded on it (darkone.system.hardware.virtual). Called by install (nixos user of the ISO) and by copy-hw.

Fenêtre de terminal
just detect-hw myserver

Transfers the age key /etc/sops/age/infra.key to the target host.

Fenêtre de terminal
just push-key myserver

Displays the MAC address of a machine’s first active interface, to declare it in etc/config.yaml before installing it. Useful when the host does not yet have a DHCP reservation and can only be reached via the dynamic address shown on its screen.

Fenêtre de terminal
just host-info myserver 10.0.0.50

Provisions a host’s encryption : shared and per-host passphrases in sops, initrd SSH key in sops then on the target, usr/secrets/luks.json manifest, gateways’ WAN IP. See Disk encryption (LUKS).

ActionEffect
(default)Prepares the secrets, then converges the machine
preOffline half only, without touching the machine
passwdRotates the per-host passphrase, then converges
showRead-only audit : keyslots and remote unlocking
Fenêtre de terminal
just luks myserver
just luks myserver show
just luks myserver passwd

Redirects SSH to a host connected outside its zone, for the duration of the installation. Colmena addresses a node by its name, which refers to its original address; this redirect points it to where the machine actually is.

Set up by just configure when needed, removed by full-install at the end of the run. Without arguments, displays the current redirects.

Fenêtre de terminal
just roaming # display
just roaming myserver # redirect (computed address)

Removes a host’s redirect, or all of them if none is given.

Fenêtre de terminal
just roaming-clear myserver
just roaming-clear

Configure the administration machine: SSH keys, age SOPS keys, .sops.yaml, default secrets, Harmonia signing key, and all internal secrets required by declared services (OAuth2 clients, backups, service tokens, etc.).

Fenêtre de terminal
just configure-admin-host

✳️ bootstrap-keys [racine] [login] [empreinte]

Section titled “✳️ bootstrap-keys [racine] [login] [empreinte]”

Creates the keys and the sops skeleton of a machine that has no nix account yet, under the given root (/, or /mnt from the installer). configure-admin-host relies on the same mechanism. The fingerprint of an account (mkpasswd, in single quotes) is optional.

Fenêtre de terminal
just bootstrap-keys /mnt alice '<empreinte>'

Builds the installation ISO image for the given architecture. It bundles the administration public key (usr/secrets/nix.pub): just full-install connects to it without a password.

Fenêtre de terminal
just build-iso # x86_64-linux (default)
just build-iso "aarch64-linux"

The apply* commands rely on colmena 🡕 and first refresh the DNF lock via update-dnf. fleet-update drives a full update using native Nix commands.

Deploys the configuration on one or more targets.

ParameterDescription
targetHostname, glob ('*'), list (a,b), colmena tag (@server)
actionswitch (default), boot, test, build
Fenêtre de terminal
just apply @all # all hosts
just apply myserver # switch (default)
just apply myserver boot # boot
just apply 'db-*' # all hosts starting with db-

Same as apply with --verbose --show-trace.

Fenêtre de terminal
just apply-verbose myserver

Applies the configuration on the current machine.

Fenêtre de terminal
just apply-local

Enables Alertmanager maintenance mode before applying, disables it after.

Fenêtre de terminal
just apply-silenced myserver

Updates, builds and deploys the entire fleet in waves. See Update the fleet with fleet-update.

Fenêtre de terminal
just fleet-update # tout le parc, interface interactive
just fleet-update --on '+server' # les hôtes d'un profil
just fleet-update --build-only # construire sans rien activer
just fleet-update --help # toutes les options

Updates the root flake inputs. In co-development, updates dnf/ inputs first and commits them (chore(flake):, amended if the latest dnf/ commit is already one).

Fenêtre de terminal
just update-flake

Syncs flake.lock with the local HEAD of dnf/ (co-development).

Fenêtre de terminal
just update-dnf

These commands interact with fleet hosts: maintenance, reboot, cleanup, and boot repair.

Opens an interactive SSH session as nix@<hôte>, on port 22 only. A host outside its zone is located by dnf-locate (see Joining a host while travelling). A host waiting for its LUKS passphrase falls under just unlock.

Fenêtre de terminal
just enter myserver

Answers the LUKS prompt of a host still sitting in its initrd, with no human present : the passphrase is read from sops and pushed through the sshd on port 2222. It waits for the host to show up (one dot per attempt), which makes it possible to chain it right after a reboot. Called automatically by just full-install. No stored passphrase accepted : from a terminal, the request is presented.

On a host without a LUKS volume, it is a logged no-op.

Fenêtre de terminal
just unlock myserver

✳️ remote-desktop <host> [ro|rw|login] / rd ⭐

Section titled “✳️ remote-desktop <host> [ro|rw|login] / rd ⭐”

Opens the remote desktop of a host. ro (default) watches the already open graphical session, rw takes control of it; both fail if nobody is logged in. login opens your own session behind a GDM login screen instead. No port is opened on the host: the stream goes through an SSH tunnel set up by nix. See Remote desktop.

Fenêtre de terminal
just rd mypc # observation
just rd mypc rw # take control
just rd mypc login # own session, via GDM

Reboots the host via colmena exec.

Fenêtre de terminal
just reboot myserver
just reboot 'web-*' # all web-*

Shuts down (poweroff) the host via colmena exec, after confirmation.

Fenêtre de terminal
just halt myserver

Removes old generations, cleans the store, then regenerates the boot entries (switch-to-configuration boot). keep sets what is retained:

keepGenerations retained
(empty)Current only, all profiles (nix-collect-garbage -d)
N (1 to 99)Last N system generations, current included
Nd (1 to 99)Those less than N days old, plus the active one on that date
Fenêtre de terminal
# Clean hosts whose name starts with "server-"
just gc "server-*" # Keep only the current generation
just gc "server-*" 3 # Keep the last 3 generations, current included
just gc "server-*" 3d # Remove generations older than 3 days

Cleans up the home directories of a host removed from the NFS share: dead XDG symlinks removed, .bak backups restored. check (default) writes nothing and shows what apply would do. hosts is a comma-separated list, or all. See Leaving the NFS home share.

Fenêtre de terminal
just nfs-cleanup myserver # dry run, writes nothing
just nfs-cleanup myserver apply # actual execution

Reinstalls the bootloader with NIXOS_INSTALL_BOOTLOADER=1.

Fenêtre de terminal
just fix-boot myserver

✳️ fix-gdm-greeters <hôtes> [check|apply]

Section titled “✳️ fix-gdm-greeters <hôtes> [check|apply]”

Realigns the UIDs of gdm-greeter* accounts with those of nixpkgs. See Troubleshooting.

Fenêtre de terminal
just fix-gdm-greeters poste-01,poste-02 # diagnostic, n'écrit rien
just fix-gdm-greeters poste-01,poste-02 apply

Passwords and keys are encrypted with SOPS. These commands manage them without manipulating encrypted files by hand.

Opens usr/secrets/secrets.yaml in vim (as user nix).

Fenêtre de terminal
just sops

Welcomes a user or resets their access: session password, Kanidm link, vault invitation, welcome sheet to copy. An already defined access is only replaced after confirmation.

ModeForKanidm link
normal / n (default)Non-technical1 h, for the admin
advanced / aTechnical24 h, for the user
Fenêtre de terminal
just invite alice # non-technical
just invite alice advanced # technical
just invite alice a '<hash>' # technical, fingerprint sent remotely

See Create a user account.

Records the fleet’s reference password (bcrypt hash in sops). Does not configure any account: just passwd <utilisateur> takes care of it.

Fenêtre de terminal
just passwd-default

Updates a user’s session password, or records the fingerprint they sent (mkpasswd -m sha-512, in single quotes).

Fenêtre de terminal
just passwd darkone
just passwd darkone '<fingerprint>'

Enrolls a YubiKey (main by default, or backup) for a user: PAM (session/sudo), LUKS and Kanidm enrollment link, in a single pass on the admin machine. action=revoke revokes the key across all machines at next deployment. See Strong authentication.

Fenêtre de terminal
just yubikey darkone # enrolls the primary key
just yubikey darkone backup # enrolls the backup key
just yubikey darkone main revoke

Rotation of the age key /etc/sops/age/infra.key in 3 steps with integrity checks.

StepAction
initGenerates a new key, keeps the old one, re-encrypts secrets
push-keysPushes the combined key (new + old) to all hosts
finalizeVerifies all hosts have the new key, removes the old one
Fenêtre de terminal
just rotate init
just rotate push-keys
just rotate finalize

These commands cover specific features: provisioning the Matrix alert bot and managing Kanidm replication.

Creates or refreshes the Matrix bot, the webhook secret, and the alert and incident channels from the network.matrix section of config.yaml. The bot account is created on the Matrix host with dnf-mas, via SSH.

Fenêtre de terminal
just configure-alert-bot

Sends a message to an alert channel (warnings or incidents), Markdown body on standard input. Channels and token come from the project : the caller only writes the text. Exit codes : 10 nothing configured, 11 message rejected by the server.

Fenêtre de terminal
just send-msg warnings < rapport.md

Collects Kanidm replication certificates from all fleet nodes into usr/secrets/replication/.

Fenêtre de terminal
just idm-sync-certs

Analyzes the health of Kanidm replication without modifying anything. Takes the supplier node (HCS) and the list of consumers (gateways, comma-separated).

Fenêtre de terminal
just idm-fix-replica hcs agate,gw

At the root of a co-development project. Git commands operate on all repositories of the project (default: src/*/, dnf, doc, and the root). The short alias for git is g.

Runs any git command on one or all projects.

Fenêtre de terminal
just git "log --oneline -5" # latest commits of all projects
just git "status" dnf # git status on dnf/ only
just git "remote -v" # remotes of all projects

add -A + commit -m on one or all projects. If the message is identical to the latest commit, the recipe amends instead of creating a new commit.

On all projects, the root is processed last, after update-dnf: its commit pins the revision of dnf/ that was just committed.

Fenêtre de terminal
just commit "fix(net): update dns config"
just commit "fix(net): update dns config" dnf # dnf/ only

Adds the current changes to the latest commit of each project (--no-edit). On all projects, the root lock is then realigned to dnf/.

Fenêtre de terminal
just amend

Displays the git status of one or all projects.

Fenêtre de terminal
just status

Displays the git diff of one or all projects.

Fenêtre de terminal
just diff

Checks for an upstream branch and ahead commits before pushing.

Fenêtre de terminal
just push

Pulls the latest changes for one or all projects.

Fenêtre de terminal
just pull

Displays the latest commit message for all projects, formatted and aligned.

Fenêtre de terminal
just git-last-log

Displays the list of repositories that git commands iterate over.

Fenêtre de terminal
just git-show-repos

Builds the generator binary (src/generator/).

Fenêtre de terminal
just gen-build

Runs the generator unit tests.

Fenêtre de terminal
just gen-test

Chains clean → amend → apply-local test (or apply-verbose <host>).

Fenêtre de terminal
just cat # tests locally
just cat myserver # applies on myserver

Displays the version, latest tag and branch of each repository, along with the generator release pinned by the framework.

Fenêtre de terminal
just versions

Publishes the whole ecosystem (generator, fleet-update, framework, documentation and project templates) after checks and simulations. See The release train.

Fenêtre de terminal
just release

AliasCommandContext
aapply✳️
alapply-local✳️
avapply-verbose✳️
cclean💠
ddevelop💠
eenter✳️
ggit🔗
amendgit-amend🔗
commitgit-commit🔗
diffgit-diff🔗
pullgit-pull🔗
pushgit-push🔗
statusgit-status🔗
rdremote-desktop✳️