Something went wrong. Try again.
ALPHA: wire is a tool to deploy nixos systems (contribution fork)
Something went wrong. Try again.
Nix
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147# SPDX-License-Identifier: AGPL-3.0-or-later# Copyright 2024-2025 wire Contributors
{ pkgs, lib, config, ...}:{ config = { systemd = { paths = lib.mapAttrs' ( _name: value: lib.nameValuePair "${value.name}-key" { description = "Monitor changes to ${value.path}. You should Require ${value.service} instead of this."; pathConfig = { PathExists = value.path; PathChanged = value.path; Unit = "${value.name}-key.service"; }; } ) config.deployment.keys;
system.activationScripts.setup-wire-rollback.text = '' mkdir -p /var/lib/wire-rollback chmod 700 /var/lib/wire-rollback '';
services = { wire-rollback = { enable = config.deployment.rollback; description = "Rolls back the NixOS profile if `/var/lib/wire-rollback/heartbeat` is not created in 30 seconds after this service starts."; documentation = [ "https://wire.althaea.zone/guides/rollback" ]; path = [ pkgs.coreutils ]; wantedBy = [ "multi-user.target" ]; script = '' set -euo pipefail
goal=$(<"/var/lib/wire-rollback/goal")
case $goal in "check" | "switch" | "boot" | "test" | "dry-activate") echo "<5>using goal $goal" ;; *) echo "<3>'$goal' is not a valid goal." exit 1 ;; esac
sleep 30
if [ -f "/var/lib/wire-rollback/heartbeat" ]; then exit 0 fi
echo "<1>/var/lib/wire-rollback/heartbeat does not exist, rolling back system"
# set current system nix-env --rollback --profile /nix/var/nix/profiles/system # get the path to the system we are now rolling back to system=$(readlink -f /nix/var/nix/profiles/system)
echo "<5>rolling back to $system"
# switch to the system using goal "$system/bin/switch-to-configuration $goal" ''; unitConfig = { ConditionPathExists = [ "/var/lib/wire-rollback/goal" "!/var/lib/wire-rollback/heartbeat" ]; }; serviceConfig = { Type = "oneshot"; Restart = "no"; StateDirectory = "wire-rollback"; NotifyAccess = "all"; RemainAfterExit = "yes";
ExecStopPost = "${pkgs.coreutils}/bin/rm -f /var/lib/wire-rollback/goal"; }; }; } // (lib.mapAttrs' ( _name: value: lib.nameValuePair "${value.name}-key" { description = "Service that requires ${value.path}"; path = [ pkgs.inotify-tools pkgs.coreutils ]; script = '' MSG="Key ${value.path} exists." systemd-notify --ready --status="$MSG"
echo "waiting to fail if the key is removed..."
while inotifywait -e delete_self "${value.path}"; do MSG="Key ${value.path} no longer exists."
systemd-notify --status="$MSG" echo $MSG
exit 1 done ''; unitConfig = { ConditionPathExists = value.path; }; serviceConfig = { Type = "simple"; Restart = "no"; NotifyAccess = "all"; RemainAfterExit = "yes"; }; } ) config.deployment.keys); };
deployment = { _keys = lib.mapAttrsToList ( _: value: value // { source = { # Attach type to internally tag serde enum t = builtins.replaceStrings [ "path" "string" "list" ] [ "Path" "String" "Command" ] ( builtins.typeOf value.source ); c = value.source; }; } ) config.deployment.keys;
_hostPlatform = config.nixpkgs.hostPlatform.system; }; };}