X-Git-Url: https://code.grnet.gr/git/snf-image-creator/blobdiff_plain/1f42adc8fcc9230ee4d317fb6dc3ee878ae0b1c3..aeb95900f10211f2d3c8ffead154a44121a2d5b5:/image_creator/dialog_main.py diff --git a/image_creator/dialog_main.py b/image_creator/dialog_main.py index b533a15..3082a1c 100644 --- a/image_creator/dialog_main.py +++ b/image_creator/dialog_main.py @@ -39,6 +39,7 @@ import os import textwrap import signal import StringIO +import optparse from image_creator import __version__ as version from image_creator.util import FatalError, MD5 @@ -47,6 +48,7 @@ from image_creator.disk import Disk from image_creator.os_type import os_cls from image_creator.kamaki_wrapper import Kamaki, ClientError from image_creator.help import get_help_file +from image_creator.dialog_wizard import wizard MSGBOX_WIDTH = 60 YESNO_WIDTH = 50 @@ -120,6 +122,15 @@ class metadata_monitor(object): d.msgbox(msg, title="Image Property Changes", width=MSGBOX_WIDTH) +def extract_metadata_string(session): + metadata = ['%s=%s' % (k, v) for (k, v) in session['metadata'].items()] + + if 'task_metadata' in session: + metadata.extend("%s=yes" % m for m in session['task_metadata']) + + return '\n'.join(metadata) + '\n' + + def confirm_exit(d, msg=''): return not d.yesno("%s Do you want to exit?" % msg, width=YESNO_WIDTH) @@ -135,8 +146,8 @@ def update_background_title(session): MB = 2 ** 20 - size = (dev.meta['SIZE'] + MB - 1) // MB - shrinked = 'shrinked' in session and session['shrinked'] == True + size = (dev.size + MB - 1) // MB + shrinked = 'shrinked' in session and session['shrinked'] postfix = " (shrinked)" if shrinked else '' title = "OS: %s, Distro: %s, Size: %dMB%s" % \ @@ -194,7 +205,7 @@ def extract_image(session): try: dev = session['device'] if "checksum" not in session: - size = dev.meta['SIZE'] + size = dev.size md5 = MD5(out) session['checksum'] = md5.compute(session['snapshot'], size) @@ -204,11 +215,8 @@ def extract_image(session): # Extract metadata file out.output("Extracting metadata file...") - metastring = '\n'.join( - ['%s=%s' % (k, v) for (k, v) in session['metadata'].items()]) - metastring += '\n' with open('%s.meta' % path, 'w') as f: - f.write(metastring) + f.write(extract_metadata_string(session)) out.success('done') # Extract md5sum file @@ -229,7 +237,7 @@ def extract_image(session): def upload_image(session): d = session["dialog"] - size = session['device'].meta['SIZE'] + size = session['device'].size if "account" not in session: d.msgbox("You need to provide your ~okeanos login username before you " @@ -258,10 +266,10 @@ def upload_image(session): break out = GaugeOutput(d, "Image Upload", "Uploading...") - if 'checksum' not in session: - md5 = MD5(out) - session['checksum'] = md5.compute(session['snapshot'], size) try: + if 'checksum' not in session: + md5 = MD5(out) + session['checksum'] = md5.compute(session['snapshot'], size) kamaki = Kamaki(session['account'], session['token'], out) try: # Upload image file @@ -271,9 +279,7 @@ def upload_image(session): "Uploading missing blocks") # Upload metadata file out.output("Uploading metadata file...") - metastring = '\n'.join( - ['%s=%s' % (k, v) for (k, v) in session['metadata'].items()]) - metastring += '\n' + metastring = extract_metadata_string(session) kamaki.upload(StringIO.StringIO(metastring), size=len(metastring), remote_path="%s.meta" % filename) out.success("done") @@ -316,9 +322,8 @@ def register_image(session): return False if "upload" not in session: - d.msgbox("You need to have an image uploaded to pithos+ before you " - "can register it to cyclades", - width=MSGBOX_WIDTH) + d.msgbox("You need to upload the image to pithos+ before you can " + "register it to cyclades", width=MSGBOX_WIDTH) return False while 1: @@ -333,12 +338,18 @@ def register_image(session): continue break + metadata = {} + metadata.update(session['metadata']) + if 'task_metadata' in session: + for key in session['task_metadata']: + metadata[key] = 'yes' + out = GaugeOutput(d, "Image Registration", "Registrating image...") try: out.output("Registring image to cyclades...") try: kamaki = Kamaki(session['account'], session['token'], out) - kamaki.register(name, session['upload'], session['metadata']) + kamaki.register(name, session['upload'], metadata) out.success('done') except ClientError as e: d.msgbox("Error in pithos+ client: %s" % e.message) @@ -354,6 +365,15 @@ def register_image(session): def kamaki_menu(session): d = session['dialog'] default_item = "Account" + + account = Kamaki.get_account() + if account: + session['account'] = account + + token = Kamaki.get_token() + if token: + session['token'] = token + while 1: account = session["account"] if "account" in session else "" token = session["token"] if "token" in session else "" @@ -362,12 +382,13 @@ def kamaki_menu(session): choices = [("Account", "Change your ~okeanos username: %s" % account), ("Token", "Change your ~okeanos token: %s" % token), ("Upload", "Upload image to pithos+"), - ("Register", "Register image to cyclades: %s" % upload)] + ("Register", "Register the image to cyclades: %s" % upload)] (code, choice) = d.menu( text="Choose one of the following or press to go back.", - width=MENU_WIDTH, choices=choices, cancel="Back", - default_item=default_item, title="Image Registration Menu") + width=MENU_WIDTH, choices=choices, cancel="Back", height=13, + menu_height=5, default_item=default_item, + title="Image Registration Menu") if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): return False @@ -384,6 +405,7 @@ def kamaki_menu(session): del session["account"] else: session["account"] = answer.strip() + Kamaki.save_account(session['account']) default_item = "Token" elif choice == "Token": default_item = "Token" @@ -397,6 +419,7 @@ def kamaki_menu(session): del session["token"] else: session["token"] = answer.strip() + Kamaki.save_token(session['account']) default_item = "Upload" elif choice == "Upload": if upload_image(session): @@ -480,6 +503,10 @@ def modify_properties(session): # ADD button elif code == d.DIALOG_EXTRA: add_property(session) + elif code == 'help': + help_file = get_help_file("image_properties") + assert os.path.exists(help_file) + d.textbox(help_file, title="Image Properties", width=70, height=40) def delete_properties(session): @@ -573,7 +600,7 @@ def sysprep(session): image_os = session['image_os'] # Is the image already shrinked? - if 'shrinked' in session and session['shrinked'] == True: + if 'shrinked' in session and session['shrinked']: msg = "It seems you have shrinked the image. Running system " \ "preparation tasks on a shrinked image is dangerous." @@ -594,7 +621,8 @@ def sysprep(session): syspreps = [s for s in all_syspreps if s not in session['exec_syspreps']] if len(syspreps) == 0: - d.msgbox("No system preparation task left to run!", width=MSGBOX_WIDTH) + d.msgbox("No system preparation task available to run!", + title="System Preperation", width=MSGBOX_WIDTH) return while 1: @@ -661,10 +689,11 @@ def shrink(session): d = session['dialog'] dev = session['device'] - shrinked = 'shrinked' in session and session['shrinked'] == True + shrinked = 'shrinked' in session and session['shrinked'] if shrinked: - d.msgbox("You have already shrinked your image!") + d.msgbox("The image is already shrinked!", title="Image Shrinking", + width=MSGBOX_WIDTH) return True msg = "This operation will shrink the last partition of the image to " \ @@ -676,7 +705,7 @@ def shrink(session): if not d.yesno("%s\n\nDo you want to continue?" % msg, width=70, height=12, title="Image Shrinking"): with metadata_monitor(session, dev.meta): - dev.out = InfoBoxOutput(d, "Image Shrinking", height=3) + dev.out = InfoBoxOutput(d, "Image Shrinking", height=4) dev.shrink() dev.out.finalize() @@ -760,7 +789,7 @@ def select_file(d, media): while 1: if media is not None: if not os.path.exists(media): - d.msgbox("The file you choose does not exist", + d.msgbox("The file `%s' you choose does not exist." % media, width=MSGBOX_WIDTH) else: break @@ -778,18 +807,21 @@ def select_file(d, media): def image_creator(d): - basename = os.path.basename(sys.argv[0]) - usage = "Usage: %s [input_media]" % basename - if len(sys.argv) > 2: - sys.stderr.write("%s\n" % usage) - return 1 + + usage = "Usage: %prog [options] []" + parser = optparse.OptionParser(version=version, usage=usage) + + options, args = parser.parse_args(sys.argv[1:]) + + if len(args) > 1: + parser.error("Wrong numver of arguments") d.setBackgroundTitle('snf-image-creator') if os.geteuid() != 0: - raise FatalError("You must run %s as root" % basename) + raise FatalError("You must run %s as root" % parser.get_prog_name()) - media = select_file(d, sys.argv[1] if len(sys.argv) == 2 else None) + media = select_file(d, args[0] if len(args) == 1 else None) out = GaugeOutput(d, "Initialization", "Initializing...") disk = Disk(media, out) @@ -803,13 +835,12 @@ def image_creator(d): snapshot = disk.snapshot() dev = disk.get_device(snapshot) - out.output("Collecting image metadata...") - metadata = {} for (key, value) in dev.meta.items(): metadata[str(key)] = str(value) dev.mount(readonly=True) + out.output("Collecting image metadata...") cls = os_cls(dev.distro, dev.ostype) image_os = cls(dev.root, dev.g, out) dev.umount() @@ -832,7 +863,28 @@ def image_creator(d): "image_os": image_os, "metadata": metadata} - main_menu(session) + msg = "snf-image-creator detected a %s system on the input media. " \ + "Would you like to run a wizards to assists you through the " \ + "image creation process?\n\nChoose to run the wizard, " \ + " to run the snf-image-creator in expert mode or press " \ + "ESC to quit the program." \ + % (dev.ostype if dev.ostype == dev.distro else "%s (%s)" % + (dev.ostype, dev.distro)) + + update_background_title(session) + + while True: + code = d.yesno(msg, width=YESNO_WIDTH, height=12) + if code == d.DIALOG_OK: + if wizard(session): + break + elif code == d.DIALOG_CANCEL: + main_menu(session) + break + + if confirm_exit(d): + break + d.infobox("Thank you for using snf-image-creator. Bye", width=53) finally: disk.cleanup()