def version(): def impl(): return "LibVirt-" + libvirt.getVersion() logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
class CommandExecuter(object): logger = logging.getLogger(support.discoverCaller()) def __init__(self, cmdId, parameters): #parameters is a dict self._cmdId = cmdId self._parameters = parameters def executeCommand(self): """ Executes (or tries to) cmd. Runs cmd, returning a tuple (stdout, stderr) with the contents of the execution """ res = None cmd = self._parameters.pop('cmd') fileForStdin = self._parameters.pop('fileForStdin') try: if fileForStdin: fileForStdin = file(fileForStdin, 'r') except Exception, e: res = defer.fail(('', str(e), -1)) #mimic process output self._execResUsage = resource.getrusage(resource.RUSAGE_CHILDREN) else:
def version(): def impl(): return ctx['vb'].version logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def takeSnapshot(vm, name, desc): def impl(): logger.debug("Taking snapshot of VM: '%s' and description: %s" % (name, desc) ) return cmdExistingVm(vm, 'takeSnapshot', (name, desc)) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
def listRunningVMs(): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def saveState(vm): def impl(): dom = conn.lookupByName(vm) return dom.save("Current") logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
def powerOff(vm): def impl(): return cmdExistingVm(vm, 'powerdown', None) logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def start(vm, guiMode): def impl(): dom = conn.lookupByName(vm) return dom.create() logger.debug("Controller method %s invoked" % support.discoverCaller()) return d
class _VBoxHeadlessProcessProtocol(protocol.ProcessProtocol): logger = logging.getLogger(support.discoverCaller()) def connectionMade(self): self.transport.closeStdin() self.logger.debug("VBoxHeadless process started!") def outReceived(self, data): self.logger.debug("VBoxHeadless stdout: %s" % data) def errReceived(self, data): self.logger.debug("VBoxHeadless stderr: %s" % data) def inConnectionLost(self): pass #we don't care about stdin. We do in fact close it ourselves def outConnectionLost(self): self.logger.info("VBoxHeadless closed its stdout") def errConnectionLost(self): self.logger.info("VBoxHeadless closed its stderr") def processExited(self, reason): #This is called when the child process has been reaped pass def processEnded(self, reason): #This is called when all the file descriptors associated with the child #process have been closed and the process has been reaped self.logger.warn("Process ended (code: %s) " % reason.value.exitCode)
def resume(vm): def impl(): dom = conn.lookupByName(vm) return dom.resume() logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
def discardState(vm): def impl(): return cmdExistingVm(vm, 'discardState', None) logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def deleteSnapshot(vm, name): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def listVMs(): def impl(): return conn.listDefinedDomains() logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def listVMsWithState(): def impl(): pass # ? over list of domains, use dom.isActive()? logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def discardState(vm): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def states(): def impl(): return ctx['const']._Values['MachineState'] logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def createVM(xmlFile): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def pause(vm): def impl(): dom = conn.lookupByName(vm) return dom.suspend() logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def reset(vm): def impl(): dom = conn.lookupByName(vm) return dom.reboot(True) logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def getStats(vm, key): def impl(): if not ctx['perf']: return return ctx['perf'].query([key], [machById(vm)]) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
def saveState(vm): def impl(): dom = conn.lookupByName(vm) return dom.save("Current") logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def getState( vm): def impl(): m = machById(vm) mstate = m.state stateName = getNameForMachineStateCode(mstate) return stateName logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def getStats(vm, key): def impl(): if not ctx['perf']: return return ctx['perf'].query([key], [machById(vm)]) logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def listVMs(): def impl(): vb = ctx['vb'] ms = getMachines() msNames = [ str(m.name) for m in ms ] return msNames logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def takeSnapshot(vm, name, desc): def impl(): logger.debug("Taking snapshot of VM: '%s' and description: %s" % (name, desc)) return cmdExistingVm(vm, 'takeSnapshot', (name, desc)) logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def createVM(vboxFile): vb = ctx['vb'] def impl(): mach = vb.openMachine(vboxFile) vb.registerMachine( mach ) logger.debug("Created VM '%s' with UUID %s" % (mach.name, mach.id)) return (True, mach.name) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
def listVMsWithState(): def impl(): vb = ctx['vb'] ms = getMachines() msNamesAndStates = [ (str(m.name), getNameForMachineStateCode(m.state)) \ for m in ms ] return dict(msNamesAndStates) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def getState(vm): def impl(): m = machById(vm) mstate = m.state stateName = getNameForMachineStateCode(mstate) return stateName logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def listVMs(): def impl(): vb = ctx['vb'] ms = getMachines() msNames = [str(m.name) for m in ms] return msNames logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
class HostStompEngine(BaseStompEngine): logger = logging.getLogger(support.discoverCaller()) def __init__(self): super(HostStompEngine, self).__init__() def connected(self, msg): #once connected, subscribe return (stomper.subscribe(destinations.CONN_DESTINATION), stomper.subscribe(destinations.CMD_RES_DESTINATION))
def listVMsWithState(): def impl(): vb = ctx['vb'] ms = getMachines() msNamesAndStates = [ (str(m.name), getNameForMachineStateCode(m.state)) \ for m in ms ] return dict(msNamesAndStates) logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def listRunningVMs(): def impl(): vb = ctx['vb'] ms = getMachines() isRunning = lambda m: m.state == ctx['const'].MachineState_Running res = filter( isRunning, ms ) res = [ str(m.name) for m in res ] return res logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def deleteSnapshot(vm, name): def impl(): mach = machById(vm) if name == "": return False snapshot = mach.findSnapshot(name) logger.debug("Deleting snapshot named '%s' and id: %s" % (name, snapshot.id) ) return cmdExistingVm(vm, 'deleteSnapshot', (snapshot.id,)) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
def listRunningVMs(): def impl(): vb = ctx['vb'] ms = getMachines() isRunning = lambda m: m.state == ctx['const'].MachineState_Running res = filter(isRunning, ms) res = [str(m.name) for m in res] return res logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def createVM(vboxFile): vb = ctx['vb'] def impl(): mach = vb.openMachine(vboxFile) vb.registerMachine(mach) logger.debug("Created VM '%s' with UUID %s" % (mach.name, mach.id)) return (True, mach.name) logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def deleteSnapshot(vm, name): def impl(): mach = machById(vm) if name == "": return False snapshot = mach.findSnapshot(name) logger.debug("Deleting snapshot named '%s' and id: %s" % (name, snapshot.id)) return cmdExistingVm(vm, 'deleteSnapshot', (snapshot.id, )) logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def listSnapshots(vm): def impl(): sl = [] if machById(vm).snapshotCount > 0: root = machById(vm).findSnapshot('') def recurseTree(snapList, node): snapList.append(node.name) for child in node.getChildren(): recurseTree(snapList, child) recurseTree(sl, root) return sl logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
class CommandRegistry(object): """ For all command-execution related. Keeps track of requests made, served and retired """ logger = logging.getLogger(support.discoverCaller()) words = inject.attr('words') vmRegistry = inject.attr('vmRegistry', VMRegistry) def __init__(self): self._cmdReqsSent = { } #cmdId: dict with keys (timestamp, to, cmd, args, env, path) self._cmdReqsRetired = {} #finished cmdReqsSent self._cmdReqsRcvd = {} def addCmdRequest(self, cmdId, requestInfoDict): self._cmdReqsSent[cmdId] = requestInfoDict def processCmdResult(self, resultsMsg): serializedResults = resultsMsg['body'].split(None, 1)[1] #serializeded data: dict with keys (cmd-id, out, err, finished?, code/signal, resources) results = support.deserialize(serializedResults) self.logger.debug("Deserialized results: %s" % results) cmdId = results.pop('cmd-id') #this comes from a word.CMD_RESULT.listenAndAct #note down for which cmd we are getting the result back assert cmdId in self._cmdReqsSent self._cmdReqsRcvd[cmdId] = results self._cmdReqsRetired[cmdId] = self._cmdReqsSent.pop(cmdId) self.logger.info("Received command results for cmd-id '%s'", cmdId) def popCmdResults(self, cmdId): # for invalid cmdIds, returning None could # result in problems with xml-rpc. Thus we # resource to an empty string, which likewise # fails a boolean test return self._cmdReqsRcvd.pop(cmdId, "") def listFinishedCmds(self): return self._cmdReqsRcvd.keys() def getCmdDetails(self, cmdId): details = self._cmdReqsSent.get(cmdId) if not details: details = self._cmdReqsRetired.get(cmdId) return support.serialize(details)
def listSnapshots(vm): def impl(): sl = [] if machById(vm).snapshotCount > 0: root = machById(vm).findSnapshot('') def recurseTree(snapList, node): snapList.append(node.name) for child in node.getChildren(): recurseTree(snapList, child) recurseTree(sl, root) return sl logger.debug("Controller method %s invoked" % support.discoverCaller()) d = threads.deferToThread(impl) return d
def states(): def impl(): return ctx['const']._Values['MachineState'] logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def deleteSnapshot(vm, name): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
def version(): def impl(): return "LibVirt-" + libvirt.getVersion() logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def start(vm, guiMode): def impl(): dom = conn.lookupByName(vm) return dom.create() logger.debug("Controller method %s invoked" % support.discoverCaller() ) return d
def listVMs(): def impl(): return conn.listDefinedDomains() logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def listVMsWithState(): def impl(): pass # ? over list of domains, use dom.isActive()? logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def powerOff(vm): def impl(): return cmdExistingVm(vm, 'powerdown', None) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
return True d = threads.deferToThread(impl) else: m = machById(vm) mName = str(m.name) processProtocol = VBoxHeadlessProcessProtocol() pseudoCWD = os.path.dirname(sys.modules[__name__].__file__) vboxBinariesPath = None #TODO: use VBOX_INSTALL_PATH cmdWithPath = os.path.join(pseudoCWD, 'scripts', 'vboxstart.bat') cmdWithArgs = ("vboxstart.bat", vboxBinariesPath, mName) cmdPath = os.path.join(pseudoCWD, 'scripts') newProc = lambda: reactor.spawnProcess( processProtocol, cmdWithPath, args=cmdWithArgs, env=None, path=cmdPath ) reactor.callWhenRunning(newProc) d = True #in order to have a unique return logger.debug("Controller method %s invoked" % support.discoverCaller() ) return d def shutdown(vm): def impl(): return cmdExistingVm(vm, 'shutdown', None) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d def reset(vm): def impl(): return cmdExistingVm(vm, 'reset', None) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d
""" try: import logging import inject from twisted.internet import defer from vmcontroller.common import support, exceptions except ImportError, e: print "Import error in %s : %s" % (__name__, e) import sys sys.exit() CONTROLLERS_PATH = "hypervisors" #relative to this file logger = logging.getLogger(support.discoverCaller()) @inject.param('config') def _createController(config): """ Creates the appropriate (hypervisor) controller based on the given configuration. This is the place where to perform particular initialization tasks for the particular hypervisor controller implementations. @param config: an instance of L{ConfigParser} """ hv = config.get('hypervisor', 'name') hvMod = None
class Host(object): logger = logging.getLogger(support.discoverCaller()) #we use injection so that we can do things lazily cmdRegistry = inject.attr('cmdRegistry', CommandRegistry) vmRegistry = inject.attr('vmRegistry', VMRegistry) fileTxs = inject.attr('fileTxs', FileTxs) words = inject.attr('words') stompProtocol = inject.attr('stompProtocol') def __init__(self): self._descriptor = EntityDescriptor('VMController-Host') self._vms = {} self._pings = {} @property def descriptor(self): return self._descriptor def ping(self, vmId, timeout_secs): def _timeout(timestamp): d = self._pings.pop(timestamp, None) if d: name = self.vmRegistry.getNameForId(vmId) d.errback(RuntimeError('PING timeout (for %s)' % name)) timestamp = str(time.time()) d = defer.Deferred() self._pings[timestamp] = d self.stompProtocol.sendMsg(self.words['PING']().howToSay(vmId)) reactor.callLater(timeout_secs, _timeout, timestamp) return d def processPong(self, msg): timestamp = msg['headers']['timestamp'] d = self._pings.pop(timestamp, None) assert d vmId = msg['headers']['from'] vmName = self.vmRegistry.getNameForId(vmId) d.callback('PONG from %s' % vmName) def sendCmdRequest(self, toVmName, cmd, args=(), env={}, path=None, fileForStdin=''): #get id for name toVmId = self.vmRegistry.getIdForName(toVmName) cmdId = str(uuid.uuid4()) toSend = self.words['CMD_RUN'](). \ howToSay(toVmId, \ cmdId, cmd, args, \ env, path, fileForStdin ) requestKeys = ('timestamp', 'toVmName', 'toVmId', 'cmd', 'args', 'env', 'path', 'fileForStdin') requestValues = (time.time(), toVmName, toVmId, cmd, args, env, path, fileForStdin) self.stompProtocol.sendMsg(toSend) self.logger.info( "Requested execution of command '%s' with cmd-id '%s'" % (cmd, cmdId)) self.cmdRegistry.addCmdRequest(cmdId, dict(zip(requestKeys, requestValues))) return cmdId def processCmdResult(self, resultsMsg): self.cmdRegistry.processCmdResult(resultsMsg) #XXX: make it possible to be blocking? def getCmdResults(self, cmdId): return self.cmdRegistry.popCmdResults(cmdId) def listFinishedCmds(self): return self.cmdRegistry.listFinishedCmds() ################################ def addVM(self, vmDescriptor): self.vmRegistry.addVM(vmDescriptor) def removeVM(): self.vmRegistry.removeVM(vmId) ################################ def cpFileToVM(self, vmId, pathToLocalFileName, pathToRemoteFileName=None): return self.fileTxs.cpFileToVM(vmId, pathToLocalFileName, pathToRemoteFileName) def cpFileFromVM(self, vmId, pathToRemoteFileName, pathToLocalFileName=None): return self.fileTxs.cpFileFromVM(vmId, pathToRemoteFileName, pathToLocalFileName)
def version(): def impl(): return ctx['vb'].version logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
def states(): def impl(): pass logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread(impl) return d
""" try: import logging import inject from twisted.internet import defer from vmcontroller.common import support, exceptions except ImportError, e: print "Import error in %s : %s" % (__name__, e) import sys sys.exit() CONTROLLERS_PATH = "hypervisors" #relative to this file logger = logging.getLogger( support.discoverCaller() ) @inject.param('config') def _createController(config): """ Creates the appropriate (hypervisor) controller based on the given configuration. This is the place where to perform particular initialization tasks for the particular hypervisor controller implementations. @param config: an instance of L{ConfigParser} """ hv = config.get('hypervisor', 'name') hvMod = None logger.debug("Hypervisor specified in config: '%s'" % hv)
def discardState(vm): def impl(): return cmdExistingVm(vm, 'discardState', None) logger.debug("Controller method %s invoked" % support.discoverCaller() ) d = threads.deferToThread( impl ) return d