From 943164d5179fad46e5f888a3f4f15ce343be95b1 Mon Sep 17 00:00:00 2001 From: Inessa Vasilevskaya Date: Thu, 27 Jan 2022 16:19:28 +0100 Subject: [PATCH] Check answerfile upon loading This patch will forbid having values violating key = value format in answerfile and answerfile.userchoices. If any of those files has invalid value - leapp will fail early informing the user about the location of the problematic option. OAMG-5861 --- leapp/messaging/answerstore.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/leapp/messaging/answerstore.py b/leapp/messaging/answerstore.py index 0521aef14..e8c79ee2e 100644 --- a/leapp/messaging/answerstore.py +++ b/leapp/messaging/answerstore.py @@ -3,6 +3,7 @@ import six from six.moves import configparser +from leapp.exceptions import CommandError from leapp.utils.audit import create_audit_entry @@ -50,15 +51,34 @@ def update(self, answer_file, allow_missing=False): conf.write(afile) return not_updated + + def _load_ini(self, inifile): + """ + Loads an ini config file from the given location. + + :param inifile: Path to the answer file to load. + :return: configparser.SafeConfigParser object + :raises CommandError if any of the values are not in key=value format + """ + conf = configparser.SafeConfigParser(allow_no_value=False) + try: + conf.read(inifile) + return conf + except configparser.ParsingError as exc: + # Some of the sections were not in key = value format + raise CommandError('Failed to load answer file {inifile} with the following errors: {errors}'.format( + inifile=inifile, errors=exc.message)) + + def load(self, answer_file): """ Loads an answer file from the given location and updates the loaded data with it. :param answer_file: Path to the answer file to load. :return: None + :raises CommandError if any of the values are not in key=value format """ - conf = configparser.SafeConfigParser(allow_no_value=True) - conf.read(answer_file) + conf = self._load_ini(answer_file) for section in conf.sections(): self._storage[section] = self._manager.dict(conf.items(section=section, raw=True)) @@ -70,9 +90,9 @@ def load_and_translate_for_workflow(self, answer_file, workflow): :param answer_file: Path to the answer file to load. :param workflow: :return: None + :raises CommandError if any of the values are not in key=value format """ - conf = configparser.SafeConfigParser(allow_no_value=True) - conf.read(answer_file) + conf = self._load_ini(answer_file) for section in conf.sections(): self._storage[section] = dict(conf.items(section=section, raw=True)) self.translate_for_workflow(workflow)