Statistics
| Branch: | Tag: | Revision:

root / image_creator / main.py @ b5430a9f

History | View | Annotate | Download (6.7 kB)

1 ae48a082 Nikos Skalkotos
#!/usr/bin/env python
2 ae48a082 Nikos Skalkotos
3 d57775d4 Nikos Skalkotos
# Copyright 2011 GRNET S.A. All rights reserved.
4 d57775d4 Nikos Skalkotos
#
5 d57775d4 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
6 d57775d4 Nikos Skalkotos
# without modification, are permitted provided that the following
7 d57775d4 Nikos Skalkotos
# conditions are met:
8 d57775d4 Nikos Skalkotos
#
9 d57775d4 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
10 d57775d4 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
11 d57775d4 Nikos Skalkotos
#      disclaimer.
12 d57775d4 Nikos Skalkotos
#
13 d57775d4 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
14 d57775d4 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
15 d57775d4 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
16 d57775d4 Nikos Skalkotos
#      provided with the distribution.
17 d57775d4 Nikos Skalkotos
#
18 d57775d4 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 d57775d4 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 d57775d4 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 d57775d4 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 d57775d4 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 d57775d4 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 d57775d4 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 d57775d4 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 d57775d4 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 d57775d4 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 d57775d4 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 d57775d4 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
30 d57775d4 Nikos Skalkotos
#
31 d57775d4 Nikos Skalkotos
# The views and conclusions contained in the software and
32 d57775d4 Nikos Skalkotos
# documentation are those of the authors and should not be
33 d57775d4 Nikos Skalkotos
# interpreted as representing official policies, either expressed
34 d57775d4 Nikos Skalkotos
# or implied, of GRNET S.A.
35 d57775d4 Nikos Skalkotos
36 aa2062ba Nikos Skalkotos
from image_creator import get_os_class
37 c408053f Nikos Skalkotos
from image_creator import __version__ as version
38 d57775d4 Nikos Skalkotos
from image_creator.disk import Disk
39 f165adc0 Nikos Skalkotos
from image_creator.util import get_command, error, success, output, FatalError
40 979096dd Nikos Skalkotos
from image_creator import util
41 d57775d4 Nikos Skalkotos
import sys
42 d57775d4 Nikos Skalkotos
import os
43 c408053f Nikos Skalkotos
import optparse
44 3ccb2618 Nikos Skalkotos
45 3ccb2618 Nikos Skalkotos
dd = get_command('dd')
46 c408053f Nikos Skalkotos
47 c408053f Nikos Skalkotos
48 0ae01e26 Nikos Skalkotos
def check_writable_dir(option, opt_str, value, parser):
49 0ae01e26 Nikos Skalkotos
    dirname = os.path.dirname(value)
50 0ae01e26 Nikos Skalkotos
    name = os.path.basename(value)
51 0ae01e26 Nikos Skalkotos
    if dirname and not os.path.isdir(dirname):
52 b5430a9f Nikos Skalkotos
        raise FatalError("`%s' is not an existing directory" % dirname)
53 c408053f Nikos Skalkotos
54 0ae01e26 Nikos Skalkotos
    if not name:
55 b5430a9f Nikos Skalkotos
        raise FatalError("`%s' is not a valid file name" % dirname)
56 c408053f Nikos Skalkotos
57 c408053f Nikos Skalkotos
    setattr(parser.values, option.dest, value)
58 c408053f Nikos Skalkotos
59 c408053f Nikos Skalkotos
60 c408053f Nikos Skalkotos
def parse_options(input_args):
61 0ae01e26 Nikos Skalkotos
    usage = "Usage: %prog [options] <input_media>"
62 c408053f Nikos Skalkotos
    parser = optparse.OptionParser(version=version, usage=usage)
63 c408053f Nikos Skalkotos
64 c408053f Nikos Skalkotos
    parser.add_option("-f", "--force", dest="force", default=False,
65 69aa33fa Nikos Skalkotos
        action="store_true", help="overwrite output files if they exist")
66 c408053f Nikos Skalkotos
67 9cbb5794 Nikos Skalkotos
    parser.add_option("--no-sysprep", dest="sysprep", default=True,
68 979096dd Nikos Skalkotos
        help="don't perform system preperation", action="store_false")
69 9cbb5794 Nikos Skalkotos
70 9cbb5794 Nikos Skalkotos
    parser.add_option("--no-shrink", dest="shrink", default=True,
71 979096dd Nikos Skalkotos
        help="don't shrink any partition", action="store_false")
72 9cbb5794 Nikos Skalkotos
73 0ae01e26 Nikos Skalkotos
    parser.add_option("-o", "--outfile", type="string", dest="outfile",
74 0ae01e26 Nikos Skalkotos
        default=None, action="callback", callback=check_writable_dir,
75 979096dd Nikos Skalkotos
        help="dump image to FILE", metavar="FILE")
76 979096dd Nikos Skalkotos
77 f165adc0 Nikos Skalkotos
    parser.add_option("--enable-sysprep", dest="enabled_syspreps", default=[],
78 b5430a9f Nikos Skalkotos
        help="run SYSPREP operation on the input media",
79 f165adc0 Nikos Skalkotos
        action="append", metavar="SYSPREP")
80 76d4a1c9 Nikos Skalkotos
81 f165adc0 Nikos Skalkotos
    parser.add_option("--disable-sysprep", dest="disabled_syspreps",
82 b5430a9f Nikos Skalkotos
        help="prevent SYSPREP operation from running on the input media",
83 f165adc0 Nikos Skalkotos
        default=[], action="append", metavar="SYSPREP")
84 f165adc0 Nikos Skalkotos
85 f165adc0 Nikos Skalkotos
    parser.add_option("--print-sysprep", dest="print_sysprep", default=False,
86 b5430a9f Nikos Skalkotos
        help="print the enabled and disabled sysprep operations for this "
87 f165adc0 Nikos Skalkotos
        "input media", action="store_true")
88 76d4a1c9 Nikos Skalkotos
89 979096dd Nikos Skalkotos
    parser.add_option("-s", "--silent", dest="silent", default=False,
90 f165adc0 Nikos Skalkotos
        help="silent mode, only output errors", action="store_true")
91 0ae01e26 Nikos Skalkotos
92 b5430a9f Nikos Skalkotos
    parser.add_option("-u", "--upload", dest="upload", type="string",
93 b5430a9f Nikos Skalkotos
        default=False, help="upload the image to pithos with name FILENAME",
94 b5430a9f Nikos Skalkotos
        metavar="FILENAME")
95 1a3f1298 Nikos Skalkotos
96 b5430a9f Nikos Skalkotos
    parser.add_option("-r", "--register", dest="register", type="string",
97 b5430a9f Nikos Skalkotos
        default=False, help="register the image to ~okeanos as IMAGENAME",
98 b5430a9f Nikos Skalkotos
        metavar="IMAGENAME")
99 1a3f1298 Nikos Skalkotos
100 c408053f Nikos Skalkotos
    options, args = parser.parse_args(input_args)
101 c408053f Nikos Skalkotos
102 0ae01e26 Nikos Skalkotos
    if len(args) != 1:
103 0ae01e26 Nikos Skalkotos
        parser.error('Wrong number of arguments')
104 c408053f Nikos Skalkotos
    options.source = args[0]
105 c408053f Nikos Skalkotos
    if not os.path.exists(options.source):
106 b5430a9f Nikos Skalkotos
        raise FatalError("Input media `%s' is not accessible" % options.source)
107 c408053f Nikos Skalkotos
108 b5430a9f Nikos Skalkotos
    if options.register and options.upload == False: 
109 b5430a9f Nikos Skalkotos
        raise FatalError("You also need to set -u when -r option is set")
110 1a3f1298 Nikos Skalkotos
111 c408053f Nikos Skalkotos
    return options
112 d57775d4 Nikos Skalkotos
113 8c574358 Nikos Skalkotos
114 22a6d232 Nikos Skalkotos
def image_creator():
115 c408053f Nikos Skalkotos
    options = parse_options(sys.argv[1:])
116 c408053f Nikos Skalkotos
117 979096dd Nikos Skalkotos
    if options.silent:
118 979096dd Nikos Skalkotos
        util.silent = True
119 979096dd Nikos Skalkotos
120 76d4a1c9 Nikos Skalkotos
    if options.outfile is None and not options.upload \
121 f165adc0 Nikos Skalkotos
                                            and not options.print_sysprep:
122 f165adc0 Nikos Skalkotos
        raise FatalError("At least one of `-o', `-u' or" \
123 f165adc0 Nikos Skalkotos
                            "`--print-sysprep' must be set")
124 76d4a1c9 Nikos Skalkotos
125 979096dd Nikos Skalkotos
    output('snf-image-creator %s\n' % version)
126 979096dd Nikos Skalkotos
127 c408053f Nikos Skalkotos
    if os.geteuid() != 0:
128 c408053f Nikos Skalkotos
        raise FatalError("You must run %s as root" \
129 c408053f Nikos Skalkotos
                        % os.path.basename(sys.argv[0]))
130 c408053f Nikos Skalkotos
131 69aa33fa Nikos Skalkotos
    if not options.force and options.outfile is not None:
132 0ae01e26 Nikos Skalkotos
        for extension in ('', '.meta'):
133 0ae01e26 Nikos Skalkotos
            filename = "%s%s" % (options.outfile, extension)
134 c408053f Nikos Skalkotos
            if os.path.exists(filename):
135 c408053f Nikos Skalkotos
                raise FatalError("Output file %s exists "
136 c408053f Nikos Skalkotos
                    "(use --force to overwrite it)." % filename)
137 c408053f Nikos Skalkotos
138 c408053f Nikos Skalkotos
    disk = Disk(options.source)
139 d57775d4 Nikos Skalkotos
    try:
140 d57775d4 Nikos Skalkotos
        dev = disk.get_device()
141 0d5a999d Nikos Skalkotos
        dev.mount()
142 22a6d232 Nikos Skalkotos
143 aa2062ba Nikos Skalkotos
        osclass = get_os_class(dev.distro, dev.ostype)
144 aa2062ba Nikos Skalkotos
        image_os = osclass(dev.root, dev.g)
145 aa2062ba Nikos Skalkotos
        metadata = image_os.get_metadata()
146 9cbb5794 Nikos Skalkotos
147 979096dd Nikos Skalkotos
        output()
148 3f70f242 Nikos Skalkotos
149 f165adc0 Nikos Skalkotos
        for sysprep in options.disabled_syspreps:
150 f165adc0 Nikos Skalkotos
            image_os.disable_sysprep(sysprep)
151 f165adc0 Nikos Skalkotos
152 f165adc0 Nikos Skalkotos
        for sysprep in options.enabled_syspreps:
153 f165adc0 Nikos Skalkotos
            image_os.enable_sysprep(sysprep)
154 76d4a1c9 Nikos Skalkotos
155 f165adc0 Nikos Skalkotos
        if options.print_sysprep:
156 f165adc0 Nikos Skalkotos
            image_os.print_syspreps()
157 76d4a1c9 Nikos Skalkotos
            output()
158 76d4a1c9 Nikos Skalkotos
159 76d4a1c9 Nikos Skalkotos
        if options.outfile is None and not options.upload:
160 76d4a1c9 Nikos Skalkotos
            return 0
161 76d4a1c9 Nikos Skalkotos
162 9cbb5794 Nikos Skalkotos
        if options.sysprep:
163 f165adc0 Nikos Skalkotos
            image_os.do_sysprep()
164 1a3f1298 Nikos Skalkotos
165 8c574358 Nikos Skalkotos
        dev.umount()
166 1a3f1298 Nikos Skalkotos
167 c408053f Nikos Skalkotos
        size = options.shrink and dev.shrink() or dev.size()
168 39cfd61a Nikos Skalkotos
        metadata['SIZE'] = str(size // 2 ** 20)
169 ae48a082 Nikos Skalkotos
170 0ae01e26 Nikos Skalkotos
        if options.outfile is not None:
171 0ae01e26 Nikos Skalkotos
            f = open('%s.%s' % (options.outfile, 'meta'), 'w')
172 0ae01e26 Nikos Skalkotos
            try:
173 0ae01e26 Nikos Skalkotos
                for key in metadata.keys():
174 0ae01e26 Nikos Skalkotos
                    f.write("%s=%s\n" % (key, metadata[key]))
175 0ae01e26 Nikos Skalkotos
            finally:
176 0ae01e26 Nikos Skalkotos
                f.close()
177 0ae01e26 Nikos Skalkotos
178 d603d80d Nikos Skalkotos
            dev.dump(options.outfile)
179 d57775d4 Nikos Skalkotos
    finally:
180 979096dd Nikos Skalkotos
        output('cleaning up...')
181 d57775d4 Nikos Skalkotos
        disk.cleanup()
182 d57775d4 Nikos Skalkotos
183 c408053f Nikos Skalkotos
    return 0
184 c408053f Nikos Skalkotos
185 ae48a082 Nikos Skalkotos
186 0ae01e26 Nikos Skalkotos
def main():
187 c408053f Nikos Skalkotos
    try:
188 0ae01e26 Nikos Skalkotos
        ret = image_creator()
189 c408053f Nikos Skalkotos
        sys.exit(ret)
190 c408053f Nikos Skalkotos
    except FatalError as e:
191 22a6d232 Nikos Skalkotos
        error(e)
192 c408053f Nikos Skalkotos
        sys.exit(1)
193 d57775d4 Nikos Skalkotos
194 0ae01e26 Nikos Skalkotos
195 0ae01e26 Nikos Skalkotos
if __name__ == '__main__':
196 0ae01e26 Nikos Skalkotos
    main()
197 ae48a082 Nikos Skalkotos
198 d57775d4 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :