Revision e77e66a9 image_creator/disk.py
b/image_creator/disk.py | ||
---|---|---|
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 | 34 |
from image_creator.util import get_command |
35 |
from image_creator.util import warn, progress, success, output, FatalError
|
|
35 |
from image_creator.util import FatalError |
|
36 | 36 |
from image_creator.gpt import GPTPartitionTable |
37 | 37 |
import stat |
38 | 38 |
import os |
... | ... | |
62 | 62 |
the Linux kernel. |
63 | 63 |
""" |
64 | 64 |
|
65 |
def __init__(self, source): |
|
65 |
def __init__(self, source, output):
|
|
66 | 66 |
"""Create a new Disk instance out of a source media. The source |
67 | 67 |
media can be an image file, a block device or a directory.""" |
68 | 68 |
self._cleanup_jobs = [] |
69 | 69 |
self._devices = [] |
70 | 70 |
self.source = source |
71 |
self.out = output |
|
71 | 72 |
|
72 | 73 |
def _add_cleanup(self, job, *args): |
73 | 74 |
self._cleanup_jobs.append((job, args)) |
... | ... | |
98 | 99 |
instance. |
99 | 100 |
""" |
100 | 101 |
|
101 |
output("Examining source media `%s'..." % self.source, False) |
|
102 |
self.out.output("Examining source media `%s'..." % self.source, False)
|
|
102 | 103 |
sourcedev = self.source |
103 | 104 |
mode = os.stat(self.source).st_mode |
104 | 105 |
if stat.S_ISDIR(mode): |
... | ... | |
111 | 112 |
raise ValueError("Invalid media source. Only block devices, " |
112 | 113 |
"regular files and directories are supported.") |
113 | 114 |
else: |
114 |
success('looks like a block device') |
|
115 |
self.out.success('looks like a block device')
|
|
115 | 116 |
|
116 | 117 |
# Take a snapshot and return it to the user |
117 |
output("Snapshotting media source...", False) |
|
118 |
self.out.output("Snapshotting media source...", False)
|
|
118 | 119 |
size = blockdev('--getsize', sourcedev) |
119 | 120 |
cowfd, cow = tempfile.mkstemp() |
120 | 121 |
os.close(cowfd) |
... | ... | |
137 | 138 |
|
138 | 139 |
finally: |
139 | 140 |
os.unlink(table) |
140 |
success('done') |
|
141 |
self.out.success('done')
|
|
141 | 142 |
return "/dev/mapper/%s" % snapshot |
142 | 143 |
|
143 | 144 |
def get_device(self, media): |
144 | 145 |
"""Returns a newly created DiskDevice instance.""" |
145 | 146 |
|
146 |
new_device = DiskDevice(media) |
|
147 |
new_device = DiskDevice(media, self.out)
|
|
147 | 148 |
self._devices.append(new_device) |
148 | 149 |
new_device.enable() |
149 | 150 |
return new_device |
... | ... | |
161 | 162 |
as created by the device-mapper. |
162 | 163 |
""" |
163 | 164 |
|
164 |
def __init__(self, device, bootable=True): |
|
165 |
def __init__(self, device, output, bootable=True):
|
|
165 | 166 |
"""Create a new DiskDevice.""" |
166 | 167 |
|
167 | 168 |
self.real_device = device |
169 |
self.out = output |
|
168 | 170 |
self.bootable = bootable |
169 | 171 |
self.progress_bar = None |
170 | 172 |
self.guestfs_device = None |
... | ... | |
180 | 182 |
|
181 | 183 |
def enable(self): |
182 | 184 |
"""Enable a newly created DiskDevice""" |
183 |
self.progressbar = progress("Launching helper VM: ", "percent")
|
|
185 |
self.progressbar = self.out.Progress("Launching helper VM", "percent")
|
|
184 | 186 |
self.progressbar.max = 100 |
185 | 187 |
self.progressbar.goto(1) |
186 | 188 |
eh = self.g.set_event_callback(self.progress_callback, |
... | ... | |
188 | 190 |
self.g.launch() |
189 | 191 |
self.guestfs_enabled = True |
190 | 192 |
self.g.delete_event_callback(eh) |
191 |
if self.progressbar is not None: |
|
192 |
output("\rLaunching helper VM...\033[K", False) |
|
193 |
success("done") |
|
194 |
self.progressbar = None |
|
193 |
self.progressbar.success('done') |
|
194 |
self.progressbar = None |
|
195 | 195 |
|
196 |
output('Inspecting Operating System...', False) |
|
196 |
self.out.output('Inspecting Operating System...', False)
|
|
197 | 197 |
roots = self.g.inspect_os() |
198 | 198 |
if len(roots) == 0: |
199 | 199 |
raise FatalError("No operating system found") |
... | ... | |
208 | 208 |
|
209 | 209 |
self.ostype = self.g.inspect_get_type(self.root) |
210 | 210 |
self.distro = self.g.inspect_get_distro(self.root) |
211 |
success('found a(n) %s system' % self.distro) |
|
211 |
self.out.success('found a(n) %s system' % self.distro)
|
|
212 | 212 |
|
213 | 213 |
def destroy(self): |
214 | 214 |
"""Destroy this DiskDevice instance.""" |
... | ... | |
229 | 229 |
def mount(self): |
230 | 230 |
"""Mount all disk partitions in a correct order.""" |
231 | 231 |
|
232 |
output("Mounting image...", False) |
|
232 |
self.out.output("Mounting image...", False)
|
|
233 | 233 |
mps = self.g.inspect_get_mountpoints(self.root) |
234 | 234 |
|
235 | 235 |
# Sort the keys to mount the fs in a correct order. |
... | ... | |
246 | 246 |
try: |
247 | 247 |
self.g.mount(dev, mp) |
248 | 248 |
except RuntimeError as msg: |
249 |
warn("%s (ignored)" % msg) |
|
250 |
success("done") |
|
249 |
self.out.warn("%s (ignored)" % msg)
|
|
250 |
self.out.success("done")
|
|
251 | 251 |
|
252 | 252 |
def umount(self): |
253 | 253 |
"""Umount all mounted filesystems.""" |
... | ... | |
307 | 307 |
|
308 | 308 |
MB = 2 ** 20 |
309 | 309 |
|
310 |
output("Shrinking image (this may take a while)...", False) |
|
310 |
self.out.output("Shrinking image (this may take a while)...", False)
|
|
311 | 311 |
|
312 | 312 |
last_part = None |
313 | 313 |
fstype = None |
... | ... | |
329 | 329 |
break |
330 | 330 |
|
331 | 331 |
if not re.match("ext[234]", fstype): |
332 |
warn("Don't know how to resize %s partitions." % fstype) |
|
332 |
self.out.warn("Don't know how to resize %s partitions." % fstype)
|
|
333 | 333 |
return self.meta['SIZE'] |
334 | 334 |
|
335 | 335 |
part_dev = "%s%d" % (self.guestfs_device, last_part['part_num']) |
... | ... | |
387 | 387 |
part_set_id(last_part['part_num'], last_part['id']) |
388 | 388 |
|
389 | 389 |
new_size = (end + 1) * sector_size |
390 |
success("new size is %dMB" % ((new_size + MB - 1) // MB)) |
|
390 |
self.out.success("new size is %dMB" % ((new_size + MB - 1) // MB))
|
|
391 | 391 |
|
392 | 392 |
if self.meta['PARTITION_TABLE'] == 'gpt': |
393 | 393 |
ptable = GPTPartitionTable(self.real_device) |
... | ... | |
407 | 407 |
blocksize = 4 * MB # 4MB |
408 | 408 |
size = self.meta['SIZE'] |
409 | 409 |
progress_size = (size + MB - 1) // MB # in MB |
410 |
progressbar = progress("Dumping image file: ", 'mb')
|
|
410 |
progressbar = self.out.Progress("Dumping image file", 'mb')
|
|
411 | 411 |
progressbar.max = progress_size |
412 | 412 |
|
413 | 413 |
with open(self.real_device, 'r') as src: |
... | ... | |
421 | 421 |
offset += sent |
422 | 422 |
left -= sent |
423 | 423 |
progressbar.goto((size - left) // MB) |
424 |
output("\rDumping image file...\033[K", False) |
|
425 |
success('image file %s was successfully created' % outfile) |
|
424 |
progressbar.success('image file %s was successfully created' % outfile) |
|
426 | 425 |
|
427 | 426 |
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai : |
Also available in: Unified diff