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/>.
23 from qcow2_format
import (
29 def cmd_dump_header(fd
):
36 def cmd_dump_header_exts(fd
):
41 def cmd_set_header(fd
, name
, value
):
45 print("'%s' is not a valid number" % value
)
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
)
54 h
.__dict
__[name
] = value
58 def cmd_add_header_ext(fd
, magic
, data
):
62 print("'%s' is not a valid magic number" % magic
)
66 h
.extensions
.append(QcowHeaderExtension
.create(magic
,
67 data
.encode('ascii')))
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
):
80 print("'%s' is not a valid magic number" % magic
)
86 for ex
in h
.extensions
:
89 h
.extensions
.remove(ex
)
92 print("No such header extension")
98 def cmd_set_feature_bit(fd
, group
, bit
):
101 if bit
< 0 or bit
>= 64:
104 print("'%s' is not a valid bit number in range [0, 64)" % bit
)
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
115 print("'%s' is not a valid group, try "
116 "'incompatible', 'compatible', or 'autoclear'" % group
)
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")
139 for name
, handler
, num_args
, desc
in cmds
:
142 elif len(args
) != num_args
:
148 print("Unknown command '%s'" % cmd
)
154 print("Usage: %s <file> <cmd> [<arg>, ...]" % sys
.argv
[0])
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:
166 main(sys
.argv
[1], sys
.argv
[2], sys
.argv
[3:])