Revision 0ae01e26
b/image_creator/__init__.py | ||
---|---|---|
50 | 50 |
|
51 | 51 |
return getattr(module, classname) |
52 | 52 |
|
53 |
class FatalError(Exception): |
|
54 |
pass |
|
53 | 55 |
|
54 | 56 |
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |
b/image_creator/disk.py | ||
---|---|---|
1 | 1 |
#!/usr/bin/env python |
2 | 2 |
|
3 | 3 |
from image_creator.util import get_command |
4 |
from image_creator import FatalError |
|
4 | 5 |
from clint.textui import progress |
5 | 6 |
|
6 | 7 |
import stat |
... | ... | |
109 | 110 |
|
110 | 111 |
def progress_generator(label=''): |
111 | 112 |
position = 0; |
112 |
for i in progress.bar(range(100),''):
|
|
113 |
for i in progress.bar(range(100),label):
|
|
113 | 114 |
if i < position: |
114 | 115 |
continue |
115 | 116 |
position = yield |
... | ... | |
139 | 140 |
def enable(self): |
140 | 141 |
"""Enable a newly created DiskDevice""" |
141 | 142 |
|
142 |
self.progressbar = progress_generator() |
|
143 |
self.progressbar = progress_generator("VM lauch: ")
|
|
143 | 144 |
self.progressbar.next() |
144 | 145 |
eh = self.g.set_event_callback(self.progress_callback, guestfs.EVENT_PROGRESS) |
145 | 146 |
self.g.launch() |
... | ... | |
151 | 152 |
|
152 | 153 |
roots = self.g.inspect_os() |
153 | 154 |
if len(roots) == 0: |
154 |
raise DiskError("No operating system found")
|
|
155 |
raise FatalError("No operating system found")
|
|
155 | 156 |
if len(roots) > 1: |
156 |
raise DiskError("Multiple operating systems found")
|
|
157 |
raise FatalError("Multiple operating systems found")
|
|
157 | 158 |
|
158 | 159 |
self.root = roots[0] |
159 | 160 |
self.ostype = self.g.inspect_get_type(self.root) |
... | ... | |
174 | 175 |
total = array[3] |
175 | 176 |
|
176 | 177 |
assert self.progress_bar is not None |
177 |
|
|
178 |
print 'posisition/total: %s/%s' % (position, total) |
|
178 | 179 |
self.progress_bar.send((position * 100)//total) |
179 | 180 |
|
180 | 181 |
if position == total: |
... | ... | |
214 | 215 |
dev = self.g.part_to_dev(self.root) |
215 | 216 |
parttype = self.g.part_get_parttype(dev) |
216 | 217 |
if parttype != 'msdos': |
217 |
raise DiskError("You have a %s partition table. "
|
|
218 |
raise FatalError("You have a %s partition table. "
|
|
218 | 219 |
"Only msdos partitions are supported" % parttype) |
219 | 220 |
|
220 | 221 |
last_partition = self.g.part_list(dev)[-1] |
221 | 222 |
|
222 | 223 |
if last_partition['part_num'] > 4: |
223 |
raise DiskError("This disk contains logical partitions. "
|
|
224 |
raise FatalError("This disk contains logical partitions. "
|
|
224 | 225 |
"Only primary partitions are supported.") |
225 | 226 |
|
226 | 227 |
part_dev = "%s%d" % (dev, last_partition['part_num']) |
b/image_creator/main.py | ||
---|---|---|
33 | 33 |
|
34 | 34 |
from image_creator import get_os_class |
35 | 35 |
from image_creator import __version__ as version |
36 |
from image_creator import FatalError |
|
36 | 37 |
from image_creator.disk import Disk |
37 | 38 |
from image_creator.util import get_command |
38 | 39 |
|
... | ... | |
43 | 44 |
dd = get_command('dd') |
44 | 45 |
|
45 | 46 |
|
46 |
class FatalError(Exception): |
|
47 |
pass |
|
47 |
def check_writable_dir(option, opt_str, value, parser): |
|
48 |
dirname = os.path.dirname(value) |
|
49 |
name = os.path.basename(value) |
|
50 |
if dirname and not os.path.isdir(dirname): |
|
51 |
parser.error("`%s' is not an existing directory" % dirname) |
|
48 | 52 |
|
53 |
if not name: |
|
54 |
parser.error("`%s' is not a valid file name" % dirname) |
|
49 | 55 |
|
50 |
def check_writable_dir(option, opt_str, value, parser): |
|
51 |
if not os.path.isdir(value): |
|
52 |
raise OptionValueError("%s is not a valid directory name" % value) |
|
53 | 56 |
setattr(parser.values, option.dest, value) |
54 | 57 |
|
55 | 58 |
|
56 | 59 |
def parse_options(input_args): |
57 |
usage = "Usage: %prog [options] <input_media> <name>"
|
|
60 |
usage = "Usage: %prog [options] <input_media>" |
|
58 | 61 |
parser = optparse.OptionParser(version=version, usage=usage) |
59 | 62 |
|
60 |
parser.add_option("-o", "--outdir", type="string", dest="outdir", |
|
61 |
default=".", action="callback", callback=check_writable_dir, |
|
62 |
help="Output files to DIR [default: working dir]", |
|
63 |
metavar="DIR") |
|
64 |
|
|
65 | 63 |
parser.add_option("-f", "--force", dest="force", default=False, |
66 | 64 |
action="store_true", help="Overwrite output files if they exist") |
67 | 65 |
|
... | ... | |
77 | 75 |
help="Don't shrink any partition before extracting the image", |
78 | 76 |
action="store_false") |
79 | 77 |
|
78 |
parser.add_option("-o", "--outfile", type="string", dest="outfile", |
|
79 |
default=None, action="callback", callback=check_writable_dir, |
|
80 |
help="Output image file", |
|
81 |
metavar="FILE") |
|
82 |
|
|
80 | 83 |
parser.add_option("-u", "--upload", dest="upload", default=False, |
81 | 84 |
help="Upload image to a pithos repository using kamaki", |
82 | 85 |
action="store_true") |
... | ... | |
86 | 89 |
|
87 | 90 |
options, args = parser.parse_args(input_args) |
88 | 91 |
|
89 |
if len(args) != 2:
|
|
90 |
parser.error('input media or name are missing')
|
|
92 |
if len(args) != 1:
|
|
93 |
parser.error('Wrong number of arguments')
|
|
91 | 94 |
options.source = args[0] |
92 |
options.name = args[1] |
|
93 |
|
|
94 | 95 |
if not os.path.exists(options.source): |
95 |
parser.error('Input media is not accessible')
|
|
96 |
parser.error('input media is not accessible')
|
|
96 | 97 |
|
97 | 98 |
if options.register: |
98 | 99 |
options.upload = True |
99 | 100 |
|
101 |
if options.outfile is None and not options.upload: |
|
102 |
parser.error('either outfile (-o) or upload (-u) must be set.') |
|
103 |
|
|
100 | 104 |
return options |
101 | 105 |
|
102 | 106 |
|
103 |
def main():
|
|
107 |
def image_creator():
|
|
104 | 108 |
|
105 | 109 |
options = parse_options(sys.argv[1:]) |
106 | 110 |
|
... | ... | |
109 | 113 |
% os.path.basename(sys.argv[0])) |
110 | 114 |
|
111 | 115 |
if not options.force: |
112 |
for extension in ('diskdump', 'meta'):
|
|
113 |
filename = "%s/%s.%s" % (options.outdir, options.name, extension)
|
|
116 |
for extension in ('', '.meta'):
|
|
117 |
filename = "%s%s" % (options.outfile, extension)
|
|
114 | 118 |
if os.path.exists(filename): |
115 | 119 |
raise FatalError("Output file %s exists " |
116 | 120 |
"(use --force to overwrite it)." % filename) |
... | ... | |
133 | 137 |
|
134 | 138 |
size = options.shrink and dev.shrink() or dev.size() |
135 | 139 |
metadata['size'] = str(size // 2 ** 20) |
140 |
|
|
141 |
outfile = "" |
|
142 |
if options.outfile is not None: |
|
143 |
outfile = options.outfile |
|
144 |
f = open('%s.%s' % (options.outfile, 'meta'), 'w') |
|
145 |
try: |
|
146 |
for key in metadata.keys(): |
|
147 |
f.write("%s=%s\n" % (key, metadata[key])) |
|
148 |
finally: |
|
149 |
f.close() |
|
150 |
else: |
|
151 |
outfd, outfile = tmpfile.mkstemp() |
|
152 |
os.close(outfd) |
|
153 |
|
|
136 | 154 |
dd('if=%s' % dev.device, |
137 |
'of=%s/%s.%s' % (options.outdir, options.name, 'diskdump'),
|
|
155 |
'of=%s' % outfile,
|
|
138 | 156 |
'bs=4M', 'count=%d' % ((size + 1) // 2 ** 22)) |
139 | 157 |
|
140 |
f = open('%s/%s.%s' % (options.outdir, options.name, 'meta'), 'w') |
|
141 |
for key in metadata.keys(): |
|
142 |
f.write("%s=%s\n" % (key, metadata[key])) |
|
143 |
f.close() |
|
144 | 158 |
finally: |
145 | 159 |
disk.cleanup() |
146 | 160 |
|
147 | 161 |
#The image is ready, lets call kamaki if necessary |
148 | 162 |
if options.upload: |
149 |
pass |
|
163 |
pass |
|
164 |
|
|
165 |
if options.outfile is None: |
|
166 |
os.unlink(outfile) |
|
150 | 167 |
|
151 | 168 |
return 0 |
152 | 169 |
|
153 | 170 |
COLOR_BLACK = "\033[00m" |
154 | 171 |
COLOR_RED = "\033[1;31m" |
155 | 172 |
|
156 |
if __name__ == '__main__':
|
|
173 |
def main():
|
|
157 | 174 |
try: |
158 |
ret = main()
|
|
175 |
ret = image_creator()
|
|
159 | 176 |
sys.exit(ret) |
160 | 177 |
except FatalError as e: |
161 | 178 |
print >> sys.stderr, "\n%sError: %s%s\n" % (COLOR_RED, e, COLOR_BLACK) |
162 | 179 |
sys.exit(1) |
163 | 180 |
|
181 |
|
|
182 |
if __name__ == '__main__': |
|
183 |
main() |
|
164 | 184 |
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |
Also available in: Unified diff