qom: Use return values to check for error where that's simpler
[qemu/ar7.git] / tests / qemu-iotests / qcow2.py
blob0910e6ac07057270c477980e5f0a5a7d6f9582be
1 #!/usr/bin/env python3
3 # Manipulations with qcow2 image
5 # Copyright (C) 2012 Red Hat, Inc.
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 import sys
23 from qcow2_format import (
24 QcowHeader,
25 QcowHeaderExtension
29 def cmd_dump_header(fd):
30 h = QcowHeader(fd)
31 h.dump()
32 print()
33 h.dump_extensions()
36 def cmd_dump_header_exts(fd):
37 h = QcowHeader(fd)
38 h.dump_extensions()
41 def cmd_set_header(fd, name, value):
42 try:
43 value = int(value, 0)
44 except ValueError:
45 print("'%s' is not a valid number" % value)
46 sys.exit(1)
48 fields = (field[2] for field in QcowHeader.fields)
49 if name not in fields:
50 print("'%s' is not a known header field" % name)
51 sys.exit(1)
53 h = QcowHeader(fd)
54 h.__dict__[name] = value
55 h.update(fd)
58 def cmd_add_header_ext(fd, magic, data):
59 try:
60 magic = int(magic, 0)
61 except ValueError:
62 print("'%s' is not a valid magic number" % magic)
63 sys.exit(1)
65 h = QcowHeader(fd)
66 h.extensions.append(QcowHeaderExtension.create(magic,
67 data.encode('ascii')))
68 h.update(fd)
71 def cmd_add_header_ext_stdio(fd, magic):
72 data = sys.stdin.read()
73 cmd_add_header_ext(fd, magic, data)
76 def cmd_del_header_ext(fd, magic):
77 try:
78 magic = int(magic, 0)
79 except ValueError:
80 print("'%s' is not a valid magic number" % magic)
81 sys.exit(1)
83 h = QcowHeader(fd)
84 found = False
86 for ex in h.extensions:
87 if ex.magic == magic:
88 found = True
89 h.extensions.remove(ex)
91 if not found:
92 print("No such header extension")
93 return
95 h.update(fd)
98 def cmd_set_feature_bit(fd, group, bit):
99 try:
100 bit = int(bit, 0)
101 if bit < 0 or bit >= 64:
102 raise ValueError
103 except ValueError:
104 print("'%s' is not a valid bit number in range [0, 64)" % bit)
105 sys.exit(1)
107 h = QcowHeader(fd)
108 if group == 'incompatible':
109 h.incompatible_features |= 1 << bit
110 elif group == 'compatible':
111 h.compatible_features |= 1 << bit
112 elif group == 'autoclear':
113 h.autoclear_features |= 1 << bit
114 else:
115 print("'%s' is not a valid group, try "
116 "'incompatible', 'compatible', or 'autoclear'" % group)
117 sys.exit(1)
119 h.update(fd)
122 cmds = [
123 ['dump-header', cmd_dump_header, 0,
124 'Dump image header and header extensions'],
125 ['dump-header-exts', cmd_dump_header_exts, 0,
126 'Dump image header extensions'],
127 ['set-header', cmd_set_header, 2, 'Set a field in the header'],
128 ['add-header-ext', cmd_add_header_ext, 2, 'Add a header extension'],
129 ['add-header-ext-stdio', cmd_add_header_ext_stdio, 1,
130 'Add a header extension, data from stdin'],
131 ['del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension'],
132 ['set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'],
136 def main(filename, cmd, args):
137 fd = open(filename, "r+b")
138 try:
139 for name, handler, num_args, desc in cmds:
140 if name != cmd:
141 continue
142 elif len(args) != num_args:
143 usage()
144 return
145 else:
146 handler(fd, *args)
147 return
148 print("Unknown command '%s'" % cmd)
149 finally:
150 fd.close()
153 def usage():
154 print("Usage: %s <file> <cmd> [<arg>, ...]" % sys.argv[0])
155 print("")
156 print("Supported commands:")
157 for name, handler, num_args, desc in cmds:
158 print(" %-20s - %s" % (name, desc))
161 if __name__ == '__main__':
162 if len(sys.argv) < 3:
163 usage()
164 sys.exit(1)
166 main(sys.argv[1], sys.argv[2], sys.argv[3:])