blob: fcfbc22b17dad2c5e5a48bb5b25bec7cbbb0c34e [file] [log] [blame]
#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Talk to a KVM guest through Libvirt and the Qemu Guest Agent
# to retrieve information from the guest
#
# System VMs have the Qemu Guest Agent installed by default
# and should properly respond to such commands
#
# Talk to KVM Instances through the Qemu Guest Agent
#
import argparse
import json
import sys
import libvirt
import libvirt_qemu
COMMANDS = ["info", "ping", "fstrim"]
class Libvirt:
def __init__(self, uri=None, timeout=5):
self.timeout = timeout
self.conn = libvirt.open(uri)
if not self.conn:
raise Exception('Failed to open connection to the hypervisor')
def get_domain(self, name):
return self.conn.lookupByName(name)
def agent_command(self, dom, cmd, flags=0, raw=False):
ret = libvirt_qemu.qemuAgentCommand(dom, json.dumps({'execute': cmd}),
self.timeout, flags)
if raw:
return ret
return json.loads(ret)['return']
class GuestCommand:
def __init__(self, domain, timeout):
self.domain = domain
self.timeout = timeout
self.virt = Libvirt(timeout=self.timeout)
self.dom = self.virt.get_domain(self.domain)
def ping(self):
result = self.virt.agent_command(self.dom, 'guest-ping')
res = False
code = 1
if len(result) == 0:
res = True
code = 0
return {'result': res}, code
def info(self):
info = dict()
info['filesystem'] = 'guest-get-fsinfo'
info['network'] = 'guest-network-get-interfaces'
result = dict()
for key, cmd in list(info.items()):
result[key] = self.virt.agent_command(self.dom, cmd)
return result, 0
def fstrim(self):
result = self.virt.agent_command(self.dom, 'guest-fstrim')
res = False
code = 1
if len(result) > 0:
res = True
code = 0
return {'result': result}, code
def main(args):
command = args.command
try:
guestcmd = GuestCommand(args.instance, args.timeout)
result = {'error': 'Command not implemented'}
code = 255
if command == 'info':
result, code = guestcmd.info()
elif command == 'ping':
result, code = guestcmd.ping()
elif command == 'fstrim':
result, code = guestcmd.fstrim()
print(json.dumps(result))
sys.exit(code)
except libvirt.libvirtError as exc:
print(json.dumps({'error': str(exc)}))
sys.exit(255)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='CloudStack Guest Tool')
parser.add_argument('instance', type=str,
help='Instance Name')
parser.add_argument('--command', type=str, required=False,
help='Command to execute', default='info',
choices=COMMANDS)
parser.add_argument('--timeout', type=int, required=False,
help='timeout in seconds', default=5)
args = parser.parse_args()
main(args)