X-Git-Url: https://code.grnet.gr/git/snf-image-creator/blobdiff_plain/1d413d1e60951a5a65f39971cbfc67501420761d..6ca928ac8e5d26fe49b22ed3b7406d240193b9ad:/image_creator/dialog_wizard.py diff --git a/image_creator/dialog_wizard.py b/image_creator/dialog_wizard.py index 693588f..f0a01f4 100644 --- a/image_creator/dialog_wizard.py +++ b/image_creator/dialog_wizard.py @@ -40,10 +40,15 @@ import StringIO from image_creator.kamaki_wrapper import Kamaki, ClientError from image_creator.util import MD5, FatalError from image_creator.output.cli import OutputWthProgress +from image_creator.dialog_util import extract_image, update_background_title PAGE_WIDTH = 70 +class WizardExit(Exception): + pass + + class Wizard: def __init__(self, session): self.session = session @@ -56,7 +61,10 @@ class Wizard: def run(self): idx = 0 while True: - idx += self.pages[idx].run(self.session, idx, len(self.pages)) + try: + idx += self.pages[idx].run(self.session, idx, len(self.pages)) + except WizardExit: + return False if idx >= len(self.pages): break @@ -69,12 +77,48 @@ class Wizard: class WizardPage: NEXT = 1 PREV = -1 - EXIT = -255 def run(self, session, index, total): raise NotImplementedError +class WizardRadioListPage(WizardPage): + + def __init__(self, name, message, choices, **kargs): + self.name = name + self.message = message + self.choices = choices + self.title = kargs['title'] if 'title' in kargs else '' + self.default = kargs['default'] if 'default' in kargs else 0 + + def run(self, session, index, total): + d = session['dialog'] + w = session['wizard'] + + choices = [] + for i in range(len(self.choices)): + default = 1 if i == self.default else 0 + choices.append((self.choices[i][0], self.choices[i][1], default)) + + while True: + (code, answer) = \ + d.radiolist(self.message, width=PAGE_WIDTH, + ok_label="Next", cancel="Back", choices=choices, + title="(%d/%d) %s" % (index + 1, total, self.title) + ) + + if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): + return self.PREV + + for i in range(len(choices)): + if self.choices[i] == answer: + self.default = i + w[name] = i + break + + return self.NEXT + + class WizardInputPage(WizardPage): def __init__(self, name, message, **kargs): @@ -90,9 +134,10 @@ class WizardInputPage(WizardPage): init = w[self.name] if self.name in w else self.init_value while True: - (code, answer) = d.inputbox(self.message, init=init, - width=PAGE_WIDTH, ok_label="Next", cancel="Back", - title="(%d/%d) %s" % (index + 1, total, self.title)) + (code, answer) = \ + d.inputbox(self.message, init=init, + width=PAGE_WIDTH, ok_label="Next", cancel="Back", + title="(%d/%d) %s" % (index + 1, total, self.title)) if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): return self.PREV @@ -118,13 +163,13 @@ class WizardYesNoPage(WizardPage): 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)) + 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 + raise WizardExit elif ret == d.DIALOG_OK: return self.NEXT @@ -132,20 +177,22 @@ class WizardYesNoPage(WizardPage): def wizard(session): name = WizardInputPage("ImageName", "Please provide a name for the image:", - title="Image Name", init=session['device'].distro) + title="Image Name", init=session['device'].distro) 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 '') + "Please provide a description for the image:", + title="Image Description", empty=True, + init=session['metadata']['DESCRIPTION'] if + 'DESCRIPTION' in session['metadata'] else '') account = WizardInputPage("account", - "Please provide your ~okeanos account e-mail:", - title="~okeanos account information", init=Kamaki.get_account()) + "Please provide your ~okeanos account e-mail:", + title="~okeanos account information", + init=Kamaki.get_account()) token = WizardInputPage("token", - "Please provide your ~okeanos account token:", - title="~okeanos account token", init=Kamaki.get_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?" + msg = "All necessary information has been gathered. Confirm and Proceed." proceed = WizardYesNoPage(msg, title="Confirmation") w = Wizard(session) @@ -157,78 +204,87 @@ def wizard(session): w.add_page(proceed) if w.run(): - extract_image(session) + create_image(session) else: return False return True -def extract_image(session): +def create_image(session): + d = session['dialog'] 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.clear() + with_progress = OutputWthProgress(True) + out = disk.out + out.add(with_progress) + try: + out.clear() - #Sysprep - device.mount(False) - image_os.do_sysprep() - metadata = image_os.meta - device.umount() + #Sysprep + device.mount(False) + image_os.do_sysprep() + metadata = image_os.meta + device.umount() - #Shrink - size = device.shrink() + #Shrink + size = device.shrink() + session['shrinked'] = True + update_background_title(session) - metadata.update(device.meta) - metadata['DESCRIPTION'] = wizard['ImageDescription'] + metadata.update(device.meta) + metadata['DESCRIPTION'] = wizard['ImageDescription'] - #MD5 - md5 = MD5(out) - checksum = md5.compute(snapshot, size) + #MD5 + md5 = MD5(out) + session['checksum'] = md5.compute(snapshot, size) - #Metadata - metastring = '\n'.join( - ['%s=%s' % (key, value) for (key, value) in metadata.items()]) - metastring += '\n' + #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)) + 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' % (session['checksum'], name) + kamaki.upload(StringIO.StringIO(md5sumstr), size=len(md5sumstr), + remote_path="%s.%s" % (name, 'md5sum')) + out.success('done') + out.output() + + out.output('Registering image with ~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)) + finally: + out.remove(with_progress) + + msg = "The image was successfully uploaded and registered with " \ + "~okeanos. Would you like to keep a local copy of the image?" + if not d.yesno(msg, width=PAGE_WIDTH): + extract_image(session) # vim: set sta sts=4 shiftwidth=4 sw=4 et ai :