Skip to content

Instantly share code, notes, and snippets.

@eloquence
Created April 11, 2020 23:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eloquence/e2fe1fcacad898b18b0712a89a3864e2 to your computer and use it in GitHub Desktop.
Save eloquence/e2fe1fcacad898b18b0712a89a3864e2 to your computer and use it in GitHub Desktop.
#!/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