from time import time import subprocess from _socket import socket import argparse import time import socket import subprocess TARGET_LINK = "f0:2f:74:30:0c:d0" 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) return (response.returncode, response.stdout, response.stderr) def weboot(): code, stdout, stderr = remote_cmd("sudo efibootmgr -n 0000") if code == 0: code, stdout, stderr = remote_cmd("sudo reboot") time.sleep(60) if code != 0: raise RuntimeError(f"weboot failed {stderr}") return code, stdout, stderr def send_wol(): response = subprocess.run(f"wakeonlan {TARGET_LINK}", shell=True, capture_output=True, text=True) return (response.returncode, response.stdout, response.stderr) def get_os(): code, stdout, stderr = remote_cmd("whoami") if code == 255 and "No route to host" in stderr: return "offline" elif code != 0: raise RuntimeError(f"win_or_linux failed {stderr}") if "Windows" in stdout: return "windows" else: return "linux" def swap_os(): match get_os(): case "windows": code, stdout, stderr = remote_cmd("shutdown /r") case "linux": code, stdout, stderr = weboot() case "offline": return False return True def boot_linux(): match get_os(): case "windows": return False case "linux": return True case "offline": send_wol() time.sleep(60) return True def boot_windows(): match get_os(): case "windows": return True case "linux": return False case "offline": boot_linux() weboot() if get_os() == "windows": return True else: return False def reboot(): orig_os = get_os() match orig_os: case "windows": code, stdout, stderr = remote_cmd("shutdown /r") time.sleep(60) weboot() return True case "linux": code, stdout, stderr = remote_cmd("sudo reboot") return True case "offline": return False def shutdown(): match get_os(): case "windows": code, stdout, stderr = remote_cmd("shutdown /s") return True case "linux": code, stdout, stderr = remote_cmd("sudo shutdown -h now") return True case "offline": return False def action_do(action): match action: case "boot_linux": if boot_linux(): print("Linux is now running") else: print("Failed to boot Linux") case "boot_windows": if boot_windows(): print("Windows is now running") else: print("Failed to boot Windows") case "swap_os": if swap_os(): print("OS swapped successfully") else: print("Failed to swap OS") case "reboot": if reboot(): print("Reboot command sent successfully") else: print("Failed to reboot") case "shutdown": if shutdown(): print("Shutdown command sent successfully") else: print("Failed to shutdown") case "winupdate": if get_os() != "offline": print("Target is in use, belaying update 1h") time.sleep(3600) action_do("winupdate") code, stdout, stderr = remote_cmd("powershell -Command \"& {Install-WindowsUpdate -AcceptAll -AutoReboot}\"") if code == 0: print("Windows update initiated successfully") else: print(f"Failed to initiate Windows update: {stderr}") #first reboot to windows time.sleep(300) weboot() #second reboot after update time.sleep(600) reboot() #shutdown time.sleep(300) shutdown() 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") action_do(parser.parse_args().action)