def revert_snapshot(guest=None, msg=None): extend_data = dict() try: assert isinstance(guest, libvirt.virDomain) assert isinstance(msg, dict) snap_flags = 0 snap_flags |= libvirt.VIR_DOMAIN_SNAPSHOT_REVERT_FORCE snapshot = guest.snapshotLookupByName(name=msg['snapshot_id']) try: guest.revertToSnapshot(snap=snapshot, flags=0) except libvirt.libvirtError, e: # 给予一次重新恢复的机会 if e.get_error_code() == libvirt.VIR_ERR_SYSTEM_ERROR: guest.revertToSnapshot(snap=snapshot, flags=snap_flags) # 如果恢复后的 Guest 为 Running 状态,则同步其系统时间。 if guest.isActive(): # https://qemu.weilnetz.de/doc/qemu-ga-ref.html#index-guest_002dset_002dtime try: libvirt_qemu.qemuAgentCommand(guest, json.dumps({ 'execute': 'guest-set-time', 'arguments': { 'time': int(ji.Common.ts() * (10**9)) } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) except libvirt.libvirtError, e: logger.error(e.message) log_emit.error(e.message)
def ping(self, dom): try: libvirt_qemu.qemuAgentCommand(dom, '{"execute": "guest-ping"}', 10, 0) return True except libvirt.libvirtError: return False return False
def fetch_file(self, in_path, out_path): ''' fetch a file from domain to local ''' super(Connection, self).fetch_file(in_path, out_path) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self._host) request_handle = { 'execute': 'guest-file-open', 'arguments': { 'path': in_path, 'mode': 'r' } } request_handle_json = json.dumps(request_handle) display.vvv(u"GA send: {0}".format(request_handle_json), host=self._host) result_handle = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_handle_json, 5, 0)) display.vvv(u"GA return: {0}".format(result_handle), host=self._host) request_read = { 'execute': 'guest-file-read', 'arguments': { 'handle': result_handle['return'], 'count': BUFSIZE } } request_read_json = json.dumps(request_read) display.vvv(u"GA send: {0}".format(request_read_json), host=self._host) with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') as out_file: try: result_read = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_read_json, 5, 0)) display.vvvvv(u"GA return: {0}".format(result_read), host=self._host) out_file.write(base64.b64decode(result_read['return']['buf-b64'])) while not result_read['return']['eof']: result_read = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_read_json, 5, 0)) display.vvvvv(u"GA return: {0}".format(result_read), host=self._host) out_file.write(base64.b64decode(result_read['return']['buf-b64'])) except Exception: traceback.print_exc() raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path)) request_close = { 'execute': 'guest-file-close', 'arguments': { 'handle': result_handle['return'] } } request_close_json = json.dumps(request_close) display.vvv(u"GA send: {0}".format(request_close_json), host=self._host) result_close = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_close_json, 5, 0)) display.vvv(u"GA return: {0}".format(result_close), host=self._host)
def update_ssh_key(dom=None, msg=None): assert isinstance(dom, libvirt.virDomain) assert isinstance(msg, dict) if not dom.isActive(): log = u'欲更新 SSH-KEY 的目标虚拟机未处于活动状态。' log_emit.warn(log) return from utils import QGA libvirt_qemu.qemuAgentCommand( dom, json.dumps({ 'execute': 'guest-exec', 'arguments': { 'path': 'mkdir', 'capture-output': False, 'arg': ['-p', '/root/.ssh'] } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) redirection_symbol = '>' ret_s = list() for i, ssh_key in enumerate(msg['ssh_keys']): if i > 0: redirection_symbol = '>>' exec_ret = libvirt_qemu.qemuAgentCommand( dom, json.dumps({ 'execute': 'guest-exec', 'arguments': { 'path': '/bin/sh', 'capture-output': True, 'arg': [ '-c', ' '.join([ 'echo', '"' + ssh_key + '"', redirection_symbol, '/root/.ssh/authorized_keys' ]) ] } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) exec_ret = json.loads(exec_ret) status_ret = QGA.get_guest_exec_status( dom=dom, pid=exec_ret['return']['pid']) # exec_ret_str = base64.b64decode(json.loads(status_ret)['return']['out-data']) # ret_s.append(json.loads(exec_ret_str)) ret_s.append(status_ret) return ret_s
def update_ssh_key(guest=None, msg=None): assert isinstance(guest, libvirt.virDomain) assert isinstance(msg, dict) libvirt_qemu.qemuAgentCommand( guest, json.dumps({ 'execute': 'guest-exec', 'arguments': { 'path': 'mkdir', 'capture-output': False, 'arg': ['-p', '/root/.ssh'] } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) redirection_symbol = '>' ret_s = list() for i, ssh_key in enumerate(msg['ssh_keys']): if i > 0: redirection_symbol = '>>' ret = libvirt_qemu.qemuAgentCommand( guest, json.dumps({ 'execute': 'guest-exec', 'arguments': { 'path': '/bin/sh', 'capture-output': True, 'arg': [ '-c', ' '.join([ 'echo', '"' + ssh_key + '"', redirection_symbol, '/root/.ssh/authorized_keys' ]) ] } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) ret = json.loads(ret) ret = libvirt_qemu.qemuAgentCommand( guest, json.dumps({ 'execute': 'guest-exec-status', 'arguments': { 'pid': ret['return']['pid'] } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) ret_s.append(json.loads(ret)) return ret_s
def _close_file(self, dom, handle): command = { "execute": "guest-file-close", "arguments": { "handle": handle, } } try: libvirt_qemu.qemuAgentCommand(dom, json.dumps(command), EXEC_TIMEOUT, 0) except Exception as err: raise exception.GuestExecutionError("failed to open file: %s" % err) from err
def main(): argument_spec = dict( connection=dict(required=False, default="qemu:///system", type="str"), name=dict(required=True, type="str"), device=dict(required=True, type="str"), ipv4=dict(default=True, choices=BOOLEANS, type="bool"), ipv6=dict(default=False, choices=BOOLEANS, type="bool"), timeout=dict(required=False, default=30, type="int"), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) if not HAS_LIBVIRT_QEMU: module.fail_json(msg="libvirt_qemu is required for this module") try: connect = libvirt.open(module.params["connection"]) domain = connect.lookupByName(module.params["name"]) network_interface_string = libvirt_qemu.qemuAgentCommand( domain, '{"execute":"guest-network-get-interfaces"}', module.params["timeout"], 0 ) network_obj = json.loads(network_interface_string) kwargs = {} for device in network_obj["return"]: if device["name"] == module.params["device"]: for ip in device["ip-addresses"]: if ip["ip-address-type"] == "ipv4" and module.params["ipv4"]: kwargs.update(ansible_virt_ipv4=ip["ip-address"]) if ip["ip-address-type"] == "ipv6" and module.params["ipv6"]: kwargs.update(ansible_virt_ipv6=ip["ip-address"]) module.exit_json(**kwargs) except Exception as e: module.fail_json(msg=str(e))
def guest_agent_available(dom): cmd = '{"execute":"guest-ping"}' try: out = qemuAgentCommand(dom, cmd, 30, 0) except libvirt.libvirtError: return False return True
def _connect(self): ''' connect to the virtual machine; nothing to do here ''' super(Connection, self)._connect() if not self._connected: self._virt_uri = self.get_option('virt_uri') self._display.vvv(u"CONNECT TO {0}".format(self._virt_uri), host=self._host) try: self.conn = libvirt.open(self._virt_uri) except libvirt.libvirtError as err: raise AnsibleConnectionFailure(to_native(err)) self._display.vvv(u"FIND DOMAIN {0}".format(self._host), host=self._host) try: self.domain = self.conn.lookupByName(self._host) except libvirt.libvirtError as err: raise AnsibleConnectionFailure(to_native(err)) request_cap = json.dumps({'execute': 'guest-info'}) response_cap = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_cap, 5, 0)) self.capabilities = response_cap['return']['supported_commands'] self._display.vvvvv(u"GUEST CAPABILITIES: {0}".format(self.capabilities), host=self._host) missing_caps = [] for cap in REQUIRED_CAPABILITIES: if cap not in self.capabilities: missing_caps.append(cap['name']) if len(missing_caps) > 0: self._display.vvv(u"REQUIRED CAPABILITIES MISSING: {0}".format(missing_caps), host=self._host) raise AnsibleConnectionFailure('Domain does not have required capabilities') display.vvv(u"ESTABLISH {0} CONNECTION".format(self.transport), host=self._host) self._connected = True
def exec_qga_command(domain, cmd, timeout=6, flags=0): LOG.debug("Going to execute qga cmd %s" % cmd) try: return libvirt_qemu.qemuAgentCommand(domain, cmd, timeout, flags) except libvirt.libvirtError as e: LOG.warn("Run qga cmd %s failed, uuid: %s, exception: %s" % (cmd, domain.UUIDString(), e)) return None
def qemuAgentCommand(self, guest, cmd, timeout=3, flag=0): try: stuff = qemuAgentCommand(guest, cmd, timeout, flag) result = json.loads(stuff) data = result['return'] except Exception, e: #print e.message data = {}
def _exec_agent_cmd(instance, command): logging.debug("command %s" % re.sub('"buf-b64":".*"', '"buf-b64":"..."', command)) result = libvirt_qemu.qemuAgentCommand(instance, command, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK, 0) json_result = json.loads(result) logging.debug("result %s " % re.sub('"buf-b64":".*"', '"buf-b64":"..."', json.dumps(json_result, sort_keys=True, indent=4))) return json_result
def _read_output(self, dom, pid): command = { "execute": "guest-exec-status", "arguments": { "pid": int(pid), } } ret = libvirt_qemu.qemuAgentCommand(dom, json.dumps(command), 10, 0) return self._get_result_body(ret)
def guest_exec_get_response(domain, pid, timeout=6, flags=0): command = json.dumps({ "execute": "guest-exec-status", "arguments": { "pid": pid } }) try: response = libvirt_qemu.qemuAgentCommand(domain, command, timeout, flags) except libvirt.libvirtError as e: pass if response: response_json = json.loads(response) while (not response_json["return"]["exited"]): time.sleep(0.12) response_json = json.loads( libvirt_qemu.qemuAgentCommand(domain, command, timeout, flags)) result = str(response_json["return"]["out-data"]).decode( 'base64', 'strict') return result
def _get_supported_commands(self, dom): try: ret = libvirt_qemu.qemuAgentCommand(dom, '{"execute": "guest-info"}', 10, 0) except Exception as err: raise exception.NotSupportedOperation( "failed to fetch guest info") from err parsed = self._parse_command_output(ret) cmds = {} for cmd in parsed["supported_commands"]: cmds[cmd["name"]] = cmd["enabled"] return cmds
def revert_snapshot(dom=None, msg=None): extend_data = dict() try: assert isinstance(dom, libvirt.virDomain) assert isinstance(msg, dict) snap_flags = 0 snap_flags |= libvirt.VIR_DOMAIN_SNAPSHOT_REVERT_FORCE snapshot = dom.snapshotLookupByName(name=msg['snapshot_id']) try: dom.revertToSnapshot(snap=snapshot, flags=0) except libvirt.libvirtError, e: # 给予一次重新恢复的机会 if e.get_error_code() == libvirt.VIR_ERR_SYSTEM_ERROR: dom.revertToSnapshot(snap=snapshot, flags=snap_flags) # 如果恢复后的 Guest 为 Running 状态,则同步其系统时间。 if dom.isActive(): # https://qemu.weilnetz.de/doc/qemu-ga-ref.html#index-guest_002dset_002dtime libvirt_qemu.qemuAgentCommand( dom, json.dumps({ 'execute': 'guest-set-time', 'arguments': { 'time': int(ji.Common.ts() * (10**9)) } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) response_emit.success( _object=msg['_object'], action=msg['action'], uuid=msg['uuid'], data=extend_data, passback_parameters=msg.get('passback_parameters'))
def is_running(_dom=None): running = False try: exec_ret = libvirt_qemu.qemuAgentCommand( _dom, json.dumps({ 'execute': 'guest-ping', 'arguments': {} }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) running = True except: pass return running
def _open_file(self, dom, filePath): command = { "execute": "guest-file-open", "arguments": { "path": filePath, "mode": "r", } } try: ret = libvirt_qemu.qemuAgentCommand(dom, json.dumps(command), EXEC_TIMEOUT, 0) except Exception as err: raise exception.GuestExecutionError("failed to open file: %s" % err) from err ret = self._parse_command_output(ret) return int(ret)
def call_qga_command(self, vm, command, args=None): """ Execute QEMU-GA command and return result as dict or None on error command the command to execute (string) args arguments to the command (dict) or None """ # First make sure the command is supported by QEMU-GA if command != _QEMU_GUEST_INFO_COMMAND: caps = self.get_caps(vm.id) if caps is None or command not in caps['commands']: self.log.debug( 'Not sending QEMU-GA command \'%s\' to vm_id=\'%s\',' ' command is not supported', command, vm.id) return None cmd = {'execute': command} if args is not None: cmd['arguments'] = args cmd = json.dumps(cmd) try: self.log.debug( 'Calling QEMU-GA command for vm_id=\'%s\', command: %s', vm.id, cmd) ret = libvirt_qemu.qemuAgentCommand(vm._dom, cmd, _COMMAND_TIMEOUT, 0) self.log.debug('Call returned: %r', ret) except libvirt.libvirtError: # Most likely the QEMU-GA is not installed or is unresponsive self.set_failure(vm.id) return None try: parsed = json.loads(ret) except ValueError: self.log.exception( 'Failed to parse string returned by QEMU-GA: %r', ret) return None if 'error' in parsed: self.log.error('Error received from QEMU-GA: %r', ret) return None if 'return' not in parsed: self.log.error( 'Invalid response from QEMU-GA: %r', ret) return None return parsed['return']
def guest_ping(dom): name = dom.name() print time.time(), name, 'start' if not dom.isActive(): return None cmd = json.dumps({"execute": "guest-ping"}) try: rsp = libvirt_qemu.qemuAgentCommand(dom, cmd, 1, 0) except libvirt.libvirtError as ex: print '%s, %s, libvirt error: %s' % (time.time(), name, ex) rsp = None except Exception as ex: print '%s, %s, unkown error: %s' % (time.time(), name, ex) rsp = None else: print time.time(), name, rsp, 'end' return rsp
def run_command(self, dom, command, parameters, wait=True): if self.ping(dom) is False: raise exception.GuestAgentNotAvailable() if self._supports_guest_exec(dom) is False: raise exception.NotSupportedOperation( "missing required guest-exec functionality") command = { "execute": "guest-exec", "arguments": { "path": command, "arg": parameters, "capture-output": True, } } try: ret = libvirt_qemu.qemuAgentCommand(dom, json.dumps(command), EXEC_TIMEOUT, 0) except Exception as err: raise exception.GuestExecutionError("failed to run command: %s" % err) from err pid = self._get_pid_from_guest_exec_result(ret) command_result = self._read_output(dom, pid) start = datetime.datetime.now() if wait: while True: if command_result["exited"] is False: now = datetime.datetime.now() if now - start > datetime.timedelta(seconds=EXEC_TIMEOUT): raise TimeoutError("timed out waiting for command") time.sleep(1) command_result = self._read_output(dom, pid) else: if command_result["exitcode"] != 0: raise exception.GuestExecutionError( "Command returned errorcode: " "%r" % command_result["exitcode"]) if command_result["signal"] != 0: raise exception.GuestExecutionError( "Command interrupted by signal: " "%r" % command_result["signal"]) break return command_result
def get_guest_exec_status(guest, pid): ret = '{"return":{"exited":false}}' i = 0 while not json.loads(ret)['return']['exited'] and i < 1000: ret = libvirt_qemu.qemuAgentCommand(guest, json.dumps({ 'execute': 'guest-exec-status', 'arguments': { 'pid': pid } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) i += 1 time.sleep(0.001) return ret
def is_running(_guest): running = False try: exec_ret = libvirt_qemu.qemuAgentCommand(_guest, json.dumps({ 'execute': 'guest-ping', 'arguments': { } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) running = True except: logger.error(traceback.format_exc()) return running
def guest_exec(domain, cmd, args=[], timeout=6, flags=0): command = json.dumps({ "execute": "guest-exec", "arguments": { "path": cmd, "arg": args, "capture-output": True } }) result = None try: result = libvirt_qemu.qemuAgentCommand(domain, command, timeout, flags) except libvirt.libvirtError as e: pass if result: return json.loads(result)["return"]["pid"] else: return None
def main(): logging.basicConfig(format='%(asctime)s.%(msecs)03d %(process)d %(levelname)s [-] %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='/var/log/ga_to_redis.log', filemode='w') conn = libvirt.open(None) if conn is None: logging.error('Failed to open connection to the libvirt') ids = conn.listDomainsID() if ids is None or len(ids) == 0: logging.error('Failed to get running domains') cf = ConfigParser.ConfigParser() cf.read('/etc/redis_ga.conf') redis_ip = cf.get('redis', 'ip') redis_port = cf.get('redis', 'port') startup_nodes = [{'host': redis_ip, 'port': redis_port}] redis_conn = rediscluster.StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True) while True: for id in ids: dom = conn.lookupByID(id) uuid = dom.UUIDString() oid = ObjectId() try: result = libvirt_qemu.qemuAgentCommand(dom, '{"execute":"guest-get-total-info"}', 1, 0) except Exception, e: if e[0] == 'Guest agent is not responding: QEMU guest agent is not available due to an error': logging.error(e) logging.info('Restarting libvirtd') os.system('systemctl restart libvirtd') conn = libvirt.open(None) else: logging.error('instance-%r %r' % (uuid, e)) else: result = eval(result)['return'] print result print oid print uuid if result != {}: redis_conn.hset('hash_data', oid, result) redis_conn.lpush('list:' + uuid, oid) time.sleep(20)
def main(): argument_spec = dict(connection=dict(required=False, default="qemu:///system", type='str'), name=dict(required=True, type='str'), device=dict(required=True, type='str'), ipv4=dict(default=True, choices=BOOLEANS, type='bool'), ipv6=dict(default=False, choices=BOOLEANS, type='bool'), timeout=dict(required=False, default=30, type='int')) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False) if not HAS_LIBVIRT_QEMU: module.fail_json(msg='libvirt_qemu is required for this module') try: connect = libvirt.open(module.params['connection']) domain = connect.lookupByName(module.params['name']) network_interface_string \ = libvirt_qemu.qemuAgentCommand(domain, '{"execute":"guest-network-get-interfaces"}', module.params['timeout'], 0) network_obj = json.loads(network_interface_string) kwargs = {} for device in network_obj['return']: if device['name'] == module.params['device']: for ip in device['ip-addresses']: if ip['ip-address-type'] == 'ipv4' and module.params[ 'ipv4']: kwargs.update(ansible_virt_ipv4=ip['ip-address']) if ip['ip-address-type'] == 'ipv6' and module.params[ 'ipv6']: kwargs.update(ansible_virt_ipv6=ip['ip-address']) module.exit_json(**kwargs) except Exception as e: module.fail_json(msg=str(e))
def get_guest_memory_info(dom=None): assert isinstance(dom, libvirt.virDomain) memory_info = dict() try: exec_ret = libvirt_qemu.qemuAgentCommand( dom, json.dumps({ 'execute': 'guest-exec', 'arguments': { 'path': 'cat', 'capture-output': True, 'arg': ['/proc/meminfo'] } }), 3, libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) exec_ret = json.loads(exec_ret) status_ret = QGA.get_guest_exec_status( dom=dom, pid=exec_ret['return']['pid']) memory_info_str = base64.b64decode( json.loads(status_ret)['return']['out-data']) for item in memory_info_str.split('\n'): if item.__len__() == 0: continue k, v = item.split(':') if k not in memory_info: memory_info[k] = dict() v = v.split() memory_info[k]['value'] = v[0] if v.__len__() > 1: memory_info[k]['unit'] = v[1] except libvirt.libvirtError as e: pass return memory_info
def _read_from_file_handle(self, dom, handle): command = { "execute": "guest-file-read", "arguments": { "handle": handle, } } try: ret = libvirt_qemu.qemuAgentCommand(dom, json.dumps(command), EXEC_TIMEOUT, 0) except Exception as err: raise exception.GuestExecutionError("failed to open file: %s" % err) from err data = self._parse_command_output(ret) if data is not dict: LOG.debug("failed to read file") return "" output = data.get("buf-b64", None) if output is None: return "" if type(output) is not str: output = output.decode() return base64.b64decode(output.encode()).decode()
# Example-02.py from __future__ import print_function import sys import libvirt, libvirt_qemu conn = libvirt.open('qemu:///system') if conn == None: print('Failed to open connection to qemu:///system', \ file=sys.stderr) exit(1) domainName = 'centos7.0' dom = conn.lookupByName(domainName) if dom == None: print('Failed to get the domain object', file=sys.stderr) ret_json = libvirt_qemu.qemuAgentCommand( dom, '{"execute": "guest-get-time"}', libvirt_qemu.VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT, 0) if ret_json == None: print('Failed to get the JSON object', file=sys.stderr) else: print(ret_json) conn.close()
def qemu_agent_command(self, command, timeout, flags): return libvirt_qemu.qemuAgentCommand(self._dom, command, timeout, flags)
def qemuAgentCommand(self, uuid, command, timeout=10): import libvirt_qemu dom = self._getDomainFromUUID(uuid) if dom is None: return None return libvirt_qemu.qemuAgentCommand(dom, command, timeout, 0)
# print '%s %s alarm!' % (result['diskstat'][j]['devname'], r) event += event_dict[r] % (result['diskstat'][j]['devname'], eval(low_rule[r]), alarm[r]) if event is not '': post_data['detail'] = event post(post_url, post_data) def post(url, data): headers = {'content-type': 'application/json'} return requests.post(url, data=json.dumps(data), headers=headers) def cut_result(result): try: result['diskstat'] = filter(lambda diskstat: 'vd' or 'disk' in diskstat['devname'], result['diskstat']) result['netspeed'] = filter(lambda netspeed: 'eth0' in netspeed['devname'], result['netspeed']) except KeyError: pass if __name__ == '__main__': conn = libvirt.open(None) ids = conn.listDomainsID() for id in ids: dom = conn.lookupByID(id) instance_uuid = dom.UUIDString() result = libvirt_qemu.qemuAgentCommand(dom, '{"execute":"guest-get-total-info"}', 1, 0) result = eval(result)['return'] match_alarm(instance_uuid, result)
def run(): logging.basicConfig(format='%(asctime)s.%(msecs)03d %(process)d %(levelname)s [-] %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='/var/log/ga_to_mongo.log', filemode='w') client = MongoClient(mongo_ip, mongo_port) db = client.jk conn = libvirt.open(None) current_collection = db['current'] total_collection = db['total'] while True: time.sleep(interval) try: ids = conn.listDomainsID() except Exception: continue if ids is None or len(ids) == 0: logging.error('Failed to get running domains') for id in ids: try: dom = conn.lookupByID(id) uuid = dom.UUIDString() result = libvirt_qemu.qemuAgentCommand(dom, '{"execute":"guest-get-total-info"}', 1, 0) result = eval(result)['return'] result['time'] = datetime.datetime.now() except Exception, e: if e[0] == 'Guest agent is not responding: QEMU guest agent is not available due to an error': os.system('systemctl restart libvirtd') conn = libvirt.open(None) else: if result != {}: global collection try: # add_data current_total = current_collection.find_one({'_id':uuid}) try: if current_total is None: current_total = result total = {'processstat': [], 'login': [], 'netstat': [{'receive': {'bytes': 0, 'frame': 0, 'drop': 0, 'packets': 0, 'fifo': 0, 'multicast': 0, 'compressed': 0, 'errs': 0}, 'transmit': {'bytes': 0, 'drop': 0, 'packets': 0, 'fifo': 0, 'carrier': 0, 'colls': 0, 'compressed': 0, 'errs': 0}, 'devname': 'eth0'}, {'receive': {'bytes': 0, 'frame': 0, 'drop': 0, 'packets': 0, 'fifo': 0, 'multicast': 0, 'compressed': 0, 'errs': 0}, 'transmit': {'bytes': 0, 'drop': 0, 'packets': 0, 'fifo': 0, 'carrier': 0, 'colls': 0, 'compressed': 0, 'errs': 0}, 'devname': 'lo'}], 'diskstat': [{'statistics': {'kb_read': 0, 'speed_kb_read': 0, 'tps': 0, 'speed_kb_write': 0, 'kb_write': 0}, 'devname': 'vda'}], 'memstat': {'total': 0, 'used': 0}} else: total = total_collection.find_one({'_id':uuid}) if result['netstat'][0]['receive']['bytes'] >= current_total['netstat'][0]['receive']['bytes']: current_total = result else: total, current_total = add_data(total, current_total) current_total = result result, current_total = add_data(total, current_total) except KeyError, e: logging.error(e) continue # send result to mongodb collection = db[uuid] collection.create_index('time', expireAfterSeconds=expire) get_speed(result) collection.insert_one(result) # alarm try: alarm.match_alarm(uuid, result) except Exception, e: logging.error(e) # send add_data to mongodb total.update({'_id': uuid}) current_total.update({'_id': uuid}) r1 = total_collection.update({'_id': uuid}, total) r2 = current_collection.update({'_id': uuid}, current_total) if r1['updatedExisting'] is False: total_collection.insert_one(total) if r2['updatedExisting'] is False: current_collection.insert_one(current_total) except pymongo.errors.AutoReconnect, e: logging.error('Failed to connect mongodb %s' % e) continue except pymongo.errors.OperationFailure, e: logging.error('Failed to connect mongodb' % e) continue
uri = 'qemu:///system' conn = libvirt.openAuth(uri,auth) dom = conn.lookupByName("instance-00000682") command = sys.argv[1] cmd_name = command.split()[0] cmd = '{"execute": "guest-exec",' \ ' "arguments":{"path": "/Windows/System32/%s", "arg": ["%s"],\ "capture-output":true,"has_capture_output":true}}'\ % (cmd_name, '","'.join(command.split()[1:])) try: ret = qemuAgentCommand(dom, cmd, 20, 0) out = jsonutils.loads(ret) pid = out['return']['pid'] cmd_status = '{"execute": "guest-exec-status",' \ ' "arguments":{"pid": %s}}' % pid time.sleep(3) ret = qemuAgentCommand(dom, cmd_status, 20, 0) out = jsonutils.loads(ret) ret = {"command" : command} ret.update(out['return']) if 'out-data' in ret: ret['out-data'] = base64.b64decode(ret['out-data']) #.decode("GB2312") if 'err-data' in ret: ret['err-data'] = base64.b64decode(ret['err-data']) #.decode("GB2312") utils.print_dict(ret) except :
def put_file(self, in_path, out_path): ''' transfer a file from local to domain ''' super(Connection, self).put_file(in_path, out_path) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self._host) if not exists(to_bytes(in_path, errors='surrogate_or_strict')): raise AnsibleFileNotFound( "file or module does not exist: %s" % in_path) request_handle = { 'execute': 'guest-file-open', 'arguments': { 'path': out_path, 'mode': 'wb+' } } request_handle_json = json.dumps(request_handle) display.vvv(u"GA send: {0}".format(request_handle_json), host=self._host) result_handle = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_handle_json, 5, 0)) display.vvv(u"GA return: {0}".format(result_handle), host=self._host) # TODO(odyssey4me): # Handle exception for file/path IOError with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file: for chunk in iter(partial(in_file.read, BUFSIZE), b''): try: request_write = { 'execute': 'guest-file-write', 'arguments': { 'handle': result_handle['return'], 'buf-b64': base64.b64encode(chunk).decode() } } request_write_json = json.dumps(request_write) display.vvvvv(u"GA send: {0}".format(request_write_json), host=self._host) result_write = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_write_json, 5, 0)) display.vvvvv(u"GA return: {0}".format(result_write), host=self._host) except Exception: traceback.print_exc() raise AnsibleError("failed to transfer file %s to %s" % (in_path, out_path)) request_close = { 'execute': 'guest-file-close', 'arguments': { 'handle': result_handle['return'] } } request_close_json = json.dumps(request_close) display.vvv(u"GA send: {0}".format(request_close_json), host=self._host) result_close = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_close_json, 5, 0)) display.vvv(u"GA return: {0}".format(result_close), host=self._host)
def exec_command(self, cmd, in_data=None, sudoable=True): """ execute a command on the virtual machine host """ super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable) self._display.vvv(u"EXEC {0}".format(cmd), host=self._host) cmd_args_list = shlex.split(to_native(cmd, errors='surrogate_or_strict')) if getattr(self._shell, "_IS_WINDOWS", False): # Become method 'runas' is done in the wrapper that is executed, # need to disable sudoable so the bare_run is not waiting for a # prompt that will not occur sudoable = False # Generate powershell commands cmd_args_list = self._shell._encode_script(cmd, as_list=True, strict_mode=False, preserve_rc=False) # TODO(odyssey4me): # Implement buffering much like the other connection plugins # Implement 'env' for the environment settings # Implement 'input-data' for whatever it might be useful for request_exec = { 'execute': 'guest-exec', 'arguments': { 'path': cmd_args_list[0], 'capture-output': True, 'arg': cmd_args_list[1:] } } request_exec_json = json.dumps(request_exec) display.vvv(u"GA send: {0}".format(request_exec_json), host=self._host) # TODO(odyssey4me): # Add timeout parameter result_exec = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_exec_json, 5, 0)) display.vvv(u"GA return: {0}".format(result_exec), host=self._host) request_status = { 'execute': 'guest-exec-status', 'arguments': { 'pid': result_exec['return']['pid'] } } request_status_json = json.dumps(request_status) display.vvv(u"GA send: {0}".format(request_status_json), host=self._host) # TODO(odyssey4me): # Work out a better way to wait until the command has exited result_status = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_status_json, 5, 0)) display.vvv(u"GA return: {0}".format(result_status), host=self._host) while not result_status['return']['exited']: result_status = json.loads(libvirt_qemu.qemuAgentCommand(self.domain, request_status_json, 5, 0)) display.vvv(u"GA return: {0}".format(result_status), host=self._host) if result_status['return'].get('out-data'): stdout = base64.b64decode(result_status['return']['out-data']) else: stdout = b'' if result_status['return'].get('err-data'): stderr = base64.b64decode(result_status['return']['err-data']) else: stderr = b'' # Decode xml from windows if getattr(self._shell, "_IS_WINDOWS", False) and stdout.startswith(b"#< CLIXML"): stdout = _parse_clixml(stdout) display.vvv(u"GA stdout: {0}".format(to_text(stdout)), host=self._host) display.vvv(u"GA stderr: {0}".format(to_text(stderr)), host=self._host) return result_status['return']['exitcode'], stdout, stderr