implemented host status, ceph integeration, monkey patched vnc port number

This commit is contained in:
ahmadbilalkhalid 2019-07-18 15:56:46 +05:00
parent ebbd04ad03
commit b021d63a3e
4 changed files with 288 additions and 38 deletions

View File

@ -4,10 +4,12 @@ url = "https://pypi.org/simple"
verify_ssl = true verify_ssl = true
[dev-packages] [dev-packages]
bandit = "*"
[packages] [packages]
python-decouple = "*" python-decouple = "*"
etcd3 = "*" etcd3 = "*"
cython = "*"
[requires] [requires]
python_version = "3.7" python_version = "3.7"

210
Pipfile.lock generated Normal file
View File

@ -0,0 +1,210 @@
{
"_meta": {
"hash": {
"sha256": "60ec9dd9adb030a2f5c569016cd23b6d3c2bf29c3ee746531017928b0b496fe7"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.7"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"cython": {
"hashes": [
"sha256:04ebf16df9406d3279a2489c3327803c782d9e17637d525bfb44ecf5ec65850f",
"sha256:1486ec88d1c73dea3846a5640054018b002608e04a791ccbd2082a47bce4440a",
"sha256:20da832a5e9a8e93d1e1eb64650258956723940968eb585506531719b55b804f",
"sha256:2464688b523d7a133b52cf1343c1c595b92fc6554af1015f74b9e49951e992d4",
"sha256:27827b68a8359e9ab6bf683c68d8ee79863a0c94a577acf56aa02cc302e16f51",
"sha256:27deeeeca0fd8933af07923e809c8fed0763d150a4fdd4082932a33b8c874ed6",
"sha256:31f4da785d5e09deb852ea59795a629c5befb6040929e7880c6f63e6668246ce",
"sha256:4828cf8fa638c35139e643f30201b240c0d156b1b9967a7321ae42d721d7224c",
"sha256:48b365e32cc5639ae2c239d7bd4f8a1d920a13a7ae92113c4c938903c9400147",
"sha256:4eb71856c1d1b33083df9318fd30143470ad6f0d1b9ad2ee61a120710842d28b",
"sha256:5b06ef8422d27d8128f8f80bdefa111eadcab246fba1d668720af4f0b97b7a0e",
"sha256:71c553640e1ddaaf143e38dbc6cd1863fa3c0738fb1830a9aaffba9a51838f30",
"sha256:73e2742ee1f923c5f213183bf493901f9630e395634fce5b739a53b7dc5d64be",
"sha256:82a632bc02063eff0b8e7ff3089aa3d912d1c7499709f51c8f04f57c8832cfe6",
"sha256:977ca1ac059e4d4a4bf5fe2224986baf42b69290453eda44822606f4deae6515",
"sha256:a7e6217d0dd864a7cc4f457172766864496efd64d24d4980df1521f75f992761",
"sha256:ad0ed7dd5dff76eb3aae8c18d95b1c9f885a91a92132728051a704fb8060d08c",
"sha256:b1b8eda9e931f0ca1aadb95a890811bdf530407e48c962643b85675329d99abf",
"sha256:cec99c79205131da3ee75becea1f3f55c57bf6a1c500431de9ae7a32ac8a5cc4",
"sha256:d4bbdaa6f61ce2ef26535a7d473d6ffa6e413013c5c580af999546bf1627ae11",
"sha256:d8bdb4208975b12048bdace46e9dd8e3dda3872432f95b53789700a1330e6060",
"sha256:dce0362ff9b61f8411d1efc9e16fc528dadbd3707a557561992457f5cb446297",
"sha256:defbbbf5653629ce5cc54091ce49c6830da8d3104de53ed2169c9efcb0720f27",
"sha256:e0c53a7e2b6d82ec3c26c009c937fc88eb8c7edf000c54334261beaf56bb08f2",
"sha256:e1065bacfe5303f107896e63263537dee90920d26050f2e23c4af12c37da2db6",
"sha256:e142837c4212c0b2c71e6773cb6740828922806b4c00ee4215be3ceb558671e6",
"sha256:f4cbbab28c93ffee6ec929cf0826f0b11d2488e53a708d51142a5e62f8cd9806",
"sha256:fa8f63b6551621eea9efea4db37ae401104352f0ebaee32f7d20be88cbe589c3"
],
"index": "pypi",
"version": "==0.29.12"
},
"etcd3": {
"hashes": [
"sha256:25a524b9f032c6631ff0097532907dea81243eaa63c3744510fd1598cc4e0e87"
],
"index": "pypi",
"version": "==0.10.0"
},
"grpcio": {
"hashes": [
"sha256:03b78b4e7dcdfe3e257bb528cc93923f9cbbab6d5babf15a60d21e9a4a70b1a2",
"sha256:1ce0ccfbdfe84387dbcbf44adb4ae16ec7ae70e166ffab478993eb1ea1cba3ce",
"sha256:22e167a9406d73dd19ffe8ed6a485f17e6eac82505be8c108897f15e68badcbb",
"sha256:31d0aeca8d8ee2301c62c5c340e0889d653b1280d68f9fa203982cb6337b050e",
"sha256:44c7f99ca17ebbcc96fc54ed00b454d8313f1eac28c563098d8b901025aff941",
"sha256:5471444f53f9db6a1f1f11f5dbc173228881df8446380b6b98f90afb8fd8348e",
"sha256:561bca3b1bde6d6564306eb05848fd155136e9c3a25d2961129b1e2edba22fce",
"sha256:5bf58e1d2c2f55365c06e8cb5abe067b88ca2e5550fb62009c41df4b54505acf",
"sha256:6b7163d1e85d76b0815df63fcc310daec02b44532bb433f743142d4febcb181f",
"sha256:766d79cddad95f5f6020037fe60ea8b98578afdf0c59d5a60c106c1bdd886303",
"sha256:770b7372d5ca68308ff66d7baee53369fa5ce985f84bcb6aa1948c1f2f7b02f2",
"sha256:7ab178da777fc0f55b6aef5a755f99726e8e4b75e3903954df07b27059b54fcf",
"sha256:8078305e77c2f6649d36b24d8778096413e474d9d7892c6f92cfb589c9d71b2e",
"sha256:85600b63a386d860eeaa955e9335e18dd0d7e5477e9214825abf2c2884488369",
"sha256:857d9b939ae128be1c0c792eb885c7ff6a386b9dea899ac4b06f4d90a31f9d87",
"sha256:87a41630c90c179fa5c593400f30a467c498972c702f348d41e19dafeb1d319e",
"sha256:8805d486c6128cc0fcc8ecf16c4095d99a8693a541ef851429ab334e028a4a97",
"sha256:8d71b7a89c306a41ccc7741fc9409b14f5b86727455c2a1c0c7cfcb0f784e1f2",
"sha256:9e1b80bd65f8f160880cb4dad7f55697f6d37b2d7f251fc0c2128e811928f369",
"sha256:9e290c84a145ae2411ee0ec9913c41cd7500e2e7485fe93632434d84ef4fda67",
"sha256:9ec9f88b5bc94bd99372f27cdd53af1c92ba06717380b127733b953cfb181174",
"sha256:a0a02a8b4ba6deadf706d5f849539b3685b72b186a3c9ef5d43e8972ed60fb6f",
"sha256:a4059c59519f5940e01a071f74ae2a60ea8f6185b03d22a09d40c7959a36b16b",
"sha256:a6e028c2a6da2ebfa2365a5b32531d311fbfec0e3600fc27e901b64f0ff7e54e",
"sha256:adcdebf9f8463df4120c427cf6c9aed39258bccd03ed37b6939e7a145d64d6e0",
"sha256:bdec982610259d07156a58f80b8c3e69be7751a9208bc577b059c5193d087fad",
"sha256:cefc4d4251ffb73feb303d4b7e9d6c367cb60f2db16d259ea28b114045f965aa",
"sha256:d4145c8aa6afbac10ad27e408f7ce15992fe89ba5d0b4abca31c0c2729864c03",
"sha256:da76dc5ad719ee99de5ea28a5629ff92172cbb4a70d8a6ae3a5b7a53c7382ce1",
"sha256:dde2452c08ef8b6426ccab6b5b6de9f06d836d9937d6870e68153cbf8cb49348",
"sha256:e3d88091d2539a4868750914a6fe7b9ec50e42b913851fc1b77423b5bd918530",
"sha256:f9c67cfe6278499d7f83559dc6322a8bbb108e307817a3d7acbfea807b3603cc"
],
"version": "==1.22.0"
},
"protobuf": {
"hashes": [
"sha256:05c36022fef3c7d3562ac22402965c0c2b9fe8421f459bb377323598996e407f",
"sha256:139b7eadcca0a861d60b523cb37d9475505e0dfb07972436b15407c2b968d87e",
"sha256:15f683006cb77fb849b1f561e509b03dd2b7dcc749086b8dd1831090d0ba4740",
"sha256:2ad566b7b7cdd8717c7af1825e19f09e8fef2787b77fcb979588944657679604",
"sha256:35cfcf97642ef62108e10a9431c77733ec7eaab8e32fe4653de20403429907cb",
"sha256:387822859ecdd012fdc25ec879f7f487da6e1d5b1ae6115e227e6be208836f71",
"sha256:4df14cbe1e7134afcfdbb9f058949e31c466de27d9b2f7fb4da9e0b67231b538",
"sha256:586c4ca37a7146d4822c700059f150ac3445ce0aef6f3ea258640838bb892dc2",
"sha256:58b11e530e954d29ab3180c48dc558a409f705bf16739fd4e0d3e07924ad7add",
"sha256:63c8c98ccb8c95f41c18fb829aeeab21c6249adee4ed75354125bdc44488f30e",
"sha256:72edcbacd0c73eef507d2ff1af99a6c27df18e66a3ff4351e401182e4de62b03",
"sha256:83dc8a561b3b954fd7002c690bb83278b8d1742a1e28abba9aaef28b0c8b437d",
"sha256:913171ecc84c2726b86574e40549a0ea619d569657c5a5ff782a3be7d81401a5",
"sha256:aabb7c741d3416671c3e6fe7c52970a226e6a8274417a97d7d795f953fadef36",
"sha256:b3452bbda12b1cbe2187d416779de07b2ab4c497d83a050e43c344778763721d",
"sha256:c5d5b8d4a9212338297fa1fa44589f69b470c0ba1d38168b432d577176b386a8",
"sha256:d86ee389c2c4fc3cebabb8ce83a8e97b6b3b5dc727b7419c1ccdc7b6e545a233",
"sha256:f2db8c754de788ab8be5e108e1e967c774c0942342b4f8aaaf14063889a6cfdc"
],
"version": "==3.9.0"
},
"python-decouple": {
"hashes": [
"sha256:1317df14b43efee4337a4aa02914bf004f010cd56d6c4bd894e6474ec8c4fe2d"
],
"index": "pypi",
"version": "==3.1"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"tenacity": {
"hashes": [
"sha256:a0c3c5f7ae0c33f5556c775ca059c12d6fd8ab7121613a713e8b7d649908571b",
"sha256:b87c1934daa0b2ccc7db153c37b8bf91d12f165936ade8628e7b962b92dc7705"
],
"version": "==5.0.4"
}
},
"develop": {
"bandit": {
"hashes": [
"sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952",
"sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"
],
"index": "pypi",
"version": "==1.6.2"
},
"gitdb2": {
"hashes": [
"sha256:83361131a1836661a155172932a13c08bda2db3674e4caa32368aa6eb02f38c2",
"sha256:e3a0141c5f2a3f635c7209d56c496ebe1ad35da82fe4d3ec4aaa36278d70648a"
],
"version": "==2.0.5"
},
"gitpython": {
"hashes": [
"sha256:563221e5a44369c6b79172f455584c9ebbb122a13368cc82cb4b5addff788f82",
"sha256:8237dc5bfd6f1366abeee5624111b9d6879393d84745a507de0fda86043b65a8"
],
"version": "==2.1.11"
},
"pbr": {
"hashes": [
"sha256:0ca44dc9fd3b04a22297c2a91082d8df2894862e8f4c86a49dac69eae9e85ca0",
"sha256:4aed6c1b1fa5020def0f22aed663d87b81bb3235f112490b07d2643d7a98c5b5"
],
"version": "==5.4.1"
},
"pyyaml": {
"hashes": [
"sha256:57acc1d8533cbe51f6662a55434f0dbecfa2b9eaf115bede8f6fd00115a0c0d3",
"sha256:588c94b3d16b76cfed8e0be54932e5729cc185caffaa5a451e7ad2f7ed8b4043",
"sha256:68c8dd247f29f9a0d09375c9c6b8fdc64b60810ebf07ba4cdd64ceee3a58c7b7",
"sha256:70d9818f1c9cd5c48bb87804f2efc8692f1023dac7f1a1a5c61d454043c1d265",
"sha256:86a93cccd50f8c125286e637328ff4eef108400dd7089b46a7be3445eecfa391",
"sha256:a0f329125a926876f647c9fa0ef32801587a12328b4a3c741270464e3e4fa778",
"sha256:a3c252ab0fa1bb0d5a3f6449a4826732f3eb6c0270925548cac342bc9b22c225",
"sha256:b4bb4d3f5e232425e25dda21c070ce05168a786ac9eda43768ab7f3ac2770955",
"sha256:cd0618c5ba5bda5f4039b9398bb7fb6a317bb8298218c3de25c47c4740e4b95e",
"sha256:ceacb9e5f8474dcf45b940578591c7f3d960e82f926c707788a570b51ba59190",
"sha256:fe6a88094b64132c4bb3b631412e90032e8cfe9745a58370462240b8cb7553cd"
],
"version": "==5.1.1"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"smmap2": {
"hashes": [
"sha256:0555a7bf4df71d1ef4218e4807bbf9b201f910174e6e08af2e138d4e517b4dde",
"sha256:29a9ffa0497e7f2be94ca0ed1ca1aa3cd4cf25a1f6b4f5f87f74b46ed91d609a"
],
"version": "==2.0.5"
},
"stevedore": {
"hashes": [
"sha256:7be098ff53d87f23d798a7ce7ae5c31f094f3deb92ba18059b1aeb1ca9fec0a0",
"sha256:7d1ce610a87d26f53c087da61f06f9b7f7e552efad2a7f6d2322632b5f932ea2"
],
"version": "==1.30.1"
}
}
}

111
main.py
View File

@ -1,4 +1,7 @@
# TODO # TODO: Use Unix File Socket for VNC instead of TCP
# QEMU Manual
# https://qemu.weilnetz.de/doc/qemu-doc.html
# For QEMU Monitor Protocol Commands Information, See # For QEMU Monitor Protocol Commands Information, See
# https://qemu.weilnetz.de/doc/qemu-doc.html#pcsys_005fmonitor # https://qemu.weilnetz.de/doc/qemu-doc.html#pcsys_005fmonitor
@ -8,15 +11,19 @@ import argparse
import qmp import qmp
import logging import logging
import os import os
import shutil import subprocess
import atexit
import signal
from etcd3_wrapper import Etcd3Wrapper from etcd3_wrapper import Etcd3Wrapper
from dataclasses import dataclass from dataclasses import dataclass
from typing import Union from typing import Union
from functools import wraps from functools import wraps
from decouple import config from decouple import config
from datetime import datetime
running_vms = [] running_vms = []
vnc_port_pool = list(range(5900, 6000))
client = Etcd3Wrapper() client = Etcd3Wrapper()
@ -35,6 +42,14 @@ logging.basicConfig(
) )
def goodbye(host):
host.value["status"] = "DEAD"
host.value["last_heartbeat"] = datetime.utcnow().isoformat()
client.put(host.key, json.dumps(host.value))
logging.info(f"Host {host.key} dead! at {host.value['last_heartbeat']}")
os.kill(os.getpid(), signal.SIGKILL)
def need_running_vm(func): def need_running_vm(func):
@wraps(func) @wraps(func)
def wrapper(e): def wrapper(e):
@ -53,7 +68,7 @@ def need_running_vm(func):
return wrapper return wrapper
def create_vm(owner_dir, vm_uuid, e): def create_vm(vm_uuid, e):
image = client.get( image = client.get(
f"/v1/image/{e.value['image_uuid']}", value_in_json=True f"/v1/image/{e.value['image_uuid']}", value_in_json=True
) )
@ -62,25 +77,34 @@ def create_vm(owner_dir, vm_uuid, e):
image_uuid = e.value["image_uuid"] image_uuid = e.value["image_uuid"]
logging.info("Creating New VM...") logging.info("Creating New VM...")
_command_to_create = f"rbd clone images/{image_uuid}@protected uservms/{vm_uuid}"
subprocess.call(_command_to_create.split(" "))
os.makedirs(f"{owner_dir}/.vm", exist_ok=True) # DELETEME: Delete when CEPH integeration is complete
if not os.path.isfile(f"{owner_dir}/.vm/{vm_uuid}.raw"): # os.makedirs(f"{owner_dir}/.vm", exist_ok=True)
shutil.copy(
f"/var/vm/{image_uuid}.raw", f"{owner_dir}/.vm/{vm_uuid}.raw" # if not os.path.isfile(f"{owner_dir}/.vm/{vm_uuid}.raw"):
) # shutil.copy(
# f"/var/vm/{image_uuid}.raw", f"{owner_dir}/.vm/{vm_uuid}.raw"
# )
e.value["status"] = "REQUESTED_START" e.value["status"] = "REQUESTED_START"
client.put(e.key, json.dumps(e.value)) client.put(e.key, json.dumps(e.value))
def start_vm(vm_path, e): def start_vm(vm_path, e):
if not os.path.isfile(vm_path): # FIXME: Assume for the moment that the image exists
logging.info(f"Image file of vm {e.key} does not exists") # Use librados to list files that exists in
logging.info(f"Setting vm {e.key} status to DELETED") # uservms pool then checkwhether the e.key.split("/").pop()
e.value["status"] = "DELETED" # exists in rbd_ls(uservms_pool)
client.put(e.key, json.dumps(e.value))
return # if not os.path.isfile(vm_path):
# logging.info(f"Image file of vm {e.key} does not exists")
# logging.info(f"Setting vm {e.key} status to DELETED")
# e.value["status"] = "DELETED"
# client.put(e.key, json.dumps(e.value))
# return
_vm = get_vm(running_vms, e.key) _vm = get_vm(running_vms, e.key)
if _vm: if _vm:
@ -89,21 +113,16 @@ def start_vm(vm_path, e):
client.put(e.key, json.dumps(e.value)) client.put(e.key, json.dumps(e.value))
return return
# FIXME: There should be better vnc port allocation scheme
vm = qmp.QEMUMachine( vm = qmp.QEMUMachine(
"/usr/bin/qemu-system-x86_64", "/usr/bin/qemu-system-x86_64",
test_dir="vm_socklog", test_dir="vm_socklog",
args=[ args=[
vm_path, vm_path,
"-boot", "-boot", "c", # First Boot Hard drive
"c", "-m", "1024", # RAM limit
"-net", # Ever growing port number
"nic", "-vnc", f":{vnc_port_pool.pop(0)}", # Allow VNC
"-net",
"user",
"-m",
"1024",
"-vnc",
f":{len(running_vms)}",
], ],
) )
try: try:
@ -118,7 +137,8 @@ def start_vm(vm_path, e):
client.put(e.key, e.value, value_in_json=True) client.put(e.key, e.value, value_in_json=True)
return return
except (qmp.QEMUMachineError, TypeError): except (qmp.QEMUMachineError, TypeError):
logging.info(f"Machine Error Occurred on {e.key}") logging.info()
logging.exception(f"Machine Error Occurred on {e.key}")
e.value["status"] = "KILLED" e.value["status"] = "KILLED"
client.put(e.key, e.value, value_in_json=True) client.put(e.key, e.value, value_in_json=True)
else: else:
@ -181,7 +201,17 @@ def get_vm(vm_list: list, vm_key) -> Union[VM, None]:
return next((vm for vm in vm_list if vm.key == vm_key), None) return next((vm for vm in vm_list if vm.key == vm_key), None)
def main(hostname): def main():
argparser = argparse.ArgumentParser()
argparser.add_argument("hostname", help="Name of this host. e.g /v1/host/1")
args = argparser.parse_args()
host = client.get(args.hostname, value_in_json=True)
host.value["status"] = "ALIVE"
host.value["last_heartbeat"] = datetime.utcnow().isoformat()
atexit.register(goodbye, host=host)
events = client.watch_prefix("/v1/vm/", timeout=10) events = client.watch_prefix("/v1/vm/", timeout=10)
# events = client.get_prefix("/v1/vm/") # events = client.get_prefix("/v1/vm/")
@ -196,8 +226,9 @@ def main(hostname):
if e_status == "TIMEOUT": if e_status == "TIMEOUT":
logging.info("Timeout") logging.info("Timeout")
_vms = filter(lambda v: v.value["hostname"] == hostname, client.get_prefix("/v1/vm", value_in_json=True)) _vms = filter(lambda v: v.value["hostname"] == args.hostname, client.get_prefix("/v1/vm", value_in_json=True))
alleged_running_vms = filter(lambda v: v.value["status"] == "RUNNING", _vms) alleged_running_vms = filter(lambda v: v.value["status"] == "RUNNING", _vms)
should_be_running = filter(lambda v: v.value["status"] == "REQUESTED_START", _vms)
for vm in alleged_running_vms: for vm in alleged_running_vms:
_vm = get_vm(running_vms, vm.key) _vm = get_vm(running_vms, vm.key)
if (_vm and not _vm.vm.is_running()) or _vm is None: if (_vm and not _vm.vm.is_running()) or _vm is None:
@ -206,20 +237,28 @@ def main(hostname):
logging.info(f"Updating {vm.key} status to KILLED") logging.info(f"Updating {vm.key} status to KILLED")
vm.value["status"] = "KILLED" vm.value["status"] = "KILLED"
client.put(vm.key, json.dumps(vm.value)) client.put(vm.key, json.dumps(vm.value))
for vm in should_be_running:
vm_path = f"rbd:uservms/{vm.key.split('/')[-1]}"
start_vm(vm_path, e)
host.value["status"] = "ALIVE"
host.value["last_heartbeat"] = datetime.utcnow().isoformat()
client.put(host.key, json.dumps(host.value))
logging.info(f"Updated last heartbeat time {host.value['last_heartbeat']}")
continue continue
e_hostname = e.value["hostname"] e_hostname = e.value["hostname"]
vm_uuid = e.key.split("/")[-1] vm_uuid = e.key.split("/")[-1]
owner_dir = f"{config('BASE_DIR')}/{e.value['owner']}"
# If it is not for me then skip it # If it is not for me then skip it
if e_hostname != hostname: if e_hostname != args.hostname:
continue continue
logging.debug(f"EVENT: {e}") logging.debug(f"EVENT: {e}")
if e_status == "SCHEDULED_DEPLOY": if e_status == "SCHEDULED_DEPLOY":
create_vm(owner_dir, vm_uuid, e) create_vm(vm_uuid, e)
elif e_status == "REQUESTED_SUSPEND": elif e_status == "REQUESTED_SUSPEND":
suspend_vm(e) suspend_vm(e)
@ -228,7 +267,11 @@ def main(hostname):
resume_vm(e) resume_vm(e)
elif e_status == "REQUESTED_START": elif e_status == "REQUESTED_START":
vm_path = f"{owner_dir}/.vm/{vm_uuid}.raw"
# DELETEME: Delete when CEPH integeration is complete
# vm_path = f"{owner_dir}/.vm/{vm_uuid}.raw"
vm_path = f"rbd:uservms/{vm_uuid}"
start_vm(vm_path, e) start_vm(vm_path, e)
elif e_status == "REQUESTED_SHUTDOWN": elif e_status == "REQUESTED_SHUTDOWN":
@ -240,8 +283,4 @@ def main(hostname):
logging.info(f"Running VMs {running_vms}") logging.info(f"Running VMs {running_vms}")
argparser = argparse.ArgumentParser() main()
argparser.add_argument("hostname", help="Name of this host. e.g /v1/host/1")
args = argparser.parse_args()
main(args.hostname)

View File

@ -234,8 +234,7 @@ class QEMUMachine(object):
else: else:
moncdev = 'socket,id=mon,path=%s' % self._vm_monitor moncdev = 'socket,id=mon,path=%s' % self._vm_monitor
args = ['-chardev', moncdev, args = ['-chardev', moncdev,
'-mon', 'chardev=mon,mode=control', '-mon', 'chardev=mon,mode=control']
'-display', 'none', '-vga', 'none']
if self._machine is not None: if self._machine is not None:
args.extend(['-machine', self._machine]) args.extend(['-machine', self._machine])
if self._console_set: if self._console_set: