Skip to content

Commit 8da0556

Browse files
widorohityadavcloud
authored andcommitted
kvm/cloudstack-guest-tool: Tool to query Qemu Guest Agent (apache#3519)
Using this tool on a hypervisor admins can query KVM Instances running on that hypervisor if they have the Qemu Guest Agent installed. All System VMs have this and they can be queried. For example: $ cloudstack-guest-tool i-2-25-VM This will print some information about network and filesystem status. root@hv-138-a05-23:~# ./cloudstack-guest-tool s-11-VM --command info|jq { "network": [ { "ip-addresses": [ { "prefix": 8, "ip-address": "127.0.0.1", "ip-address-type": "ipv4" } ], "name": "lo", "hardware-address": "00:00:00:00:00:00" }, { "ip-addresses": [ { "prefix": 16, "ip-address": "169.254.242.169", "ip-address-type": "ipv4" } ], "name": "eth0", "hardware-address": "0e:00:a9:fe:f2:a9" }, ... ... "filesystem": [ { "mountpoint": "/var", "disk": [ { "bus": 0, "bus-type": "virtio", "target": 0, "unit": 0, "pci-controller": { "slot": 7, "bus": 0, "domain": 0, "function": 0 } } ], "type": "ext4", "name": "vda6" }, Signed-off-by: Wido den Hollander <wido@widodh.nl>
1 parent fbec3b3 commit 8da0556

File tree

4 files changed

+134
-0
lines changed

4 files changed

+134
-0
lines changed

agent/bindir/cloud-guest-tool.in

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/usr/bin/env python
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
19+
#
20+
# Talk to a KVM guest through Libvirt and the Qemu Guest Agent
21+
# to retrieve information from the guest
22+
#
23+
# System VMs have the Qemu Guest Agent installed by default
24+
# and should properly respond to such commands
25+
26+
#
27+
# Talk to KVM Instances through the Qemu Guest Agent
28+
#
29+
30+
import argparse
31+
import json
32+
import sys
33+
import libvirt
34+
import libvirt_qemu
35+
36+
COMMANDS = ["info", "ping", "fstrim"]
37+
38+
39+
class Libvirt:
40+
def __init__(self, uri=None, timeout=5):
41+
self.timeout = timeout
42+
self.conn = libvirt.open(uri)
43+
if not self.conn:
44+
raise Exception('Failed to open connection to the hypervisor')
45+
46+
def get_domain(self, name):
47+
return self.conn.lookupByName(name)
48+
49+
def agent_command(self, dom, cmd, flags=0, raw=False):
50+
ret = libvirt_qemu.qemuAgentCommand(dom, json.dumps({'execute': cmd}),
51+
self.timeout, flags)
52+
if raw:
53+
return ret
54+
55+
return json.loads(ret)['return']
56+
57+
class GuestCommand:
58+
def __init__(self, domain, timeout):
59+
self.domain = domain
60+
self.timeout = timeout
61+
self.virt = Libvirt(timeout=self.timeout)
62+
self.dom = self.virt.get_domain(self.domain)
63+
64+
def ping(self):
65+
result = self.virt.agent_command(self.dom, 'guest-ping')
66+
67+
res = False
68+
code = 1
69+
if len(result) == 0:
70+
res = True
71+
code = 0
72+
73+
return {'result': res}, code
74+
75+
def info(self):
76+
info = dict()
77+
info['filesystem'] = 'guest-get-fsinfo'
78+
info['network'] = 'guest-network-get-interfaces'
79+
80+
result = dict()
81+
for key, cmd in info.items():
82+
result[key] = self.virt.agent_command(self.dom, cmd)
83+
84+
return result, 0
85+
86+
def fstrim(self):
87+
result = self.virt.agent_command(self.dom, 'guest-fstrim')
88+
89+
res = False
90+
code = 1
91+
if len(result) > 0:
92+
res = True
93+
code = 0
94+
95+
return {'result': result}, code
96+
97+
98+
def main(args):
99+
command = args.command
100+
101+
try:
102+
guestcmd = GuestCommand(args.instance, args.timeout)
103+
result = {'error': 'Command not implemented'}
104+
code = 255
105+
106+
if command == 'info':
107+
result, code = guestcmd.info()
108+
elif command == 'ping':
109+
result, code = guestcmd.ping()
110+
elif command == 'fstrim':
111+
result, code = guestcmd.fstrim()
112+
113+
print(json.dumps(result))
114+
sys.exit(code)
115+
except libvirt.libvirtError as exc:
116+
print(json.dumps({'error': str(exc)}))
117+
sys.exit(255)
118+
119+
if __name__ == '__main__':
120+
parser = argparse.ArgumentParser(description='CloudStack Guest Tool')
121+
parser.add_argument('instance', type=str,
122+
help='Instance Name')
123+
parser.add_argument('--command', type=str, required=False,
124+
help='Command to execute', default='info',
125+
choices=COMMANDS)
126+
parser.add_argument('--timeout', type=int, required=False,
127+
help='timeout in seconds', default=5)
128+
args = parser.parse_args()
129+
main(args)

debian/rules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ override_dh_auto_install:
5252
install -D agent/target/transformed/cloud-ssh $(DESTDIR)/usr/bin/cloudstack-ssh
5353
install -D agent/target/transformed/cloudstack-agent-profile.sh $(DESTDIR)/$(SYSCONFDIR)/profile.d/cloudstack-agent-profile.sh
5454
install -D agent/target/transformed/cloudstack-agent-upgrade $(DESTDIR)/usr/bin/cloudstack-agent-upgrade
55+
install -D agent/target/transformed/cloud-guest-tool $(DESTDIR)/usr/bin/cloudstack-guest-tool
5556
install -D agent/target/transformed/libvirtqemuhook $(DESTDIR)/usr/share/$(PACKAGE)-agent/lib/
5657
install -D agent/target/transformed/* $(DESTDIR)/$(SYSCONFDIR)/$(PACKAGE)/agent
5758

packaging/centos63/cloud.spec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ install -D agent/target/transformed/environment.properties ${RPM_BUILD_ROOT}%{_s
319319
install -D agent/target/transformed/log4j-cloud.xml ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent/log4j-cloud.xml
320320
install -D agent/target/transformed/cloud-setup-agent ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-agent
321321
install -D agent/target/transformed/cloudstack-agent-upgrade ${RPM_BUILD_ROOT}%{_bindir}/%{name}-agent-upgrade
322+
install -D agent/target/transformed/cloud-guest-tool ${RPM_BUILD_ROOT}%{_bindir}/%{name}-guest-tool
322323
install -D agent/target/transformed/libvirtqemuhook ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/libvirtqemuhook
323324
install -D agent/target/transformed/cloud-ssh ${RPM_BUILD_ROOT}%{_bindir}/%{name}-ssh
324325
install -D agent/target/transformed/cloudstack-agent-profile.sh ${RPM_BUILD_ROOT}%{_sysconfdir}/profile.d/%{name}-agent-profile.sh
@@ -562,6 +563,7 @@ pip install --upgrade /usr/share/cloudstack-marvin/Marvin-*.tar.gz
562563
%files agent
563564
%attr(0755,root,root) %{_bindir}/%{name}-setup-agent
564565
%attr(0755,root,root) %{_bindir}/%{name}-agent-upgrade
566+
%attr(0755,root,root) %{_bindir}/%{name}-guest-tool
565567
%attr(0755,root,root) %{_bindir}/%{name}-ssh
566568
%attr(0755,root,root) %{_sysconfdir}/init.d/%{name}-agent
567569
%attr(0644,root,root) %{_sysconfdir}/profile.d/%{name}-agent-profile.sh

packaging/centos7/cloud.spec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ install -D agent/target/transformed/environment.properties ${RPM_BUILD_ROOT}%{_s
294294
install -D agent/target/transformed/log4j-cloud.xml ${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/agent/log4j-cloud.xml
295295
install -D agent/target/transformed/cloud-setup-agent ${RPM_BUILD_ROOT}%{_bindir}/%{name}-setup-agent
296296
install -D agent/target/transformed/cloudstack-agent-upgrade ${RPM_BUILD_ROOT}%{_bindir}/%{name}-agent-upgrade
297+
install -D agent/target/transformed/cloud-guest-tool ${RPM_BUILD_ROOT}%{_bindir}/%{name}-guest-tool
297298
install -D agent/target/transformed/libvirtqemuhook ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/libvirtqemuhook
298299
install -D agent/target/transformed/cloud-ssh ${RPM_BUILD_ROOT}%{_bindir}/%{name}-ssh
299300
install -D agent/target/transformed/cloudstack-agent-profile.sh ${RPM_BUILD_ROOT}%{_sysconfdir}/profile.d/%{name}-agent-profile.sh
@@ -510,6 +511,7 @@ pip install --upgrade /usr/share/cloudstack-marvin/Marvin-*.tar.gz
510511
%files agent
511512
%attr(0755,root,root) %{_bindir}/%{name}-setup-agent
512513
%attr(0755,root,root) %{_bindir}/%{name}-agent-upgrade
514+
%attr(0755,root,root) %{_bindir}/%{name}-guest-tool
513515
%attr(0755,root,root) %{_bindir}/%{name}-ssh
514516
%attr(0644,root,root) %{_unitdir}/%{name}-agent.service
515517
%config(noreplace) %{_sysconfdir}/default/%{name}-agent

0 commit comments

Comments
 (0)