Statistics
| Branch: | Tag: | Revision:

root / image_creator / dialog_menu.py @ 023e1217

History | View | Annotate | Download (24.5 kB)

1 023e1217 Nikos Skalkotos
#!/usr/bin/env python
2 023e1217 Nikos Skalkotos
3 023e1217 Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
4 023e1217 Nikos Skalkotos
#
5 023e1217 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
6 023e1217 Nikos Skalkotos
# without modification, are permitted provided that the following
7 023e1217 Nikos Skalkotos
# conditions are met:
8 023e1217 Nikos Skalkotos
#
9 023e1217 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
10 023e1217 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
11 023e1217 Nikos Skalkotos
#      disclaimer.
12 023e1217 Nikos Skalkotos
#
13 023e1217 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
14 023e1217 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
15 023e1217 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
16 023e1217 Nikos Skalkotos
#      provided with the distribution.
17 023e1217 Nikos Skalkotos
#
18 023e1217 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 023e1217 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 023e1217 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 023e1217 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 023e1217 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 023e1217 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 023e1217 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 023e1217 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 023e1217 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 023e1217 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 023e1217 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 023e1217 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
30 023e1217 Nikos Skalkotos
#
31 023e1217 Nikos Skalkotos
# The views and conclusions contained in the software and
32 023e1217 Nikos Skalkotos
# documentation are those of the authors and should not be
33 023e1217 Nikos Skalkotos
# interpreted as representing official policies, either expressed
34 023e1217 Nikos Skalkotos
# or implied, of GRNET S.A.
35 023e1217 Nikos Skalkotos
36 023e1217 Nikos Skalkotos
import sys
37 023e1217 Nikos Skalkotos
import os
38 023e1217 Nikos Skalkotos
import textwrap
39 023e1217 Nikos Skalkotos
import StringIO
40 023e1217 Nikos Skalkotos
41 023e1217 Nikos Skalkotos
from image_creator import __version__ as version
42 023e1217 Nikos Skalkotos
from image_creator.util import MD5
43 023e1217 Nikos Skalkotos
from image_creator.output.dialog import GaugeOutput, InfoBoxOutput
44 023e1217 Nikos Skalkotos
from image_creator.kamaki_wrapper import Kamaki, ClientError
45 023e1217 Nikos Skalkotos
from image_creator.help import get_help_file
46 023e1217 Nikos Skalkotos
from image_creator.dialog_util import SMALL_WIDTH, WIDTH, \
47 023e1217 Nikos Skalkotos
    update_background_title, confirm_reset, confirm_exit, Reset, extract_image
48 023e1217 Nikos Skalkotos
49 023e1217 Nikos Skalkotos
CONFIGURATION_TASKS = [
50 023e1217 Nikos Skalkotos
    ("Partition table manipulation", ["FixPartitionTable"],
51 023e1217 Nikos Skalkotos
        ["linux", "windows"]),
52 023e1217 Nikos Skalkotos
    ("File system resize",
53 023e1217 Nikos Skalkotos
        ["FilesystemResizeUnmounted", "FilesystemResizeMounted"],
54 023e1217 Nikos Skalkotos
        ["linux", "windows"]),
55 023e1217 Nikos Skalkotos
    ("Swap partition configuration", ["AddSwap"], ["linux"]),
56 023e1217 Nikos Skalkotos
    ("SSH keys removal", ["DeleteSSHKeys"], ["linux"]),
57 023e1217 Nikos Skalkotos
    ("Temporal RDP disabling", ["DisableRemoteDesktopConnections"],
58 023e1217 Nikos Skalkotos
        ["windows"]),
59 023e1217 Nikos Skalkotos
    ("SELinux relabeling at next boot", ["SELinuxAutorelabel"], ["linux"]),
60 023e1217 Nikos Skalkotos
    ("Hostname/Computer Name assignment", ["AssignHostname"],
61 023e1217 Nikos Skalkotos
        ["windows", "linux"]),
62 023e1217 Nikos Skalkotos
    ("Password change", ["ChangePassword"], ["windows", "linux"]),
63 023e1217 Nikos Skalkotos
    ("File injection", ["EnforcePersonality"], ["windows", "linux"])
64 023e1217 Nikos Skalkotos
]
65 023e1217 Nikos Skalkotos
66 023e1217 Nikos Skalkotos
67 023e1217 Nikos Skalkotos
class metadata_monitor(object):
68 023e1217 Nikos Skalkotos
    def __init__(self, session, meta):
69 023e1217 Nikos Skalkotos
        self.session = session
70 023e1217 Nikos Skalkotos
        self.meta = meta
71 023e1217 Nikos Skalkotos
72 023e1217 Nikos Skalkotos
    def __enter__(self):
73 023e1217 Nikos Skalkotos
        self.old = {}
74 023e1217 Nikos Skalkotos
        for (k, v) in self.meta.items():
75 023e1217 Nikos Skalkotos
            self.old[k] = v
76 023e1217 Nikos Skalkotos
77 023e1217 Nikos Skalkotos
    def __exit__(self, type, value, traceback):
78 023e1217 Nikos Skalkotos
        d = self.session['dialog']
79 023e1217 Nikos Skalkotos
80 023e1217 Nikos Skalkotos
        altered = {}
81 023e1217 Nikos Skalkotos
        added = {}
82 023e1217 Nikos Skalkotos
83 023e1217 Nikos Skalkotos
        for (k, v) in self.meta.items():
84 023e1217 Nikos Skalkotos
            if k not in self.old:
85 023e1217 Nikos Skalkotos
                added[k] = v
86 023e1217 Nikos Skalkotos
            elif self.old[k] != v:
87 023e1217 Nikos Skalkotos
                altered[k] = v
88 023e1217 Nikos Skalkotos
89 023e1217 Nikos Skalkotos
        if not (len(added) or len(altered)):
90 023e1217 Nikos Skalkotos
            return
91 023e1217 Nikos Skalkotos
92 023e1217 Nikos Skalkotos
        msg = "The last action has changed some image properties:\n\n"
93 023e1217 Nikos Skalkotos
        if len(added):
94 023e1217 Nikos Skalkotos
            msg += "New image properties:\n"
95 023e1217 Nikos Skalkotos
            for (k, v) in added.items():
96 023e1217 Nikos Skalkotos
                msg += '    %s: "%s"\n' % (k, v)
97 023e1217 Nikos Skalkotos
            msg += "\n"
98 023e1217 Nikos Skalkotos
        if len(altered):
99 023e1217 Nikos Skalkotos
            msg += "Updated image properties:\n"
100 023e1217 Nikos Skalkotos
            for (k, v) in altered.items():
101 023e1217 Nikos Skalkotos
                msg += '    %s: "%s" -> "%s"\n' % (k, self.old[k], v)
102 023e1217 Nikos Skalkotos
            msg += "\n"
103 023e1217 Nikos Skalkotos
104 023e1217 Nikos Skalkotos
        self.session['metadata'].update(added)
105 023e1217 Nikos Skalkotos
        self.session['metadata'].update(altered)
106 023e1217 Nikos Skalkotos
        d.msgbox(msg, title="Image Property Changes", width=SMALL_WIDTH)
107 023e1217 Nikos Skalkotos
108 023e1217 Nikos Skalkotos
109 023e1217 Nikos Skalkotos
def extract_metadata_string(session):
110 023e1217 Nikos Skalkotos
    metadata = ['%s=%s' % (k, v) for (k, v) in session['metadata'].items()]
111 023e1217 Nikos Skalkotos
112 023e1217 Nikos Skalkotos
    if 'task_metadata' in session:
113 023e1217 Nikos Skalkotos
        metadata.extend("%s=yes" % m for m in session['task_metadata'])
114 023e1217 Nikos Skalkotos
115 023e1217 Nikos Skalkotos
    return '\n'.join(metadata) + '\n'
116 023e1217 Nikos Skalkotos
117 023e1217 Nikos Skalkotos
118 023e1217 Nikos Skalkotos
def upload_image(session):
119 023e1217 Nikos Skalkotos
    d = session["dialog"]
120 023e1217 Nikos Skalkotos
    dev = session['device']
121 023e1217 Nikos Skalkotos
    size = dev.size
122 023e1217 Nikos Skalkotos
123 023e1217 Nikos Skalkotos
    if "account" not in session:
124 023e1217 Nikos Skalkotos
        d.msgbox("You need to provide your ~okeanos login username before you "
125 023e1217 Nikos Skalkotos
                 "can upload images to pithos+", width=SMALL_WIDTH)
126 023e1217 Nikos Skalkotos
        return False
127 023e1217 Nikos Skalkotos
128 023e1217 Nikos Skalkotos
    if "token" not in session:
129 023e1217 Nikos Skalkotos
        d.msgbox("You need to provide your ~okeanos account authentication "
130 023e1217 Nikos Skalkotos
                 "token before you can upload images to pithos+",
131 023e1217 Nikos Skalkotos
                 width=SMALL_WIDTH)
132 023e1217 Nikos Skalkotos
        return False
133 023e1217 Nikos Skalkotos
134 023e1217 Nikos Skalkotos
    while 1:
135 023e1217 Nikos Skalkotos
        init = session["upload"] if "upload" in session else ''
136 023e1217 Nikos Skalkotos
        (code, answer) = d.inputbox("Please provide a filename:", init=init,
137 023e1217 Nikos Skalkotos
                                    width=WIDTH)
138 023e1217 Nikos Skalkotos
139 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
140 023e1217 Nikos Skalkotos
            return False
141 023e1217 Nikos Skalkotos
142 023e1217 Nikos Skalkotos
        filename = answer.strip()
143 023e1217 Nikos Skalkotos
        if len(filename) == 0:
144 023e1217 Nikos Skalkotos
            d.msgbox("Filename cannot be empty", width=SMALL_WIDTH)
145 023e1217 Nikos Skalkotos
            continue
146 023e1217 Nikos Skalkotos
        session['upload'] = filename
147 023e1217 Nikos Skalkotos
        break
148 023e1217 Nikos Skalkotos
149 023e1217 Nikos Skalkotos
    gauge = GaugeOutput(d, "Image Upload", "Uploading...")
150 023e1217 Nikos Skalkotos
    try:
151 023e1217 Nikos Skalkotos
        out = dev.out
152 023e1217 Nikos Skalkotos
        out.add(gauge)
153 023e1217 Nikos Skalkotos
        try:
154 023e1217 Nikos Skalkotos
            if 'checksum' not in session:
155 023e1217 Nikos Skalkotos
                md5 = MD5(out)
156 023e1217 Nikos Skalkotos
                session['checksum'] = md5.compute(session['snapshot'], size)
157 023e1217 Nikos Skalkotos
158 023e1217 Nikos Skalkotos
            kamaki = Kamaki(session['account'], session['token'], out)
159 023e1217 Nikos Skalkotos
            try:
160 023e1217 Nikos Skalkotos
                # Upload image file
161 023e1217 Nikos Skalkotos
                with open(session['snapshot'], 'rb') as f:
162 023e1217 Nikos Skalkotos
                    session["pithos_uri"] = \
163 023e1217 Nikos Skalkotos
                        kamaki.upload(f, size, filename,
164 023e1217 Nikos Skalkotos
                                      "Calculating block hashes",
165 023e1217 Nikos Skalkotos
                                      "Uploading missing blocks")
166 023e1217 Nikos Skalkotos
                # Upload metadata file
167 023e1217 Nikos Skalkotos
                out.output("Uploading metadata file...")
168 023e1217 Nikos Skalkotos
                metastring = extract_metadata_string(session)
169 023e1217 Nikos Skalkotos
                kamaki.upload(StringIO.StringIO(metastring),
170 023e1217 Nikos Skalkotos
                              size=len(metastring),
171 023e1217 Nikos Skalkotos
                              remote_path="%s.meta" % filename)
172 023e1217 Nikos Skalkotos
                out.success("done")
173 023e1217 Nikos Skalkotos
174 023e1217 Nikos Skalkotos
                # Upload md5sum file
175 023e1217 Nikos Skalkotos
                out.output("Uploading md5sum file...")
176 023e1217 Nikos Skalkotos
                md5str = "%s %s\n" % (session['checksum'], filename)
177 023e1217 Nikos Skalkotos
                kamaki.upload(StringIO.StringIO(md5str), size=len(md5str),
178 023e1217 Nikos Skalkotos
                              remote_path="%s.md5sum" % filename)
179 023e1217 Nikos Skalkotos
                out.success("done")
180 023e1217 Nikos Skalkotos
181 023e1217 Nikos Skalkotos
            except ClientError as e:
182 023e1217 Nikos Skalkotos
                d.msgbox("Error in pithos+ client: %s" % e.message,
183 023e1217 Nikos Skalkotos
                         title="Pithos+ Client Error", width=SMALL_WIDTH)
184 023e1217 Nikos Skalkotos
                if 'pithos_uri' in session:
185 023e1217 Nikos Skalkotos
                    del session['pithos_uri']
186 023e1217 Nikos Skalkotos
                return False
187 023e1217 Nikos Skalkotos
        finally:
188 023e1217 Nikos Skalkotos
            out.remove(gauge)
189 023e1217 Nikos Skalkotos
    finally:
190 023e1217 Nikos Skalkotos
        gauge.cleanup()
191 023e1217 Nikos Skalkotos
192 023e1217 Nikos Skalkotos
    d.msgbox("Image file `%s' was successfully uploaded to pithos+" % filename,
193 023e1217 Nikos Skalkotos
             width=SMALL_WIDTH)
194 023e1217 Nikos Skalkotos
195 023e1217 Nikos Skalkotos
    return True
196 023e1217 Nikos Skalkotos
197 023e1217 Nikos Skalkotos
198 023e1217 Nikos Skalkotos
def register_image(session):
199 023e1217 Nikos Skalkotos
    d = session["dialog"]
200 023e1217 Nikos Skalkotos
    dev = session['device']
201 023e1217 Nikos Skalkotos
202 023e1217 Nikos Skalkotos
    if "account" not in session:
203 023e1217 Nikos Skalkotos
        d.msgbox("You need to provide your ~okeanos login username before you "
204 023e1217 Nikos Skalkotos
                 "can register an images to cyclades",
205 023e1217 Nikos Skalkotos
                 width=SMALL_WIDTH)
206 023e1217 Nikos Skalkotos
        return False
207 023e1217 Nikos Skalkotos
208 023e1217 Nikos Skalkotos
    if "token" not in session:
209 023e1217 Nikos Skalkotos
        d.msgbox("You need to provide your ~okeanos account authentication "
210 023e1217 Nikos Skalkotos
                 "token before you can register an images to cyclades",
211 023e1217 Nikos Skalkotos
                 width=SMALL_WIDTH)
212 023e1217 Nikos Skalkotos
        return False
213 023e1217 Nikos Skalkotos
214 023e1217 Nikos Skalkotos
    if "pithos_uri" not in session:
215 023e1217 Nikos Skalkotos
        d.msgbox("You need to upload the image to pithos+ before you can "
216 023e1217 Nikos Skalkotos
                 "register it to cyclades", width=SMALL_WIDTH)
217 023e1217 Nikos Skalkotos
        return False
218 023e1217 Nikos Skalkotos
219 023e1217 Nikos Skalkotos
    while 1:
220 023e1217 Nikos Skalkotos
        (code, answer) = d.inputbox("Please provide a registration name:",
221 023e1217 Nikos Skalkotos
                                    width=WIDTH)
222 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
223 023e1217 Nikos Skalkotos
            return False
224 023e1217 Nikos Skalkotos
225 023e1217 Nikos Skalkotos
        name = answer.strip()
226 023e1217 Nikos Skalkotos
        if len(name) == 0:
227 023e1217 Nikos Skalkotos
            d.msgbox("Registration name cannot be empty", width=SMALL_WIDTH)
228 023e1217 Nikos Skalkotos
            continue
229 023e1217 Nikos Skalkotos
        break
230 023e1217 Nikos Skalkotos
231 023e1217 Nikos Skalkotos
    metadata = {}
232 023e1217 Nikos Skalkotos
    metadata.update(session['metadata'])
233 023e1217 Nikos Skalkotos
    if 'task_metadata' in session:
234 023e1217 Nikos Skalkotos
        for key in session['task_metadata']:
235 023e1217 Nikos Skalkotos
            metadata[key] = 'yes'
236 023e1217 Nikos Skalkotos
237 023e1217 Nikos Skalkotos
    gauge = GaugeOutput(d, "Image Registration", "Registering image...")
238 023e1217 Nikos Skalkotos
    try:
239 023e1217 Nikos Skalkotos
        out = dev.out
240 023e1217 Nikos Skalkotos
        out.add(gauge)
241 023e1217 Nikos Skalkotos
        try:
242 023e1217 Nikos Skalkotos
            out.output("Registering image with Cyclades...")
243 023e1217 Nikos Skalkotos
            try:
244 023e1217 Nikos Skalkotos
                kamaki = Kamaki(session['account'], session['token'], out)
245 023e1217 Nikos Skalkotos
                kamaki.register(name, session['pithos_uri'], metadata)
246 023e1217 Nikos Skalkotos
                out.success('done')
247 023e1217 Nikos Skalkotos
            except ClientError as e:
248 023e1217 Nikos Skalkotos
                d.msgbox("Error in pithos+ client: %s" % e.message)
249 023e1217 Nikos Skalkotos
                return False
250 023e1217 Nikos Skalkotos
        finally:
251 023e1217 Nikos Skalkotos
            out.remove(gauge)
252 023e1217 Nikos Skalkotos
    finally:
253 023e1217 Nikos Skalkotos
        gauge.cleanup()
254 023e1217 Nikos Skalkotos
255 023e1217 Nikos Skalkotos
    d.msgbox("Image `%s' was successfully registered with Cyclades as `%s'" %
256 023e1217 Nikos Skalkotos
             (session['upload'], name), width=SMALL_WIDTH)
257 023e1217 Nikos Skalkotos
    return True
258 023e1217 Nikos Skalkotos
259 023e1217 Nikos Skalkotos
260 023e1217 Nikos Skalkotos
def kamaki_menu(session):
261 023e1217 Nikos Skalkotos
    d = session['dialog']
262 023e1217 Nikos Skalkotos
    default_item = "Account"
263 023e1217 Nikos Skalkotos
264 023e1217 Nikos Skalkotos
    account = Kamaki.get_account()
265 023e1217 Nikos Skalkotos
    if account:
266 023e1217 Nikos Skalkotos
        session['account'] = account
267 023e1217 Nikos Skalkotos
268 023e1217 Nikos Skalkotos
    token = Kamaki.get_token()
269 023e1217 Nikos Skalkotos
    if token:
270 023e1217 Nikos Skalkotos
        session['token'] = token
271 023e1217 Nikos Skalkotos
272 023e1217 Nikos Skalkotos
    while 1:
273 023e1217 Nikos Skalkotos
        account = session["account"] if "account" in session else "<none>"
274 023e1217 Nikos Skalkotos
        token = session["token"] if "token" in session else "<none>"
275 023e1217 Nikos Skalkotos
        upload = session["upload"] if "upload" in session else "<none>"
276 023e1217 Nikos Skalkotos
277 023e1217 Nikos Skalkotos
        choices = [("Account", "Change your ~okeanos username: %s" % account),
278 023e1217 Nikos Skalkotos
                   ("Token", "Change your ~okeanos token: %s" % token),
279 023e1217 Nikos Skalkotos
                   ("Upload", "Upload image to pithos+"),
280 023e1217 Nikos Skalkotos
                   ("Register", "Register the image to cyclades: %s" % upload)]
281 023e1217 Nikos Skalkotos
282 023e1217 Nikos Skalkotos
        (code, choice) = d.menu(
283 023e1217 Nikos Skalkotos
            text="Choose one of the following or press <Back> to go back.",
284 023e1217 Nikos Skalkotos
            width=WIDTH, choices=choices, cancel="Back", height=13,
285 023e1217 Nikos Skalkotos
            menu_height=5, default_item=default_item,
286 023e1217 Nikos Skalkotos
            title="Image Registration Menu")
287 023e1217 Nikos Skalkotos
288 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
289 023e1217 Nikos Skalkotos
            return False
290 023e1217 Nikos Skalkotos
291 023e1217 Nikos Skalkotos
        if choice == "Account":
292 023e1217 Nikos Skalkotos
            default_item = "Account"
293 023e1217 Nikos Skalkotos
            (code, answer) = d.inputbox(
294 023e1217 Nikos Skalkotos
                "Please provide your ~okeanos account e-mail address:",
295 023e1217 Nikos Skalkotos
                init=session["account"] if "account" in session else '',
296 023e1217 Nikos Skalkotos
                width=WIDTH)
297 023e1217 Nikos Skalkotos
            if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
298 023e1217 Nikos Skalkotos
                continue
299 023e1217 Nikos Skalkotos
            if len(answer) == 0 and "account" in session:
300 023e1217 Nikos Skalkotos
                    del session["account"]
301 023e1217 Nikos Skalkotos
            else:
302 023e1217 Nikos Skalkotos
                session["account"] = answer.strip()
303 023e1217 Nikos Skalkotos
                Kamaki.save_account(session['account'])
304 023e1217 Nikos Skalkotos
                default_item = "Token"
305 023e1217 Nikos Skalkotos
        elif choice == "Token":
306 023e1217 Nikos Skalkotos
            default_item = "Token"
307 023e1217 Nikos Skalkotos
            (code, answer) = d.inputbox(
308 023e1217 Nikos Skalkotos
                "Please provide your ~okeanos account authetication token:",
309 023e1217 Nikos Skalkotos
                init=session["token"] if "token" in session else '',
310 023e1217 Nikos Skalkotos
                width=WIDTH)
311 023e1217 Nikos Skalkotos
            if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
312 023e1217 Nikos Skalkotos
                continue
313 023e1217 Nikos Skalkotos
            if len(answer) == 0 and "token" in session:
314 023e1217 Nikos Skalkotos
                del session["token"]
315 023e1217 Nikos Skalkotos
            else:
316 023e1217 Nikos Skalkotos
                session["token"] = answer.strip()
317 023e1217 Nikos Skalkotos
                Kamaki.save_token(session['token'])
318 023e1217 Nikos Skalkotos
                default_item = "Upload"
319 023e1217 Nikos Skalkotos
        elif choice == "Upload":
320 023e1217 Nikos Skalkotos
            if upload_image(session):
321 023e1217 Nikos Skalkotos
                default_item = "Register"
322 023e1217 Nikos Skalkotos
            else:
323 023e1217 Nikos Skalkotos
                default_item = "Upload"
324 023e1217 Nikos Skalkotos
        elif choice == "Register":
325 023e1217 Nikos Skalkotos
            if register_image(session):
326 023e1217 Nikos Skalkotos
                return True
327 023e1217 Nikos Skalkotos
            else:
328 023e1217 Nikos Skalkotos
                default_item = "Register"
329 023e1217 Nikos Skalkotos
330 023e1217 Nikos Skalkotos
331 023e1217 Nikos Skalkotos
def add_property(session):
332 023e1217 Nikos Skalkotos
    d = session['dialog']
333 023e1217 Nikos Skalkotos
334 023e1217 Nikos Skalkotos
    while 1:
335 023e1217 Nikos Skalkotos
        (code, answer) = d.inputbox("Please provide a name for a new image"
336 023e1217 Nikos Skalkotos
                                    " property:", width=WIDTH)
337 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
338 023e1217 Nikos Skalkotos
            return False
339 023e1217 Nikos Skalkotos
340 023e1217 Nikos Skalkotos
        name = answer.strip()
341 023e1217 Nikos Skalkotos
        if len(name) == 0:
342 023e1217 Nikos Skalkotos
            d.msgbox("A property name cannot be empty", width=SMALL_WIDTH)
343 023e1217 Nikos Skalkotos
            continue
344 023e1217 Nikos Skalkotos
345 023e1217 Nikos Skalkotos
        break
346 023e1217 Nikos Skalkotos
347 023e1217 Nikos Skalkotos
    while 1:
348 023e1217 Nikos Skalkotos
        (code, answer) = d.inputbox("Please provide a value for image "
349 023e1217 Nikos Skalkotos
                                    "property %s" % name, width=WIDTH)
350 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
351 023e1217 Nikos Skalkotos
            return False
352 023e1217 Nikos Skalkotos
353 023e1217 Nikos Skalkotos
        value = answer.strip()
354 023e1217 Nikos Skalkotos
        if len(value) == 0:
355 023e1217 Nikos Skalkotos
            d.msgbox("Value cannot be empty", width=SMALL_WIDTH)
356 023e1217 Nikos Skalkotos
            continue
357 023e1217 Nikos Skalkotos
358 023e1217 Nikos Skalkotos
        break
359 023e1217 Nikos Skalkotos
360 023e1217 Nikos Skalkotos
    session['metadata'][name] = value
361 023e1217 Nikos Skalkotos
362 023e1217 Nikos Skalkotos
    return True
363 023e1217 Nikos Skalkotos
364 023e1217 Nikos Skalkotos
365 023e1217 Nikos Skalkotos
def modify_properties(session):
366 023e1217 Nikos Skalkotos
    d = session['dialog']
367 023e1217 Nikos Skalkotos
368 023e1217 Nikos Skalkotos
    while 1:
369 023e1217 Nikos Skalkotos
        choices = []
370 023e1217 Nikos Skalkotos
        for (key, val) in session['metadata'].items():
371 023e1217 Nikos Skalkotos
            choices.append((str(key), str(val)))
372 023e1217 Nikos Skalkotos
373 023e1217 Nikos Skalkotos
        (code, choice) = d.menu(
374 023e1217 Nikos Skalkotos
            "In this menu you can edit existing image properties or add new "
375 023e1217 Nikos Skalkotos
            "ones. Be careful! Most properties have special meaning and "
376 023e1217 Nikos Skalkotos
            "alter the image deployment behaviour. Press <HELP> to see more "
377 023e1217 Nikos Skalkotos
            "information about image properties. Press <BACK> when done.",
378 023e1217 Nikos Skalkotos
            height=18, width=WIDTH, choices=choices, menu_height=10,
379 023e1217 Nikos Skalkotos
            ok_label="Edit", extra_button=1, extra_label="Add", cancel="Back",
380 023e1217 Nikos Skalkotos
            help_button=1, title="Image Properties")
381 023e1217 Nikos Skalkotos
382 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
383 023e1217 Nikos Skalkotos
            return True
384 023e1217 Nikos Skalkotos
        # Edit button
385 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_OK:
386 023e1217 Nikos Skalkotos
            (code, answer) = d.inputbox("Please provide a new value for the "
387 023e1217 Nikos Skalkotos
                                        "image property with name `%s':" %
388 023e1217 Nikos Skalkotos
                                        choice,
389 023e1217 Nikos Skalkotos
                                        init=session['metadata'][choice],
390 023e1217 Nikos Skalkotos
                                        width=WIDTH)
391 023e1217 Nikos Skalkotos
            if code not in (d.DIALOG_CANCEL, d.DIALOG_ESC):
392 023e1217 Nikos Skalkotos
                value = answer.strip()
393 023e1217 Nikos Skalkotos
                if len(value) == 0:
394 023e1217 Nikos Skalkotos
                    d.msgbox("Value cannot be empty!")
395 023e1217 Nikos Skalkotos
                    continue
396 023e1217 Nikos Skalkotos
                else:
397 023e1217 Nikos Skalkotos
                    session['metadata'][choice] = value
398 023e1217 Nikos Skalkotos
        # ADD button
399 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_EXTRA:
400 023e1217 Nikos Skalkotos
            add_property(session)
401 023e1217 Nikos Skalkotos
        elif code == 'help':
402 023e1217 Nikos Skalkotos
            help_file = get_help_file("image_properties")
403 023e1217 Nikos Skalkotos
            assert os.path.exists(help_file)
404 023e1217 Nikos Skalkotos
            d.textbox(help_file, title="Image Properties", width=70, height=40)
405 023e1217 Nikos Skalkotos
406 023e1217 Nikos Skalkotos
407 023e1217 Nikos Skalkotos
def delete_properties(session):
408 023e1217 Nikos Skalkotos
    d = session['dialog']
409 023e1217 Nikos Skalkotos
410 023e1217 Nikos Skalkotos
    choices = []
411 023e1217 Nikos Skalkotos
    for (key, val) in session['metadata'].items():
412 023e1217 Nikos Skalkotos
        choices.append((key, "%s" % val, 0))
413 023e1217 Nikos Skalkotos
414 023e1217 Nikos Skalkotos
    (code, to_delete) = d.checklist("Choose which properties to delete:",
415 023e1217 Nikos Skalkotos
                                    choices=choices, width=WIDTH)
416 023e1217 Nikos Skalkotos
417 023e1217 Nikos Skalkotos
    # If the user exits with ESC or CANCEL, the returned tag list is empty.
418 023e1217 Nikos Skalkotos
    for i in to_delete:
419 023e1217 Nikos Skalkotos
        del session['metadata'][i]
420 023e1217 Nikos Skalkotos
421 023e1217 Nikos Skalkotos
    cnt = len(to_delete)
422 023e1217 Nikos Skalkotos
    if cnt > 0:
423 023e1217 Nikos Skalkotos
        d.msgbox("%d image properties were deleted." % cnt, width=SMALL_WIDTH)
424 023e1217 Nikos Skalkotos
        return True
425 023e1217 Nikos Skalkotos
    else:
426 023e1217 Nikos Skalkotos
        return False
427 023e1217 Nikos Skalkotos
428 023e1217 Nikos Skalkotos
429 023e1217 Nikos Skalkotos
def exclude_tasks(session):
430 023e1217 Nikos Skalkotos
    d = session['dialog']
431 023e1217 Nikos Skalkotos
432 023e1217 Nikos Skalkotos
    index = 0
433 023e1217 Nikos Skalkotos
    displayed_index = 1
434 023e1217 Nikos Skalkotos
    choices = []
435 023e1217 Nikos Skalkotos
    mapping = {}
436 023e1217 Nikos Skalkotos
    if 'excluded_tasks' not in session:
437 023e1217 Nikos Skalkotos
        session['excluded_tasks'] = []
438 023e1217 Nikos Skalkotos
439 023e1217 Nikos Skalkotos
    if -1 in session['excluded_tasks']:
440 023e1217 Nikos Skalkotos
        if not d.yesno("Image deployment configuration is disabled. "
441 023e1217 Nikos Skalkotos
                       "Do you wish to enable it?", width=SMALL_WIDTH):
442 023e1217 Nikos Skalkotos
            session['excluded_tasks'].remove(-1)
443 023e1217 Nikos Skalkotos
        else:
444 023e1217 Nikos Skalkotos
            return False
445 023e1217 Nikos Skalkotos
446 023e1217 Nikos Skalkotos
    for (msg, task, osfamily) in CONFIGURATION_TASKS:
447 023e1217 Nikos Skalkotos
        if session['metadata']['OSFAMILY'] in osfamily:
448 023e1217 Nikos Skalkotos
            checked = 1 if index in session['excluded_tasks'] else 0
449 023e1217 Nikos Skalkotos
            choices.append((str(displayed_index), msg, checked))
450 023e1217 Nikos Skalkotos
            mapping[displayed_index] = index
451 023e1217 Nikos Skalkotos
            displayed_index += 1
452 023e1217 Nikos Skalkotos
        index += 1
453 023e1217 Nikos Skalkotos
454 023e1217 Nikos Skalkotos
    while 1:
455 023e1217 Nikos Skalkotos
        (code, tags) = d.checklist(
456 023e1217 Nikos Skalkotos
            text="Please choose which configuration tasks you would like to "
457 023e1217 Nikos Skalkotos
                 "prevent from running during image deployment. "
458 023e1217 Nikos Skalkotos
                 "Press <No Config> to supress any configuration. "
459 023e1217 Nikos Skalkotos
                 "Press <Help> for more help on the image deployment "
460 023e1217 Nikos Skalkotos
                 "configuration tasks.",
461 023e1217 Nikos Skalkotos
            choices=choices, height=19, list_height=8, width=WIDTH,
462 023e1217 Nikos Skalkotos
            help_button=1, extra_button=1, extra_label="No Config",
463 023e1217 Nikos Skalkotos
            title="Exclude Configuration Tasks")
464 023e1217 Nikos Skalkotos
465 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
466 023e1217 Nikos Skalkotos
            return False
467 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_HELP:
468 023e1217 Nikos Skalkotos
            help_file = get_help_file("configuration_tasks")
469 023e1217 Nikos Skalkotos
            assert os.path.exists(help_file)
470 023e1217 Nikos Skalkotos
            d.textbox(help_file, title="Configuration Tasks",
471 023e1217 Nikos Skalkotos
                      width=70, height=40)
472 023e1217 Nikos Skalkotos
        # No Config button
473 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_EXTRA:
474 023e1217 Nikos Skalkotos
            session['excluded_tasks'] = [-1]
475 023e1217 Nikos Skalkotos
            session['task_metadata'] = ["EXCLUDE_ALL_TASKS"]
476 023e1217 Nikos Skalkotos
            break
477 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_OK:
478 023e1217 Nikos Skalkotos
            session['excluded_tasks'] = []
479 023e1217 Nikos Skalkotos
            for tag in tags:
480 023e1217 Nikos Skalkotos
                session['excluded_tasks'].append(mapping[int(tag)])
481 023e1217 Nikos Skalkotos
482 023e1217 Nikos Skalkotos
            exclude_metadata = []
483 023e1217 Nikos Skalkotos
            for task in session['excluded_tasks']:
484 023e1217 Nikos Skalkotos
                exclude_metadata.extend(CONFIGURATION_TASKS[task][1])
485 023e1217 Nikos Skalkotos
486 023e1217 Nikos Skalkotos
            session['task_metadata'] = map(lambda x: "EXCLUDE_TASK_%s" % x,
487 023e1217 Nikos Skalkotos
                                           exclude_metadata)
488 023e1217 Nikos Skalkotos
            break
489 023e1217 Nikos Skalkotos
490 023e1217 Nikos Skalkotos
    return True
491 023e1217 Nikos Skalkotos
492 023e1217 Nikos Skalkotos
493 023e1217 Nikos Skalkotos
def sysprep(session):
494 023e1217 Nikos Skalkotos
    d = session['dialog']
495 023e1217 Nikos Skalkotos
    image_os = session['image_os']
496 023e1217 Nikos Skalkotos
497 023e1217 Nikos Skalkotos
    # Is the image already shrinked?
498 023e1217 Nikos Skalkotos
    if 'shrinked' in session and session['shrinked']:
499 023e1217 Nikos Skalkotos
        msg = "It seems you have shrinked the image. Running system " \
500 023e1217 Nikos Skalkotos
              "preparation tasks on a shrinked image is dangerous."
501 023e1217 Nikos Skalkotos
502 023e1217 Nikos Skalkotos
        if d.yesno("%s\n\nDo you really want to continue?" % msg,
503 023e1217 Nikos Skalkotos
                   width=SMALL_WIDTH, defaultno=1):
504 023e1217 Nikos Skalkotos
            return
505 023e1217 Nikos Skalkotos
506 023e1217 Nikos Skalkotos
    wrapper = textwrap.TextWrapper(width=WIDTH - 5)
507 023e1217 Nikos Skalkotos
508 023e1217 Nikos Skalkotos
    help_title = "System Preperation Tasks"
509 023e1217 Nikos Skalkotos
    sysprep_help = "%s\n%s\n\n" % (help_title, '=' * len(help_title))
510 023e1217 Nikos Skalkotos
511 023e1217 Nikos Skalkotos
    if 'exec_syspreps' not in session:
512 023e1217 Nikos Skalkotos
        session['exec_syspreps'] = []
513 023e1217 Nikos Skalkotos
514 023e1217 Nikos Skalkotos
    all_syspreps = image_os.list_syspreps()
515 023e1217 Nikos Skalkotos
    # Only give the user the choice between syspreps that have not ran yet
516 023e1217 Nikos Skalkotos
    syspreps = [s for s in all_syspreps if s not in session['exec_syspreps']]
517 023e1217 Nikos Skalkotos
518 023e1217 Nikos Skalkotos
    if len(syspreps) == 0:
519 023e1217 Nikos Skalkotos
        d.msgbox("No system preparation task available to run!",
520 023e1217 Nikos Skalkotos
                 title="System Preperation", width=SMALL_WIDTH)
521 023e1217 Nikos Skalkotos
        return
522 023e1217 Nikos Skalkotos
523 023e1217 Nikos Skalkotos
    while 1:
524 023e1217 Nikos Skalkotos
        choices = []
525 023e1217 Nikos Skalkotos
        index = 0
526 023e1217 Nikos Skalkotos
        for sysprep in syspreps:
527 023e1217 Nikos Skalkotos
            name, descr = image_os.sysprep_info(sysprep)
528 023e1217 Nikos Skalkotos
            display_name = name.replace('-', ' ').capitalize()
529 023e1217 Nikos Skalkotos
            sysprep_help += "%s\n" % display_name
530 023e1217 Nikos Skalkotos
            sysprep_help += "%s\n" % ('-' * len(display_name))
531 023e1217 Nikos Skalkotos
            sysprep_help += "%s\n\n" % wrapper.fill(" ".join(descr.split()))
532 023e1217 Nikos Skalkotos
            enabled = 1 if sysprep.enabled else 0
533 023e1217 Nikos Skalkotos
            choices.append((str(index + 1), display_name, enabled))
534 023e1217 Nikos Skalkotos
            index += 1
535 023e1217 Nikos Skalkotos
536 023e1217 Nikos Skalkotos
        (code, tags) = d.checklist(
537 023e1217 Nikos Skalkotos
            "Please choose which system preparation tasks you would like to "
538 023e1217 Nikos Skalkotos
            "run on the image. Press <Help> to see details about the system "
539 023e1217 Nikos Skalkotos
            "preparation tasks.", title="Run system preparation tasks",
540 023e1217 Nikos Skalkotos
            choices=choices, width=70, ok_label="Run", help_button=1)
541 023e1217 Nikos Skalkotos
542 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
543 023e1217 Nikos Skalkotos
            return False
544 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_HELP:
545 023e1217 Nikos Skalkotos
            d.scrollbox(sysprep_help, width=WIDTH)
546 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_OK:
547 023e1217 Nikos Skalkotos
            # Enable selected syspreps and disable the rest
548 023e1217 Nikos Skalkotos
            for i in range(len(syspreps)):
549 023e1217 Nikos Skalkotos
                if str(i + 1) in tags:
550 023e1217 Nikos Skalkotos
                    image_os.enable_sysprep(syspreps[i])
551 023e1217 Nikos Skalkotos
                    session['exec_syspreps'].append(syspreps[i])
552 023e1217 Nikos Skalkotos
                else:
553 023e1217 Nikos Skalkotos
                    image_os.disable_sysprep(syspreps[i])
554 023e1217 Nikos Skalkotos
555 023e1217 Nikos Skalkotos
            infobox = InfoBoxOutput(d, "Image Configuration")
556 023e1217 Nikos Skalkotos
            try:
557 023e1217 Nikos Skalkotos
                dev = session['device']
558 023e1217 Nikos Skalkotos
                dev.out.add(infobox)
559 023e1217 Nikos Skalkotos
                try:
560 023e1217 Nikos Skalkotos
                    dev.mount(readonly=False)
561 023e1217 Nikos Skalkotos
                    try:
562 023e1217 Nikos Skalkotos
                        # The checksum is invalid. We have mounted the image rw
563 023e1217 Nikos Skalkotos
                        if 'checksum' in session:
564 023e1217 Nikos Skalkotos
                            del session['checksum']
565 023e1217 Nikos Skalkotos
566 023e1217 Nikos Skalkotos
                        # Monitor the metadata changes during syspreps
567 023e1217 Nikos Skalkotos
                        with metadata_monitor(session, image_os.meta):
568 023e1217 Nikos Skalkotos
                            image_os.do_sysprep()
569 023e1217 Nikos Skalkotos
                            infobox.finalize()
570 023e1217 Nikos Skalkotos
571 023e1217 Nikos Skalkotos
                        # Disable syspreps that have ran
572 023e1217 Nikos Skalkotos
                        for sysprep in session['exec_syspreps']:
573 023e1217 Nikos Skalkotos
                            image_os.disable_sysprep(sysprep)
574 023e1217 Nikos Skalkotos
                    finally:
575 023e1217 Nikos Skalkotos
                        dev.umount()
576 023e1217 Nikos Skalkotos
                finally:
577 023e1217 Nikos Skalkotos
                    dev.out.remove(infobox)
578 023e1217 Nikos Skalkotos
            finally:
579 023e1217 Nikos Skalkotos
                infobox.cleanup()
580 023e1217 Nikos Skalkotos
            break
581 023e1217 Nikos Skalkotos
    return True
582 023e1217 Nikos Skalkotos
583 023e1217 Nikos Skalkotos
584 023e1217 Nikos Skalkotos
def shrink(session):
585 023e1217 Nikos Skalkotos
    d = session['dialog']
586 023e1217 Nikos Skalkotos
    dev = session['device']
587 023e1217 Nikos Skalkotos
588 023e1217 Nikos Skalkotos
    shrinked = 'shrinked' in session and session['shrinked']
589 023e1217 Nikos Skalkotos
590 023e1217 Nikos Skalkotos
    if shrinked:
591 023e1217 Nikos Skalkotos
        d.msgbox("The image is already shrinked!", title="Image Shrinking",
592 023e1217 Nikos Skalkotos
                 width=SMALL_WIDTH)
593 023e1217 Nikos Skalkotos
        return True
594 023e1217 Nikos Skalkotos
595 023e1217 Nikos Skalkotos
    msg = "This operation will shrink the last partition of the image to " \
596 023e1217 Nikos Skalkotos
          "reduce the total image size. If the last partition is a swap " \
597 023e1217 Nikos Skalkotos
          "partition, then this partition is removed and the partition " \
598 023e1217 Nikos Skalkotos
          "before that is shrinked. The removed swap partition will be " \
599 023e1217 Nikos Skalkotos
          "recreated during image deployment."
600 023e1217 Nikos Skalkotos
601 023e1217 Nikos Skalkotos
    if not d.yesno("%s\n\nDo you want to continue?" % msg, width=WIDTH,
602 023e1217 Nikos Skalkotos
                   height=12, title="Image Shrinking"):
603 023e1217 Nikos Skalkotos
        with metadata_monitor(session, dev.meta):
604 023e1217 Nikos Skalkotos
            infobox = InfoBoxOutput(d, "Image Shrinking", height=4)
605 023e1217 Nikos Skalkotos
            dev.out.add(infobox)
606 023e1217 Nikos Skalkotos
            try:
607 023e1217 Nikos Skalkotos
                dev.shrink()
608 023e1217 Nikos Skalkotos
                infobox.finalize()
609 023e1217 Nikos Skalkotos
            finally:
610 023e1217 Nikos Skalkotos
                dev.out.remove(infobox)
611 023e1217 Nikos Skalkotos
612 023e1217 Nikos Skalkotos
        session['shrinked'] = True
613 023e1217 Nikos Skalkotos
        update_background_title(session)
614 023e1217 Nikos Skalkotos
    else:
615 023e1217 Nikos Skalkotos
        return False
616 023e1217 Nikos Skalkotos
617 023e1217 Nikos Skalkotos
    return True
618 023e1217 Nikos Skalkotos
619 023e1217 Nikos Skalkotos
620 023e1217 Nikos Skalkotos
def customization_menu(session):
621 023e1217 Nikos Skalkotos
    d = session['dialog']
622 023e1217 Nikos Skalkotos
623 023e1217 Nikos Skalkotos
    choices = [("Sysprep", "Run various image preparation tasks"),
624 023e1217 Nikos Skalkotos
               ("Shrink", "Shrink image"),
625 023e1217 Nikos Skalkotos
               ("View/Modify", "View/Modify image properties"),
626 023e1217 Nikos Skalkotos
               ("Delete", "Delete image properties"),
627 023e1217 Nikos Skalkotos
               ("Exclude", "Exclude various deployment tasks from running")]
628 023e1217 Nikos Skalkotos
629 023e1217 Nikos Skalkotos
    default_item = 0
630 023e1217 Nikos Skalkotos
631 023e1217 Nikos Skalkotos
    actions = {"Sysprep": sysprep,
632 023e1217 Nikos Skalkotos
               "Shrink": shrink,
633 023e1217 Nikos Skalkotos
               "View/Modify": modify_properties,
634 023e1217 Nikos Skalkotos
               "Delete": delete_properties,
635 023e1217 Nikos Skalkotos
               "Exclude": exclude_tasks}
636 023e1217 Nikos Skalkotos
    while 1:
637 023e1217 Nikos Skalkotos
        (code, choice) = d.menu(
638 023e1217 Nikos Skalkotos
            text="Choose one of the following or press <Back> to exit.",
639 023e1217 Nikos Skalkotos
            width=WIDTH, choices=choices, cancel="Back", height=13,
640 023e1217 Nikos Skalkotos
            menu_height=len(choices), default_item=choices[default_item][0],
641 023e1217 Nikos Skalkotos
            title="Image Customization Menu")
642 023e1217 Nikos Skalkotos
643 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
644 023e1217 Nikos Skalkotos
            break
645 023e1217 Nikos Skalkotos
        elif choice in actions:
646 023e1217 Nikos Skalkotos
            default_item = [entry[0] for entry in choices].index(choice)
647 023e1217 Nikos Skalkotos
            if actions[choice](session):
648 023e1217 Nikos Skalkotos
                default_item = (default_item + 1) % len(choices)
649 023e1217 Nikos Skalkotos
650 023e1217 Nikos Skalkotos
651 023e1217 Nikos Skalkotos
def main_menu(session):
652 023e1217 Nikos Skalkotos
    d = session['dialog']
653 023e1217 Nikos Skalkotos
    dev = session['device']
654 023e1217 Nikos Skalkotos
655 023e1217 Nikos Skalkotos
    update_background_title(session)
656 023e1217 Nikos Skalkotos
657 023e1217 Nikos Skalkotos
    choices = [("Customize", "Customize image & ~okeanos deployment options"),
658 023e1217 Nikos Skalkotos
               ("Register", "Register image to ~okeanos"),
659 023e1217 Nikos Skalkotos
               ("Extract", "Dump image to local file system"),
660 023e1217 Nikos Skalkotos
               ("Reset", "Reset everything and start over again"),
661 023e1217 Nikos Skalkotos
               ("Help", "Get help for using snf-image-creator")]
662 023e1217 Nikos Skalkotos
663 023e1217 Nikos Skalkotos
    default_item = "Customize"
664 023e1217 Nikos Skalkotos
665 023e1217 Nikos Skalkotos
    actions = {"Customize": customization_menu, "Register": kamaki_menu,
666 023e1217 Nikos Skalkotos
               "Extract": extract_image}
667 023e1217 Nikos Skalkotos
    while 1:
668 023e1217 Nikos Skalkotos
        (code, choice) = d.menu(
669 023e1217 Nikos Skalkotos
            text="Choose one of the following or press <Exit> to exit.",
670 023e1217 Nikos Skalkotos
            width=WIDTH, choices=choices, cancel="Exit", height=13,
671 023e1217 Nikos Skalkotos
            default_item=default_item, menu_height=len(choices),
672 023e1217 Nikos Skalkotos
            title="Image Creator for ~okeanos (snf-image-creator version %s)" %
673 023e1217 Nikos Skalkotos
                  version)
674 023e1217 Nikos Skalkotos
675 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
676 023e1217 Nikos Skalkotos
            if confirm_exit(d):
677 023e1217 Nikos Skalkotos
                break
678 023e1217 Nikos Skalkotos
        elif choice == "Reset":
679 023e1217 Nikos Skalkotos
            if confirm_reset(d):
680 023e1217 Nikos Skalkotos
                d.infobox("Resetting snf-image-creator. Please wait...",
681 023e1217 Nikos Skalkotos
                          width=SMALL_WIDTH)
682 023e1217 Nikos Skalkotos
                raise Reset
683 023e1217 Nikos Skalkotos
        elif choice in actions:
684 023e1217 Nikos Skalkotos
            actions[choice](session)
685 023e1217 Nikos Skalkotos
686 023e1217 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :