Beispiel #1
0
    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)
Beispiel #2
0
 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)
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
 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))
Beispiel #8
0
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
Beispiel #10
0
def guest_agent_available(dom):
    cmd = '{"execute":"guest-ping"}'
    try:
        out = qemuAgentCommand(dom, cmd, 30, 0)
    except libvirt.libvirtError:
        return False
    return True
Beispiel #11
0
 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
Beispiel #12
0
 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_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 _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
Beispiel #15
0
 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)
Beispiel #16
0
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
Beispiel #17
0
 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
Beispiel #18
0
    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'))
Beispiel #19
0
        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
Beispiel #20
0
 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)
Beispiel #21
0
    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']
Beispiel #22
0
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
Beispiel #23
0
    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']
Beispiel #24
0
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
Beispiel #25
0
    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
Beispiel #26
0
    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
Beispiel #27
0
        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
Beispiel #28
0
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
Beispiel #29
0
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))
Beispiel #31
0
    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
Beispiel #32
0
 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()
Beispiel #34
0
 def qemu_agent_command(self, command, timeout, flags):
     return libvirt_qemu.qemuAgentCommand(self._dom, command, timeout,
                                          flags)
Beispiel #35
0
 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)
Beispiel #36
0
 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)
Beispiel #37
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
Beispiel #39
0
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