Revision 22a6d232 image_creator/main.py

b/image_creator/main.py
37 37
from image_creator import __version__ as version
38 38
from image_creator import FatalError
39 39
from image_creator.disk import Disk
40
from image_creator.util import get_command
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 43

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

  
108 110

  
109
def image_creator():
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

  
110 137

  
138
def image_creator():
139
    puts('snf-image-creator %s\n' % version)
111 140
    options = parse_options(sys.argv[1:])
112 141

  
113 142
    if os.geteuid() != 0:
......
125 154
    try:
126 155
        dev = disk.get_device()
127 156
        dev.mount()
157

  
128 158
        osclass = get_os_class(dev.distro, dev.ostype)
129 159
        image_os = osclass(dev.root, dev.g)
130 160
        metadata = image_os.get_metadata()
......
140 170
        size = options.shrink and dev.shrink() or dev.size()
141 171
        metadata['size'] = str(size // 2 ** 20)
142 172

  
143
        outfile = ""
144 173
        if options.outfile is not None:
145
            outfile = options.outfile
146 174
            f = open('%s.%s' % (options.outfile, 'meta'), 'w')
147 175
            try:
148 176
                for key in metadata.keys():
149 177
                    f.write("%s=%s\n" % (key, metadata[key]))
150 178
            finally:
151 179
                f.close()
152
        else:
153
            outfd, outfile = tmpfile.mkstemp()
154
            os.close(outfd)
155 180

  
156
        dd('if=%s' % dev.device,
157
            'of=%s' % outfile,
158
            'bs=4M', 'count=%d' % ((size + 1) // 2 ** 22))
181
            extract_image(dev.device, options.outfile, size)
159 182

  
160 183
    finally:
184
        puts('cleaning up...')
161 185
        disk.cleanup()
162 186

  
163
    #The image is ready, lets call kamaki if necessary
164
    if options.upload:
165
        pass
166

  
167
    if options.outfile is None:
168
        os.unlink(outfile)
169

  
170 187
    return 0
171 188

  
172
COLOR_BLACK = "\033[00m"
173
COLOR_RED = "\033[1;31m"
174

  
175 189

  
176 190
def main():
177 191
    try:
178 192
        ret = image_creator()
179 193
        sys.exit(ret)
180 194
    except FatalError as e:
181
        print >> sys.stderr, "\n%sError: %s%s\n" % (COLOR_RED, e, COLOR_BLACK)
195
        error(e)
182 196
        sys.exit(1)
183 197

  
184 198

  

Also available in: Unified diff