Revision d603d80d

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 :
b/image_creator/main.py
38 38
from image_creator import FatalError
39 39
from image_creator.disk import Disk
40 40
from image_creator.util import get_command, error, progress_generator, success
41
from clint.textui import puts, indent
42
from sendfile import sendfile
41
from clint.textui import puts
43 42

  
44 43
import sys
45 44
import os
......
108 107
    return options
109 108

  
110 109

  
111
def extract_image(device, outfile, size):
112
    blocksize = 4194304  # 4MB
113
    progress_size = (size + 1048575) // 1048576  # in MB
114
    progressbar = progress_generator("Dumping image file: ",
115
                                                    progress_size)
116
    source = open(device, "r")
117
    try:
118
        dest = open(outfile, "w")
119
        try:
120
            left = size
121
            offset = 0
122
            progressbar.next()
123
            while left > 0:
124
                length = min(left, blocksize)
125
                sent = sendfile(dest.fileno(), source.fileno(), offset, length)
126
                offset += sent
127
                left -= sent
128
                for i in range(4):
129
                    progressbar.next()
130
        finally:
131
            dest.close()
132
    finally:
133
        source.close()
134

  
135
    success('Image file %s was successfully created' % outfile)
136

  
137

  
138 110
def image_creator():
139 111
    puts('snf-image-creator %s\n' % version)
140 112
    options = parse_options(sys.argv[1:])
......
180 152
            finally:
181 153
                f.close()
182 154

  
183
            extract_image(dev.device, options.outfile, size)
155
            dev.dump(options.outfile)
184 156
    finally:
185 157
        puts('cleaning up...')
186 158
        disk.cleanup()
b/image_creator/util.py
69 69
        position = yield
70 70
    yield  # suppress the StopIteration exception
71 71

  
72

  
73 72
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :

Also available in: Unified diff