darwin: add imalison migration target

This commit is contained in:
2026-05-02 21:05:35 -07:00
parent b4a7096ac9
commit d652f80d05
5 changed files with 171 additions and 80 deletions

76
nix-darwin/flake.lock generated
View File

@@ -48,6 +48,23 @@
} }
}, },
"brew-src": { "brew-src": {
"flake": false,
"locked": {
"lastModified": 1777253336,
"narHash": "sha256-IYVi28jebMUfQ3MDPG9IkSrLsf09Y7ShsNo+n4cmURU=",
"owner": "Homebrew",
"repo": "brew",
"rev": "b9763ee5280dc1acb3036383b3608084eebac6b7",
"type": "github"
},
"original": {
"owner": "Homebrew",
"ref": "5.1.8",
"repo": "brew",
"type": "github"
}
},
"brew-src_2": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1776478798, "lastModified": 1776478798,
@@ -64,23 +81,6 @@
"type": "github" "type": "github"
} }
}, },
"brew-src_2": {
"flake": false,
"locked": {
"lastModified": 1774235677,
"narHash": "sha256-0ryNYmzDAeRlrzPTAgmzGH/Cgc8iv/LBN6jWGUANvIk=",
"owner": "Homebrew",
"repo": "brew",
"rev": "894a3d23ac0c8aaf561b9874b528b9cb2e839201",
"type": "github"
},
"original": {
"owner": "Homebrew",
"ref": "5.1.1",
"repo": "brew",
"type": "github"
}
},
"claude-code-nix": { "claude-code-nix": {
"inputs": { "inputs": {
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
@@ -89,11 +89,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1777126457, "lastModified": 1777604373,
"narHash": "sha256-jE5KMGZc9p2H86gCi38o2H3loV/OwICJVa8YbDmpDyg=", "narHash": "sha256-cQ+Z/fx5o43bD3PFZaz9yeEOVbAH1jqzdOiEP0ytW4M=",
"owner": "sadjow", "owner": "sadjow",
"repo": "claude-code-nix", "repo": "claude-code-nix",
"rev": "002de6e1b2d10f4646c68af360d9dc92b89a6be9", "rev": "8bd0a84bcfbd7e76eaa1c3421fc59861eb8a8f24",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -377,11 +377,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1777151655, "lastModified": 1777659959,
"narHash": "sha256-Th3a5OZyEy4kCoyLfefnt+2dwRIrFQqYgMsayF9qzFw=", "narHash": "sha256-ax3229dUvNuwTQwo2o68kOQ24dvOlJ/BrVYY4miD1bI=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "6f59831b23d03bbf4fbd13ad167ae25da294cc14", "rev": "5c1b74905c7261e8280dcda3623dbe677a1bc158",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -415,11 +415,11 @@
"homebrew-cask": { "homebrew-cask": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1777159046, "lastModified": 1777656023,
"narHash": "sha256-/3NNjeudK+0vc4ZyCIyIf80gbhDyXWjJzLUuMaPilMI=", "narHash": "sha256-h2aRm8tXWVRA9DN2JTwPwoZ4RZdJM4kYa6HnHamZqdo=",
"owner": "homebrew", "owner": "homebrew",
"repo": "homebrew-cask", "repo": "homebrew-cask",
"rev": "191adc33f03f399c8d97c438c8a1a9acea173f0b", "rev": "bdf39e6ffff60aa5a5b752f242094b25b96d232e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -431,11 +431,11 @@
"homebrew-core": { "homebrew-core": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1777157463, "lastModified": 1777660361,
"narHash": "sha256-SM5CtkgezWUgd2zmIQVBcRtWpSE3VVgj5dP6nnQ5sBo=", "narHash": "sha256-QWdFILBUcdvYHM3pcU7h4HgwSiX8zf8vOesUz48NAFQ=",
"owner": "homebrew", "owner": "homebrew",
"repo": "homebrew-core", "repo": "homebrew-core",
"rev": "8a0c7637b90ce943cd9f4520c8a1d13df81ee276", "rev": "bbc26e4e60ac052340242afc4a4712f2bad35704",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -455,11 +455,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1777109987, "lastModified": 1777434099,
"narHash": "sha256-8obD0vLqaPIhu5q6guZ3XN70+9OGzA2GWKQC4/PNcVo=", "narHash": "sha256-GutKXyfGI7o89Dge4bP0yt0CQn1rqA6LyYDOH4GemdE=",
"owner": "colonelpanic8", "owner": "colonelpanic8",
"repo": "keepbook", "repo": "keepbook",
"rev": "a130c6592f215e8e5727e9fd6eafd234f09f9341", "rev": "240fe454c26e7dbdd25a2fa4f0b436bf1c4f937b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -493,11 +493,11 @@
"brew-src": "brew-src_2" "brew-src": "brew-src_2"
}, },
"locked": { "locked": {
"lastModified": 1774720267, "lastModified": 1777250621,
"narHash": "sha256-YYftFe8jyfpQI649yfr0E+dqEXE2jznZNcYvy/lKV1U=", "narHash": "sha256-WynkkG0hdZ5niYPJUbVg7oMfu8MVwGGzKZ6lKmfa+O8=",
"owner": "zhaofengli-wip", "owner": "zhaofengli-wip",
"repo": "nix-homebrew", "repo": "nix-homebrew",
"rev": "a7760a3a83f7609f742861afb5732210fdc437ed", "rev": "aeb2069920742d0d6570089e8b3b8620050bacf2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -524,11 +524,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1776949667, "lastModified": 1777425547,
"narHash": "sha256-GMSVw35Q+294GlrTUKlx087E31z7KurReQ1YHSKp5iw=", "narHash": "sha256-d57AbflkNfZNoFaZDzssEq1RfPoM9dLtOGI2O+N/68Q=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "01fbdeef22b76df85ea168fbfe1bfd9e63681b30", "rev": "ebc08544afa77957cc348ba72dc490ec73b87f68",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -15,7 +15,7 @@
}; };
nix-homebrew.url = "github:zhaofengli-wip/nix-homebrew"; nix-homebrew.url = "github:zhaofengli-wip/nix-homebrew";
brew-src = { brew-src = {
url = "github:Homebrew/brew/5.1.7"; url = "github:Homebrew/brew/5.1.8";
flake = false; flake = false;
}; };
@@ -71,27 +71,26 @@
... ...
}: let }: let
libDir = ../dotfiles/lib; libDir = ../dotfiles/lib;
# Keep this on the currently-existing macOS account until the target user
# exists locally and its home directory has been migrated.
activePrimaryUser = "kat"; activePrimaryUser = "kat";
targetPrimaryUser = "imalison"; targetPrimaryUser = "imalison";
primaryUser = activePrimaryUser;
personalUsers = [ personalUsers = [
activePrimaryUser activePrimaryUser
targetPrimaryUser targetPrimaryUser
]; ];
# Home Manager activation should only target accounts that exist today.
# Add targetPrimaryUser here when the macOS account is ready.
enabledHomeUsers = [
activePrimaryUser
];
sharedHomeModules = [ sharedHomeModules = [
./home/common.nix ./home/common.nix
./home/git-sync.nix ./home/git-sync.nix
./home/syncthing.nix ./home/syncthing.nix
]; ];
homeForUser = user: "/Users/${user}"; homeForUser = user: "/Users/${user}";
configuration = { mkUserDescription = user:
if user == targetPrimaryUser
then "Ivan Malison"
else null;
mkConfiguration = {
primaryUser,
enabledHomeUsers ? [primaryUser],
}: {
pkgs, pkgs,
lib, lib,
config, config,
@@ -229,8 +228,13 @@
system.activationScripts.postActivation.text = '' system.activationScripts.postActivation.text = ''
echo >&2 "current-host screensaver defaults..." echo >&2 "current-host screensaver defaults..."
launchctl asuser "$(id -u -- ${primaryUser})" sudo --user=${primaryUser} -- defaults -currentHost write com.apple.screensaver askForPassword -bool false primary_uid="$(id -u -- ${primaryUser})"
launchctl asuser "$(id -u -- ${primaryUser})" sudo --user=${primaryUser} -- defaults -currentHost write com.apple.screensaver askForPasswordDelay -int 0 if launchctl print "gui/$primary_uid" >/dev/null 2>&1; then
launchctl asuser "$primary_uid" sudo --user=${primaryUser} -- defaults -currentHost write com.apple.screensaver askForPassword -bool false
launchctl asuser "$primary_uid" sudo --user=${primaryUser} -- defaults -currentHost write com.apple.screensaver askForPasswordDelay -int 0
else
echo >&2 "skipping current-host screensaver defaults; ${primaryUser} has no GUI launchd session"
fi
''; '';
power.sleep = { power.sleep = {
@@ -287,7 +291,6 @@
essentialPkgs essentialPkgs
++ [ ++ [
pkgs.gnupg pkgs.gnupg
pkgs.spotify
]; ];
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
@@ -310,20 +313,26 @@
"ghostty" "ghostty"
"hammerspoon" "hammerspoon"
"raycast" "raycast"
"spotify"
"vlc" "vlc"
]; ];
masApps = { masApps = {
Xcode = 497799835; Xcode = 497799835;
}; };
onActivation.cleanup = "zap"; greedyCasks = true;
onActivation = {
cleanup = "zap";
};
}; };
# Auto upgrade nix package and the daemon service. # Auto upgrade nix package and the daemon service.
launchd.user.envVariables.PATH = config.environment.systemPath; launchd.user = lib.mkIf (primaryUser == activePrimaryUser) {
launchd.user.agents.hammerspoon.serviceConfig = { envVariables.PATH = config.environment.systemPath;
agents.hammerspoon.serviceConfig = {
ProgramArguments = ["/usr/bin/open" "-gja" "Hammerspoon"]; ProgramArguments = ["/usr/bin/open" "-gja" "Hammerspoon"];
RunAtLoad = true; RunAtLoad = true;
}; };
};
programs.direnv.enable = true; programs.direnv.enable = true;
@@ -354,6 +363,7 @@
lib.genAttrs personalUsers (user: { lib.genAttrs personalUsers (user: {
name = user; name = user;
home = homeForUser user; home = homeForUser user;
description = mkUserDescription user;
openssh.authorizedKeys.keys = inputs.railbird-secrets.keys.kanivanKeys; openssh.authorizedKeys.keys = inputs.railbird-secrets.keys.kanivanKeys;
}) })
// { // {
@@ -380,8 +390,11 @@
users = lib.genAttrs enabledHomeUsers (_: {}); users = lib.genAttrs enabledHomeUsers (_: {});
}; };
}; };
in { mkDarwinSystem = {
darwinConfigurations."mac-demarco-mini" = nix-darwin.lib.darwinSystem { primaryUser,
enabledHomeUsers ? [primaryUser],
}:
nix-darwin.lib.darwinSystem {
modules = [ modules = [
agenix.darwinModules.default agenix.darwinModules.default
home-manager.darwinModules.home-manager home-manager.darwinModules.home-manager
@@ -394,8 +407,8 @@
package = package =
inputs.brew-src inputs.brew-src
// { // {
name = "brew-5.1.7"; name = "brew-5.1.8";
version = "5.1.7"; version = "5.1.8";
}; };
taps = { taps = {
"homebrew/homebrew-core" = inputs.homebrew-core; "homebrew/homebrew-core" = inputs.homebrew-core;
@@ -403,9 +416,22 @@
}; };
}; };
} }
configuration (mkConfiguration {inherit primaryUser enabledHomeUsers;})
]; ];
}; };
in {
# The default remains on the currently existing macOS account. Switch to
# mac-demarco-mini-imalison after the target login account and home are in
# place.
darwinConfigurations."mac-demarco-mini" = mkDarwinSystem {
primaryUser = activePrimaryUser;
enabledHomeUsers = [activePrimaryUser];
};
darwinConfigurations."mac-demarco-mini-imalison" = mkDarwinSystem {
primaryUser = targetPrimaryUser;
enabledHomeUsers = [targetPrimaryUser];
};
# Expose the package set, including overlays, for convenience. # Expose the package set, including overlays, for convenience.
darwinPackages = self.darwinConfigurations."mac-demarco-mini".pkgs; darwinPackages = self.darwinConfigurations."mac-demarco-mini".pkgs;

View File

@@ -153,7 +153,11 @@ in {
done < "$password_store_gpg_id" done < "$password_store_gpg_id"
if [ "$needs_import" -eq 1 ]; then if [ "$needs_import" -eq 1 ]; then
if [ -n "''${XDG_RUNTIME_DIR:-}" ] && [ -r "${gpgKeyPath}" ] && [ -r "${gpgPassphrasePath}" ]; then
${importGpgKeyScript} ${importGpgKeyScript}
else
echo "Skipping GPG key import; agenix runtime secrets are not available yet" >&2
fi
fi fi
fi fi
''; '';

View File

@@ -1,8 +1,21 @@
hostname := "mac-demarco-mini" hostname := "mac-demarco-mini"
target-hostname := "mac-demarco-mini-imalison"
build:
sudo -H /run/current-system/sw/bin/nix run nix-darwin -- build --flake .#{{hostname}}
build-imalison:
sudo -H /run/current-system/sw/bin/nix run nix-darwin -- build --flake .#{{target-hostname}}
check-imalison:
./scripts/check-imalison-ready.sh
switch: switch:
sudo -H /run/current-system/sw/bin/nix run nix-darwin -- switch --flake .#{{hostname}} sudo -H /run/current-system/sw/bin/nix run nix-darwin -- switch --flake .#{{hostname}}
switch-imalison: check-imalison
sudo -H /run/current-system/sw/bin/nix run nix-darwin -- switch --flake .#{{target-hostname}}
update: update:
/run/current-system/sw/bin/nix flake update /run/current-system/sw/bin/nix flake update
just switch just switch

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
set -euo pipefail
target_user="${TARGET_USER:-imalison}"
target_home="${TARGET_HOME:-/Users/${target_user}}"
dotfiles_checkout="${DOTFILES_CHECKOUT:-${target_home}/dotfiles}"
failures=0
check() {
local description="$1"
shift
if "$@" >/dev/null 2>&1; then
printf 'ok: %s\n' "$description"
else
printf 'missing: %s\n' "$description" >&2
failures=$((failures + 1))
fi
}
check "macOS user ${target_user} exists" id -u "$target_user"
check "home directory ${target_home} exists" sudo test -d "$target_home"
check "home directory is owned by ${target_user}" sudo sh -c '[ "$(stat -f "%Su" "$1")" = "$2" ]' sh "$target_home" "$target_user"
check "dotfiles checkout exists at ${dotfiles_checkout}" sudo test -d "$dotfiles_checkout/.git"
check "nix-darwin checkout exists under target home" sudo test -d "$dotfiles_checkout/nix-darwin"
check "SSH identity exists for agenix and git" sudo test -r "$target_home/.ssh/id_ed25519"
check "password store exists for pass/git-sync" sudo test -d "$target_home/.password-store"
check "org checkout exists for git-sync" sudo test -d "$target_home/org"
if [ "$failures" -ne 0 ]; then
cat >&2 <<EOF
${target_user} is not ready for nix-darwin activation yet.
Create or rename the macOS login account first, migrate the home data into
${target_home}, then rerun:
just check-imalison
Once every check passes, switch with:
just switch-imalison
EOF
exit 1
fi
printf '\n%s is ready for the imalison nix-darwin target.\n' "$target_user"