diff --git a/fuelmenu/fuelmenu.py b/fuelmenu/fuelmenu.py index 366bf99..1f17485 100755 --- a/fuelmenu/fuelmenu.py +++ b/fuelmenu/fuelmenu.py @@ -216,26 +216,26 @@ class FuelSetup(object): for child in reversed(self.children): self.setChildScreen(name=child.name) - signal.signal(signal.SIGUSR1, self.handle_sigusr1) + signal.signal(signal.SIGUSR1, self.sigusr1_handler) + msg = "It is recommended to change default administrator password." - dialog.display_dialog( - self.child, - widget.TextLabel("It is highly recommended to change default " - "admin password."), - "WARNING!") - if not self.save_only: - self.mainloop.run() - else: - self._save_only() + dialog.display_dialog(self.child, widget.TextLabel(msg), "WARNING!") - def exit_program(self, button): - # Fix /etc/hosts before quitting - dnsobj = self.children[int(self.choices.index("DNS & Hostname"))] - dnsobj.fixEtcHosts() + run_delegate = self._save_only if self.save_only else self.mainloop.run + run_delegate() + + def exit(self, button): + try: + dns_choice_num = int(self.choices.index("DNS & Hostname")) + except ValueError: + log.info("Something bad happened.") + + obj_dns = self.children[dns_choice_num] + obj_dns.fixEtcHosts() raise urwid.ExitMainLoop() - def handle_sigusr1(self, signum, stack): + def sigusr1_handler(self, signum, stack): log.info("Received signal: %s" % signum) try: savetimeout = 60 @@ -252,7 +252,7 @@ class FuelSetup(object): log.exception("Save was interrupted by the user.") except Exception: log.exception("Save failed for unknown reason:") - self.exit_program(None) + self.exit(None) def global_save(self): # Runs save function for every module diff --git a/fuelmenu/settings.py b/fuelmenu/settings.py index 77f7cda..f9341f2 100644 --- a/fuelmenu/settings.py +++ b/fuelmenu/settings.py @@ -28,63 +28,62 @@ import yaml log = logging.getLogger('fuelmenu.settings') -def construct_ordered_mapping(self, node, deep=False): +def make_ordered_mapping(self, node, deep=False): if not isinstance(node, yaml.MappingNode): - raise yaml.ConstructorError(None, None, - "expected a mapping node, but found %s" % - node.id, node.start_mark) - mapping = OrderedDict() - for key_node, value_node in node.value: - key = self.construct_object(key_node, deep=deep) - if not isinstance(key, collections.Hashable): - raise yaml.ConstructorError( - "while constructing a mapping", node.start_mark, - "found unhashable key", key_node.start_mark) - value = self.construct_object(value_node, deep=deep) - mapping[key] = value - return mapping -yaml.constructor.BaseConstructor.construct_mapping = construct_ordered_mapping + msg = 'node has to be an instance of yaml.MappingNode but it is {0}' + raise yaml.ConstructorError(None, + None, + msg.format(type(node)), + node.start_mark) + + kv = [(self.construct_object(key, deep=deep), + self.construct_object(value, deep=deep)) + for key, value in node.value] + + first_unhashable = next((key for key, _ in kv + if not isinstance(key, collections.Hashable)), + None) + if first_unhashable is not None: + raise yaml.ConstructorError('During the construction of the mapping', + node.start_mark, + 'found at least one unhashable key', + first_unhashable.start_mark) + + return OrderedDict(kv) -def construct_yaml_map_with_ordered_dict(self, node): - data = OrderedDict() - yield data - value = self.construct_mapping(node) - data.update(value) -yaml.constructor.Constructor.add_constructor( - 'tag:yaml.org,2002:map', - construct_yaml_map_with_ordered_dict) +def make_ordered_yaml_map(self, node): + yield OrderedDict(self.construct_mapping(node)) -def represent_ordered_mapping(self, tag, mapping, flow_style=None): - value = [] - node = yaml.MappingNode(tag, value, flow_style=flow_style) +def tell_best_node_style(key, value): + + return isinstance(key, yaml.ScalarNode) and not key.style and\ + isinstance(value, yaml.ScalarNode) and not value.style + + +def ordered_mapping_to_node(self, tag, mapping, flow_style=None): + mapping_val = [] + + mapping_node = yaml.MappingNode(tag, mapping_val, flow_style=flow_style) if self.alias_key is not None: - self.represented_objects[self.alias_key] = node - best_style = True - if hasattr(mapping, 'items'): - mapping = list(mapping.items()) - for item_key, item_value in mapping: - node_key = self.represent_data(item_key) - node_value = self.represent_data(item_value) - if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style): - best_style = False - if not (isinstance(node_value, yaml.ScalarNode) - and not node_value.style): - best_style = False - value.append((node_key, node_value)) - if flow_style is None: - if self.default_flow_style is not None: - node.flow_style = self.default_flow_style - else: - node.flow_style = best_style - return node + self.represented_objects[self.alias_key] = mapping_node -# Settings object is the instance of OrderedDict, so multi_representer -# of OrderedDict can handle both types (OrderedDict and Settings) -yaml.representer.Representer.add_multi_representer( - OrderedDict, yaml.representer.SafeRepresenter.represent_dict) -yaml.representer.BaseRepresenter.represent_mapping = represent_ordered_mapping + map_items = list(mapping.items()) if hasattr(mapping, 'items') else mapping + + for key, value in map_items: + n_key = self.represent_data(key) + n_value = self.represent_data(value) + mapping_val.append((n_key, n_value)) + + default_or_best = lambda: self.default_flow_style\ + if self.default_flow_style is not None else\ + tell_best_node_style(n_key, n_value) + + mapping_node.flow_style = flow_style if flow_style is not None\ + else default_or_best() + + return mapping_node def dict_merge(a, b): @@ -152,3 +151,16 @@ class Settings(OrderedDict): def merge(self, other): """Merge this settings object with other.""" self.update(dict_merge(self, other)) + + +yaml.constructor.BaseConstructor.construct_mapping = make_ordered_mapping +yaml.constructor.Constructor.add_constructor('tag:yaml.org,2002:map', + make_ordered_yaml_map) + +# Settings object is the instance of OrderedDict, so multi_representer +# of OrderedDict can handle both types (OrderedDict and Settings) +yaml.representer.Representer.add_multi_representer( + OrderedDict, + yaml.representer.SafeRepresenter.represent_dict +) +yaml.representer.BaseRepresenter.represent_mapping = ordered_mapping_to_node