Archived
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe9fc7364b | ||
|
|
1ce4589830 | ||
|
|
7417cc1b0a | ||
|
|
ec44b7955b | ||
|
|
cf3d8ea9a5 | ||
|
|
756e45743c | ||
|
|
7e8755d141 | ||
|
|
8194707478 | ||
|
|
164d14eb87 | ||
|
|
720399b00d | ||
|
|
601db79689 | ||
|
|
fc8f7baf3e |
No files matched your search
@@ -81,4 +81,70 @@
|
||||
programs.firefox.enable = true;
|
||||
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# GUI-specific Home Manager additions for the IPA primary user, extending
|
||||
# the baseline in modules/ipa/client.nix with desktop apps and services
|
||||
# that only make sense on a graphical workstation.
|
||||
home-manager.users.${vars.ipaUser} = { pkgs, ... }: {
|
||||
home = {
|
||||
packages = with pkgs; [
|
||||
git
|
||||
vim
|
||||
nextcloud-client
|
||||
chromium
|
||||
claude-code
|
||||
fish
|
||||
sops
|
||||
];
|
||||
sessionVariables = {
|
||||
EDITOR = "vim";
|
||||
SOPS_AGE_KEY_FILE = "/home/${vars.ipaUser}/.config/sops/age/keys.txt";
|
||||
};
|
||||
file = {
|
||||
".local/share/applications/proxmox-chromium-app.desktop".text = ''
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Proxmox (Chromium)
|
||||
Exec=chromium --app=https://pve.${vars.homeDomain}:${toString vars.ports.pveWeb} --window-size=1920,1080 --window-position=0,0
|
||||
Icon=/home/${vars.ipaUser}/.local/share/icons/proxmox.png
|
||||
Terminal=false
|
||||
Categories=Hypervisor;
|
||||
StartupWMClass=PVE
|
||||
'';
|
||||
".local/share/applications/pbs-chromium-app.desktop".text = ''
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Proxmox Backup Server (Chromium)
|
||||
Exec=chromium --app=https://${vars.pbsIp}:${toString vars.ports.pbsWeb} --window-size=1920,1080 --window-position=0,0
|
||||
Icon=/home/${vars.ipaUser}/.local/share/icons/proxmox.png
|
||||
Terminal=false
|
||||
Categories=backup;
|
||||
'';
|
||||
".local/share/applications/proxmox-firefox-app.desktop".text = ''
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Proxmox (Firefox)
|
||||
Exec=firefox --new-instance https://pve.${vars.homeDomain}:${toString vars.ports.pveWeb} --profile ProxmoxWebApp --window-size=1920,1080 --class ProxmoxWebApp
|
||||
Icon=/home/${vars.ipaUser}/.local/share/icons/proxmox.png
|
||||
Terminal=false
|
||||
Categories=Hypervisor;
|
||||
StartupWMClass=PVE
|
||||
'';
|
||||
".local/share/applications/pbs-firefox-app.desktop".text = ''
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Proxmox Backup Server (Firefox)
|
||||
Exec=firefox --new-window https://${vars.pbsIp}:${toString vars.ports.pbsWeb} --profile PbsWebApp --window-size=1920,1080 --class PbsWebApp
|
||||
Icon=/home/${vars.ipaUser}/.local/share/icons/proxmox.png
|
||||
Terminal=false
|
||||
Categories=backup;
|
||||
StartupWMClass=PBS
|
||||
'';
|
||||
};
|
||||
};
|
||||
services.nextcloud-client = {
|
||||
enable = true;
|
||||
startInBackground = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
{ lib, pkgs, vars, ... }:
|
||||
|
||||
let
|
||||
gid = toString vars.dockerAccessGid;
|
||||
in
|
||||
{
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
@@ -16,4 +19,27 @@
|
||||
docker-compose
|
||||
docker-buildx
|
||||
];
|
||||
|
||||
# NixOS's group activation uses plain `groupmod` without --non-unique.
|
||||
# When SSSD is active it exposes the IPA "docker-access" group at
|
||||
# vars.dockerAccessGid via NSS, so groupmod sees that GID as already in
|
||||
# use and silently skips the change (warning: "not applying GID change").
|
||||
# This script runs after the normal "groups" step and applies the change
|
||||
# with --non-unique (which lets the local docker group share the GID with
|
||||
# the SSSD-provided IPA group). If the GID actually changed it also
|
||||
# restarts docker.socket so the socket is recreated with the new GID.
|
||||
system.activationScripts.docker-group-gid = {
|
||||
deps = [ "groups" ];
|
||||
text = ''
|
||||
current=$(grep "^docker:" /etc/group | cut -d: -f3)
|
||||
if [ "$current" != "${gid}" ]; then
|
||||
${pkgs.shadow}/bin/groupmod --non-unique -g ${gid} docker
|
||||
if ${pkgs.systemd}/bin/systemctl is-active --quiet docker.socket; then
|
||||
${pkgs.systemd}/bin/systemctl stop docker.service docker.socket
|
||||
rm -f /var/run/docker.sock
|
||||
${pkgs.systemd}/bin/systemctl start docker.socket docker.service
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
+17
-1
@@ -60,6 +60,15 @@ lib.mkIf enabled {
|
||||
pam.services = {
|
||||
sshd.makeHomeDir = true;
|
||||
lightdm.makeHomeDir = true;
|
||||
|
||||
# pam_unix returns PAM_AUTHINFO_UNAVAIL without prompting when the local
|
||||
# stub has "!" in shadow (account locked), so PAM_AUTHTOK is never set
|
||||
# and pam_sss's use_first_pass fails with "No authentication token".
|
||||
# Changing to try_first_pass makes pam_sss prompt independently when no
|
||||
# prior module has set the token, restoring IPA password login via
|
||||
# LightDM and su.
|
||||
login.rules.auth.sss.settings = lib.mkForce { try_first_pass = true; };
|
||||
su.rules.auth.sss.settings = lib.mkForce { try_first_pass = true; };
|
||||
};
|
||||
|
||||
# HM with useUserPackages = true (flake.nix) sets users.users.${ipaUser}.packages,
|
||||
@@ -170,6 +179,13 @@ lib.mkIf enabled {
|
||||
group = "users";
|
||||
extraGroups = [ "wheel" ];
|
||||
createHome = false;
|
||||
# "!" is not a password hash — it is the standard "account locked" marker.
|
||||
# It cannot authenticate anyone locally. It exists solely so NixOS generates
|
||||
# a shadow entry for this stub user; without one pam_unix returns
|
||||
# PAM_AUTHINFO_UNAVAIL before prompting, which means PAM_AUTHTOK is never
|
||||
# set and the subsequent pam_sss use_first_pass call has nothing to work
|
||||
# with — blocking LightDM and su logins even when IPA/SSSD auth succeeds.
|
||||
hashedPassword = "!";
|
||||
};
|
||||
|
||||
# Home Manager config for the IPA primary user, applied on every enrolled
|
||||
@@ -186,7 +202,7 @@ lib.mkIf enabled {
|
||||
homeDirectory = lib.mkForce "/home/${vars.ipaUser}";
|
||||
stateVersion = "26.05";
|
||||
packages = with pkgs; [ tmux sshfs ];
|
||||
sessionVariables.EDITOR = "nano";
|
||||
sessionVariables.EDITOR = lib.mkDefault "nano";
|
||||
};
|
||||
programs.home-manager.enable = true;
|
||||
programs.bash.enable = true;
|
||||
|
||||
@@ -103,11 +103,16 @@ n2_ssh "mkdir -p /etc/corosync"
|
||||
n2_scp "$AUTHKEY" "$AUTHKEY"
|
||||
n2_ssh "chmod 0400 '${AUTHKEY}'"
|
||||
|
||||
log "Restarting corosync on both nodes..."
|
||||
log "Restarting corosync and pacemaker on both nodes..."
|
||||
systemctl restart corosync
|
||||
n2_ssh "systemctl restart corosync"
|
||||
sleep 3
|
||||
|
||||
log "Starting pacemaker on both nodes (may have failed at boot before authkey was placed)..."
|
||||
systemctl start pacemaker 2>/dev/null || systemctl restart pacemaker 2>/dev/null || true
|
||||
n2_ssh "systemctl start pacemaker 2>/dev/null || systemctl restart pacemaker 2>/dev/null || true"
|
||||
sleep 2
|
||||
|
||||
# ── 1. Corosync quorum ────────────────────────────────────────────────────
|
||||
log "Waiting for corosync quorum..."
|
||||
for i in $(seq 1 30); do
|
||||
|
||||
@@ -355,58 +355,6 @@ if ! $SKIP_CLUSTER_INIT; then
|
||||
"sudo mkdir -p /root/.ssh && sudo cp /tmp/cluster-init-key /root/.ssh/cluster-init-key && \
|
||||
sudo chmod 600 /root/.ssh/cluster-init-key && rm -f /tmp/cluster-init-key"
|
||||
|
||||
# Fix targetctl.service on both nodes: the iscsi-target.nix module bakes
|
||||
# pkgs.targetcli-fb for the targetctl binary, but targetctl is actually in
|
||||
# rtslib-fb (a different store path). Apply a runtime dropin that corrects
|
||||
# both ExecStart and ExecStop before Pacemaker ever touches the service.
|
||||
# The fixed iscsi-target.nix module will make this redundant on next rebuild.
|
||||
logn "Patching targetctl.service on both nodes..."
|
||||
_patch_targetctl() {
|
||||
local ip="$1"
|
||||
ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no "${HA_USER}@${ip}" sudo bash << 'PATCH'
|
||||
set -euo pipefail
|
||||
TC=$(find /nix/store -maxdepth 4 -path '*/python3*env/bin/targetctl' 2>/dev/null | head -1)
|
||||
PY=$(find /nix/store -maxdepth 4 -path '*/python3*env/bin/python3' -name 'python3' 2>/dev/null | \
|
||||
while IFS= read -r p; do "$p" -c "import rtslib_fb" 2>/dev/null && echo "$p" && break; done | head -1)
|
||||
[[ -n "$TC" && -n "$PY" ]] || { echo "targetctl or python3+rtslib_fb not found"; exit 1; }
|
||||
# Write stop script that saves LIO config then tears down kernel state
|
||||
"$PY" - "$TC" "$PY" << 'PYEOF'
|
||||
import sys, os, stat
|
||||
tc, py = sys.argv[1], sys.argv[2]
|
||||
script = f"""#!{py}
|
||||
import subprocess, sys, rtslib_fb
|
||||
root = rtslib_fb.RTSRoot()
|
||||
targets = list(root.targets)
|
||||
if targets:
|
||||
r = subprocess.run(["{tc}", "save", "/etc/target/saveconfig.json"], capture_output=True)
|
||||
print(f"saved {{len(targets)}} target(s); rc={{r.returncode}}")
|
||||
else:
|
||||
print("no active LIO targets")
|
||||
for t in targets:
|
||||
try:
|
||||
for tpg in list(t.tpgs): tpg.enable = False
|
||||
t.delete()
|
||||
except Exception as e: print(f"warn: {{e}}", file=sys.stderr)
|
||||
for so in list(root.storage_objects):
|
||||
try: so.delete()
|
||||
except Exception as e: print(f"warn: {{e}}", file=sys.stderr)
|
||||
print("LIO kernel target cleared")
|
||||
"""
|
||||
path = "/run/ha-targetctl-stop.py"
|
||||
with open(path, "w") as f: f.write(script)
|
||||
os.chmod(path, 0o755)
|
||||
print(f"wrote {path}")
|
||||
PYEOF
|
||||
mkdir -p /run/systemd/system/targetctl.service.d
|
||||
printf '[Service]\nExecStart=\nExecStart=%s restore /etc/target/saveconfig.json\nExecStop=\nExecStop=/run/ha-targetctl-stop.py\n' \
|
||||
"$TC" > /run/systemd/system/targetctl.service.d/fix-exec.conf
|
||||
systemctl daemon-reload
|
||||
echo "patched on $(hostname)"
|
||||
PATCH
|
||||
}
|
||||
_patch_targetctl "${NODE1_IP}"
|
||||
_patch_targetctl "${NODE2_IP}"
|
||||
|
||||
logn "Uploading cluster-init.sh to ${NODE1_HOST}..."
|
||||
scp -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no \
|
||||
"$CLUSTER_INIT" "${HA_USER}@${NODE1_IP}:/tmp/cluster-init.sh"
|
||||
|
||||
Reference in new issue
Block a user