Created
April 11, 2020 23:12
-
-
Save eloquence/e2fe1fcacad898b18b0712a89a3864e2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/python3 | |
import subprocess | |
import sys | |
import time | |
def main(): | |
if len(sys.argv) == 1: | |
print("Syntax: force-shutdown.py vm-name") | |
exit(1) | |
vm = sys.argv[1] | |
vm_state = get_state(vm) | |
if vm_state == 0: | |
force_shutdown(vm) | |
elif vm_state == 1: | |
print("VM '{}' is not running.".format(vm)) | |
exit(0) | |
elif vm_state == 2: | |
print("VM '{}' does not exist.".format(vm)) | |
exit(1) | |
else: | |
print("VM '{}' is in an unknown state. Attempting shutdown.".format(vm)) | |
force_shutdown(vm) | |
def force_shutdown(vm): | |
print("Attempting to shut down VM '{}'.".format(vm)) | |
try: | |
subprocess.check_output( | |
["qvm-run", "-u", "root", vm, "poweroff"], stderr=subprocess.STDOUT | |
) | |
except subprocess.CalledProcessError as e: | |
# Exit codes 1 and 143 may occur with successful shutdown; log others | |
if e.returncode != 1 and e.returncode != 143: | |
print( | |
"poweroff returned exit code {} and the following output:\n".format( | |
e.returncode | |
) | |
) | |
print(e.output.decode("utf-8")) | |
wait_shutdown(vm) | |
def wait_shutdown(vm, timeout=60.0, interval=0.2): | |
start_time = time.time() | |
stop_time = start_time + timeout | |
print("Polling VM '{}' until it is shut down.".format(vm), end="", flush=True) | |
while time.time() < stop_time: | |
vm_state = get_state(vm) | |
elapsed = time.time() - start_time | |
if vm_state == 0: | |
print(".", end="", flush=True) | |
elif vm_state == 1: | |
print( | |
"\nVM '{}' sucessfully shut down. Elapsed time: {:.2f} seconds".format( | |
vm, elapsed | |
) | |
) | |
return | |
elif vm_state > 1: | |
print("\nVM '{}' entered an unknown state.".format(vm)) | |
return | |
time.sleep(interval) | |
print( | |
"\nVM '{}' did not shut down in the provided timeout of {} seconds.".format( | |
vm, timeout | |
) | |
) | |
def get_state(vm): | |
try: | |
subprocess.check_call(["qvm-check", "--running", vm], stderr=subprocess.DEVNULL) | |
except subprocess.CalledProcessError as e: | |
return e.returncode | |
return 0 | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment