Statistics
| Branch: | Tag: | Revision:

root / image_creator / main.py @ c408053f

History | View | Annotate | Download (4.5 kB)

1 d57775d4 Nikos Skalkotos
# Copyright 2011 GRNET S.A. All rights reserved.
2 d57775d4 Nikos Skalkotos
#
3 d57775d4 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
4 d57775d4 Nikos Skalkotos
# without modification, are permitted provided that the following
5 d57775d4 Nikos Skalkotos
# conditions are met:
6 d57775d4 Nikos Skalkotos
#
7 d57775d4 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
8 d57775d4 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
9 d57775d4 Nikos Skalkotos
#      disclaimer.
10 d57775d4 Nikos Skalkotos
#
11 d57775d4 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
12 d57775d4 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
13 d57775d4 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
14 d57775d4 Nikos Skalkotos
#      provided with the distribution.
15 d57775d4 Nikos Skalkotos
#
16 d57775d4 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 d57775d4 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 d57775d4 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 d57775d4 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 d57775d4 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 d57775d4 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 d57775d4 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 d57775d4 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 d57775d4 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 d57775d4 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 d57775d4 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 d57775d4 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
28 d57775d4 Nikos Skalkotos
#
29 d57775d4 Nikos Skalkotos
# The views and conclusions contained in the software and
30 d57775d4 Nikos Skalkotos
# documentation are those of the authors and should not be
31 d57775d4 Nikos Skalkotos
# interpreted as representing official policies, either expressed
32 d57775d4 Nikos Skalkotos
# or implied, of GRNET S.A.
33 d57775d4 Nikos Skalkotos
34 aa2062ba Nikos Skalkotos
from image_creator import get_os_class
35 c408053f Nikos Skalkotos
from image_creator import __version__ as version
36 d57775d4 Nikos Skalkotos
from image_creator.disk import Disk
37 d57775d4 Nikos Skalkotos
import sys
38 d57775d4 Nikos Skalkotos
import os
39 c408053f Nikos Skalkotos
import optparse
40 c408053f Nikos Skalkotos
from pbs import dd
41 c408053f Nikos Skalkotos
42 c408053f Nikos Skalkotos
43 c408053f Nikos Skalkotos
class FatalError(Exception):
44 c408053f Nikos Skalkotos
    pass
45 c408053f Nikos Skalkotos
46 c408053f Nikos Skalkotos
47 c408053f Nikos Skalkotos
def check_writable_dir(option, opt_str, value, parser):
48 c408053f Nikos Skalkotos
    if not os.path.isdir(value):
49 c408053f Nikos Skalkotos
        raise OptionValueError("%s is not a valid directory name" % value)
50 c408053f Nikos Skalkotos
    setattr(parser.values, option.dest, value)
51 c408053f Nikos Skalkotos
52 c408053f Nikos Skalkotos
53 c408053f Nikos Skalkotos
def parse_options(input_args):
54 c408053f Nikos Skalkotos
    usage = "Usage: %prog [options] <input_media> <name>"
55 c408053f Nikos Skalkotos
    parser = optparse.OptionParser(version=version, usage=usage)
56 c408053f Nikos Skalkotos
57 c408053f Nikos Skalkotos
    parser.add_option("-o", "--outdir", type="string", dest="outdir",
58 c408053f Nikos Skalkotos
        default=".", action="callback", callback=check_writable_dir,
59 c408053f Nikos Skalkotos
        help="Output files to DIR [default: working dir]",
60 c408053f Nikos Skalkotos
        metavar="DIR")
61 c408053f Nikos Skalkotos
62 c408053f Nikos Skalkotos
    parser.add_option("-f", "--force", dest="force", default=False,
63 c408053f Nikos Skalkotos
        action="store_true", help="Overwrite output files if they exist")
64 c408053f Nikos Skalkotos
65 c408053f Nikos Skalkotos
    parser.add_option("--no-shrink", dest="shrink", default=True,
66 c408053f Nikos Skalkotos
        help="Don't shrink any partition before extracting the image",
67 c408053f Nikos Skalkotos
        action="store_false")
68 c408053f Nikos Skalkotos
69 c408053f Nikos Skalkotos
    options, args = parser.parse_args(input_args)
70 c408053f Nikos Skalkotos
71 c408053f Nikos Skalkotos
    if len(args) != 2:
72 c408053f Nikos Skalkotos
        parser.error('input media or name are missing')
73 c408053f Nikos Skalkotos
    options.source = args[0]
74 c408053f Nikos Skalkotos
    options.name = args[1]
75 c408053f Nikos Skalkotos
76 c408053f Nikos Skalkotos
    if not os.path.exists(options.source):
77 c408053f Nikos Skalkotos
        parser.error('Input media is not accessible')
78 c408053f Nikos Skalkotos
79 c408053f Nikos Skalkotos
    return options
80 d57775d4 Nikos Skalkotos
81 8c574358 Nikos Skalkotos
82 d57775d4 Nikos Skalkotos
def main():
83 d57775d4 Nikos Skalkotos
84 c408053f Nikos Skalkotos
    options = parse_options(sys.argv[1:])
85 c408053f Nikos Skalkotos
86 c408053f Nikos Skalkotos
    if os.geteuid() != 0:
87 c408053f Nikos Skalkotos
        raise FatalError("You must run %s as root" \
88 c408053f Nikos Skalkotos
                        % os.path.basename(sys.argv[0]))
89 c408053f Nikos Skalkotos
90 c408053f Nikos Skalkotos
    if not options.force:
91 c408053f Nikos Skalkotos
        for ext in ('diskdump', 'meta'):
92 c408053f Nikos Skalkotos
            filename = "%s/%s.%s" % (options.outdir, options.name, ext)
93 c408053f Nikos Skalkotos
            if os.path.exists(filename):
94 c408053f Nikos Skalkotos
                raise FatalError("Output file %s exists "
95 c408053f Nikos Skalkotos
                    "(use --force to overwrite it)." % filename)
96 c408053f Nikos Skalkotos
97 c408053f Nikos Skalkotos
    disk = Disk(options.source)
98 d57775d4 Nikos Skalkotos
    try:
99 d57775d4 Nikos Skalkotos
        dev = disk.get_device()
100 0d5a999d Nikos Skalkotos
        dev.mount()
101 aa2062ba Nikos Skalkotos
        osclass = get_os_class(dev.distro, dev.ostype)
102 aa2062ba Nikos Skalkotos
        image_os = osclass(dev.root, dev.g)
103 aa2062ba Nikos Skalkotos
        metadata = image_os.get_metadata()
104 0d5a999d Nikos Skalkotos
        image_os.data_cleanup()
105 8c574358 Nikos Skalkotos
        dev.umount()
106 c408053f Nikos Skalkotos
        size = options.shrink and dev.shrink() or dev.size()
107 c408053f Nikos Skalkotos
        metadata['size'] = str(size // 2 ** 20)
108 0d5a999d Nikos Skalkotos
109 c408053f Nikos Skalkotos
        dd('if=%s' % dev.device,
110 c408053f Nikos Skalkotos
            'of=%s/%s.%s' % (options.outdir, options.name, 'diskdump'),
111 c408053f Nikos Skalkotos
            'bs=4M', 'count=%d' % ((size + 1) // 2 ** 22))
112 c408053f Nikos Skalkotos
113 c408053f Nikos Skalkotos
        f = open('%s/%s.%s' % (options.outdir, options.name, 'meta'), 'w')
114 c408053f Nikos Skalkotos
        for key in metadata.keys():
115 c408053f Nikos Skalkotos
            f.write("%s=%s\n" % (key, metadata[key]))
116 c408053f Nikos Skalkotos
        f.close()
117 d57775d4 Nikos Skalkotos
    finally:
118 d57775d4 Nikos Skalkotos
        disk.cleanup()
119 d57775d4 Nikos Skalkotos
120 c408053f Nikos Skalkotos
    return 0
121 c408053f Nikos Skalkotos
122 c408053f Nikos Skalkotos
COLOR_BLACK = "\033[00m"
123 c408053f Nikos Skalkotos
COLOR_RED = "\033[1;31m"
124 c408053f Nikos Skalkotos
125 d57775d4 Nikos Skalkotos
if __name__ == '__main__':
126 c408053f Nikos Skalkotos
    try:
127 c408053f Nikos Skalkotos
        ret = main()
128 c408053f Nikos Skalkotos
        sys.exit(ret)
129 c408053f Nikos Skalkotos
    except FatalError as e:
130 c408053f Nikos Skalkotos
        print >> sys.stderr, "\n%sError: %s%s\n" % (COLOR_RED, e, COLOR_BLACK)
131 c408053f Nikos Skalkotos
        sys.exit(1)
132 d57775d4 Nikos Skalkotos
133 d57775d4 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :