tests/boot-sector: Fix the bad s390x assembler code
[qemu/ar7.git] / scripts / qmp / qemu-ga-client
blob30cf8a9a0da6a436bf3ab52c3ffcbaa932ded79c
1 #!/usr/bin/python
3 # QEMU Guest Agent Client
5 # Copyright (C) 2012 Ryota Ozaki <ozaki.ryota@gmail.com>
7 # This work is licensed under the terms of the GNU GPL, version 2. See
8 # the COPYING file in the top-level directory.
10 # Usage:
12 # Start QEMU with:
14 # # qemu [...] -chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
15 # -device virtio-serial -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
17 # Run the script:
19 # $ qemu-ga-client --address=/tmp/qga.sock <command> [args...]
21 # or
23 # $ export QGA_CLIENT_ADDRESS=/tmp/qga.sock
24 # $ qemu-ga-client <command> [args...]
26 # For example:
28 # $ qemu-ga-client cat /etc/resolv.conf
29 # # Generated by NetworkManager
30 # nameserver 10.0.2.3
31 # $ qemu-ga-client fsfreeze status
32 # thawed
33 # $ qemu-ga-client fsfreeze freeze
34 # 2 filesystems frozen
36 # See also: https://wiki.qemu.org/Features/QAPI/GuestAgent
39 from __future__ import print_function
40 import os
41 import sys
42 import base64
43 import random
45 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
46 from qemu import qmp
49 class QemuGuestAgent(qmp.QEMUMonitorProtocol):
50 def __getattr__(self, name):
51 def wrapper(**kwds):
52 return self.command('guest-' + name.replace('_', '-'), **kwds)
53 return wrapper
56 class QemuGuestAgentClient:
57 error = QemuGuestAgent.error
59 def __init__(self, address):
60 self.qga = QemuGuestAgent(address)
61 self.qga.connect(negotiate=False)
63 def sync(self, timeout=3):
64 # Avoid being blocked forever
65 if not self.ping(timeout):
66 raise EnvironmentError('Agent seems not alive')
67 uid = random.randint(0, (1 << 32) - 1)
68 while True:
69 ret = self.qga.sync(id=uid)
70 if isinstance(ret, int) and int(ret) == uid:
71 break
73 def __file_read_all(self, handle):
74 eof = False
75 data = ''
76 while not eof:
77 ret = self.qga.file_read(handle=handle, count=1024)
78 _data = base64.b64decode(ret['buf-b64'])
79 data += _data
80 eof = ret['eof']
81 return data
83 def read(self, path):
84 handle = self.qga.file_open(path=path)
85 try:
86 data = self.__file_read_all(handle)
87 finally:
88 self.qga.file_close(handle=handle)
89 return data
91 def info(self):
92 info = self.qga.info()
94 msgs = []
95 msgs.append('version: ' + info['version'])
96 msgs.append('supported_commands:')
97 enabled = [c['name'] for c in info['supported_commands'] if c['enabled']]
98 msgs.append('\tenabled: ' + ', '.join(enabled))
99 disabled = [c['name'] for c in info['supported_commands'] if not c['enabled']]
100 msgs.append('\tdisabled: ' + ', '.join(disabled))
102 return '\n'.join(msgs)
104 def __gen_ipv4_netmask(self, prefixlen):
105 mask = int('1' * prefixlen + '0' * (32 - prefixlen), 2)
106 return '.'.join([str(mask >> 24),
107 str((mask >> 16) & 0xff),
108 str((mask >> 8) & 0xff),
109 str(mask & 0xff)])
111 def ifconfig(self):
112 nifs = self.qga.network_get_interfaces()
114 msgs = []
115 for nif in nifs:
116 msgs.append(nif['name'] + ':')
117 if 'ip-addresses' in nif:
118 for ipaddr in nif['ip-addresses']:
119 if ipaddr['ip-address-type'] == 'ipv4':
120 addr = ipaddr['ip-address']
121 mask = self.__gen_ipv4_netmask(int(ipaddr['prefix']))
122 msgs.append("\tinet %s netmask %s" % (addr, mask))
123 elif ipaddr['ip-address-type'] == 'ipv6':
124 addr = ipaddr['ip-address']
125 prefix = ipaddr['prefix']
126 msgs.append("\tinet6 %s prefixlen %s" % (addr, prefix))
127 if nif['hardware-address'] != '00:00:00:00:00:00':
128 msgs.append("\tether " + nif['hardware-address'])
130 return '\n'.join(msgs)
132 def ping(self, timeout):
133 self.qga.settimeout(timeout)
134 try:
135 self.qga.ping()
136 except self.qga.timeout:
137 return False
138 return True
140 def fsfreeze(self, cmd):
141 if cmd not in ['status', 'freeze', 'thaw']:
142 raise Exception('Invalid command: ' + cmd)
144 return getattr(self.qga, 'fsfreeze' + '_' + cmd)()
146 def fstrim(self, minimum=0):
147 return getattr(self.qga, 'fstrim')(minimum=minimum)
149 def suspend(self, mode):
150 if mode not in ['disk', 'ram', 'hybrid']:
151 raise Exception('Invalid mode: ' + mode)
153 try:
154 getattr(self.qga, 'suspend' + '_' + mode)()
155 # On error exception will raise
156 except self.qga.timeout:
157 # On success command will timed out
158 return
160 def shutdown(self, mode='powerdown'):
161 if mode not in ['powerdown', 'halt', 'reboot']:
162 raise Exception('Invalid mode: ' + mode)
164 try:
165 self.qga.shutdown(mode=mode)
166 except self.qga.timeout:
167 return
170 def _cmd_cat(client, args):
171 if len(args) != 1:
172 print('Invalid argument')
173 print('Usage: cat <file>')
174 sys.exit(1)
175 print(client.read(args[0]))
178 def _cmd_fsfreeze(client, args):
179 usage = 'Usage: fsfreeze status|freeze|thaw'
180 if len(args) != 1:
181 print('Invalid argument')
182 print(usage)
183 sys.exit(1)
184 if args[0] not in ['status', 'freeze', 'thaw']:
185 print('Invalid command: ' + args[0])
186 print(usage)
187 sys.exit(1)
188 cmd = args[0]
189 ret = client.fsfreeze(cmd)
190 if cmd == 'status':
191 print(ret)
192 elif cmd == 'freeze':
193 print("%d filesystems frozen" % ret)
194 else:
195 print("%d filesystems thawed" % ret)
198 def _cmd_fstrim(client, args):
199 if len(args) == 0:
200 minimum = 0
201 else:
202 minimum = int(args[0])
203 print(client.fstrim(minimum))
206 def _cmd_ifconfig(client, args):
207 print(client.ifconfig())
210 def _cmd_info(client, args):
211 print(client.info())
214 def _cmd_ping(client, args):
215 if len(args) == 0:
216 timeout = 3
217 else:
218 timeout = float(args[0])
219 alive = client.ping(timeout)
220 if not alive:
221 print("Not responded in %s sec" % args[0])
222 sys.exit(1)
225 def _cmd_suspend(client, args):
226 usage = 'Usage: suspend disk|ram|hybrid'
227 if len(args) != 1:
228 print('Less argument')
229 print(usage)
230 sys.exit(1)
231 if args[0] not in ['disk', 'ram', 'hybrid']:
232 print('Invalid command: ' + args[0])
233 print(usage)
234 sys.exit(1)
235 client.suspend(args[0])
238 def _cmd_shutdown(client, args):
239 client.shutdown()
240 _cmd_powerdown = _cmd_shutdown
243 def _cmd_halt(client, args):
244 client.shutdown('halt')
247 def _cmd_reboot(client, args):
248 client.shutdown('reboot')
251 commands = [m.replace('_cmd_', '') for m in dir() if '_cmd_' in m]
254 def main(address, cmd, args):
255 if not os.path.exists(address):
256 print('%s not found' % address)
257 sys.exit(1)
259 if cmd not in commands:
260 print('Invalid command: ' + cmd)
261 print('Available commands: ' + ', '.join(commands))
262 sys.exit(1)
264 try:
265 client = QemuGuestAgentClient(address)
266 except QemuGuestAgent.error as e:
267 import errno
269 print(e)
270 if e.errno == errno.ECONNREFUSED:
271 print('Hint: qemu is not running?')
272 sys.exit(1)
274 if cmd == 'fsfreeze' and args[0] == 'freeze':
275 client.sync(60)
276 elif cmd != 'ping':
277 client.sync()
279 globals()['_cmd_' + cmd](client, args)
282 if __name__ == '__main__':
283 import sys
284 import os
285 import optparse
287 address = os.environ['QGA_CLIENT_ADDRESS'] if 'QGA_CLIENT_ADDRESS' in os.environ else None
289 usage = "%prog [--address=<unix_path>|<ipv4_address>] <command> [args...]\n"
290 usage += '<command>: ' + ', '.join(commands)
291 parser = optparse.OptionParser(usage=usage)
292 parser.add_option('--address', action='store', type='string',
293 default=address, help='Specify a ip:port pair or a unix socket path')
294 options, args = parser.parse_args()
296 address = options.address
297 if address is None:
298 parser.error('address is not specified')
299 sys.exit(1)
301 if len(args) == 0:
302 parser.error('Less argument')
303 sys.exit(1)
305 main(address, args[0], args[1:])