m2m16c (Mac mini M2 8c/16 Go loué) ; prepare : pm2 ls avant startup + chown ~/.pm2 (fichiers root après sudo)
2 changed files +7 −2
modified
mld/config.py
+3 −0
@@ -47,6 +47,7 @@ NODES = { | |||||
| 47 | "M1M64": {"cores": 10, "ram_gb": 64, "model": "Mac Studio"}, # ajouté 2026-09-08 (Mac13,1, M1 Max, loué, hors LAN — voir REMOTE_NODES) | 47 | "M1M64": {"cores": 10, "ram_gb": 64, "model": "Mac Studio"}, # ajouté 2026-09-08 (Mac13,1, M1 Max, loué, hors LAN — voir REMOTE_NODES) | ||
| 48 | "m2m16b": {"cores": 10, "ram_gb": 16, "model": "Mac mini"}, # ajouté 2026-09-08 (Mac14,12, M2 Pro, loué, hors LAN — voir REMOTE_NODES) | 48 | "m2m16b": {"cores": 10, "ram_gb": 16, "model": "Mac mini"}, # ajouté 2026-09-08 (Mac14,12, M2 Pro, loué, hors LAN — voir REMOTE_NODES) | ||
| 49 | "m1m16": {"cores": 8, "ram_gb": 16, "model": "Mac mini"}, # ajouté 2026-09-08 (Macmini9,1, M1, loué, hors LAN — voir REMOTE_NODES) | 49 | "m1m16": {"cores": 8, "ram_gb": 16, "model": "Mac mini"}, # ajouté 2026-09-08 (Macmini9,1, M1, loué, hors LAN — voir REMOTE_NODES) | ||
| 50 | + "m2m16c": {"cores": 8, "ram_gb": 16, "model": "Mac mini"}, # ajouté 2026-09-08 (Mac14,3, M2, loué, hors LAN — voir REMOTE_NODES) | ||||
| 50 | } | 51 | } | ||
| 51 | 52 | ||||
| 52 | # Nœuds HORS LAN : IP publique fixe + autre utilisateur + autre mot de passe sudo. Ils ne sont pas trouvés par le | 53 | # Nœuds HORS LAN : IP publique fixe + autre utilisateur + autre mot de passe sudo. Ils ne sont pas trouvés par le | ||
@@ -55,6 +56,7 @@ REMOTE_NODES = { | |||||
| 55 | "M1M64": {"host": "45.74.241.221", "user": "simon", "sudo_pw_file": os.path.join(STATE, ".sudo-M1M64")}, | 56 | "M1M64": {"host": "45.74.241.221", "user": "simon", "sudo_pw_file": os.path.join(STATE, ".sudo-M1M64")}, | ||
| 56 | "m2m16b": {"host": "208.52.154.68", "user": "administrator", "sudo_pw_file": os.path.join(STATE, ".sudo-m2m16b")}, | 57 | "m2m16b": {"host": "208.52.154.68", "user": "administrator", "sudo_pw_file": os.path.join(STATE, ".sudo-m2m16b")}, | ||
| 57 | "m1m16": {"host": "207.254.29.71", "user": "administrator", "sudo_pw_file": os.path.join(STATE, ".sudo-m1m16")}, | 58 | "m1m16": {"host": "207.254.29.71", "user": "administrator", "sudo_pw_file": os.path.join(STATE, ".sudo-m1m16")}, | ||
| 59 | + "m2m16c": {"host": "207.254.29.128", "user": "administrator", "sudo_pw_file": os.path.join(STATE, ".sudo-m2m16c")}, | ||||
| 58 | } | 60 | } | ||
| 59 | 61 | ||||
| 60 | 62 | ||||
@@ -86,6 +88,7 @@ RESERVED = { | |||||
| 86 | "M1M64": "nœud distant hors LAN (loué, user simon) : pas de LAN 192.168.2.x ni de gardiens Ka → placement seulement avec --node", | 88 | "M1M64": "nœud distant hors LAN (loué, user simon) : pas de LAN 192.168.2.x ni de gardiens Ka → placement seulement avec --node", | ||
| 87 | "m2m16b": "nœud distant hors LAN (loué, user administrator) : pas de LAN 192.168.2.x ni de gardiens Ka → placement seulement avec --node", | 89 | "m2m16b": "nœud distant hors LAN (loué, user administrator) : pas de LAN 192.168.2.x ni de gardiens Ka → placement seulement avec --node", | ||
| 88 | "m1m16": "nœud distant hors LAN (loué, user administrator) : pas de LAN 192.168.2.x ni de gardiens Ka → placement seulement avec --node", | 90 | "m1m16": "nœud distant hors LAN (loué, user administrator) : pas de LAN 192.168.2.x ni de gardiens Ka → placement seulement avec --node", | ||
| 91 | + "m2m16c": "nœud distant hors LAN (loué, user administrator) : pas de LAN 192.168.2.x ni de gardiens Ka → placement seulement avec --node", | ||||
| 89 | } | 92 | } | ||
| 90 | 93 | ||||
| 91 | # Rôles : gateway = jamais d'app ; worker = éligible. Un nœud absent du scan est « offline ». | 94 | # Rôles : gateway = jamais d'app ; worker = éligible. Un nœud absent du scan est « offline ». | ||
modified
mld/prepare.py
+4 −2
@@ -41,15 +41,17 @@ def prepare(alias, runtimes=None, ka_helpers=False): | |||||
| 41 | pw = _sudo_pw(alias) | 41 | pw = _sudo_pw(alias) | ||
| 42 | # pm2 startup doit tourner sous sudo (écrit le plist + launchctl load) ; l'ancien `${cmd#sudo }` le lançait sans sudo → « à faire manuellement » | 42 | # pm2 startup doit tourner sous sudo (écrit le plist + launchctl load) ; l'ancien `${cmd#sudo }` le lançait sans sudo → « à faire manuellement » | ||
| 43 | if pw: | 43 | if pw: | ||
| 44 | − script += ("mkdir -p ~/Library/LaunchAgents; if ! ls ~/Library/LaunchAgents 2>/dev/null | grep -qi pm2; then " | 44 | + # `pm2 ls` d'abord (crée ~/.pm2 sous l'utilisateur), puis chown après le startup sous sudo : sinon root laisse des fichiers dans ~/.pm2 → EACCES pm2.log | ||
| 45 | + script += ("mkdir -p ~/Library/LaunchAgents; pm2 ls >/dev/null 2>&1; if ! ls ~/Library/LaunchAgents 2>/dev/null | grep -qi pm2; then " | ||||
| 45 | "if echo %s | sudo -S -p '' env PATH=\"$PATH\" pm2 startup launchd -u %s --hp %s >/dev/null 2>&1; then echo ' pm2 startup: ok'; else echo ' pm2 startup: ÉCHEC'; fi; fi\n" | 46 | "if echo %s | sudo -S -p '' env PATH=\"$PATH\" pm2 startup launchd -u %s --hp %s >/dev/null 2>&1; then echo ' pm2 startup: ok'; else echo ' pm2 startup: ÉCHEC'; fi; fi\n" | ||
| 47 | + "echo %s | sudo -S -p '' chown -R %s ~/.pm2 2>/dev/null\n" | ||||
| 46 | "launchctl list 2>/dev/null | grep -qi pm2 || launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/pm2.*.plist >/dev/null 2>&1; " | 48 | "launchctl list 2>/dev/null | grep -qi pm2 || launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/pm2.*.plist >/dev/null 2>&1; " | ||
| 47 | "launchctl list 2>/dev/null | grep -qi pm2 && echo ' pm2 launchd: chargé' || echo ' pm2 launchd: NON chargé'\n" | 49 | "launchctl list 2>/dev/null | grep -qi pm2 && echo ' pm2 launchd: chargé' || echo ' pm2 launchd: NON chargé'\n" | ||
| 48 | # nœud sans session graphique (loué, M2U64…) : le domaine gui n'existe pas au boot → LaunchDaemon système avec UserName | 50 | # nœud sans session graphique (loué, M2U64…) : le domaine gui n'existe pas au boot → LaunchDaemon système avec UserName | ||
| 49 | "if ! launchctl print gui/$(id -u) >/dev/null 2>&1; then P=$(ls ~/Library/LaunchAgents/pm2.*.plist 2>/dev/null | head -1); " | 51 | "if ! launchctl print gui/$(id -u) >/dev/null 2>&1; then P=$(ls ~/Library/LaunchAgents/pm2.*.plist 2>/dev/null | head -1); " | ||
| 50 | "if [ -n \"$P\" ]; then L=$(/usr/libexec/PlistBuddy -c 'Print :Label' \"$P\"); D=/Library/LaunchDaemons/$(basename \"$P\"); " | 52 | "if [ -n \"$P\" ]; then L=$(/usr/libexec/PlistBuddy -c 'Print :Label' \"$P\"); D=/Library/LaunchDaemons/$(basename \"$P\"); " | ||
| 51 | "echo %s | sudo -S -p '' sh -c \"cp '$P' '$D' && /usr/libexec/PlistBuddy -c 'Delete :UserName' '$D' 2>/dev/null; /usr/libexec/PlistBuddy -c 'Add :UserName string %s' '$D' && chown root:wheel '$D' && chmod 644 '$D' && launchctl bootout system/$L 2>/dev/null; launchctl bootstrap system '$D' 2>/dev/null; launchctl print system/$L >/dev/null 2>&1 && echo ' pm2 LaunchDaemon (pas de session graphique) : chargé' || echo ' pm2 LaunchDaemon : NON chargé'\"; fi; fi\n") % ( | 53 | "echo %s | sudo -S -p '' sh -c \"cp '$P' '$D' && /usr/libexec/PlistBuddy -c 'Delete :UserName' '$D' 2>/dev/null; /usr/libexec/PlistBuddy -c 'Add :UserName string %s' '$D' && chown root:wheel '$D' && chmod 644 '$D' && launchctl bootout system/$L 2>/dev/null; launchctl bootstrap system '$D' 2>/dev/null; launchctl print system/$L >/dev/null 2>&1 && echo ' pm2 LaunchDaemon (pas de session graphique) : chargé' || echo ' pm2 LaunchDaemon : NON chargé'\"; fi; fi\n") % ( | ||
| 52 | − shlex.quote(pw), config.user_of(alias), config.home_of(alias), shlex.quote(pw), config.user_of(alias)) | 54 | + shlex.quote(pw), config.user_of(alias), config.home_of(alias), shlex.quote(pw), config.user_of(alias), shlex.quote(pw), config.user_of(alias)) | ||
| 53 | else: | 55 | else: | ||
| 54 | script += "echo ' pm2 startup: mot de passe sudo absent (%s)'\n" % config.sudo_pw_file(alias) | 56 | script += "echo ' pm2 startup: mot de passe sudo absent (%s)'\n" % config.sudo_pw_file(alias) | ||
| 55 | rc, out, err = ssh.run(ip, script, timeout=1800) | 57 | rc, out, err = ssh.run(ip, script, timeout=1800) | ||
| 56 | 58 | ||||