3 # Manipulations with qcow2 image
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 from qcow2_format import (
27 def cmd_dump_header(fd):
33 def cmd_dump_header_exts(fd):
38 def cmd_set_header(fd, name, value):
42 print("'%s' is not a valid number" % value)
45 fields = (field[2] for field in QcowHeader.fields)
46 if name not in fields:
47 print("'%s' is not a known header field" % name)
51 h.__dict__[name] = value
55 def cmd_add_header_ext(fd, magic, data):
59 print("'%s' is not a valid magic number" % magic)
63 h.extensions.append(QcowHeaderExtension.create(magic,
64 data.encode('ascii')))
68 def cmd_add_header_ext_stdio(fd, magic):
69 data = sys.stdin.read()
70 cmd_add_header_ext(fd, magic, data)
73 def cmd_del_header_ext(fd, magic):
77 print("'%s' is not a valid magic number" % magic)
83 for ex in h.extensions:
86 h.extensions.remove(ex)
89 print("No such header extension")
95 def cmd_set_feature_bit(fd, group, bit):
98 if bit < 0 or bit >= 64:
101 print("'%s' is not a valid bit number in range [0, 64)" % bit)
105 if group == 'incompatible':
106 h.incompatible_features |= 1 << bit
107 elif group == 'compatible':
108 h.compatible_features |= 1 << bit
109 elif group == 'autoclear':
110 h.autoclear_features |= 1 << bit
112 print("'%s' is not a valid group, try "
113 "'incompatible', 'compatible', or 'autoclear'" % group)
120 ['dump-header', cmd_dump_header, 0,
121 'Dump image header and header extensions'],
122 ['dump-header-exts', cmd_dump_header_exts, 0,
123 'Dump image header extensions'],
124 ['set-header', cmd_set_header, 2, 'Set a field in the header'],
125 ['add-header-ext', cmd_add_header_ext, 2, 'Add a header extension'],
126 ['add-header-ext-stdio', cmd_add_header_ext_stdio, 1,
127 'Add a header extension, data from stdin'],
128 ['del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension'],
129 ['set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'],
133 def main(filename, cmd, args):
134 fd = open(filename, "r+b")
136 for name, handler, num_args, desc in cmds:
139 elif len(args) != num_args:
145 print("Unknown command '%s'" % cmd)
151 print("Usage: %s <file> <cmd> [<arg>, ...]" % sys.argv[0])
153 print("Supported commands:")
154 for name, handler, num_args, desc in cmds:
155 print(" %-20s - %s" % (name, desc))
158 if __name__ == '__main__':
159 if len(sys.argv) < 3:
163 main(sys.argv[1], sys.argv[2], sys.argv[3:])