Add machine property api
This commit is contained in:
parent
79bf279f4a
commit
4d2723e048
|
@ -149,6 +149,60 @@ class ZApiMachineRestart(object):
|
||||||
return machine_id
|
return machine_id
|
||||||
|
|
||||||
|
|
||||||
|
@cherrypy.popargs("prop")
|
||||||
|
class ZApiMachineProperty(object):
|
||||||
|
"""
|
||||||
|
Endpoint to modify machine properties
|
||||||
|
"""
|
||||||
|
exposed = True
|
||||||
|
|
||||||
|
def __init__(self, root):
|
||||||
|
self.root = root
|
||||||
|
|
||||||
|
@cherrypy.tools.json_out()
|
||||||
|
def GET(self, machine_id, prop):
|
||||||
|
"""
|
||||||
|
Fetch a property from a machine
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
machine = self.root.master.machines[machine_id]
|
||||||
|
return machine.properties[prop]
|
||||||
|
except KeyError:
|
||||||
|
raise cherrypy.HTTPError(status=404)
|
||||||
|
|
||||||
|
@cherrypy.tools.json_out()
|
||||||
|
def PUT(self, machine_id, prop, value):
|
||||||
|
"""
|
||||||
|
Set a property on a machine.
|
||||||
|
"""
|
||||||
|
value = json.loads(value)
|
||||||
|
try:
|
||||||
|
machine = self.root.master.machines[machine_id]
|
||||||
|
assert machine.machine.get_status() == "stopped", "Machine must be stopped to modify"
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
raise cherrypy.HTTPError(status=404)
|
||||||
|
|
||||||
|
machine.properties[prop] = value
|
||||||
|
machine.save()
|
||||||
|
return [machine_id, prop, value]
|
||||||
|
|
||||||
|
@cherrypy.tools.json_out()
|
||||||
|
def DELETE(self, machine_id, prop):
|
||||||
|
"""
|
||||||
|
Remove a property on a machine.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
machine = self.root.master.machines[machine_id]
|
||||||
|
assert machine.machine.get_status() == "stopped", "Machine must be stopped to modify"
|
||||||
|
except KeyError:
|
||||||
|
raise cherrypy.HTTPError(status=404)
|
||||||
|
|
||||||
|
del machine.properties[prop]
|
||||||
|
machine.save()
|
||||||
|
return [machine_id, prop]
|
||||||
|
|
||||||
|
|
||||||
@cherrypy.popargs("machine_id")
|
@cherrypy.popargs("machine_id")
|
||||||
class ZApiMachines():
|
class ZApiMachines():
|
||||||
"""
|
"""
|
||||||
|
@ -166,6 +220,7 @@ class ZApiMachines():
|
||||||
self.stop = ZApiMachineStop(self.root)
|
self.stop = ZApiMachineStop(self.root)
|
||||||
self.start = ZApiMachineStart(self.root)
|
self.start = ZApiMachineStart(self.root)
|
||||||
self.restart = ZApiMachineRestart(self.root)
|
self.restart = ZApiMachineRestart(self.root)
|
||||||
|
self.property = ZApiMachineProperty(self.root)
|
||||||
|
|
||||||
@cherrypy.tools.json_out()
|
@cherrypy.tools.json_out()
|
||||||
def GET(self, machine_id=None, summary=False):
|
def GET(self, machine_id=None, summary=False):
|
||||||
|
|
|
@ -107,15 +107,18 @@ class QMachine(Machine):
|
||||||
args = []
|
args = []
|
||||||
for iface in self.spec.properties.get("netifaces"):
|
for iface in self.spec.properties.get("netifaces"):
|
||||||
iface_type = iface.get("type")
|
iface_type = iface.get("type")
|
||||||
|
iface_args = {"type": iface_type}
|
||||||
|
|
||||||
if iface_type == "tap":
|
if iface_type == "tap":
|
||||||
if "ifname" not in iface:
|
if "ifname" in iface:
|
||||||
iface["ifname"] = tap_name
|
iface_args["ifname"] = iface.get("ifname")
|
||||||
iface["script"] = "/root/zhypervisor/testenv/bin/zd_ifup" # TODO don't hard code
|
iface_args["script"] = "/root/zhypervisor/testenv/bin/zd_ifup" # TODO don't hard code
|
||||||
iface["downscript"] = "no"
|
iface_args["downscript"] = "no"
|
||||||
|
else:
|
||||||
|
iface_args.update(iface)
|
||||||
|
|
||||||
args.append("-net")
|
args.append("-net")
|
||||||
args.append(QMachine.format_args(iface))
|
args.append(QMachine.format_args(iface_args))
|
||||||
return args
|
return args
|
||||||
|
|
||||||
# return ['-net', 'nic,vlan=0,model=e1000,macaddr=82:25:60:41:D5:97',
|
# return ['-net', 'nic,vlan=0,model=e1000,macaddr=82:25:60:41:D5:97',
|
||||||
|
|
|
@ -67,6 +67,11 @@ class ZHypervisorDaemon(object):
|
||||||
machine_id = machine_info["machine_id"]
|
machine_id = machine_info["machine_id"]
|
||||||
self.add_machine(machine_id, machine_info["spec"])
|
self.add_machine(machine_id, machine_info["spec"])
|
||||||
|
|
||||||
|
# Launch if machine is an autostarted machine
|
||||||
|
machine = self.machines[machine_id]
|
||||||
|
if machine.options.get("autostart", False) and machine.machine.get_status() == "stopped":
|
||||||
|
machine.start()
|
||||||
|
|
||||||
def signal_handler(self, signum, frame):
|
def signal_handler(self, signum, frame):
|
||||||
"""
|
"""
|
||||||
Handle signals sent to the daemon. On any, exit.
|
Handle signals sent to the daemon. On any, exit.
|
||||||
|
@ -148,11 +153,7 @@ class ZHypervisorDaemon(object):
|
||||||
if write:
|
if write:
|
||||||
self.state.write_machine(machine_id, machine_spec)
|
self.state.write_machine(machine_id, machine_spec)
|
||||||
|
|
||||||
# Launch if machine is an autostarted machine
|
def forceful_stop(self, machine_id, timeout=30): # make this timeout longer?
|
||||||
if machine.options.get("autostart", False) and machine.machine.get_status() == "stopped":
|
|
||||||
machine.start()
|
|
||||||
|
|
||||||
def forceful_stop(self, machine_id, timeout=10): # make this timeout longer?
|
|
||||||
"""
|
"""
|
||||||
Gracefully stop a machine by asking it nicely, waiting some time, then forcefully killing it.
|
Gracefully stop a machine by asking it nicely, waiting some time, then forcefully killing it.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -39,6 +39,13 @@ class MachineSpec(object):
|
||||||
self.machine.block_respawns = True
|
self.machine.block_respawns = True
|
||||||
self.machine.stop_machine()
|
self.machine.stop_machine()
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
"""
|
||||||
|
Write the machine's config to disk
|
||||||
|
"""
|
||||||
|
self.master.add_machine(self.machine_id, {"options": self.options, "properties": self.properties},
|
||||||
|
write=True)
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
"""
|
"""
|
||||||
Return a serializable form of this machine's specs
|
Return a serializable form of this machine's specs
|
||||||
|
|
Loading…
Reference in New Issue