class WizardExit(Exception):
+ """Exception used to exit the wizard"""
pass
class WizardInvalidData(Exception):
+ """Exception triggered when the user provided data are invalid"""
pass
class Wizard:
+ """Represents a dialog-based wizard
+
+ The wizard is a collection of pages that have a "Next" and a "Back" button
+ on them. The pages are used to collect user data.
+ """
+
def __init__(self, session):
self.session = session
self.pages = []
self.d = session['dialog']
def add_page(self, page):
+ """Add a new page to the wizard"""
self.pages.append(page)
def run(self):
+ """Run the wizard"""
idx = 0
while True:
try:
class WizardPage(object):
+ """Represents a page in a wizard"""
NEXT = 1
PREV = -1
setattr(self, "display", display)
def run(self, session, index, total):
+ """Display this wizard page
+
+ This function is used by the wizard program when accessing a page.
+ """
raise NotImplementedError
class WizardRadioListPage(WizardPage):
-
+ """Represent a Radio List in a wizard"""
def __init__(self, name, printable, message, choices, **kargs):
super(WizardRadioListPage, self).__init__(**kargs)
self.name = name
class WizardInputPage(WizardPage):
-
+ """Represents an input field in a wizard"""
def __init__(self, name, printable, message, **kargs):
super(WizardInputPage, self).__init__(**kargs)
self.name = name
self.printable = printable
self.message = message
+ self.info = "%s: <none>" % self.printable
self.title = kargs['title'] if 'title' in kargs else ''
self.init = kargs['init'] if 'init' in kargs else ''
return self.NEXT
-def wizard(session):
+def start_wizard(session):
+ """Run the image creation wizard"""
init_token = Kamaki.get_token()
if init_token is None:
init_token = ""
name = WizardInputPage(
"ImageName", "Image Name", "Please provide a name for the image:",
- title="Image Name", init=session['device'].distro)
+ title="Image Name", init=session['image'].distro)
descr = WizardInputPage(
"ImageDescription", "Image Description",
title="Registration Type", default="Private")
def validate_account(token):
+ """Check if a token is valid"""
d = session['dialog']
if len(token) == 0:
def create_image(session):
+ """Create an image using the information collected by the wizard"""
d = session['dialog']
- disk = session['disk']
- device = session['device']
- snapshot = session['snapshot']
- image_os = session['image_os']
+ image = session['image']
wizard = session['wizard']
# Save Kamaki credentials
Kamaki.save_token(wizard['Account']['auth_token'])
with_progress = OutputWthProgress(True)
- out = disk.out
+ out = image.out
out.add(with_progress)
try:
out.clear()
#Sysprep
- device.mount(False)
- image_os.do_sysprep()
- metadata = image_os.meta
- device.umount()
+ image.mount(False)
+ image.os.do_sysprep()
+ metadata = image.os.meta
+ image.umount()
#Shrink
- size = device.shrink()
+ size = image.shrink()
session['shrinked'] = True
update_background_title(session)
- metadata.update(device.meta)
+ metadata.update(image.meta)
metadata['DESCRIPTION'] = wizard['ImageDescription']
#MD5
md5 = MD5(out)
- session['checksum'] = md5.compute(snapshot, size)
+ session['checksum'] = md5.compute(image.device, size)
#Metadata
metastring = '\n'.join(
name = "%s-%s.diskdump" % (wizard['ImageName'],
time.strftime("%Y%m%d%H%M"))
pithos_file = ""
- with open(snapshot, 'rb') as f:
+ with open(image.device, 'rb') as f:
pithos_file = kamaki.upload(f, size, name,
"(1/4) Calculating block hashes",
"(2/4) Uploading missing blocks")