Revision c408053f

b/image_creator/disk.py
59 59

  
60 60
    def get_device(self):
61 61
        """Returns a newly created DiskDevice instance.
62
        
62

  
63 63
        This instance is a snapshot of the original source media of
64 64
        the Disk instance.
65 65
        """
......
195 195
        start = last_partition['part_start'] / sector_size
196 196
        end = start + (block_size * block_cnt) / sector_size - 1
197 197

  
198
        self.g.part_del(dev, last_partition['part_num'])
199
        self.g.part_add(dev, 'p', start, end)
200

  
198 201
        return (end + 1) * sector_size
199 202

  
203
    def size(self):
204
        """Returns the "payload" size of the device.
205

  
206
        The size returned by this method is the size of the space occupied by
207
        the partitions (including the space before the first partition).
208
        """
209
        dev = self.g.part_to_dev(self.root)
210
        last = self.g.part_list(dev)[-1]
211

  
212
        return last['part_end']
200 213

  
201 214
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
b/image_creator/main.py
32 32
# or implied, of GRNET S.A.
33 33

  
34 34
from image_creator import get_os_class
35
from image_creator import __version__ as version
35 36
from image_creator.disk import Disk
36 37
import sys
37 38
import os
39
import optparse
40
from pbs import dd
41

  
42

  
43
class FatalError(Exception):
44
    pass
45

  
46

  
47
def check_writable_dir(option, opt_str, value, parser):
48
    if not os.path.isdir(value):
49
        raise OptionValueError("%s is not a valid directory name" % value)
50
    setattr(parser.values, option.dest, value)
51

  
52

  
53
def parse_options(input_args):
54
    usage = "Usage: %prog [options] <input_media> <name>"
55
    parser = optparse.OptionParser(version=version, usage=usage)
56

  
57
    parser.add_option("-o", "--outdir", type="string", dest="outdir",
58
        default=".", action="callback", callback=check_writable_dir,
59
        help="Output files to DIR [default: working dir]",
60
        metavar="DIR")
61

  
62
    parser.add_option("-f", "--force", dest="force", default=False,
63
        action="store_true", help="Overwrite output files if they exist")
64

  
65
    parser.add_option("--no-shrink", dest="shrink", default=True,
66
        help="Don't shrink any partition before extracting the image",
67
        action="store_false")
68

  
69
    options, args = parser.parse_args(input_args)
70

  
71
    if len(args) != 2:
72
        parser.error('input media or name are missing')
73
    options.source = args[0]
74
    options.name = args[1]
75

  
76
    if not os.path.exists(options.source):
77
        parser.error('Input media is not accessible')
78

  
79
    return options
38 80

  
39 81

  
40 82
def main():
41
    if len(sys.argv) != 3:
42
        sys.exit("Usage: %s <source> <output_file>" %
43
                        os.path.basename(sys.argv[0]))
44
    source = sys.argv[1]
45
    dest = sys.argv[2]
46 83

  
47
    disk = Disk(source)
84
    options = parse_options(sys.argv[1:])
85

  
86
    if os.geteuid() != 0:
87
        raise FatalError("You must run %s as root" \
88
                        % os.path.basename(sys.argv[0]))
89

  
90
    if not options.force:
91
        for ext in ('diskdump', 'meta'):
92
            filename = "%s/%s.%s" % (options.outdir, options.name, ext)
93
            if os.path.exists(filename):
94
                raise FatalError("Output file %s exists "
95
                    "(use --force to overwrite it)." % filename)
96

  
97
    disk = Disk(options.source)
48 98
    try:
49 99
        dev = disk.get_device()
50 100
        dev.mount()
51 101
        osclass = get_os_class(dev.distro, dev.ostype)
52 102
        image_os = osclass(dev.root, dev.g)
53 103
        metadata = image_os.get_metadata()
54
        for key in metadata.keys():
55
            print "%s=%s" % (key, metadata[key])
56 104
        image_os.data_cleanup()
57 105
        dev.umount()
58
        #dev.shrink()
106
        size = options.shrink and dev.shrink() or dev.size()
107
        metadata['size'] = str(size // 2 ** 20)
59 108

  
109
        dd('if=%s' % dev.device,
110
            'of=%s/%s.%s' % (options.outdir, options.name, 'diskdump'),
111
            'bs=4M', 'count=%d' % ((size + 1) // 2 ** 22))
112

  
113
        f = open('%s/%s.%s' % (options.outdir, options.name, 'meta'), 'w')
114
        for key in metadata.keys():
115
            f.write("%s=%s\n" % (key, metadata[key]))
116
        f.close()
60 117
    finally:
61 118
        disk.cleanup()
62 119

  
120
    return 0
121

  
122
COLOR_BLACK = "\033[00m"
123
COLOR_RED = "\033[1;31m"
124

  
63 125
if __name__ == '__main__':
64
    main()
126
    try:
127
        ret = main()
128
        sys.exit(ret)
129
    except FatalError as e:
130
        print >> sys.stderr, "\n%sError: %s%s\n" % (COLOR_RED, e, COLOR_BLACK)
131
        sys.exit(1)
65 132

  
66 133
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
b/image_creator/os_type/__init__.py
71 71
    def get_metadata(self):
72 72
        """Returns some descriptive metadata about the OS."""
73 73
        meta = {}
74
        meta["OSFAMILY"] = self.g.inspect_get_type(self.root)
75
        meta["OS"] = self.g.inspect_get_distro(self.root)
76
        meta["description"] = self.g.inspect_get_product_name(self.root)
74
        meta['ROOT_PARTITION'] = "%d" % self.g.part_to_partnum(self.root)
75
        meta['OSFAMILY'] = self.g.inspect_get_type(self.root)
76
        meta['OS'] = self.g.inspect_get_distro(self.root)
77
        meta['description'] = self.g.inspect_get_product_name(self.root)
77 78

  
78 79
        return meta
79 80

  

Also available in: Unified diff