Statistics
| Branch: | Tag: | Revision:

root / image_creator / main.py @ 69aa33fa

History | View | Annotate | Download (5.5 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 0ae01e26 Nikos Skalkotos
from image_creator import FatalError
39 d57775d4 Nikos Skalkotos
from image_creator.disk import Disk
40 22a6d232 Nikos Skalkotos
from image_creator.util import get_command, error, progress_generator, success
41 d603d80d Nikos Skalkotos
from clint.textui import puts
42 3ccb2618 Nikos Skalkotos
43 d57775d4 Nikos Skalkotos
import sys
44 d57775d4 Nikos Skalkotos
import os
45 c408053f Nikos Skalkotos
import optparse
46 3ccb2618 Nikos Skalkotos
47 3ccb2618 Nikos Skalkotos
dd = get_command('dd')
48 c408053f Nikos Skalkotos
49 c408053f Nikos Skalkotos
50 0ae01e26 Nikos Skalkotos
def check_writable_dir(option, opt_str, value, parser):
51 0ae01e26 Nikos Skalkotos
    dirname = os.path.dirname(value)
52 0ae01e26 Nikos Skalkotos
    name = os.path.basename(value)
53 0ae01e26 Nikos Skalkotos
    if dirname and not os.path.isdir(dirname):
54 0ae01e26 Nikos Skalkotos
        parser.error("`%s' is not an existing directory" % dirname)
55 c408053f Nikos Skalkotos
56 0ae01e26 Nikos Skalkotos
    if not name:
57 0ae01e26 Nikos Skalkotos
        parser.error("`%s' is not a valid file name" % dirname)
58 c408053f Nikos Skalkotos
59 c408053f Nikos Skalkotos
    setattr(parser.values, option.dest, value)
60 c408053f Nikos Skalkotos
61 c408053f Nikos Skalkotos
62 c408053f Nikos Skalkotos
def parse_options(input_args):
63 0ae01e26 Nikos Skalkotos
    usage = "Usage: %prog [options] <input_media>"
64 c408053f Nikos Skalkotos
    parser = optparse.OptionParser(version=version, usage=usage)
65 c408053f Nikos Skalkotos
66 c408053f Nikos Skalkotos
    parser.add_option("-f", "--force", dest="force", default=False,
67 69aa33fa Nikos Skalkotos
        action="store_true", help="overwrite output files if they exist")
68 c408053f Nikos Skalkotos
69 1a3f1298 Nikos Skalkotos
    parser.add_option("--no-cleanup", dest="cleanup", default=True,
70 69aa33fa Nikos Skalkotos
        help="don't cleanup sensitive data",
71 1a3f1298 Nikos Skalkotos
        action="store_false")
72 1a3f1298 Nikos Skalkotos
73 9cbb5794 Nikos Skalkotos
    parser.add_option("--no-sysprep", dest="sysprep", default=True,
74 69aa33fa Nikos Skalkotos
        help="don't perform system preperation",
75 9cbb5794 Nikos Skalkotos
        action="store_false")
76 9cbb5794 Nikos Skalkotos
77 9cbb5794 Nikos Skalkotos
    parser.add_option("--no-shrink", dest="shrink", default=True,
78 69aa33fa Nikos Skalkotos
        help="don't shrink any partition",
79 9cbb5794 Nikos Skalkotos
        action="store_false")
80 9cbb5794 Nikos Skalkotos
81 0ae01e26 Nikos Skalkotos
    parser.add_option("-o", "--outfile", type="string", dest="outfile",
82 0ae01e26 Nikos Skalkotos
        default=None, action="callback", callback=check_writable_dir,
83 69aa33fa Nikos Skalkotos
        help="dump image to FILE",
84 0ae01e26 Nikos Skalkotos
        metavar="FILE")
85 0ae01e26 Nikos Skalkotos
86 1a3f1298 Nikos Skalkotos
    parser.add_option("-u", "--upload", dest="upload", default=False,
87 69aa33fa Nikos Skalkotos
        help="upload the image to pithos",
88 1a3f1298 Nikos Skalkotos
        action="store_true")
89 1a3f1298 Nikos Skalkotos
90 1a3f1298 Nikos Skalkotos
    parser.add_option("-r", "--register", dest="register", default=False,
91 69aa33fa Nikos Skalkotos
        help="register the image to ~okeanos", action="store_true")
92 1a3f1298 Nikos Skalkotos
93 c408053f Nikos Skalkotos
    options, args = parser.parse_args(input_args)
94 c408053f Nikos Skalkotos
95 0ae01e26 Nikos Skalkotos
    if len(args) != 1:
96 0ae01e26 Nikos Skalkotos
        parser.error('Wrong number of arguments')
97 c408053f Nikos Skalkotos
    options.source = args[0]
98 c408053f Nikos Skalkotos
    if not os.path.exists(options.source):
99 0ae01e26 Nikos Skalkotos
        parser.error('input media is not accessible')
100 c408053f Nikos Skalkotos
101 1a3f1298 Nikos Skalkotos
    if options.register:
102 1a3f1298 Nikos Skalkotos
        options.upload = True
103 1a3f1298 Nikos Skalkotos
104 0ae01e26 Nikos Skalkotos
    if options.outfile is None and not options.upload:
105 0ae01e26 Nikos Skalkotos
        parser.error('either outfile (-o) or upload (-u) must be set.')
106 0ae01e26 Nikos Skalkotos
107 c408053f Nikos Skalkotos
    return options
108 d57775d4 Nikos Skalkotos
109 8c574358 Nikos Skalkotos
110 22a6d232 Nikos Skalkotos
def image_creator():
111 22a6d232 Nikos Skalkotos
    puts('snf-image-creator %s\n' % version)
112 c408053f Nikos Skalkotos
    options = parse_options(sys.argv[1:])
113 c408053f Nikos Skalkotos
114 c408053f Nikos Skalkotos
    if os.geteuid() != 0:
115 c408053f Nikos Skalkotos
        raise FatalError("You must run %s as root" \
116 c408053f Nikos Skalkotos
                        % os.path.basename(sys.argv[0]))
117 c408053f Nikos Skalkotos
118 69aa33fa Nikos Skalkotos
    if not options.force and options.outfile is not None:
119 0ae01e26 Nikos Skalkotos
        for extension in ('', '.meta'):
120 0ae01e26 Nikos Skalkotos
            filename = "%s%s" % (options.outfile, extension)
121 c408053f Nikos Skalkotos
            if os.path.exists(filename):
122 c408053f Nikos Skalkotos
                raise FatalError("Output file %s exists "
123 c408053f Nikos Skalkotos
                    "(use --force to overwrite it)." % filename)
124 c408053f Nikos Skalkotos
125 c408053f Nikos Skalkotos
    disk = Disk(options.source)
126 d57775d4 Nikos Skalkotos
    try:
127 d57775d4 Nikos Skalkotos
        dev = disk.get_device()
128 0d5a999d Nikos Skalkotos
        dev.mount()
129 22a6d232 Nikos Skalkotos
130 aa2062ba Nikos Skalkotos
        osclass = get_os_class(dev.distro, dev.ostype)
131 aa2062ba Nikos Skalkotos
        image_os = osclass(dev.root, dev.g)
132 aa2062ba Nikos Skalkotos
        metadata = image_os.get_metadata()
133 9cbb5794 Nikos Skalkotos
134 3f70f242 Nikos Skalkotos
        puts()
135 3f70f242 Nikos Skalkotos
136 9cbb5794 Nikos Skalkotos
        if options.sysprep:
137 9cbb5794 Nikos Skalkotos
            image_os.sysprep()
138 ae48a082 Nikos Skalkotos
139 1a3f1298 Nikos Skalkotos
        if options.cleanup:
140 1a3f1298 Nikos Skalkotos
            image_os.data_cleanup()
141 1a3f1298 Nikos Skalkotos
142 8c574358 Nikos Skalkotos
        dev.umount()
143 1a3f1298 Nikos Skalkotos
144 c408053f Nikos Skalkotos
        size = options.shrink and dev.shrink() or dev.size()
145 c408053f Nikos Skalkotos
        metadata['size'] = str(size // 2 ** 20)
146 ae48a082 Nikos Skalkotos
147 0ae01e26 Nikos Skalkotos
        if options.outfile is not None:
148 0ae01e26 Nikos Skalkotos
            f = open('%s.%s' % (options.outfile, 'meta'), 'w')
149 0ae01e26 Nikos Skalkotos
            try:
150 0ae01e26 Nikos Skalkotos
                for key in metadata.keys():
151 0ae01e26 Nikos Skalkotos
                    f.write("%s=%s\n" % (key, metadata[key]))
152 0ae01e26 Nikos Skalkotos
            finally:
153 0ae01e26 Nikos Skalkotos
                f.close()
154 0ae01e26 Nikos Skalkotos
155 d603d80d Nikos Skalkotos
            dev.dump(options.outfile)
156 d57775d4 Nikos Skalkotos
    finally:
157 22a6d232 Nikos Skalkotos
        puts('cleaning up...')
158 d57775d4 Nikos Skalkotos
        disk.cleanup()
159 d57775d4 Nikos Skalkotos
160 c408053f Nikos Skalkotos
    return 0
161 c408053f Nikos Skalkotos
162 ae48a082 Nikos Skalkotos
163 0ae01e26 Nikos Skalkotos
def main():
164 c408053f Nikos Skalkotos
    try:
165 0ae01e26 Nikos Skalkotos
        ret = image_creator()
166 c408053f Nikos Skalkotos
        sys.exit(ret)
167 c408053f Nikos Skalkotos
    except FatalError as e:
168 22a6d232 Nikos Skalkotos
        error(e)
169 c408053f Nikos Skalkotos
        sys.exit(1)
170 d57775d4 Nikos Skalkotos
171 0ae01e26 Nikos Skalkotos
172 0ae01e26 Nikos Skalkotos
if __name__ == '__main__':
173 0ae01e26 Nikos Skalkotos
    main()
174 ae48a082 Nikos Skalkotos
175 d57775d4 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :