diff --git a/hosts/tower/configuration.nix b/hosts/tower/configuration.nix index f8d9813..64ac02c 100644 --- a/hosts/tower/configuration.nix +++ b/hosts/tower/configuration.nix @@ -61,6 +61,6 @@ }; systemPackages = [ pkgs.efibootmgr - ] + ]; }; } # end file diff --git a/util/wol_man.py b/util/wol_man.py index cd178f5..c0d58fa 100644 --- a/util/wol_man.py +++ b/util/wol_man.py @@ -11,10 +11,12 @@ TARGET_HOSTNAME = "tower.home.the.malice.zone" TARGET_IP = socket.gethostbyname(TARGET_HOSTNAME) def remote_cmd(command): - response = subprocess.run(f"ssh tower '{command}", shell=True, capture_output=True, text=True) + print(f"Executing: ssh tower '{command}'") + response = subprocess.run(f"ssh tower '{command}'", shell=True, capture_output=True, text=True) return (response.returncode, response.stdout, response.stderr) def weboot(): + print("Rebooting to windows") code, stdout, stderr = remote_cmd("sudo efibootmgr -n 0000") if code == 0: code, stdout, stderr = remote_cmd("sudo reboot") @@ -24,19 +26,23 @@ def weboot(): return code, stdout, stderr def send_wol(): + print(f"Broadcasting WOL packet to {TARGET_LINK}") response = subprocess.run(f"wakeonlan {TARGET_LINK}", shell=True, capture_output=True, text=True) return (response.returncode, response.stdout, response.stderr) def get_os(): + print("Determining target OS") code, stdout, stderr = remote_cmd("whoami") if code == 255 and "No route to host" in stderr: + print("Target is offline") return "offline" elif code != 0: raise RuntimeError(f"win_or_linux failed {stderr}") - if "Windows" in stdout: + if "windows" in stdout.lower(): + print("Target is running Windows") return "windows" - else: + print("Target is running Linux") return "linux" def swap_os(): @@ -50,23 +56,31 @@ def swap_os(): return True def boot_linux(): + print("Booting Linux") match get_os(): case "windows": + print("Tower is busy") return False case "linux": + print("Linux is already running") return True case "offline": + print("Booting via WOL") send_wol() time.sleep(60) return True def boot_windows(): + print("Booting Windows") match get_os(): case "windows": + print("Windows is already running") return True case "linux": + print("Tower is busy") return False case "offline": + print("Booting via WOL") boot_linux() weboot() if get_os() == "windows": @@ -75,6 +89,7 @@ def boot_windows(): return False def reboot(): + print("Rebooting target") orig_os = get_os() match orig_os: case "windows": @@ -86,21 +101,29 @@ def reboot(): code, stdout, stderr = remote_cmd("sudo reboot") return True case "offline": + print("Target is offline, cannot reboot") return False def shutdown(): + print("Shutting down target") match get_os(): case "windows": code, stdout, stderr = remote_cmd("shutdown /s") + time.sleep(30) return True case "linux": code, stdout, stderr = remote_cmd("sudo shutdown -h now") + time.sleep(30) return True case "offline": + print("Target is already offline") return False def action_do(action): match action: + case "get_os": + os = get_os() + print(f"Current OS: {os}") case "boot_linux": if boot_linux(): print("Linux is now running") @@ -131,6 +154,11 @@ def action_do(action): print("Target is in use, belaying update 1h") time.sleep(3600) action_do("winupdate") + if boot_windows(): + print("Initiating Windows update") + else: + print("Failed to boot Windows for update") + return code, stdout, stderr = remote_cmd("powershell -Command \"& {Install-WindowsUpdate -AcceptAll -AutoReboot}\"") if code == 0: print("Windows update initiated successfully") @@ -146,8 +174,10 @@ def action_do(action): time.sleep(300) shutdown() -def main():: +def main(): parser = argparse.ArgumentParser(description="WOL and reboot utility") - parser.add_argument("action", choices=["boot_linux", "boot_windows", "swap_os", "reboot", "shutdown", "winupdate"], help="Action to perform") + parser.add_argument("action", choices=["get_os", "boot_linux", "boot_windows", "swap_os", "reboot", "shutdown", "winupdate"], help="Action to perform") action_do(parser.parse_args().action) +if __name__ == "__main__": + main() \ No newline at end of file