Statistics
| Branch: | Tag: | Revision:

root / image_creator / main.py @ 9297c398

History | View | Annotate | Download (5.2 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 3ccb2618 Nikos Skalkotos
from image_creator.util import get_command
38 3ccb2618 Nikos Skalkotos
39 d57775d4 Nikos Skalkotos
import sys
40 d57775d4 Nikos Skalkotos
import os
41 c408053f Nikos Skalkotos
import optparse
42 3ccb2618 Nikos Skalkotos
43 3ccb2618 Nikos Skalkotos
dd = get_command('dd')
44 c408053f Nikos Skalkotos
45 c408053f Nikos Skalkotos
46 c408053f Nikos Skalkotos
class FatalError(Exception):
47 c408053f Nikos Skalkotos
    pass
48 c408053f Nikos Skalkotos
49 c408053f Nikos Skalkotos
50 c408053f Nikos Skalkotos
def check_writable_dir(option, opt_str, value, parser):
51 c408053f Nikos Skalkotos
    if not os.path.isdir(value):
52 c408053f Nikos Skalkotos
        raise OptionValueError("%s is not a valid directory name" % value)
53 c408053f Nikos Skalkotos
    setattr(parser.values, option.dest, value)
54 c408053f Nikos Skalkotos
55 c408053f Nikos Skalkotos
56 c408053f Nikos Skalkotos
def parse_options(input_args):
57 c408053f Nikos Skalkotos
    usage = "Usage: %prog [options] <input_media> <name>"
58 c408053f Nikos Skalkotos
    parser = optparse.OptionParser(version=version, usage=usage)
59 c408053f Nikos Skalkotos
60 c408053f Nikos Skalkotos
    parser.add_option("-o", "--outdir", type="string", dest="outdir",
61 c408053f Nikos Skalkotos
        default=".", action="callback", callback=check_writable_dir,
62 c408053f Nikos Skalkotos
        help="Output files to DIR [default: working dir]",
63 c408053f Nikos Skalkotos
        metavar="DIR")
64 c408053f Nikos Skalkotos
65 c408053f Nikos Skalkotos
    parser.add_option("-f", "--force", dest="force", default=False,
66 c408053f Nikos Skalkotos
        action="store_true", help="Overwrite output files if they exist")
67 c408053f Nikos Skalkotos
68 c408053f Nikos Skalkotos
    parser.add_option("--no-shrink", dest="shrink", default=True,
69 c408053f Nikos Skalkotos
        help="Don't shrink any partition before extracting the image",
70 c408053f Nikos Skalkotos
        action="store_false")
71 c408053f Nikos Skalkotos
72 1a3f1298 Nikos Skalkotos
    parser.add_option("--no-cleanup", dest="cleanup", default=True,
73 1a3f1298 Nikos Skalkotos
        help="Don't cleanup sensitive data before extracting the image",
74 1a3f1298 Nikos Skalkotos
        action="store_false")
75 1a3f1298 Nikos Skalkotos
76 1a3f1298 Nikos Skalkotos
    parser.add_option("-u", "--upload", dest="upload", default=False,
77 1a3f1298 Nikos Skalkotos
        help="Upload image to a pithos repository using kamaki",
78 1a3f1298 Nikos Skalkotos
        action="store_true")
79 1a3f1298 Nikos Skalkotos
80 1a3f1298 Nikos Skalkotos
    parser.add_option("-r", "--register", dest="register", default=False,
81 1a3f1298 Nikos Skalkotos
        help="Register image to okeanos using kamaki", action="store_true")
82 1a3f1298 Nikos Skalkotos
83 c408053f Nikos Skalkotos
    options, args = parser.parse_args(input_args)
84 c408053f Nikos Skalkotos
85 c408053f Nikos Skalkotos
    if len(args) != 2:
86 c408053f Nikos Skalkotos
        parser.error('input media or name are missing')
87 c408053f Nikos Skalkotos
    options.source = args[0]
88 c408053f Nikos Skalkotos
    options.name = args[1]
89 c408053f Nikos Skalkotos
90 c408053f Nikos Skalkotos
    if not os.path.exists(options.source):
91 c408053f Nikos Skalkotos
        parser.error('Input media is not accessible')
92 c408053f Nikos Skalkotos
93 1a3f1298 Nikos Skalkotos
    if options.register:
94 1a3f1298 Nikos Skalkotos
        options.upload = True
95 1a3f1298 Nikos Skalkotos
96 c408053f Nikos Skalkotos
    return options
97 d57775d4 Nikos Skalkotos
98 8c574358 Nikos Skalkotos
99 d57775d4 Nikos Skalkotos
def main():
100 d57775d4 Nikos Skalkotos
101 c408053f Nikos Skalkotos
    options = parse_options(sys.argv[1:])
102 c408053f Nikos Skalkotos
103 c408053f Nikos Skalkotos
    if os.geteuid() != 0:
104 c408053f Nikos Skalkotos
        raise FatalError("You must run %s as root" \
105 c408053f Nikos Skalkotos
                        % os.path.basename(sys.argv[0]))
106 c408053f Nikos Skalkotos
107 c408053f Nikos Skalkotos
    if not options.force:
108 1a3f1298 Nikos Skalkotos
        for extension in ('diskdump', 'meta'):
109 1a3f1298 Nikos Skalkotos
            filename = "%s/%s.%s" % (options.outdir, options.name, extension)
110 c408053f Nikos Skalkotos
            if os.path.exists(filename):
111 c408053f Nikos Skalkotos
                raise FatalError("Output file %s exists "
112 c408053f Nikos Skalkotos
                    "(use --force to overwrite it)." % filename)
113 c408053f Nikos Skalkotos
114 c408053f Nikos Skalkotos
    disk = Disk(options.source)
115 d57775d4 Nikos Skalkotos
    try:
116 d57775d4 Nikos Skalkotos
        dev = disk.get_device()
117 0d5a999d Nikos Skalkotos
        dev.mount()
118 aa2062ba Nikos Skalkotos
        osclass = get_os_class(dev.distro, dev.ostype)
119 aa2062ba Nikos Skalkotos
        image_os = osclass(dev.root, dev.g)
120 aa2062ba Nikos Skalkotos
        metadata = image_os.get_metadata()
121 1a3f1298 Nikos Skalkotos
        
122 1a3f1298 Nikos Skalkotos
        if options.cleanup:
123 1a3f1298 Nikos Skalkotos
            image_os.data_cleanup()
124 1a3f1298 Nikos Skalkotos
125 8c574358 Nikos Skalkotos
        dev.umount()
126 1a3f1298 Nikos Skalkotos
127 c408053f Nikos Skalkotos
        size = options.shrink and dev.shrink() or dev.size()
128 c408053f Nikos Skalkotos
        metadata['size'] = str(size // 2 ** 20)
129 c408053f Nikos Skalkotos
        dd('if=%s' % dev.device,
130 c408053f Nikos Skalkotos
            'of=%s/%s.%s' % (options.outdir, options.name, 'diskdump'),
131 c408053f Nikos Skalkotos
            'bs=4M', 'count=%d' % ((size + 1) // 2 ** 22))
132 c408053f Nikos Skalkotos
133 c408053f Nikos Skalkotos
        f = open('%s/%s.%s' % (options.outdir, options.name, 'meta'), 'w')
134 c408053f Nikos Skalkotos
        for key in metadata.keys():
135 c408053f Nikos Skalkotos
            f.write("%s=%s\n" % (key, metadata[key]))
136 c408053f Nikos Skalkotos
        f.close()
137 d57775d4 Nikos Skalkotos
    finally:
138 d57775d4 Nikos Skalkotos
        disk.cleanup()
139 d57775d4 Nikos Skalkotos
140 1a3f1298 Nikos Skalkotos
    #The image is ready, lets call kamaki if necessary
141 1a3f1298 Nikos Skalkotos
    if options.upload:
142 1a3f1298 Nikos Skalkotos
       pass 
143 1a3f1298 Nikos Skalkotos
144 c408053f Nikos Skalkotos
    return 0
145 c408053f Nikos Skalkotos
146 c408053f Nikos Skalkotos
COLOR_BLACK = "\033[00m"
147 c408053f Nikos Skalkotos
COLOR_RED = "\033[1;31m"
148 c408053f Nikos Skalkotos
149 d57775d4 Nikos Skalkotos
if __name__ == '__main__':
150 c408053f Nikos Skalkotos
    try:
151 c408053f Nikos Skalkotos
        ret = main()
152 c408053f Nikos Skalkotos
        sys.exit(ret)
153 c408053f Nikos Skalkotos
    except FatalError as e:
154 c408053f Nikos Skalkotos
        print >> sys.stderr, "\n%sError: %s%s\n" % (COLOR_RED, e, COLOR_BLACK)
155 c408053f Nikos Skalkotos
        sys.exit(1)
156 d57775d4 Nikos Skalkotos
157 d57775d4 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :