def _register_watches(self, libvirt_domain): if libvirt_domain: name = libvirt_domain.name() if name in self._qdb: return if not libvirt_domain.isActive(): return # open separate connection to Qubes DB: # 1. to not confuse pull() with responses to real commands sent from # other threads (like read, write etc) with watch events # 2. to not think whether QubesDB is thread-safe (it isn't) try: self._qdb[name] = QubesDB(name) except Error as e: if e.args[0] != 2: raise libvirt.virEventAddTimeout(500, self._retry_register_watches, libvirt_domain) return else: name = "dom0" self._qdb[name] = QubesDB(name) try: self._qdb[name].watch('/qubes-block-devices') except Error as e: if e.args[0] == 102: # Connection reset by peer # QubesDB daemon not running - most likely we've connected to # stale daemon which just exited; retry later libvirt.virEventAddTimeout(500, self._retry_register_watches, libvirt_domain) return self._qdb_events[name] = libvirt.virEventAddHandle( self._qdb[name].watch_fd(), libvirt.VIR_EVENT_HANDLE_READABLE, self._qdb_handler, name)
def waitForAction(self, domid, timeout=None, events=None): libvirt.virEventRegisterDefaultImpl() rocon = libvirt.openReadOnly() run = {'state': True, 'timeout': False} def timecb(timerid, opaque): run['state'] = False run['timeout'] = True def callback(con, domain, event, detail, opaque): if domain.UUIDString() == domid: if events is not None and event in events: run['state'] = False return True if timeout: libvirt.virEventAddTimeout(timeout, timecb, None) rocon.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, callback, rocon) while run['state']: libvirt.virEventRunDefaultImpl() if run['timeout']: raise TimeoutError("Failed to wait for state")
def startVM(sample): VMName = sample["guest_image"] runTime = sample["time_to_run"] sample_file = sample["submission_file"] try: if api_config["VM"][VMName]["snapshot"]: snapshot_name = api_config["VM"][VMName]["snapshot"] except KeyError: return abort(404, "Internal memory snapshot not present.") tenjint_path = check_path("tenjint_config_path") emulator_path = check_path("emulator_path") VM_folder = check_path("VM_folder_name") samples_folder = check_path("samples_store") disk_snapshot = check_disk_snapshot(VMName) destFile = generate_token() destPath = VM_folder + destFile + '.qcow2' sample["domain"] = destFile sample["status"] = "running" shutil.copyfile(disk_snapshot, destPath) domain_uuid = uuid.uuid4() xmlPath = os.getcwd() + '/template.xml' tree = ET.parse(xmlPath) root = tree.getroot() vmi_string = "vmi=on,vmi-configs=" + tenjint_path root[0][3].set('value', vmi_string) root[1].text = destFile root[2].text = str(domain_uuid) root[12][0].text = emulator_path root[12][1][1].set('file', destPath) root[12][3][0].set("dir", samples_folder) root[13][5].set('value', snapshot_name) tree.write(xmlPath) xmlstr = ET.tostring(root, method='xml') xmlstr = str(xmlstr, 'utf-8') plugin_dir = check_path("plugin_dir") with open(plugin_dir + "sample.json", "w") as outfile: json.dump({"file": sample_file}, outfile) try: conn = libvirt.open('qemu:///system') if conn == None: print('Failed to open connection to qemu:///system', file=sys.stderr) exit(1) dom = conn.defineXML(xmlstr) if dom == None: print('Failed to define a domain from an XML definition.', file=sys.stderr) exit(1) if dom.create() < 0: print('Can not boot guest domain.', file=sys.stderr) exit(1) libvirt.virEventAddTimeout(runTime, myDomainTimeoutCalllback, destFile) db.submission.started.insert_one(sample) except libvirt.libvirtError: abort(404, "Libvirt could not be configured")
def add_timeout(self, timeout, cb, opaque): try: return libvirt.virEventAddTimeout(timeout, cb, opaque) except libvirt.libvirtError, e: message = e.get_error_message() code = e.get_error_code() raise exception.LibvirtAPI(message, code)
def startVM(sample): VMName = sample["guest_image"] runTime = sample["time_to_run"] sample_file = sample["submission_file"] tenjint_path = check_path("tenjint_config_path") VM_folder = check_path("VM_folder_name") samples_folder = check_path("samples_store") disk_snapshot = check_disk_snapshot(VMName) disk_snapshot_name = check_snapshot(VMName, "disk-snap-name") snapshot_name = check_snapshot(VMName, "snapshot") destFile = generate_token(32) destPath = VM_folder + destFile + '.qcow2' sample["domain"] = destFile sample["status"] = "running" shutil.copyfile(disk_snapshot, destPath) xmlstr = VMTemplate(disk_snapshot_name, destFile, destPath, tenjint_path, snapshot_name, samples_folder) xmlstr = str(xmlstr, 'utf-8') plugin_dir = check_path("plugin_dir") with open(plugin_dir + "sample.json", "w") as outfile: json.dump({"file": sample_file}, outfile) db.submission.started.insert_one(sample) try: conn = libvirt.open('qemu:///system') if conn == None: print('Failed to open connection to qemu:///system', file=sys.stderr) exit(1) dom = conn.defineXML(xmlstr) if dom == None: print('Failed to define a domain from an XML definition.', file=sys.stderr) exit(1) if dom.create() < 0: print('Can not boot guest domain.', file=sys.stderr) exit(1) libvirt.virEventAddTimeout(runTime, myDomainTimeoutCalllback, destFile) except libvirt.libvirtError: abort(404, "Libvirt could not be configured")
def __init__(self): # Register default implementation of event handlers if libvirt.virEventRegisterDefaultImpl() < 0: raise OperationFailed('KCHEVENT0001E') # Run a background thread with the event loop. Using cherrypy # BackgroundTask class due to issues when using threading module with # cherrypy. self.event_loop_thread = cherrypy.process.plugins.BackgroundTask( 2, self._event_loop_run) self.event_loop_thread.setName('KimchiLibvirtEventLoop') self.event_loop_thread.setDaemon(True) self.event_loop_thread.start() # Set an event timeout to control the self._event_loop_run if libvirt.virEventAddTimeout(0, self._kimchi_EventTimeout, None) < 0: raise OperationFailed('KCHEVENT0002E')
def __init__(self): # Register default implementation of event handlers if libvirt.virEventRegisterDefaultImpl() < 0: raise OperationFailed('KCHEVENT0001E') # Run a background thread with the event loop. Using cherrypy # BackgroundTask class due to issues when using threading module with # cherrypy. self.event_loop_thread = cherrypy.process.plugins.BackgroundTask( 2, self._event_loop_run ) self.event_loop_thread.setName('KimchiLibvirtEventLoop') self.event_loop_thread.setDaemon(True) self.event_loop_thread.start() # Set an event timeout to control the self._event_loop_run if libvirt.virEventAddTimeout(0, self._kimchi_EventTimeout, None) < 0: raise OperationFailed('KCHEVENT0002E')
def wait_for_guest_agent(conn, domain, timeout): done = False def timeoutEventCallback(timer, opaque): logging.info("timeout event:") nonlocal done done = True def domainEventAgentLifecycleCallback (conn, dom, state, reason, opaque): logging.info("agentLifecycle event: domain '%s' state %d reason %d" % (dom.name(), state, reason)) if state == libvirt.VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED: nonlocal done done = True timer_id = libvirt.virEventAddTimeout(timeout*1000, timeoutEventCallback, None) conn.domainEventRegisterAny(domain, libvirt.VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE, domainEventAgentLifecycleCallback, None) while not done: libvirt.virEventRunDefaultImpl() libvirt.virEventRemoveTimeout(timer_id)