def preseed(self, name, value, seen=True): value = misc.debconf_escape(value) try: self.db.set(name, value) except debconf.DebconfError: self.db.register('debian-installer/dummy', name) self.db.set(name, value) self.db.subst(name, 'ID', name) if seen: self.db.fset(name, 'seen', 'true')
def preseed(self, name, value, seen=True): value = misc.debconf_escape(value) try: value = value.encode("UTF-8", "ignore") except UnicodeDecodeError: pass try: self.db.set(name, value) except debconf.DebconfError: self.db.register('debian-installer/dummy', name) self.db.set(name, value) self.db.subst(name, 'ID', name) if seen: self.db.fset(name, 'seen', 'true')
def test_debconf_escape(self): self.assertEqual(misc.debconf_escape('\\A test string\n'), '\\\\A\\ test\\ string\\n')
def process_line(self): line = self.tryreadline() if line is None: return True if line == '': return False # TODO: handle escaped input line = line.rstrip('\n') params = line.split(None, 1) if not params: return True command = params[0].upper() if len(params) > 1: rest = params[1] else: rest = '' # Split parameters according to the command name. if valid_commands.get(command, 0) == 0: params = [rest] elif valid_commands[command] is None: params = rest.split() else: params = rest.split(None, valid_commands[command] - 1) self.debug('filter', '<--', command, *params) if line == '' or line.startswith(' ') or command not in valid_commands: # Work around confmodules that try to send multi-line commands; # this works (sort of, and by fluke) in cdebconf, but debconf # doesn't like it. self.debug('filter', 'ignoring unknown (multi-line?) command') return True if command == 'CAPB': self.escaping = 'escape' in params self.progress_cancel = 'progresscancel' in params for widget in self.find_widgets(['CAPB'], 'capb'): self.debug('filter', 'capb widget found') widget.capb(params) if 'escape' not in params: params.append('escape') if command == 'INPUT' and len(params) == 2: (priority, question) = params input_widgets = self.find_widgets([question]) if len(input_widgets) > 0: if self.automatic: if self.db.fget(question, 'seen') == 'true': self.reply(30, 'question skipped', log=True) self.next_go_backup = False return True self.debug('filter', 'widget found for', question) if not input_widgets[0].run(priority, question): self.debug('filter', 'widget requested backup') self.next_go_backup = True else: self.next_go_backup = False self.reply(0, 'question will be asked', log=True) return True elif 'ERROR' in self.widgets: # If it's an error template, fall back to generic error # handling. try: if self.question_type(question) == 'error': widget = self.widgets['ERROR'] self.debug('filter', 'error widget found for', question) if not widget.error(priority, question): self.debug('filter', 'widget requested backup') self.next_go_backup = True else: self.next_go_backup = False self.reply(0, 'question will be asked', log=True) return True except debconf.DebconfError: pass if command == 'SET' and len(params) >= 2: question = params[0] value = ' '.join(params[1:]) for widget in self.find_widgets([question], 'set'): self.debug('filter', 'widget found for', question) widget.set(question, value) if command == 'SUBST' and len(params) >= 3: (question, key) = params[0:2] value = ' '.join(params[2:]) for widget in self.find_widgets([question], 'subst'): self.debug('filter', 'widget found for', question) widget.subst(question, key, value) if command == 'METAGET' and len(params) == 2: (question, field) = params for widget in self.find_widgets([question], 'metaget'): self.debug('filter', 'widget found for', question) widget.metaget(question, field) if command == 'PROGRESS' and len(params) >= 1: subcommand = params[0].upper() cancelled = False if subcommand == 'START' and len(params) == 4: progress_min = int(params[1]) progress_max = int(params[2]) progress_title = params[3] for widget in self.find_widgets([progress_title, 'PROGRESS'], 'progress_start'): self.debug('filter', 'widget found for', progress_title) widget.progress_start(progress_min, progress_max, progress_title) self.progress_bars.insert(0, progress_title) elif len(self.progress_bars) != 0: if subcommand == 'SET' and len(params) == 2: progress_val = int(params[1]) for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_set'): self.debug('filter', 'widget found for', self.progress_bars[0]) if not widget.progress_set(self.progress_bars[0], progress_val): cancelled = True elif subcommand == 'STEP' and len(params) == 2: progress_inc = int(params[1]) for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_step'): self.debug('filter', 'widget found for', self.progress_bars[0]) if not widget.progress_step(self.progress_bars[0], progress_inc): cancelled = True elif subcommand == 'INFO' and len(params) == 2: progress_info = params[1] for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_info'): self.debug('filter', 'widget found for', self.progress_bars[0]) if not widget.progress_info(self.progress_bars[0], progress_info): cancelled = True elif subcommand == 'STOP' and len(params) == 1: for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_stop'): self.debug('filter', 'widget found for', self.progress_bars[0]) widget.progress_stop() self.progress_bars.pop() elif subcommand == 'REGION' and len(params) == 3: progress_region_start = int(params[1]) progress_region_end = int(params[2]) for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_region'): self.debug('filter', 'widget found for', self.progress_bars[0]) widget.progress_region(self.progress_bars[0], progress_region_start, progress_region_end) # We handle all progress bars ourselves; don't pass them through # to the debconf frontend. if self.progress_cancel and cancelled: self.reply(30, 'progress bar cancelled', log=True) else: self.reply(0, 'OK', log=True) return True if command == 'GO' and self.next_go_backup: self.reply(30, 'backup', log=True) return True if command == 'PURGE': # PURGE probably corresponds to a package being removed, but # since we don't know which package that is at this level, # passing it through will purge our own templates rather than # the package's. self.reply(0, log=True) return True if command == 'STOP': return True if command == 'X_LOADTEMPLATEFILE' and len(params) >= 1: # The template file we've been asked to load might actually be # in the /target chroot rather than in the root filesystem. If # so, rewrite the command. if params[0].startswith('/'): target_template = os.path.join('/target', params[0][1:]) if os.path.exists(target_template): params[0] = target_template try: if not self.escaping: params = [misc.debconf_escape(param) for param in params] data = self.db.command(command, *params) self.reply(0, data) # Visible elements reset the backup state. If we just reset the # backup state on GO, then invisible elements would not be # properly skipped over in multi-stage backups. if command == 'INPUT': self.next_go_backup = False except debconf.DebconfError as e: self.reply(*e.args) return True
def process_line(self): line = self.tryreadline() if line is None: return True if line == '': return False # TODO: handle escaped input line = line.rstrip('\n') params = line.split(None, 1) if not params: return True command = params[0].upper() if len(params) > 1: rest = params[1] else: rest = '' # Split parameters according to the command name. if valid_commands.get(command, 0) == 0: params = [rest] elif valid_commands[command] is None: params = rest.split() else: params = rest.split(None, valid_commands[command] - 1) self.debug('filter', '<--', command, *params) if line == '' or line.startswith(' ') or command not in valid_commands: # Work around confmodules that try to send multi-line commands; # this works (sort of, and by fluke) in cdebconf, but debconf # doesn't like it. self.debug('filter', 'ignoring unknown (multi-line?) command') return True if command == 'CAPB': self.escaping = 'escape' in params self.progress_cancel = 'progresscancel' in params for widget in self.find_widgets(['CAPB'], 'capb'): self.debug('filter', 'capb widget found') widget.capb(params) if 'escape' not in params: params.append('escape') if command == 'INPUT' and len(params) == 2: (priority, question) = params input_widgets = self.find_widgets([question]) if len(input_widgets) > 0: if self.automatic: if self.db.fget(question, 'seen') == 'true': self.reply(30, 'question skipped', log=True) self.next_go_backup = False return True self.debug('filter', 'widget found for', question) if not input_widgets[0].run(priority, question): self.debug('filter', 'widget requested backup') self.next_go_backup = True else: self.next_go_backup = False self.reply(0, 'question will be asked', log=True) return True elif 'ERROR' in self.widgets: # If it's an error template, fall back to generic error # handling. try: if self.question_type(question) == 'error': widget = self.widgets['ERROR'] self.debug('filter', 'error widget found for', question) if not widget.error(priority, question): self.debug('filter', 'widget requested backup') self.next_go_backup = True else: self.next_go_backup = False self.reply(0, 'question will be asked', log=True) return True except debconf.DebconfError: pass if command == 'SET' and len(params) >= 2: question = params[0] value = ' '.join(params[1:]) for widget in self.find_widgets([question], 'set'): self.debug('filter', 'widget found for', question) widget.set(question, value) if command == 'SUBST' and len(params) >= 3: (question, key) = params[0:2] value = ' '.join(params[2:]) for widget in self.find_widgets([question], 'subst'): self.debug('filter', 'widget found for', question) widget.subst(question, key, value) if command == 'METAGET' and len(params) == 2: (question, field) = params for widget in self.find_widgets([question], 'metaget'): self.debug('filter', 'widget found for', question) widget.metaget(question, field) if command == 'PROGRESS' and len(params) >= 1: subcommand = params[0].upper() cancelled = False if subcommand == 'START' and len(params) == 4: progress_min = int(params[1]) progress_max = int(params[2]) progress_title = params[3] for widget in self.find_widgets( [progress_title, 'PROGRESS'], 'progress_start'): self.debug('filter', 'widget found for', progress_title) widget.progress_start(progress_min, progress_max, progress_title) self.progress_bars.insert(0, progress_title) elif len(self.progress_bars) != 0: if subcommand == 'SET' and len(params) == 2: progress_val = int(params[1]) for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_set'): self.debug('filter', 'widget found for', self.progress_bars[0]) if not widget.progress_set(self.progress_bars[0], progress_val): cancelled = True elif subcommand == 'STEP' and len(params) == 2: progress_inc = int(params[1]) for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_step'): self.debug('filter', 'widget found for', self.progress_bars[0]) if not widget.progress_step(self.progress_bars[0], progress_inc): cancelled = True elif subcommand == 'INFO' and len(params) == 2: progress_info = params[1] for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_info'): self.debug('filter', 'widget found for', self.progress_bars[0]) if not widget.progress_info(self.progress_bars[0], progress_info): cancelled = True elif subcommand == 'STOP' and len(params) == 1: for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_stop'): self.debug('filter', 'widget found for', self.progress_bars[0]) widget.progress_stop() self.progress_bars.pop() elif subcommand == 'REGION' and len(params) == 3: progress_region_start = int(params[1]) progress_region_end = int(params[2]) for widget in self.find_widgets( [self.progress_bars[0], 'PROGRESS'], 'progress_region'): self.debug('filter', 'widget found for', self.progress_bars[0]) widget.progress_region(self.progress_bars[0], progress_region_start, progress_region_end) # We handle all progress bars ourselves; don't pass them through # to the debconf frontend. if self.progress_cancel and cancelled: self.reply(30, 'progress bar cancelled', log=True) else: self.reply(0, 'OK', log=True) return True if command == 'GO' and self.next_go_backup: self.reply(30, 'backup', log=True) return True if command == 'PURGE': # PURGE probably corresponds to a package being removed, but # since we don't know which package that is at this level, # passing it through will purge our own templates rather than # the package's. self.reply(0, log=True) return True if command == 'STOP': return True if command == 'X_LOADTEMPLATEFILE' and len(params) >= 1: # The template file we've been asked to load might actually be # in the /target chroot rather than in the root filesystem. If # so, rewrite the command. if params[0].startswith('/'): target_template = os.path.join('/target', params[0][1:]) if os.path.exists(target_template): params[0] = target_template try: if not self.escaping: params = [misc.debconf_escape(param) for param in params] data = self.db.command(command, *params) self.reply(0, data) # Visible elements reset the backup state. If we just reset the # backup state on GO, then invisible elements would not be # properly skipped over in multi-stage backups. if command == 'INPUT': self.next_go_backup = False except debconf.DebconfError as e: self.reply(*e.args) return True