Statistics
| Branch: | Tag: | Revision:

root / image_creator / dialog_menu.py @ 71b0ab28

History | View | Annotate | Download (25.3 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 os
37 023e1217 Nikos Skalkotos
import textwrap
38 023e1217 Nikos Skalkotos
import StringIO
39 023e1217 Nikos Skalkotos
40 023e1217 Nikos Skalkotos
from image_creator import __version__ as version
41 71b0ab28 Nikos Skalkotos
from image_creator.util import MD5, FatalError
42 023e1217 Nikos Skalkotos
from image_creator.output.dialog import GaugeOutput, InfoBoxOutput
43 023e1217 Nikos Skalkotos
from image_creator.kamaki_wrapper import Kamaki, ClientError
44 023e1217 Nikos Skalkotos
from image_creator.help import get_help_file
45 023e1217 Nikos Skalkotos
from image_creator.dialog_util import SMALL_WIDTH, WIDTH, \
46 0a116b9d Nikos Skalkotos
    update_background_title, confirm_reset, confirm_exit, Reset, \
47 0a116b9d Nikos Skalkotos
    extract_image, extract_metadata_string
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 61d14323 Nikos Skalkotos
class MetadataMonitor(object):
68 88f83027 Nikos Skalkotos
    """Monitors image metadata chages"""
69 023e1217 Nikos Skalkotos
    def __init__(self, session, meta):
70 023e1217 Nikos Skalkotos
        self.session = session
71 023e1217 Nikos Skalkotos
        self.meta = meta
72 023e1217 Nikos Skalkotos
73 023e1217 Nikos Skalkotos
    def __enter__(self):
74 023e1217 Nikos Skalkotos
        self.old = {}
75 023e1217 Nikos Skalkotos
        for (k, v) in self.meta.items():
76 023e1217 Nikos Skalkotos
            self.old[k] = v
77 023e1217 Nikos Skalkotos
78 023e1217 Nikos Skalkotos
    def __exit__(self, type, value, traceback):
79 023e1217 Nikos Skalkotos
        d = self.session['dialog']
80 023e1217 Nikos Skalkotos
81 023e1217 Nikos Skalkotos
        altered = {}
82 023e1217 Nikos Skalkotos
        added = {}
83 023e1217 Nikos Skalkotos
84 023e1217 Nikos Skalkotos
        for (k, v) in self.meta.items():
85 023e1217 Nikos Skalkotos
            if k not in self.old:
86 023e1217 Nikos Skalkotos
                added[k] = v
87 023e1217 Nikos Skalkotos
            elif self.old[k] != v:
88 023e1217 Nikos Skalkotos
                altered[k] = v
89 023e1217 Nikos Skalkotos
90 023e1217 Nikos Skalkotos
        if not (len(added) or len(altered)):
91 023e1217 Nikos Skalkotos
            return
92 023e1217 Nikos Skalkotos
93 023e1217 Nikos Skalkotos
        msg = "The last action has changed some image properties:\n\n"
94 023e1217 Nikos Skalkotos
        if len(added):
95 023e1217 Nikos Skalkotos
            msg += "New image properties:\n"
96 023e1217 Nikos Skalkotos
            for (k, v) in added.items():
97 023e1217 Nikos Skalkotos
                msg += '    %s: "%s"\n' % (k, v)
98 023e1217 Nikos Skalkotos
            msg += "\n"
99 023e1217 Nikos Skalkotos
        if len(altered):
100 023e1217 Nikos Skalkotos
            msg += "Updated image properties:\n"
101 023e1217 Nikos Skalkotos
            for (k, v) in altered.items():
102 023e1217 Nikos Skalkotos
                msg += '    %s: "%s" -> "%s"\n' % (k, self.old[k], v)
103 023e1217 Nikos Skalkotos
            msg += "\n"
104 023e1217 Nikos Skalkotos
105 023e1217 Nikos Skalkotos
        self.session['metadata'].update(added)
106 023e1217 Nikos Skalkotos
        self.session['metadata'].update(altered)
107 023e1217 Nikos Skalkotos
        d.msgbox(msg, title="Image Property Changes", width=SMALL_WIDTH)
108 023e1217 Nikos Skalkotos
109 023e1217 Nikos Skalkotos
110 023e1217 Nikos Skalkotos
def upload_image(session):
111 88f83027 Nikos Skalkotos
    """Upload the image to pithos+"""
112 023e1217 Nikos Skalkotos
    d = session["dialog"]
113 f5174d2c Nikos Skalkotos
    image = session['image']
114 66719e36 Nikos Skalkotos
    meta = session['metadata']
115 f5174d2c Nikos Skalkotos
    size = image.size
116 023e1217 Nikos Skalkotos
117 023e1217 Nikos Skalkotos
    if "account" not in session:
118 66719e36 Nikos Skalkotos
        d.msgbox("You need to provide your ~okeanos credentials before you "
119 023e1217 Nikos Skalkotos
                 "can upload images to pithos+", width=SMALL_WIDTH)
120 023e1217 Nikos Skalkotos
        return False
121 023e1217 Nikos Skalkotos
122 023e1217 Nikos Skalkotos
    while 1:
123 66719e36 Nikos Skalkotos
        if 'upload' in session:
124 66719e36 Nikos Skalkotos
            init = session['upload']
125 66719e36 Nikos Skalkotos
        elif 'OS' in meta:
126 66719e36 Nikos Skalkotos
            init = "%s.diskdump" % meta['OS']
127 66719e36 Nikos Skalkotos
        else:
128 66719e36 Nikos Skalkotos
            init = ""
129 023e1217 Nikos Skalkotos
        (code, answer) = d.inputbox("Please provide a filename:", init=init,
130 023e1217 Nikos Skalkotos
                                    width=WIDTH)
131 023e1217 Nikos Skalkotos
132 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
133 023e1217 Nikos Skalkotos
            return False
134 023e1217 Nikos Skalkotos
135 023e1217 Nikos Skalkotos
        filename = answer.strip()
136 023e1217 Nikos Skalkotos
        if len(filename) == 0:
137 023e1217 Nikos Skalkotos
            d.msgbox("Filename cannot be empty", width=SMALL_WIDTH)
138 023e1217 Nikos Skalkotos
            continue
139 03eb7dc8 Nikos Skalkotos
140 03eb7dc8 Nikos Skalkotos
        kamaki = Kamaki(session['account'], None)
141 03eb7dc8 Nikos Skalkotos
        overwrite = []
142 03eb7dc8 Nikos Skalkotos
        for f in (filename, "%s.md5sum" % filename, "%s.meta" % filename):
143 03eb7dc8 Nikos Skalkotos
            if kamaki.object_exists(f):
144 03eb7dc8 Nikos Skalkotos
                overwrite.append(f)
145 03eb7dc8 Nikos Skalkotos
146 03eb7dc8 Nikos Skalkotos
        if len(overwrite) > 0:
147 03eb7dc8 Nikos Skalkotos
            if d.yesno("The following pithos object(s) already exist(s):\n"
148 03eb7dc8 Nikos Skalkotos
                       "%s\nDo you want to overwrite them?" %
149 03eb7dc8 Nikos Skalkotos
                       "\n".join(overwrite), width=WIDTH, defaultno=1):
150 03eb7dc8 Nikos Skalkotos
                continue
151 03eb7dc8 Nikos Skalkotos
152 023e1217 Nikos Skalkotos
        session['upload'] = filename
153 023e1217 Nikos Skalkotos
        break
154 023e1217 Nikos Skalkotos
155 023e1217 Nikos Skalkotos
    gauge = GaugeOutput(d, "Image Upload", "Uploading...")
156 023e1217 Nikos Skalkotos
    try:
157 f5174d2c Nikos Skalkotos
        out = image.out
158 023e1217 Nikos Skalkotos
        out.add(gauge)
159 03eb7dc8 Nikos Skalkotos
        kamaki.out = out
160 023e1217 Nikos Skalkotos
        try:
161 023e1217 Nikos Skalkotos
            if 'checksum' not in session:
162 023e1217 Nikos Skalkotos
                md5 = MD5(out)
163 f5174d2c Nikos Skalkotos
                session['checksum'] = md5.compute(image.device, size)
164 023e1217 Nikos Skalkotos
165 023e1217 Nikos Skalkotos
            try:
166 023e1217 Nikos Skalkotos
                # Upload image file
167 f5174d2c Nikos Skalkotos
                with open(image.device, 'rb') as f:
168 023e1217 Nikos Skalkotos
                    session["pithos_uri"] = \
169 023e1217 Nikos Skalkotos
                        kamaki.upload(f, size, filename,
170 023e1217 Nikos Skalkotos
                                      "Calculating block hashes",
171 023e1217 Nikos Skalkotos
                                      "Uploading missing blocks")
172 023e1217 Nikos Skalkotos
                # Upload md5sum file
173 023e1217 Nikos Skalkotos
                out.output("Uploading md5sum file...")
174 023e1217 Nikos Skalkotos
                md5str = "%s %s\n" % (session['checksum'], filename)
175 023e1217 Nikos Skalkotos
                kamaki.upload(StringIO.StringIO(md5str), size=len(md5str),
176 023e1217 Nikos Skalkotos
                              remote_path="%s.md5sum" % filename)
177 023e1217 Nikos Skalkotos
                out.success("done")
178 023e1217 Nikos Skalkotos
179 023e1217 Nikos Skalkotos
            except ClientError as e:
180 023e1217 Nikos Skalkotos
                d.msgbox("Error in pithos+ client: %s" % e.message,
181 023e1217 Nikos Skalkotos
                         title="Pithos+ Client Error", width=SMALL_WIDTH)
182 023e1217 Nikos Skalkotos
                if 'pithos_uri' in session:
183 023e1217 Nikos Skalkotos
                    del session['pithos_uri']
184 023e1217 Nikos Skalkotos
                return False
185 023e1217 Nikos Skalkotos
        finally:
186 023e1217 Nikos Skalkotos
            out.remove(gauge)
187 023e1217 Nikos Skalkotos
    finally:
188 023e1217 Nikos Skalkotos
        gauge.cleanup()
189 023e1217 Nikos Skalkotos
190 023e1217 Nikos Skalkotos
    d.msgbox("Image file `%s' was successfully uploaded to pithos+" % filename,
191 023e1217 Nikos Skalkotos
             width=SMALL_WIDTH)
192 023e1217 Nikos Skalkotos
193 023e1217 Nikos Skalkotos
    return True
194 023e1217 Nikos Skalkotos
195 023e1217 Nikos Skalkotos
196 023e1217 Nikos Skalkotos
def register_image(session):
197 88f83027 Nikos Skalkotos
    """Register image with cyclades"""
198 023e1217 Nikos Skalkotos
    d = session["dialog"]
199 023e1217 Nikos Skalkotos
200 37d581b8 Nikos Skalkotos
    is_public = False
201 37d581b8 Nikos Skalkotos
202 023e1217 Nikos Skalkotos
    if "account" not in session:
203 37d581b8 Nikos Skalkotos
        d.msgbox("You need to provide your ~okeanos credentians before you "
204 f5174d2c Nikos Skalkotos
                 "can register an images with cyclades", width=SMALL_WIDTH)
205 023e1217 Nikos Skalkotos
        return False
206 023e1217 Nikos Skalkotos
207 023e1217 Nikos Skalkotos
    if "pithos_uri" not in session:
208 023e1217 Nikos Skalkotos
        d.msgbox("You need to upload the image to pithos+ before you can "
209 aa486e93 Nikos Skalkotos
                 "register it with cyclades", width=SMALL_WIDTH)
210 023e1217 Nikos Skalkotos
        return False
211 023e1217 Nikos Skalkotos
212 023e1217 Nikos Skalkotos
    while 1:
213 023e1217 Nikos Skalkotos
        (code, answer) = d.inputbox("Please provide a registration name:",
214 023e1217 Nikos Skalkotos
                                    width=WIDTH)
215 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
216 023e1217 Nikos Skalkotos
            return False
217 023e1217 Nikos Skalkotos
218 023e1217 Nikos Skalkotos
        name = answer.strip()
219 023e1217 Nikos Skalkotos
        if len(name) == 0:
220 023e1217 Nikos Skalkotos
            d.msgbox("Registration name cannot be empty", width=SMALL_WIDTH)
221 023e1217 Nikos Skalkotos
            continue
222 37d581b8 Nikos Skalkotos
223 66719e36 Nikos Skalkotos
        ret = d.yesno("Make the image public?\\nA public image is accessible "
224 37d581b8 Nikos Skalkotos
                      "by every user of the service.", defaultno=1,
225 37d581b8 Nikos Skalkotos
                      width=WIDTH)
226 37d581b8 Nikos Skalkotos
        if ret not in (0, 1):
227 37d581b8 Nikos Skalkotos
            continue
228 37d581b8 Nikos Skalkotos
229 37d581b8 Nikos Skalkotos
        is_public = True if ret == 0 else False
230 37d581b8 Nikos Skalkotos
231 023e1217 Nikos Skalkotos
        break
232 023e1217 Nikos Skalkotos
233 023e1217 Nikos Skalkotos
    metadata = {}
234 023e1217 Nikos Skalkotos
    metadata.update(session['metadata'])
235 023e1217 Nikos Skalkotos
    if 'task_metadata' in session:
236 023e1217 Nikos Skalkotos
        for key in session['task_metadata']:
237 023e1217 Nikos Skalkotos
            metadata[key] = 'yes'
238 023e1217 Nikos Skalkotos
239 37d581b8 Nikos Skalkotos
    img_type = "public" if is_public else "private"
240 023e1217 Nikos Skalkotos
    gauge = GaugeOutput(d, "Image Registration", "Registering image...")
241 023e1217 Nikos Skalkotos
    try:
242 f5174d2c Nikos Skalkotos
        out = session['image'].out
243 023e1217 Nikos Skalkotos
        out.add(gauge)
244 023e1217 Nikos Skalkotos
        try:
245 023e1217 Nikos Skalkotos
            try:
246 03eb7dc8 Nikos Skalkotos
                out.output("Registering %s image with Cyclades..." % img_type)
247 31160dc8 Nikos Skalkotos
                kamaki = Kamaki(session['account'], out)
248 37d581b8 Nikos Skalkotos
                kamaki.register(name, session['pithos_uri'], metadata,
249 37d581b8 Nikos Skalkotos
                                is_public)
250 023e1217 Nikos Skalkotos
                out.success('done')
251 03eb7dc8 Nikos Skalkotos
                # Upload metadata file
252 03eb7dc8 Nikos Skalkotos
                out.output("Uploading metadata file...")
253 03eb7dc8 Nikos Skalkotos
                metastring = extract_metadata_string(session)
254 03eb7dc8 Nikos Skalkotos
                kamaki.upload(StringIO.StringIO(metastring),
255 03eb7dc8 Nikos Skalkotos
                              size=len(metastring),
256 03eb7dc8 Nikos Skalkotos
                              remote_path="%s.meta" % session['upload'])
257 03eb7dc8 Nikos Skalkotos
                out.success("done")
258 3afe6b44 Nikos Skalkotos
                if is_public:
259 3afe6b44 Nikos Skalkotos
                    out.output("Sharing metadata and md5sum files...")
260 3afe6b44 Nikos Skalkotos
                    kamaki.share("%s.meta" % session['upload'])
261 3afe6b44 Nikos Skalkotos
                    kamaki.share("%s.md5sum" % session['upload'])
262 3afe6b44 Nikos Skalkotos
                    out.success('done')
263 023e1217 Nikos Skalkotos
            except ClientError as e:
264 023e1217 Nikos Skalkotos
                d.msgbox("Error in pithos+ client: %s" % e.message)
265 023e1217 Nikos Skalkotos
                return False
266 023e1217 Nikos Skalkotos
        finally:
267 023e1217 Nikos Skalkotos
            out.remove(gauge)
268 023e1217 Nikos Skalkotos
    finally:
269 023e1217 Nikos Skalkotos
        gauge.cleanup()
270 023e1217 Nikos Skalkotos
271 37d581b8 Nikos Skalkotos
    d.msgbox("%s image `%s' was successfully registered with Cyclades as `%s'"
272 37d581b8 Nikos Skalkotos
             % (img_type.title(), session['upload'], name), width=SMALL_WIDTH)
273 023e1217 Nikos Skalkotos
    return True
274 023e1217 Nikos Skalkotos
275 023e1217 Nikos Skalkotos
276 023e1217 Nikos Skalkotos
def kamaki_menu(session):
277 88f83027 Nikos Skalkotos
    """Show kamaki related actions"""
278 023e1217 Nikos Skalkotos
    d = session['dialog']
279 023e1217 Nikos Skalkotos
    default_item = "Account"
280 023e1217 Nikos Skalkotos
281 31160dc8 Nikos Skalkotos
    if 'account' not in session:
282 31160dc8 Nikos Skalkotos
        token = Kamaki.get_token()
283 31160dc8 Nikos Skalkotos
        if token:
284 31160dc8 Nikos Skalkotos
            session['account'] = Kamaki.get_account(token)
285 31160dc8 Nikos Skalkotos
            if not session['account']:
286 31160dc8 Nikos Skalkotos
                del session['account']
287 31160dc8 Nikos Skalkotos
                Kamaki.save_token('')  # The token was not valid. Remove it
288 023e1217 Nikos Skalkotos
289 023e1217 Nikos Skalkotos
    while 1:
290 31160dc8 Nikos Skalkotos
        account = session["account"]['username'] if "account" in session else \
291 31160dc8 Nikos Skalkotos
            "<none>"
292 023e1217 Nikos Skalkotos
        upload = session["upload"] if "upload" in session else "<none>"
293 023e1217 Nikos Skalkotos
294 31160dc8 Nikos Skalkotos
        choices = [("Account", "Change your ~okeanos account: %s" % account),
295 023e1217 Nikos Skalkotos
                   ("Upload", "Upload image to pithos+"),
296 023e1217 Nikos Skalkotos
                   ("Register", "Register the image to cyclades: %s" % upload)]
297 023e1217 Nikos Skalkotos
298 023e1217 Nikos Skalkotos
        (code, choice) = d.menu(
299 023e1217 Nikos Skalkotos
            text="Choose one of the following or press <Back> to go back.",
300 023e1217 Nikos Skalkotos
            width=WIDTH, choices=choices, cancel="Back", height=13,
301 023e1217 Nikos Skalkotos
            menu_height=5, default_item=default_item,
302 023e1217 Nikos Skalkotos
            title="Image Registration Menu")
303 023e1217 Nikos Skalkotos
304 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
305 023e1217 Nikos Skalkotos
            return False
306 023e1217 Nikos Skalkotos
307 023e1217 Nikos Skalkotos
        if choice == "Account":
308 023e1217 Nikos Skalkotos
            default_item = "Account"
309 023e1217 Nikos Skalkotos
            (code, answer) = d.inputbox(
310 66719e36 Nikos Skalkotos
                "Please provide your ~okeanos authentication token:",
311 31160dc8 Nikos Skalkotos
                init=session["account"]['auth_token'] if "account" in session
312 31160dc8 Nikos Skalkotos
                else '', width=WIDTH)
313 023e1217 Nikos Skalkotos
            if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
314 023e1217 Nikos Skalkotos
                continue
315 023e1217 Nikos Skalkotos
            if len(answer) == 0 and "account" in session:
316 023e1217 Nikos Skalkotos
                    del session["account"]
317 023e1217 Nikos Skalkotos
            else:
318 31160dc8 Nikos Skalkotos
                token = answer.strip()
319 31160dc8 Nikos Skalkotos
                session['account'] = Kamaki.get_account(token)
320 31160dc8 Nikos Skalkotos
                if session['account'] is not None:
321 31160dc8 Nikos Skalkotos
                    Kamaki.save_token(token)
322 31160dc8 Nikos Skalkotos
                    default_item = "Upload"
323 31160dc8 Nikos Skalkotos
                else:
324 31160dc8 Nikos Skalkotos
                    del session['account']
325 31160dc8 Nikos Skalkotos
                    d.msgbox("The token you provided is not valid!",
326 37d581b8 Nikos Skalkotos
                             width=SMALL_WIDTH)
327 023e1217 Nikos Skalkotos
        elif choice == "Upload":
328 023e1217 Nikos Skalkotos
            if upload_image(session):
329 023e1217 Nikos Skalkotos
                default_item = "Register"
330 023e1217 Nikos Skalkotos
            else:
331 023e1217 Nikos Skalkotos
                default_item = "Upload"
332 023e1217 Nikos Skalkotos
        elif choice == "Register":
333 023e1217 Nikos Skalkotos
            if register_image(session):
334 023e1217 Nikos Skalkotos
                return True
335 023e1217 Nikos Skalkotos
            else:
336 023e1217 Nikos Skalkotos
                default_item = "Register"
337 023e1217 Nikos Skalkotos
338 023e1217 Nikos Skalkotos
339 023e1217 Nikos Skalkotos
def add_property(session):
340 88f83027 Nikos Skalkotos
    """Add a new property to the image"""
341 023e1217 Nikos Skalkotos
    d = session['dialog']
342 023e1217 Nikos Skalkotos
343 023e1217 Nikos Skalkotos
    while 1:
344 023e1217 Nikos Skalkotos
        (code, answer) = d.inputbox("Please provide a name for a new image"
345 023e1217 Nikos Skalkotos
                                    " property:", width=WIDTH)
346 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
347 023e1217 Nikos Skalkotos
            return False
348 023e1217 Nikos Skalkotos
349 023e1217 Nikos Skalkotos
        name = answer.strip()
350 023e1217 Nikos Skalkotos
        if len(name) == 0:
351 023e1217 Nikos Skalkotos
            d.msgbox("A property name cannot be empty", width=SMALL_WIDTH)
352 023e1217 Nikos Skalkotos
            continue
353 023e1217 Nikos Skalkotos
354 023e1217 Nikos Skalkotos
        break
355 023e1217 Nikos Skalkotos
356 023e1217 Nikos Skalkotos
    while 1:
357 023e1217 Nikos Skalkotos
        (code, answer) = d.inputbox("Please provide a value for image "
358 023e1217 Nikos Skalkotos
                                    "property %s" % name, width=WIDTH)
359 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
360 023e1217 Nikos Skalkotos
            return False
361 023e1217 Nikos Skalkotos
362 023e1217 Nikos Skalkotos
        value = answer.strip()
363 023e1217 Nikos Skalkotos
        if len(value) == 0:
364 023e1217 Nikos Skalkotos
            d.msgbox("Value cannot be empty", width=SMALL_WIDTH)
365 023e1217 Nikos Skalkotos
            continue
366 023e1217 Nikos Skalkotos
367 023e1217 Nikos Skalkotos
        break
368 023e1217 Nikos Skalkotos
369 023e1217 Nikos Skalkotos
    session['metadata'][name] = value
370 023e1217 Nikos Skalkotos
371 023e1217 Nikos Skalkotos
    return True
372 023e1217 Nikos Skalkotos
373 023e1217 Nikos Skalkotos
374 023e1217 Nikos Skalkotos
def modify_properties(session):
375 88f83027 Nikos Skalkotos
    """Modify an existing image property"""
376 023e1217 Nikos Skalkotos
    d = session['dialog']
377 023e1217 Nikos Skalkotos
378 023e1217 Nikos Skalkotos
    while 1:
379 023e1217 Nikos Skalkotos
        choices = []
380 023e1217 Nikos Skalkotos
        for (key, val) in session['metadata'].items():
381 023e1217 Nikos Skalkotos
            choices.append((str(key), str(val)))
382 023e1217 Nikos Skalkotos
383 023e1217 Nikos Skalkotos
        (code, choice) = d.menu(
384 023e1217 Nikos Skalkotos
            "In this menu you can edit existing image properties or add new "
385 023e1217 Nikos Skalkotos
            "ones. Be careful! Most properties have special meaning and "
386 023e1217 Nikos Skalkotos
            "alter the image deployment behaviour. Press <HELP> to see more "
387 023e1217 Nikos Skalkotos
            "information about image properties. Press <BACK> when done.",
388 023e1217 Nikos Skalkotos
            height=18, width=WIDTH, choices=choices, menu_height=10,
389 023e1217 Nikos Skalkotos
            ok_label="Edit", extra_button=1, extra_label="Add", cancel="Back",
390 023e1217 Nikos Skalkotos
            help_button=1, title="Image Properties")
391 023e1217 Nikos Skalkotos
392 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
393 023e1217 Nikos Skalkotos
            return True
394 023e1217 Nikos Skalkotos
        # Edit button
395 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_OK:
396 023e1217 Nikos Skalkotos
            (code, answer) = d.inputbox("Please provide a new value for the "
397 023e1217 Nikos Skalkotos
                                        "image property with name `%s':" %
398 023e1217 Nikos Skalkotos
                                        choice,
399 023e1217 Nikos Skalkotos
                                        init=session['metadata'][choice],
400 023e1217 Nikos Skalkotos
                                        width=WIDTH)
401 023e1217 Nikos Skalkotos
            if code not in (d.DIALOG_CANCEL, d.DIALOG_ESC):
402 023e1217 Nikos Skalkotos
                value = answer.strip()
403 023e1217 Nikos Skalkotos
                if len(value) == 0:
404 023e1217 Nikos Skalkotos
                    d.msgbox("Value cannot be empty!")
405 023e1217 Nikos Skalkotos
                    continue
406 023e1217 Nikos Skalkotos
                else:
407 023e1217 Nikos Skalkotos
                    session['metadata'][choice] = value
408 023e1217 Nikos Skalkotos
        # ADD button
409 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_EXTRA:
410 023e1217 Nikos Skalkotos
            add_property(session)
411 023e1217 Nikos Skalkotos
        elif code == 'help':
412 023e1217 Nikos Skalkotos
            help_file = get_help_file("image_properties")
413 023e1217 Nikos Skalkotos
            assert os.path.exists(help_file)
414 023e1217 Nikos Skalkotos
            d.textbox(help_file, title="Image Properties", width=70, height=40)
415 023e1217 Nikos Skalkotos
416 023e1217 Nikos Skalkotos
417 023e1217 Nikos Skalkotos
def delete_properties(session):
418 88f83027 Nikos Skalkotos
    """Delete an image property"""
419 023e1217 Nikos Skalkotos
    d = session['dialog']
420 023e1217 Nikos Skalkotos
421 023e1217 Nikos Skalkotos
    choices = []
422 023e1217 Nikos Skalkotos
    for (key, val) in session['metadata'].items():
423 023e1217 Nikos Skalkotos
        choices.append((key, "%s" % val, 0))
424 023e1217 Nikos Skalkotos
425 023e1217 Nikos Skalkotos
    (code, to_delete) = d.checklist("Choose which properties to delete:",
426 023e1217 Nikos Skalkotos
                                    choices=choices, width=WIDTH)
427 023e1217 Nikos Skalkotos
428 023e1217 Nikos Skalkotos
    # If the user exits with ESC or CANCEL, the returned tag list is empty.
429 023e1217 Nikos Skalkotos
    for i in to_delete:
430 023e1217 Nikos Skalkotos
        del session['metadata'][i]
431 023e1217 Nikos Skalkotos
432 023e1217 Nikos Skalkotos
    cnt = len(to_delete)
433 023e1217 Nikos Skalkotos
    if cnt > 0:
434 023e1217 Nikos Skalkotos
        d.msgbox("%d image properties were deleted." % cnt, width=SMALL_WIDTH)
435 023e1217 Nikos Skalkotos
        return True
436 023e1217 Nikos Skalkotos
    else:
437 023e1217 Nikos Skalkotos
        return False
438 023e1217 Nikos Skalkotos
439 023e1217 Nikos Skalkotos
440 023e1217 Nikos Skalkotos
def exclude_tasks(session):
441 88f83027 Nikos Skalkotos
    """Exclude specific tasks from running during image deployment"""
442 023e1217 Nikos Skalkotos
    d = session['dialog']
443 023e1217 Nikos Skalkotos
444 023e1217 Nikos Skalkotos
    index = 0
445 023e1217 Nikos Skalkotos
    displayed_index = 1
446 023e1217 Nikos Skalkotos
    choices = []
447 023e1217 Nikos Skalkotos
    mapping = {}
448 023e1217 Nikos Skalkotos
    if 'excluded_tasks' not in session:
449 023e1217 Nikos Skalkotos
        session['excluded_tasks'] = []
450 023e1217 Nikos Skalkotos
451 023e1217 Nikos Skalkotos
    if -1 in session['excluded_tasks']:
452 023e1217 Nikos Skalkotos
        if not d.yesno("Image deployment configuration is disabled. "
453 023e1217 Nikos Skalkotos
                       "Do you wish to enable it?", width=SMALL_WIDTH):
454 023e1217 Nikos Skalkotos
            session['excluded_tasks'].remove(-1)
455 023e1217 Nikos Skalkotos
        else:
456 023e1217 Nikos Skalkotos
            return False
457 023e1217 Nikos Skalkotos
458 023e1217 Nikos Skalkotos
    for (msg, task, osfamily) in CONFIGURATION_TASKS:
459 023e1217 Nikos Skalkotos
        if session['metadata']['OSFAMILY'] in osfamily:
460 023e1217 Nikos Skalkotos
            checked = 1 if index in session['excluded_tasks'] else 0
461 023e1217 Nikos Skalkotos
            choices.append((str(displayed_index), msg, checked))
462 023e1217 Nikos Skalkotos
            mapping[displayed_index] = index
463 023e1217 Nikos Skalkotos
            displayed_index += 1
464 023e1217 Nikos Skalkotos
        index += 1
465 023e1217 Nikos Skalkotos
466 023e1217 Nikos Skalkotos
    while 1:
467 023e1217 Nikos Skalkotos
        (code, tags) = d.checklist(
468 023e1217 Nikos Skalkotos
            text="Please choose which configuration tasks you would like to "
469 023e1217 Nikos Skalkotos
                 "prevent from running during image deployment. "
470 023e1217 Nikos Skalkotos
                 "Press <No Config> to supress any configuration. "
471 023e1217 Nikos Skalkotos
                 "Press <Help> for more help on the image deployment "
472 023e1217 Nikos Skalkotos
                 "configuration tasks.",
473 023e1217 Nikos Skalkotos
            choices=choices, height=19, list_height=8, width=WIDTH,
474 023e1217 Nikos Skalkotos
            help_button=1, extra_button=1, extra_label="No Config",
475 023e1217 Nikos Skalkotos
            title="Exclude Configuration Tasks")
476 023e1217 Nikos Skalkotos
477 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
478 023e1217 Nikos Skalkotos
            return False
479 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_HELP:
480 023e1217 Nikos Skalkotos
            help_file = get_help_file("configuration_tasks")
481 023e1217 Nikos Skalkotos
            assert os.path.exists(help_file)
482 023e1217 Nikos Skalkotos
            d.textbox(help_file, title="Configuration Tasks",
483 023e1217 Nikos Skalkotos
                      width=70, height=40)
484 023e1217 Nikos Skalkotos
        # No Config button
485 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_EXTRA:
486 023e1217 Nikos Skalkotos
            session['excluded_tasks'] = [-1]
487 023e1217 Nikos Skalkotos
            session['task_metadata'] = ["EXCLUDE_ALL_TASKS"]
488 023e1217 Nikos Skalkotos
            break
489 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_OK:
490 023e1217 Nikos Skalkotos
            session['excluded_tasks'] = []
491 023e1217 Nikos Skalkotos
            for tag in tags:
492 023e1217 Nikos Skalkotos
                session['excluded_tasks'].append(mapping[int(tag)])
493 023e1217 Nikos Skalkotos
494 023e1217 Nikos Skalkotos
            exclude_metadata = []
495 023e1217 Nikos Skalkotos
            for task in session['excluded_tasks']:
496 023e1217 Nikos Skalkotos
                exclude_metadata.extend(CONFIGURATION_TASKS[task][1])
497 023e1217 Nikos Skalkotos
498 023e1217 Nikos Skalkotos
            session['task_metadata'] = map(lambda x: "EXCLUDE_TASK_%s" % x,
499 023e1217 Nikos Skalkotos
                                           exclude_metadata)
500 023e1217 Nikos Skalkotos
            break
501 023e1217 Nikos Skalkotos
502 023e1217 Nikos Skalkotos
    return True
503 023e1217 Nikos Skalkotos
504 023e1217 Nikos Skalkotos
505 023e1217 Nikos Skalkotos
def sysprep(session):
506 88f83027 Nikos Skalkotos
    """Perform various system preperation tasks on the image"""
507 023e1217 Nikos Skalkotos
    d = session['dialog']
508 f5174d2c Nikos Skalkotos
    image = session['image']
509 023e1217 Nikos Skalkotos
510 023e1217 Nikos Skalkotos
    # Is the image already shrinked?
511 023e1217 Nikos Skalkotos
    if 'shrinked' in session and session['shrinked']:
512 023e1217 Nikos Skalkotos
        msg = "It seems you have shrinked the image. Running system " \
513 023e1217 Nikos Skalkotos
              "preparation tasks on a shrinked image is dangerous."
514 023e1217 Nikos Skalkotos
515 023e1217 Nikos Skalkotos
        if d.yesno("%s\n\nDo you really want to continue?" % msg,
516 023e1217 Nikos Skalkotos
                   width=SMALL_WIDTH, defaultno=1):
517 023e1217 Nikos Skalkotos
            return
518 023e1217 Nikos Skalkotos
519 023e1217 Nikos Skalkotos
    wrapper = textwrap.TextWrapper(width=WIDTH - 5)
520 023e1217 Nikos Skalkotos
521 023e1217 Nikos Skalkotos
    help_title = "System Preperation Tasks"
522 023e1217 Nikos Skalkotos
    sysprep_help = "%s\n%s\n\n" % (help_title, '=' * len(help_title))
523 023e1217 Nikos Skalkotos
524 fa65eda1 Nikos Skalkotos
    syspreps = image.os.list_syspreps()
525 023e1217 Nikos Skalkotos
526 023e1217 Nikos Skalkotos
    if len(syspreps) == 0:
527 023e1217 Nikos Skalkotos
        d.msgbox("No system preparation task available to run!",
528 023e1217 Nikos Skalkotos
                 title="System Preperation", width=SMALL_WIDTH)
529 023e1217 Nikos Skalkotos
        return
530 023e1217 Nikos Skalkotos
531 023e1217 Nikos Skalkotos
    while 1:
532 023e1217 Nikos Skalkotos
        choices = []
533 023e1217 Nikos Skalkotos
        index = 0
534 023e1217 Nikos Skalkotos
        for sysprep in syspreps:
535 f5174d2c Nikos Skalkotos
            name, descr = image.os.sysprep_info(sysprep)
536 023e1217 Nikos Skalkotos
            display_name = name.replace('-', ' ').capitalize()
537 023e1217 Nikos Skalkotos
            sysprep_help += "%s\n" % display_name
538 023e1217 Nikos Skalkotos
            sysprep_help += "%s\n" % ('-' * len(display_name))
539 023e1217 Nikos Skalkotos
            sysprep_help += "%s\n\n" % wrapper.fill(" ".join(descr.split()))
540 023e1217 Nikos Skalkotos
            enabled = 1 if sysprep.enabled else 0
541 023e1217 Nikos Skalkotos
            choices.append((str(index + 1), display_name, enabled))
542 023e1217 Nikos Skalkotos
            index += 1
543 023e1217 Nikos Skalkotos
544 023e1217 Nikos Skalkotos
        (code, tags) = d.checklist(
545 023e1217 Nikos Skalkotos
            "Please choose which system preparation tasks you would like to "
546 023e1217 Nikos Skalkotos
            "run on the image. Press <Help> to see details about the system "
547 023e1217 Nikos Skalkotos
            "preparation tasks.", title="Run system preparation tasks",
548 023e1217 Nikos Skalkotos
            choices=choices, width=70, ok_label="Run", help_button=1)
549 023e1217 Nikos Skalkotos
550 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
551 023e1217 Nikos Skalkotos
            return False
552 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_HELP:
553 023e1217 Nikos Skalkotos
            d.scrollbox(sysprep_help, width=WIDTH)
554 023e1217 Nikos Skalkotos
        elif code == d.DIALOG_OK:
555 023e1217 Nikos Skalkotos
            # Enable selected syspreps and disable the rest
556 023e1217 Nikos Skalkotos
            for i in range(len(syspreps)):
557 023e1217 Nikos Skalkotos
                if str(i + 1) in tags:
558 f5174d2c Nikos Skalkotos
                    image.os.enable_sysprep(syspreps[i])
559 023e1217 Nikos Skalkotos
                else:
560 f5174d2c Nikos Skalkotos
                    image.os.disable_sysprep(syspreps[i])
561 023e1217 Nikos Skalkotos
562 fa65eda1 Nikos Skalkotos
            if len([s for s in image.os.list_syspreps() if s.enabled]) == 0:
563 fa65eda1 Nikos Skalkotos
                d.msgbox("No system preperation task is selected!",
564 fa65eda1 Nikos Skalkotos
                         title="System Preperation", width=SMALL_WIDTH)
565 fa65eda1 Nikos Skalkotos
                continue
566 fa65eda1 Nikos Skalkotos
567 023e1217 Nikos Skalkotos
            infobox = InfoBoxOutput(d, "Image Configuration")
568 023e1217 Nikos Skalkotos
            try:
569 f5174d2c Nikos Skalkotos
                image.out.add(infobox)
570 023e1217 Nikos Skalkotos
                try:
571 71b0ab28 Nikos Skalkotos
                    # The checksum is invalid. We have mounted the image rw
572 71b0ab28 Nikos Skalkotos
                    if 'checksum' in session:
573 71b0ab28 Nikos Skalkotos
                        del session['checksum']
574 71b0ab28 Nikos Skalkotos
575 71b0ab28 Nikos Skalkotos
                    # Monitor the metadata changes during syspreps
576 71b0ab28 Nikos Skalkotos
                    with MetadataMonitor(session, image.os.meta):
577 71b0ab28 Nikos Skalkotos
                        try:
578 f5174d2c Nikos Skalkotos
                            image.os.do_sysprep()
579 023e1217 Nikos Skalkotos
                            infobox.finalize()
580 71b0ab28 Nikos Skalkotos
                        except FatalError as e:
581 71b0ab28 Nikos Skalkotos
                            title = "System Preparation"
582 71b0ab28 Nikos Skalkotos
                            d.msgbox("System Preparation failed: %s" % e,
583 71b0ab28 Nikos Skalkotos
                                     title=title, width=SMALL_WIDTH)
584 023e1217 Nikos Skalkotos
                finally:
585 f5174d2c Nikos Skalkotos
                    image.out.remove(infobox)
586 023e1217 Nikos Skalkotos
            finally:
587 023e1217 Nikos Skalkotos
                infobox.cleanup()
588 023e1217 Nikos Skalkotos
            break
589 023e1217 Nikos Skalkotos
    return True
590 023e1217 Nikos Skalkotos
591 023e1217 Nikos Skalkotos
592 023e1217 Nikos Skalkotos
def shrink(session):
593 88f83027 Nikos Skalkotos
    """Shrink the image"""
594 023e1217 Nikos Skalkotos
    d = session['dialog']
595 f5174d2c Nikos Skalkotos
    image = session['image']
596 023e1217 Nikos Skalkotos
597 023e1217 Nikos Skalkotos
    shrinked = 'shrinked' in session and session['shrinked']
598 023e1217 Nikos Skalkotos
599 023e1217 Nikos Skalkotos
    if shrinked:
600 023e1217 Nikos Skalkotos
        d.msgbox("The image is already shrinked!", title="Image Shrinking",
601 023e1217 Nikos Skalkotos
                 width=SMALL_WIDTH)
602 023e1217 Nikos Skalkotos
        return True
603 023e1217 Nikos Skalkotos
604 023e1217 Nikos Skalkotos
    msg = "This operation will shrink the last partition of the image to " \
605 023e1217 Nikos Skalkotos
          "reduce the total image size. If the last partition is a swap " \
606 023e1217 Nikos Skalkotos
          "partition, then this partition is removed and the partition " \
607 023e1217 Nikos Skalkotos
          "before that is shrinked. The removed swap partition will be " \
608 023e1217 Nikos Skalkotos
          "recreated during image deployment."
609 023e1217 Nikos Skalkotos
610 023e1217 Nikos Skalkotos
    if not d.yesno("%s\n\nDo you want to continue?" % msg, width=WIDTH,
611 023e1217 Nikos Skalkotos
                   height=12, title="Image Shrinking"):
612 f5174d2c Nikos Skalkotos
        with MetadataMonitor(session, image.meta):
613 023e1217 Nikos Skalkotos
            infobox = InfoBoxOutput(d, "Image Shrinking", height=4)
614 f5174d2c Nikos Skalkotos
            image.out.add(infobox)
615 023e1217 Nikos Skalkotos
            try:
616 f5174d2c Nikos Skalkotos
                image.shrink()
617 023e1217 Nikos Skalkotos
                infobox.finalize()
618 023e1217 Nikos Skalkotos
            finally:
619 f5174d2c Nikos Skalkotos
                image.out.remove(infobox)
620 023e1217 Nikos Skalkotos
621 023e1217 Nikos Skalkotos
        session['shrinked'] = True
622 023e1217 Nikos Skalkotos
        update_background_title(session)
623 023e1217 Nikos Skalkotos
    else:
624 023e1217 Nikos Skalkotos
        return False
625 023e1217 Nikos Skalkotos
626 023e1217 Nikos Skalkotos
    return True
627 023e1217 Nikos Skalkotos
628 023e1217 Nikos Skalkotos
629 023e1217 Nikos Skalkotos
def customization_menu(session):
630 88f83027 Nikos Skalkotos
    """Show image customization menu"""
631 023e1217 Nikos Skalkotos
    d = session['dialog']
632 023e1217 Nikos Skalkotos
633 023e1217 Nikos Skalkotos
    choices = [("Sysprep", "Run various image preparation tasks"),
634 023e1217 Nikos Skalkotos
               ("Shrink", "Shrink image"),
635 023e1217 Nikos Skalkotos
               ("View/Modify", "View/Modify image properties"),
636 023e1217 Nikos Skalkotos
               ("Delete", "Delete image properties"),
637 023e1217 Nikos Skalkotos
               ("Exclude", "Exclude various deployment tasks from running")]
638 023e1217 Nikos Skalkotos
639 023e1217 Nikos Skalkotos
    default_item = 0
640 023e1217 Nikos Skalkotos
641 023e1217 Nikos Skalkotos
    actions = {"Sysprep": sysprep,
642 023e1217 Nikos Skalkotos
               "Shrink": shrink,
643 023e1217 Nikos Skalkotos
               "View/Modify": modify_properties,
644 023e1217 Nikos Skalkotos
               "Delete": delete_properties,
645 023e1217 Nikos Skalkotos
               "Exclude": exclude_tasks}
646 023e1217 Nikos Skalkotos
    while 1:
647 023e1217 Nikos Skalkotos
        (code, choice) = d.menu(
648 023e1217 Nikos Skalkotos
            text="Choose one of the following or press <Back> to exit.",
649 023e1217 Nikos Skalkotos
            width=WIDTH, choices=choices, cancel="Back", height=13,
650 023e1217 Nikos Skalkotos
            menu_height=len(choices), default_item=choices[default_item][0],
651 023e1217 Nikos Skalkotos
            title="Image Customization Menu")
652 023e1217 Nikos Skalkotos
653 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
654 023e1217 Nikos Skalkotos
            break
655 023e1217 Nikos Skalkotos
        elif choice in actions:
656 023e1217 Nikos Skalkotos
            default_item = [entry[0] for entry in choices].index(choice)
657 023e1217 Nikos Skalkotos
            if actions[choice](session):
658 023e1217 Nikos Skalkotos
                default_item = (default_item + 1) % len(choices)
659 023e1217 Nikos Skalkotos
660 023e1217 Nikos Skalkotos
661 023e1217 Nikos Skalkotos
def main_menu(session):
662 88f83027 Nikos Skalkotos
    """Show the main menu of the program"""
663 023e1217 Nikos Skalkotos
    d = session['dialog']
664 023e1217 Nikos Skalkotos
665 023e1217 Nikos Skalkotos
    update_background_title(session)
666 023e1217 Nikos Skalkotos
667 023e1217 Nikos Skalkotos
    choices = [("Customize", "Customize image & ~okeanos deployment options"),
668 023e1217 Nikos Skalkotos
               ("Register", "Register image to ~okeanos"),
669 023e1217 Nikos Skalkotos
               ("Extract", "Dump image to local file system"),
670 023e1217 Nikos Skalkotos
               ("Reset", "Reset everything and start over again"),
671 023e1217 Nikos Skalkotos
               ("Help", "Get help for using snf-image-creator")]
672 023e1217 Nikos Skalkotos
673 023e1217 Nikos Skalkotos
    default_item = "Customize"
674 023e1217 Nikos Skalkotos
675 023e1217 Nikos Skalkotos
    actions = {"Customize": customization_menu, "Register": kamaki_menu,
676 023e1217 Nikos Skalkotos
               "Extract": extract_image}
677 023e1217 Nikos Skalkotos
    while 1:
678 023e1217 Nikos Skalkotos
        (code, choice) = d.menu(
679 023e1217 Nikos Skalkotos
            text="Choose one of the following or press <Exit> to exit.",
680 023e1217 Nikos Skalkotos
            width=WIDTH, choices=choices, cancel="Exit", height=13,
681 023e1217 Nikos Skalkotos
            default_item=default_item, menu_height=len(choices),
682 023e1217 Nikos Skalkotos
            title="Image Creator for ~okeanos (snf-image-creator version %s)" %
683 023e1217 Nikos Skalkotos
                  version)
684 023e1217 Nikos Skalkotos
685 023e1217 Nikos Skalkotos
        if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
686 023e1217 Nikos Skalkotos
            if confirm_exit(d):
687 023e1217 Nikos Skalkotos
                break
688 023e1217 Nikos Skalkotos
        elif choice == "Reset":
689 023e1217 Nikos Skalkotos
            if confirm_reset(d):
690 023e1217 Nikos Skalkotos
                d.infobox("Resetting snf-image-creator. Please wait...",
691 023e1217 Nikos Skalkotos
                          width=SMALL_WIDTH)
692 023e1217 Nikos Skalkotos
                raise Reset
693 aa04fb4e Nikos Skalkotos
        elif choice == "Help":
694 aa04fb4e Nikos Skalkotos
            d.msgbox("For help, check the online documentation:\n\nhttp://www"
695 aa04fb4e Nikos Skalkotos
                     ".synnefo.org/docs/snf-image-creator/latest/",
696 aa04fb4e Nikos Skalkotos
                     width=WIDTH, title="Help")
697 023e1217 Nikos Skalkotos
        elif choice in actions:
698 023e1217 Nikos Skalkotos
            actions[choice](session)
699 023e1217 Nikos Skalkotos
700 023e1217 Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :