Statistics
| Branch: | Tag: | Revision:

root / image_creator / dialog_main.py @ e6f134b3

History | View | Annotate | Download (7.6 kB)

1 672cabb9 Nikos Skalkotos
#!/usr/bin/env python
2 672cabb9 Nikos Skalkotos
3 672cabb9 Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
4 672cabb9 Nikos Skalkotos
#
5 672cabb9 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
6 672cabb9 Nikos Skalkotos
# without modification, are permitted provided that the following
7 672cabb9 Nikos Skalkotos
# conditions are met:
8 672cabb9 Nikos Skalkotos
#
9 672cabb9 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
10 672cabb9 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
11 672cabb9 Nikos Skalkotos
#      disclaimer.
12 672cabb9 Nikos Skalkotos
#
13 672cabb9 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
14 672cabb9 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
15 672cabb9 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
16 672cabb9 Nikos Skalkotos
#      provided with the distribution.
17 672cabb9 Nikos Skalkotos
#
18 672cabb9 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 672cabb9 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 672cabb9 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 672cabb9 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 672cabb9 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 672cabb9 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 672cabb9 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 672cabb9 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 672cabb9 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 672cabb9 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 672cabb9 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 672cabb9 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
30 672cabb9 Nikos Skalkotos
#
31 672cabb9 Nikos Skalkotos
# The views and conclusions contained in the software and
32 672cabb9 Nikos Skalkotos
# documentation are those of the authors and should not be
33 672cabb9 Nikos Skalkotos
# interpreted as representing official policies, either expressed
34 672cabb9 Nikos Skalkotos
# or implied, of GRNET S.A.
35 672cabb9 Nikos Skalkotos
36 672cabb9 Nikos Skalkotos
import dialog
37 672cabb9 Nikos Skalkotos
import sys
38 672cabb9 Nikos Skalkotos
import os
39 672cabb9 Nikos Skalkotos
import textwrap
40 672cabb9 Nikos Skalkotos
import signal
41 5a0399d8 Nikos Skalkotos
import optparse
42 672cabb9 Nikos Skalkotos
43 672cabb9 Nikos Skalkotos
from image_creator import __version__ as version
44 023e1217 Nikos Skalkotos
from image_creator.util import FatalError
45 c3fe132c Nikos Skalkotos
from image_creator.output import Output
46 789a3763 Nikos Skalkotos
from image_creator.output.cli import SimpleOutput
47 023e1217 Nikos Skalkotos
from image_creator.output.dialog import GaugeOutput
48 c3fe132c Nikos Skalkotos
from image_creator.output.composite import CompositeOutput
49 672cabb9 Nikos Skalkotos
from image_creator.disk import Disk
50 672cabb9 Nikos Skalkotos
from image_creator.os_type import os_cls
51 09ed3d46 Nikos Skalkotos
from image_creator.dialog_wizard import wizard
52 023e1217 Nikos Skalkotos
from image_creator.dialog_menu import main_menu
53 023e1217 Nikos Skalkotos
from image_creator.dialog_util import SMALL_WIDTH, WIDTH, confirm_exit, \
54 023e1217 Nikos Skalkotos
    Reset, update_background_title
55 672cabb9 Nikos Skalkotos
56 672cabb9 Nikos Skalkotos
57 789a3763 Nikos Skalkotos
def image_creator(d, media, out):
58 672cabb9 Nikos Skalkotos
59 a42a42b3 Nikos Skalkotos
    d.setBackgroundTitle('snf-image-creator')
60 a42a42b3 Nikos Skalkotos
61 789a3763 Nikos Skalkotos
    gauge = GaugeOutput(d, "Initialization", "Initializing...")
62 789a3763 Nikos Skalkotos
    out.add(gauge)
63 672cabb9 Nikos Skalkotos
    disk = Disk(media, out)
64 672cabb9 Nikos Skalkotos
65 9afc4b89 Nikos Skalkotos
    def signal_handler(signum, frame):
66 789a3763 Nikos Skalkotos
        gauge.cleanup()
67 672cabb9 Nikos Skalkotos
        disk.cleanup()
68 672cabb9 Nikos Skalkotos
69 672cabb9 Nikos Skalkotos
    signal.signal(signal.SIGINT, signal_handler)
70 9c354f13 Nikos Skalkotos
    signal.signal(signal.SIGTERM, signal_handler)
71 672cabb9 Nikos Skalkotos
    try:
72 672cabb9 Nikos Skalkotos
        snapshot = disk.snapshot()
73 672cabb9 Nikos Skalkotos
        dev = disk.get_device(snapshot)
74 672cabb9 Nikos Skalkotos
75 a42a42b3 Nikos Skalkotos
        metadata = {}
76 a42a42b3 Nikos Skalkotos
        for (key, value) in dev.meta.items():
77 a42a42b3 Nikos Skalkotos
            metadata[str(key)] = str(value)
78 a42a42b3 Nikos Skalkotos
79 7f623b20 Nikos Skalkotos
        dev.mount(readonly=True)
80 ea947a64 Nikos Skalkotos
        out.output("Collecting image metadata...")
81 7f623b20 Nikos Skalkotos
        cls = os_cls(dev.distro, dev.ostype)
82 7f623b20 Nikos Skalkotos
        image_os = cls(dev.root, dev.g, out)
83 7f623b20 Nikos Skalkotos
        dev.umount()
84 a42a42b3 Nikos Skalkotos
85 a42a42b3 Nikos Skalkotos
        for (key, value) in image_os.meta.items():
86 a42a42b3 Nikos Skalkotos
            metadata[str(key)] = str(value)
87 a42a42b3 Nikos Skalkotos
88 7f623b20 Nikos Skalkotos
        out.success("done")
89 789a3763 Nikos Skalkotos
        gauge.cleanup()
90 789a3763 Nikos Skalkotos
        out.remove(gauge)
91 672cabb9 Nikos Skalkotos
92 789a3763 Nikos Skalkotos
        # Make sure the signal handler does not call gauge.cleanup again
93 672cabb9 Nikos Skalkotos
        def dummy(self):
94 672cabb9 Nikos Skalkotos
            pass
95 789a3763 Nikos Skalkotos
        gauge.cleanup = type(GaugeOutput.cleanup)(dummy, gauge, GaugeOutput)
96 672cabb9 Nikos Skalkotos
97 672cabb9 Nikos Skalkotos
        session = {"dialog": d,
98 672cabb9 Nikos Skalkotos
                   "disk": disk,
99 2a21ff92 Nikos Skalkotos
                   "snapshot": snapshot,
100 672cabb9 Nikos Skalkotos
                   "device": dev,
101 7f623b20 Nikos Skalkotos
                   "image_os": image_os,
102 672cabb9 Nikos Skalkotos
                   "metadata": metadata}
103 672cabb9 Nikos Skalkotos
104 cf4f52b6 Nikos Skalkotos
        msg = "snf-image-creator detected a %s system on the input media. " \
105 b9cd03ee Nikos Skalkotos
              "Would you like to run a wizard to assist you through the " \
106 b9cd03ee Nikos Skalkotos
              "image creation process?\n\nChoose <Wizard> to run the wizard," \
107 023e1217 Nikos Skalkotos
              " <Expert> to run the snf-image-creator in expert mode or " \
108 023e1217 Nikos Skalkotos
              "press ESC to quit the program." \
109 fbdf1d8f Nikos Skalkotos
              % (dev.ostype if dev.ostype == dev.distro else "%s (%s)" %
110 fbdf1d8f Nikos Skalkotos
                 (dev.ostype, dev.distro))
111 cf4f52b6 Nikos Skalkotos
112 3c33e68a Nikos Skalkotos
        update_background_title(session)
113 3c33e68a Nikos Skalkotos
114 cf4f52b6 Nikos Skalkotos
        while True:
115 023e1217 Nikos Skalkotos
            code = d.yesno(msg, width=WIDTH, height=12, yes_label="Wizard",
116 023e1217 Nikos Skalkotos
                           no_label="Expert")
117 cf4f52b6 Nikos Skalkotos
            if code == d.DIALOG_OK:
118 cf4f52b6 Nikos Skalkotos
                if wizard(session):
119 cf4f52b6 Nikos Skalkotos
                    break
120 cf4f52b6 Nikos Skalkotos
            elif code == d.DIALOG_CANCEL:
121 cf4f52b6 Nikos Skalkotos
                main_menu(session)
122 cf4f52b6 Nikos Skalkotos
                break
123 5a0399d8 Nikos Skalkotos
124 24684bbb Nikos Skalkotos
            if confirm_exit(d):
125 cf4f52b6 Nikos Skalkotos
                break
126 5a0399d8 Nikos Skalkotos
127 672cabb9 Nikos Skalkotos
        d.infobox("Thank you for using snf-image-creator. Bye", width=53)
128 672cabb9 Nikos Skalkotos
    finally:
129 672cabb9 Nikos Skalkotos
        disk.cleanup()
130 672cabb9 Nikos Skalkotos
131 672cabb9 Nikos Skalkotos
    return 0
132 672cabb9 Nikos Skalkotos
133 672cabb9 Nikos Skalkotos
134 789a3763 Nikos Skalkotos
def select_file(d, media):
135 789a3763 Nikos Skalkotos
    root = os.sep
136 789a3763 Nikos Skalkotos
    while 1:
137 789a3763 Nikos Skalkotos
        if media is not None:
138 789a3763 Nikos Skalkotos
            if not os.path.exists(media):
139 789a3763 Nikos Skalkotos
                d.msgbox("The file `%s' you choose does not exist." % media,
140 023e1217 Nikos Skalkotos
                         width=SMALL_WIDTH)
141 789a3763 Nikos Skalkotos
            else:
142 789a3763 Nikos Skalkotos
                break
143 789a3763 Nikos Skalkotos
144 b686bde9 Nikos Skalkotos
        (code, media) = d.fselect(root, 10, 60, extra_button=1,
145 6523456e Nikos Skalkotos
            title="Please select an input media.",
146 6523456e Nikos Skalkotos
            extra_label="Running System")
147 789a3763 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
148 789a3763 Nikos Skalkotos
            if confirm_exit(d, "You canceled the media selection dialog box."):
149 789a3763 Nikos Skalkotos
                sys.exit(0)
150 789a3763 Nikos Skalkotos
            else:
151 789a3763 Nikos Skalkotos
                media = None
152 789a3763 Nikos Skalkotos
                continue
153 b686bde9 Nikos Skalkotos
        elif code == d.DIALOG_EXTRA:
154 b686bde9 Nikos Skalkotos
            media = '/'
155 789a3763 Nikos Skalkotos
156 789a3763 Nikos Skalkotos
    return media
157 789a3763 Nikos Skalkotos
158 789a3763 Nikos Skalkotos
159 672cabb9 Nikos Skalkotos
def main():
160 672cabb9 Nikos Skalkotos
161 672cabb9 Nikos Skalkotos
    d = dialog.Dialog(dialog="dialog")
162 672cabb9 Nikos Skalkotos
163 f9d8c3d9 Nikos Skalkotos
    # Add extra button in dialog library
164 f9d8c3d9 Nikos Skalkotos
    dialog._common_args_syntax["extra_button"] = \
165 f9d8c3d9 Nikos Skalkotos
        lambda enable: dialog._simple_option("--extra-button", enable)
166 f9d8c3d9 Nikos Skalkotos
167 f9d8c3d9 Nikos Skalkotos
    dialog._common_args_syntax["extra_label"] = \
168 f9d8c3d9 Nikos Skalkotos
        lambda string: ("--extra-label", string)
169 f9d8c3d9 Nikos Skalkotos
170 b9cd03ee Nikos Skalkotos
    # Allow yes-no label overwriting
171 b9cd03ee Nikos Skalkotos
    dialog._common_args_syntax["yes_label"] = \
172 b9cd03ee Nikos Skalkotos
        lambda string: ("--yes-label", string)
173 b9cd03ee Nikos Skalkotos
174 b9cd03ee Nikos Skalkotos
    dialog._common_args_syntax["no_label"] = \
175 b9cd03ee Nikos Skalkotos
        lambda string: ("--no-label", string)
176 b9cd03ee Nikos Skalkotos
177 789a3763 Nikos Skalkotos
    usage = "Usage: %prog [options] [<input_media>]"
178 789a3763 Nikos Skalkotos
    parser = optparse.OptionParser(version=version, usage=usage)
179 789a3763 Nikos Skalkotos
    parser.add_option("-l", "--logfile", type="string", dest="logfile",
180 789a3763 Nikos Skalkotos
                      default=None, help="log all messages to FILE",
181 789a3763 Nikos Skalkotos
                      metavar="FILE")
182 789a3763 Nikos Skalkotos
183 789a3763 Nikos Skalkotos
    options, args = parser.parse_args(sys.argv[1:])
184 789a3763 Nikos Skalkotos
185 789a3763 Nikos Skalkotos
    if len(args) > 1:
186 789a3763 Nikos Skalkotos
        parser.error("Wrong number of arguments")
187 789a3763 Nikos Skalkotos
188 789a3763 Nikos Skalkotos
    d.setBackgroundTitle('snf-image-creator')
189 789a3763 Nikos Skalkotos
190 789a3763 Nikos Skalkotos
    try:
191 789a3763 Nikos Skalkotos
        if os.geteuid() != 0:
192 023e1217 Nikos Skalkotos
            raise FatalError("You must run %s as root" %
193 789a3763 Nikos Skalkotos
                             parser.get_prog_name())
194 789a3763 Nikos Skalkotos
195 789a3763 Nikos Skalkotos
        media = select_file(d, args[0] if len(args) == 1 else None)
196 789a3763 Nikos Skalkotos
197 789a3763 Nikos Skalkotos
        logfile = None
198 789a3763 Nikos Skalkotos
        if options.logfile is not None:
199 672cabb9 Nikos Skalkotos
            try:
200 789a3763 Nikos Skalkotos
                logfile = open(options.logfile, 'w')
201 789a3763 Nikos Skalkotos
            except IOError as e:
202 789a3763 Nikos Skalkotos
                raise FatalError(
203 023e1217 Nikos Skalkotos
                    "Unable to open logfile `%s' for writing. Reason: %s" %
204 789a3763 Nikos Skalkotos
                    (options.logfile, e.strerror))
205 789a3763 Nikos Skalkotos
        try:
206 789a3763 Nikos Skalkotos
            log = SimpleOutput(False, logfile) if logfile is not None \
207 023e1217 Nikos Skalkotos
                else Output()
208 789a3763 Nikos Skalkotos
            while 1:
209 789a3763 Nikos Skalkotos
                try:
210 c3fe132c Nikos Skalkotos
                    out = CompositeOutput([log])
211 023e1217 Nikos Skalkotos
                    out.output("Starting %s v%s..." %
212 789a3763 Nikos Skalkotos
                               (parser.get_prog_name(), version))
213 789a3763 Nikos Skalkotos
                    ret = image_creator(d, media, out)
214 789a3763 Nikos Skalkotos
                    sys.exit(ret)
215 789a3763 Nikos Skalkotos
                except Reset:
216 789a3763 Nikos Skalkotos
                    log.output("Resetting everything...")
217 789a3763 Nikos Skalkotos
                    continue
218 789a3763 Nikos Skalkotos
        finally:
219 789a3763 Nikos Skalkotos
            if logfile is not None:
220 789a3763 Nikos Skalkotos
                logfile.close()
221 789a3763 Nikos Skalkotos
    except FatalError as e:
222 023e1217 Nikos Skalkotos
        msg = textwrap.fill(str(e), width=WIDTH)
223 023e1217 Nikos Skalkotos
        d.infobox(msg, width=WIDTH, title="Fatal Error")
224 789a3763 Nikos Skalkotos
        sys.exit(1)
225 672cabb9 Nikos Skalkotos
226 672cabb9 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :