From fbdf1d8feb0d1a6cf3b4e94bb374de17d72f5914 Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos Date: Wed, 8 Aug 2012 11:43:20 +0300 Subject: [PATCH] Make the dialog wizard workable A user can now create and upload an image using the wizard --- image_creator/dialog_main.py | 4 +- image_creator/dialog_wizard.py | 122 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 117 insertions(+), 9 deletions(-) diff --git a/image_creator/dialog_main.py b/image_creator/dialog_main.py index 6513344..6af191e 100644 --- a/image_creator/dialog_main.py +++ b/image_creator/dialog_main.py @@ -868,8 +868,8 @@ def image_creator(d): "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.distro, dev.ostype)) + % (dev.ostype if dev.ostype == dev.distro else "%s (%s)" % + (dev.ostype, dev.distro)) update_background_title(session) diff --git a/image_creator/dialog_wizard.py b/image_creator/dialog_wizard.py index d404ba4..967a79f 100644 --- a/image_creator/dialog_wizard.py +++ b/image_creator/dialog_wizard.py @@ -34,8 +34,12 @@ # or implied, of GRNET S.A. import dialog +import time +import StringIO -from image_creator.kamaki_wrapper import Kamaki +from image_creator.kamaki_wrapper import Kamaki, ClientError +from image_creator.util import MD5, FatalError +from image_creator.output.cli import OutputWthProgress PAGE_WIDTH = 70 @@ -65,6 +69,13 @@ class Wizard: class WizardPage: NEXT = 1 PREV = -1 + EXIT = -255 + + def run(self, session, index, total): + raise NotImplementedError + + +class WizardInputPage(WizardPage): def __init__(self, name, message, **kargs): self.name = name @@ -96,28 +107,125 @@ class WizardPage: return self.NEXT +class WizardYesNoPage(WizardPage): + + def __init__(self, message, **kargs): + self.message = message + self.title = kargs['title'] if 'title' in kargs else '' + + def run(self, session, index, total): + d = session['dialog'] + + while True: + ret = d.yesno(self.message, width=PAGE_WIDTH, ok_label="Yes", + cancel="Back", extra_button=1, extra_label="Quit", + title="(%d/%d) %s" % (index + 1, total, self.title)) + + if ret == d.DIALOG_CANCEL: + return self.PREV + elif ret == d.DIALOG_EXTRA: + return self.EXIT + elif ret == d.DIALOG_OK: + return self.NEXT + + def wizard(session): - name = WizardPage("ImageName", "Please provide a name for the image:", + name = WizardInputPage("ImageName", "Please provide a name for the image:", title="Image Name", init=session['device'].distro) - descr = WizardPage("ImageDescription", + descr = WizardInputPage("ImageDescription", "Please provide a description for the image:", title="Image Description", empty=True, init=session['metadata']['DESCRIPTION'] if 'DESCRIPTION' in session['metadata'] else '') - account = WizardPage("account", + account = WizardInputPage("account", "Please provide your ~okeanos account e-mail:", title="~okeanos account information", init=Kamaki.get_account()) - token = WizardPage("token", + token = WizardInputPage("token", "Please provide your ~okeanos account token:", title="~okeanos account token", init=Kamaki.get_token()) + msg = "Do you wish to continue with the image extraction process?" + proceed = WizardYesNoPage(msg, title="Confirmation") + w = Wizard(session) + w.add_page(name) w.add_page(descr) w.add_page(account) w.add_page(token) - - return w.run() + w.add_page(proceed) + + if w.run(): + extract_image(session) + else: + return False + + return True + + +def extract_image(session): + disk = session['disk'] + device = session['device'] + snapshot = session['snapshot'] + image_os = session['image_os'] + wizard = session['wizard'] + + out = OutputWthProgress(True) + #Initialize the output + disk.out = out + device.out = out + image_os.out = out + + out.output() + + #Sysprep + device.mount(False) + image_os.do_sysprep() + metadata = image_os.meta + device.umount() + + #Shrink + size = device.shrink() + + #MD5 + md5 = MD5(out) + checksum = md5.compute(snapshot, size) + + #Metadata + metastring = '\n'.join( + ['%s=%s' % (key, value) for (key, value) in metadata.items()]) + metastring += '\n' + + out.output() + try: + out.output("Uploading image to pithos:") + kamaki = Kamaki(wizard['account'], wizard['token'], out) + + name = "%s-%s.diskdump" % (wizard['ImageName'], + time.strftime("%Y%m%d%H%M")) + pithos_file = "" + with open(snapshot, 'rb') as f: + pithos_file = kamaki.upload(f, size, name, + "(1/4) Calculating block hashes", + "(2/4) Uploading missing blocks") + + out.output("(3/4) Uploading metadata file...", False) + kamaki.upload(StringIO.StringIO(metastring), size=len(metastring), + remote_path="%s.%s" % (name, 'meta')) + out.success('done') + out.output("(4/4) Uploading md5sum file...", False) + md5sumstr = '%s %s\n' % (checksum, name) + kamaki.upload(StringIO.StringIO(md5sumstr), size=len(md5sumstr), + remote_path="%s.%s" % (name, 'md5sum')) + out.success('done') + out.output() + + out.output('Registring image to ~okeanos...', False) + kamaki.register(wizard['ImageName'], pithos_file, metadata) + out.success('done') + out.output() + except ClientError as e: + raise FatalError("Pithos client: %d %s" % (e.status, e.message)) # vim: set sta sts=4 shiftwidth=4 sw=4 et ai : -- 1.7.10.4