Revision d603d80d image_creator/disk.py
b/image_creator/disk.py | ||
---|---|---|
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 |
from image_creator.util import get_command, warn, progress_generator |
|
34 |
from image_creator.util import get_command, warn, progress_generator, success
|
|
35 | 35 |
from image_creator import FatalError |
36 |
from clint.textui import indent, puts, colored
|
|
36 |
from clint.textui import puts
|
|
37 | 37 |
|
38 | 38 |
import stat |
39 | 39 |
import os |
... | ... | |
43 | 43 |
import sys |
44 | 44 |
import guestfs |
45 | 45 |
import time |
46 |
from sendfile import sendfile |
|
46 | 47 |
|
47 | 48 |
|
48 | 49 |
class DiskError(Exception): |
... | ... | |
104 | 105 |
sourcedev = self.source |
105 | 106 |
mode = os.stat(self.source).st_mode |
106 | 107 |
if stat.S_ISDIR(mode): |
107 |
puts(colored.green('looks like a directory'))
|
|
108 |
success('looks like a directory')
|
|
108 | 109 |
return self._losetup(self._dir_to_disk()) |
109 | 110 |
elif stat.S_ISREG(mode): |
110 |
puts(colored.green('looks like an image file'))
|
|
111 |
success('looks like an image file')
|
|
111 | 112 |
sourcedev = self._losetup(self.source) |
112 | 113 |
elif not stat.S_ISBLK(mode): |
113 | 114 |
raise ValueError("Invalid media source. Only block devices, " |
114 | 115 |
"regular files and directories are supported.") |
115 | 116 |
else: |
116 |
puts(colored.green('looks like a block device'))
|
|
117 |
success('looks like a block device')
|
|
117 | 118 |
|
118 | 119 |
# Take a snapshot and return it to the user |
119 | 120 |
puts("Snapshotting media source...", False) |
... | ... | |
140 | 141 |
|
141 | 142 |
finally: |
142 | 143 |
os.unlink(table) |
143 |
puts(colored.green('done'))
|
|
144 |
success('done')
|
|
144 | 145 |
new_device = DiskDevice("/dev/mapper/%s" % snapshot) |
145 | 146 |
self._devices.append(new_device) |
146 | 147 |
new_device.enable() |
... | ... | |
197 | 198 |
self.root = roots[0] |
198 | 199 |
self.ostype = self.g.inspect_get_type(self.root) |
199 | 200 |
self.distro = self.g.inspect_get_distro(self.root) |
200 |
puts(colored.green('found a %s system' % self.distro))
|
|
201 |
success('found a %s system' % self.distro)
|
|
201 | 202 |
|
202 | 203 |
def destroy(self): |
203 | 204 |
"""Destroy this DiskDevice instance.""" |
... | ... | |
250 | 251 |
(in bytes) is returned. |
251 | 252 |
""" |
252 | 253 |
puts("Shrinking image (this may take a while)...", False) |
254 |
sys.stdout.flush() |
|
253 | 255 |
|
254 | 256 |
dev = self.g.part_to_dev(self.root) |
255 | 257 |
parttype = self.g.part_get_parttype(dev) |
... | ... | |
287 | 289 |
self.g.part_add(dev, 'p', start, end) |
288 | 290 |
|
289 | 291 |
new_size = (end + 1) * sector_size |
290 |
puts(colored.green("new image size is %dMB\n" % (new_size // 2 ** 20)))
|
|
291 |
|
|
292 |
success("new image size is %dMB" %
|
|
293 |
((new_size + 2 ** 20 - 1) // 2 ** 20)) |
|
292 | 294 |
return new_size |
293 | 295 |
|
294 | 296 |
def size(self): |
... | ... | |
302 | 304 |
|
303 | 305 |
return last['part_end'] + 1 |
304 | 306 |
|
307 |
def dump(self, outfile): |
|
308 |
"""Dumps the content of device into a file. |
|
309 |
|
|
310 |
This method will only dump the actual payload, found by reading the |
|
311 |
partition table. Empty space in the end of the device will be ignored. |
|
312 |
""" |
|
313 |
blocksize = 2 ** 22 # 4MB |
|
314 |
size = self.size() |
|
315 |
progress_size = (size + 2 ** 20 - 1) // 2 ** 20 # in MB |
|
316 |
progressbar = progress_generator("Dumping image file: ", progress_size) |
|
317 |
|
|
318 |
source = open(self.device, "r") |
|
319 |
try: |
|
320 |
dest = open(outfile, "w") |
|
321 |
try: |
|
322 |
left = size |
|
323 |
offset = 0 |
|
324 |
progressbar.next() |
|
325 |
while left > 0: |
|
326 |
length = min(left, blocksize) |
|
327 |
sent = sendfile(dest.fileno(), source.fileno(), offset, |
|
328 |
length) |
|
329 |
offset += sent |
|
330 |
left -= sent |
|
331 |
for i in range((length + 2 ** 20 - 1) // 2 ** 20): |
|
332 |
progressbar.next() |
|
333 |
finally: |
|
334 |
dest.close() |
|
335 |
finally: |
|
336 |
source.close() |
|
337 |
|
|
338 |
success('Image file %s was successfully created' % outfile) |
|
339 |
|
|
305 | 340 |
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |
Also available in: Unified diff