From 4cc83e2e97d8ace96450968b1d3f7a2c052fc4ea Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos <skalkoto@grnet.gr> Date: Fri, 21 Nov 2014 13:19:37 +0200 Subject: [PATCH] Add support list sysprep parameters The type for those parameters is list:<type> --- image_creator/dialog_menu.py | 3 +- image_creator/dialog_util.py | 101 +++++++++++++++++++++++++----- image_creator/os_type/__init__.py | 57 ++++++++++++----- 3 files changed, 128 insertions(+), 33 deletions(-) diff --git a/image_creator/dialog_menu.py b/image_creator/dialog_menu.py index 284d2c0..c38e2a8 100644 --- a/image_creator/dialog_menu.py +++ b/image_creator/dialog_menu.py @@ -656,7 +656,8 @@ def sysprep_params(session): if param.hidden: continue - value = str(param.value) + value = "|".join([str(i) for i in param.value]) if param.is_list \ + else str(param.value) if len(value) == 0: value = "<not_set>" choices.append((name, value)) diff --git a/image_creator/dialog_util.py b/image_creator/dialog_util.py index 6d93a3e..e85f84c 100644 --- a/image_creator/dialog_util.py +++ b/image_creator/dialog_util.py @@ -334,40 +334,107 @@ def edit_cloud(session, name): return True +def _get_sysprep_param_value(session, param, default, title=None, + delete=False): + """Get the value of a sysprep parameter""" + d = session['dialog'] + + if param.type in ("file", "dir"): + if not title: + title = "Please select a %s to use for the `%s' parameter" % \ + ('file' if param.type == 'file' else 'directory', param.name) + ftype = "br" if param.type == 'file' else 'd' + + value = select_file(d, ftype=ftype, title=title) + else: + if not title: + title = ("Please provide a new value for configuration parameter: " + "`%s' or press <Delete> to completely delete it." % + param.name) + (code, answer) = d.inputbox(title, width=WIDTH, init=str(default), + extra_button=int(delete), + extra_label="Delete") + + if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): + return (None, False) + if code == d.DIALOG_EXTRA: + return ("", True) + + value = answer.strip() + + return (value, False) + + def update_sysprep_param(session, name, title=None): """Modify the value of a sysprep parameter""" + d = session['dialog'] image = session['image'] param = image.os.sysprep_params[name] + default_item = 1 while 1: - if param.type in ("file", "dir"): - if not title: - title = "Please select a %s to use for the `%s' parameter" % \ - ('file' if param.type == 'file' else 'directory', name) - ftype = "br" if param.type == 'file' else 'd' - - value = select_file(d, ftype=ftype, title=title) - if value is None: - return False + value = [] + for i in param.value: + value.append(i) + if param.is_list: + choices = [(str(i+1), str(value[i])) for i in xrange(len(value))] + if len(choices) == 0: + action = 'add' + default_value = "" + else: + (code, choice) = d.menu( + "Please press <Edit> to edit or remove a value or <Add> " + "to add a new one. Press <Back> to go back.", height=18, + width=WIDTH, choices=choices, menu_height=10, + ok_label="Edit", extra_button=1, extra_label="Add", + cancel="Back", default_item=str(default_item), title=name) + + if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): + return True + elif code == d.DIALOG_EXTRA: + action = 'add' + default_value = "" + elif code == d.DIALOG_OK: + action = 'edit' + choice = int(choice) + default_value = choices[choice-1][1] + default_item = choice else: - if not title: - title = "Please provide a new value for configuration " \ - "parameter: `%s'" % name - (code, answer) = d.inputbox( - title, width=WIDTH, init=str(param.value)) + default_value = param.value + action = 'edit' - if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): + (new_value, delete) = _get_sysprep_param_value( + session, param, default_value, title, + delete=(param.is_list and action == 'edit')) + + if new_value is None: + if not param.is_list or len(param.value) == 0: return False + continue - value = answer.strip() + if param.is_list: + if action == 'add': + value = value + [new_value] + if action == 'edit': + if delete: + del value[choice-1] + else: + value[choice-1] = new_value if param.set_value(value) is False: d.msgbox("Error: %s" % param.error, width=WIDTH) param.error = None continue - break + elif param.is_list: + if action == 'add': + default_item = len(param.value) + elif delete: + default_item = (default_item - 1) if default_item > 1 else 1 + + if not param.is_list or len(param.value) == 0: + break return True diff --git a/image_creator/os_type/__init__.py b/image_creator/os_type/__init__.py index 10944a8..e65e753 100644 --- a/image_creator/os_type/__init__.py +++ b/image_creator/os_type/__init__.py @@ -98,11 +98,11 @@ def sysprep(message, enabled=True, **kwargs): class SysprepParam(object): """This class represents a system preparation parameter""" - def __init__(self, type, default, description, **kwargs): + def __init__(self, name, type, default, description, **kwargs): - assert hasattr(self, "_check_%s" % type), "Invalid type: %s" % type - - self.type = type + self.name = name + self.is_list = type.startswith('list:') + self.type = type.split(':', 1)[1] if self.is_list else type self.default = default self.description = description self.value = default @@ -110,15 +110,25 @@ class SysprepParam(object): self.check = kwargs['check'] if 'check' in kwargs else lambda x: x self.hidden = kwargs['hidden'] if 'hidden' in kwargs else False + assert hasattr(self, "_check_%s" % self.type), \ + "Invalid type: %s" % self.type + def set_value(self, value): """Update the value of the parameter""" check_type = getattr(self, "_check_%s" % self.type) - try: - self.value = self.check(check_type(value)) - except ValueError as e: - self.error = e.message - return False + + tmp = [] + + for item in value if self.is_list else [value]: + try: + tmp.append(self.check(check_type(item))) + except ValueError as e: + self.error = e.message + return False + + self.value = tmp if self.is_list else tmp[0] + return True def _check_posint(self, value): @@ -185,7 +195,7 @@ def add_sysprep_param(name, type, default, descr, **kwargs): self.sysprep_params = {} self.sysprep_params[name] = \ - SysprepParam(type, default, descr, **extra) + SysprepParam(name, type, default, descr, **extra) init(self, *args, **kwargs) return inner return wrapper @@ -223,6 +233,19 @@ class OSBase(object): self.out.warn("Ignoring invalid `%s' parameter." % key) continue param = self.sysprep_params[key] + if param.is_list: + def split_in_comma(val): + tmp = val.split(',') + prev = "" + for i in xrange(len(tmp)): + item = prev + tmp[i] + if item.endswith('\\'): + prev = item[:-1] + continue + prev = "" + yield item + val = list(split_in_comma(val)) + if not param.set_value(val): raise FatalError("Invalid value for sysprep parameter: " "`%s'. Reason: %s" % (key, param.error)) @@ -401,15 +424,19 @@ class OSBase(object): wrapper = textwrap.TextWrapper() wrapper.subsequent_indent = " " - wrapper.width = 72 + wrapper.width = 80 for name, param in public_params: if param.hidden: continue - self.out.output("NAME: %s" % name) - self.out.output("VALUE: %s" % param.value) - self.out.output( - wrapper.fill("DESCRIPTION: %s" % param.description)) + self.out.output("NAME:".ljust(13) + name) + self.out.output(wrapper.fill("DESCRIPTION:".ljust(13) + + "%s" % param.description)) + self.out.output("TYPE:".ljust(13) + "%s%s" % + ("list:" if param.is_list else "", param.type)) + self.out.output("VALUE:".ljust(13) + + ("\n".ljust(14).join(param.value) if param.is_list + else param.value)) self.out.output() def do_sysprep(self): -- GitLab