def error(self, priority, question): if question == 'partman-partitioning/impossible_resize': # Back up silently. return False elif question == 'partman-partitioning/bad_new_partition_size': if self.creating_partition: # Break out of creating the partition. self.creating_partition['bad_size'] = True elif question in ('partman-partitioning/bad_new_size', 'partman-partitioning/big_new_size', 'partman-partitioning/small_new_size', 'partman-partitioning/new_size_commit_failed'): if self.editing_partition: # Break out of resizing the partition. self.editing_partition['bad_size'] = True else: # Break out of resizing the partition in cases where partman # fed us bad boundary values. These are bugs in partman, but # we should handle the result as gracefully as possible. self.bad_auto_size = True elif question == 'partman-basicfilesystems/bad_mountpoint': # Break out of creating or editing the partition. if self.creating_partition: self.creating_partition['bad_mountpoint'] = True elif self.editing_partition: self.editing_partition['bad_mountpoint'] = True self.frontend.error_dialog(self.description(question), self.extended_description(question)) return FilteredCommand.error(self, priority, question)
def error(self, priority, question): if question.startswith('passwd/username-'): self.frontend.username_error(self.extended_description(question)) elif question.startswith('user-setup/password-'): self.frontend.password_error(self.extended_description(question)) else: self.frontend.error_dialog(self.description(question), self.extended_description(question)) return FilteredCommand.error(self, priority, question)
def run(self, priority, question): if self.done: return self.succeeded if question.startswith('partman/confirm'): if question == 'partman/confirm': self.db.set('ubiquity/partman-made-changes', 'true') else: self.db.set('ubiquity/partman-made-changes', 'false') self.preseed(question, 'true') return True elif question == 'partman/exception_handler': if priority == 'critical' or priority == 'high': response = self.frontend.question_dialog( self.description(question), self.extended_description(question), self.choices(question), use_templates=False) self.preseed(question, response, seen=False) else: self.preseed(question, 'unhandled', seen=False) return True elif question == 'partman/exception_handler_note': if priority == 'critical' or priority == 'high': self.frontend.error_dialog(self.description(question), self.extended_description(question)) return FilteredCommand.error(self, priority, question) else: return True elif self.question_type(question) == 'boolean': response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ('ubiquity/text/go_back', 'ubiquity/text/continue')) answer_reversed = False if (question == 'partman-jfs/jfs_boot' or question == 'partman-jfs/jfs_root'): answer_reversed = True if response is None or response == 'ubiquity/text/continue': answer = answer_reversed else: answer = not answer_reversed self.succeeded = False self.done = True self.frontend.return_to_partitioning() if answer: self.preseed(question, 'true') else: self.preseed(question, 'false') return True else: return FilteredCommand.run(self, priority, question)
def run(self, priority, question): if self.done: return self.succeeded if question.startswith('partman/confirm'): self.db.set('ubiquity/partman-confirm', question[8:]) self.preseed(question, 'true') return True elif question == 'partman/exception_handler': if priority == 'critical' or priority == 'high': response = self.frontend.question_dialog( self.description(question), self.extended_description(question), self.choices(question), use_templates=False) self.preseed(question, response, seen=False) else: self.preseed(question, 'unhandled', seen=False) return True elif question == 'partman/exception_handler_note': if priority == 'critical' or priority == 'high': self.frontend.error_dialog(self.description(question), self.extended_description(question)) return FilteredCommand.error(self, priority, question) else: return True elif self.question_type(question) == 'boolean': response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ('ubiquity/text/go_back', 'ubiquity/text/continue')) answer_reversed = False if (question == 'partman-jfs/jfs_boot' or question == 'partman-jfs/jfs_root'): answer_reversed = True if response is None or response == 'ubiquity/text/continue': answer = answer_reversed else: answer = not answer_reversed self.succeeded = False self.done = True self.frontend.return_to_partitioning() if answer: self.preseed(question, 'true') else: self.preseed(question, 'false') return True else: return FilteredCommand.run(self, priority, question)
def error(self, priority, question): if question == "hw-detect/modprobe_error": # don't need to display this, and it's non-fatal return True elif question == "apt-setup/security-updates-failed": fatal = False else: fatal = True self.frontend.error_dialog(self.description(question), self.extended_description(question), fatal) if fatal: return FilteredCommand.error(self, priority, question) else: return True
def error(self, priority, question): if question == 'hw-detect/modprobe_error': # don't need to display this, and it's non-fatal return True elif question == 'apt-setup/security-updates-failed': fatal = False else: fatal = True self.frontend.error_dialog(self.description(question), self.extended_description(question), fatal) if fatal: return FilteredCommand.error(self, priority, question) else: return True
def error(self, priority, question): if question == 'hw-detect/modprobe_error': # don't need to display this, and it's non-fatal return True elif question == 'apt-setup/security-updates-failed': fatal = False elif (question == 'ubiquity/install/broken_active_directory' or question == 'ubiquity/install/broken_luks_add_key'): fatal = False else: fatal = True self.frontend.error_dialog(self.description(question), self.extended_description(question), fatal) if fatal: return FilteredCommand.error(self, priority, question) else: return True
def error(self, priority, question): self.frontend.error_dialog(self.description(question), self.extended_description(question)) return FilteredCommand.error(self, priority, question)
def error(self, priority, question): self.frontend.error_dialog(self.description(question), self.extended_description(question)) return FilteredCommand.error(self, priority, question)
def run(self, priority, question): if self.done: # user answered confirmation question or backed up return self.succeeded self.current_question = question options = self.snoop() menu_options = self.snoop_menu(options) self.debug('Partman: state = %s', self.__state) if question.endswith('automatically_partition'): self.autopartition_question = question choices = self.choices(question) if self.auto_state is None: self.some_device_desc = \ self.description('partman-auto/text/use_device') self.resize_desc = \ self.description('partman-auto/text/resize_use_free') self.manual_desc = \ self.description('partman-auto/text/custom_partitioning') self.extra_options = {} if choices: self.auto_state = [0, None] else: self.auto_state[0] += 1 while self.auto_state[0] < len(choices): self.auto_state[1] = choices[self.auto_state[0]] if (self.auto_state[1] == self.some_device_desc or self.auto_state[1] == self.resize_desc): break else: self.auto_state[0] += 1 if self.auto_state[0] < len(choices): # Don't preseed_as_c, because Perl debconf is buggy in that # it doesn't expand variables in the result of METAGET # choices-c. All locales have the same variables anyway so # it doesn't matter. self.preseed(question, self.auto_state[1]) self.succeeded = True return True else: self.auto_state = None if self.resize_desc not in self.extra_options: try: del choices[choices.index(self.resize_desc)] except ValueError: pass self.frontend.set_autopartition_choices( choices, self.extra_options, self.resize_desc, self.manual_desc) elif question == 'partman-auto/select_disk': if self.auto_state is not None: self.extra_options[self.auto_state[1]] = self.choices(question) # Back up to autopartitioning question. self.succeeded = False return False else: assert self.extra_choice is not None self.preseed(question, self.extra_choice) self.succeeded = True return True elif question == 'partman/choose_partition': self.autopartition_question = None # not autopartitioning any more if not self.building_cache and self.update_partitions: # Rebuild our cache of just these partitions. self.__state = [['', None, None]] self.building_cache = True if 'ALL' in self.update_partitions: self.update_partitions = None if self.building_cache: state = self.__state[-1] if state[0] == question: # advance to next partition self.frontend.debconf_progress_step(1) self.frontend.refresh() self.debug('Partman: update_partitions = %s', self.update_partitions) state[1] = None while self.update_partitions: state[1] = self.update_partitions[0] del self.update_partitions[0] if state[1] not in self.partition_cache: self.debug('Partman: %s not found in cache', partition) state[1] = None self.frontend.debconf_progress_step(1) self.frontend.refresh() else: break if state[1] is not None: # Move on to the next partition. partition = self.partition_cache[state[1]] self.debug('Partman: Building cache (%s)', partition['parted']['path']) self.preseed(question, partition['display']) return True else: # Finished building the cache. self.debug('Partman: Finished building cache') self.__state.pop() self.update_partitions = None self.building_cache = False self.frontend.debconf_progress_stop() self.frontend.refresh() self.frontend.update_partman( self.disk_cache, self.partition_cache, self.cache_order) else: self.debug('Partman: Building cache') os.seteuid(0) parted = parted_server.PartedServer() matches = self.find_script(menu_options, 'partition_tree') # If we're only updating our cache for certain # partitions, then self.update_partitions will be a list # of the partitions to update; otherwise, we build the # cache from scratch. rebuild_all = self.update_partitions is None if rebuild_all: self.disk_cache = {} self.partition_cache = {} self.cache_order = [] # Clear out the partitions we're updating to make sure # stale keys are removed. if self.update_partitions is not None: for devpart in self.update_partitions: if devpart in self.partition_cache: del self.partition_cache[devpart] # Initialise any items we haven't heard of yet. for script, arg, option in matches: dev, part_id = self.split_devpart(arg) if not dev: continue parted.select_disk(dev) self.cache_order.append(arg) if part_id: if rebuild_all or arg not in self.partition_cache: self.partition_cache[arg] = { 'dev': dev, 'id': part_id } else: if rebuild_all or arg not in self.disk_cache: device = parted.readline_device_entry('device') self.disk_cache[arg] = { 'dev': dev, 'device': device } if self.update_partitions is None: self.update_partitions = self.partition_cache.keys() else: self.update_partitions = [devpart for devpart in self.update_partitions if devpart in self.partition_cache] # Update the display names of all disks and partitions. for script, arg, option in matches: dev, part_id = self.split_devpart(arg) if not dev: continue parted.select_disk(dev) if part_id: self.partition_cache[arg]['display'] = option else: self.disk_cache[arg]['display'] = option # Get basic information from parted_server for each # partition being updated. for devpart in self.update_partitions: dev, part_id = self.split_devpart(devpart) if not dev: continue parted.select_disk(dev) info = parted.partition_info(part_id) self.partition_cache[devpart]['parted'] = { 'num': info[0], 'id': info[1], 'size': info[2], 'type': info[3], 'fs': info[4], 'path': info[5], 'name': info[6] } drop_privileges() self.frontend.debconf_progress_start( 0, len(self.update_partitions), self.description('partman/progress/init/parted')) self.frontend.refresh() self.debug('Partman: update_partitions = %s', self.update_partitions) # Selecting a disk will ask to create a new disklabel, # so don't bother with that. devpart = None if self.partition_cache: while self.update_partitions: devpart = self.update_partitions[0] del self.update_partitions[0] if devpart not in self.partition_cache: self.debug('Partman: %s not found in cache', partition) devpart = None self.frontend.debconf_progress_step(1) self.frontend.refresh() else: break if devpart is not None: partition = self.partition_cache[devpart] self.debug('Partman: Building cache (%s)', partition['parted']['path']) self.__state.append([question, devpart, None]) self.preseed(question, partition['display']) return True else: self.debug('Partman: Finished building cache ' '(no partitions to update)') self.update_partitions = None self.building_cache = False self.frontend.debconf_progress_stop() self.frontend.refresh() self.frontend.update_partman( self.disk_cache, self.partition_cache, self.cache_order) elif self.creating_partition: devpart = self.creating_partition['devpart'] if devpart in self.partition_cache: self.frontend.update_partman( self.disk_cache, self.partition_cache, self.cache_order) elif self.editing_partition: devpart = self.editing_partition['devpart'] if devpart in self.partition_cache: self.frontend.update_partman( self.disk_cache, self.partition_cache, self.cache_order) elif self.deleting_partition: raise AssertionError, "Deleting partition didn't rebuild cache?" if self.debug_enabled(): import pprint self.debug('disk_cache:') printer = pprint.PrettyPrinter() for line in printer.pformat(self.disk_cache).split('\n'): self.debug('%s', line) self.debug('disk_cache end') self.debug('partition_cache:') printer = pprint.PrettyPrinter() for line in printer.pformat(self.partition_cache).split('\n'): self.debug('%s', line) self.debug('partition_cache end') self.__state = [['', None, None]] self.creating_label = None self.creating_partition = None self.editing_partition = None self.deleting_partition = None self.undoing = False self.finish_partitioning = False FilteredCommand.run(self, priority, question) if self.finish_partitioning or self.done: if self.succeeded: self.preseed_script(question, menu_options, 'finish') return self.succeeded elif self.creating_label: devpart = self.creating_label['devpart'] if devpart in self.disk_cache: disk = self.disk_cache[devpart] # No need to use self.__state to keep track of this. self.preseed(question, disk['display']) return True elif self.creating_partition: devpart = self.creating_partition['devpart'] if devpart in self.partition_cache: partition = self.partition_cache[devpart] self.__state.append([question, devpart, None]) self.preseed(question, partition['display']) return True elif self.editing_partition: devpart = self.editing_partition['devpart'] if devpart in self.partition_cache: partition = self.partition_cache[devpart] self.__state.append([question, devpart, None]) self.preseed(question, partition['display']) return True elif self.deleting_partition: devpart = self.deleting_partition['devpart'] if devpart in self.partition_cache: partition = self.partition_cache[devpart] # No need to use self.__state to keep track of this. self.preseed(question, partition['display']) return True elif self.undoing: self.preseed_script(question, menu_options, 'undo') return True else: raise AssertionError, ("Returned to %s with nothing to do" % question) elif question == 'partman-partitioning/confirm_new_label': if self.creating_label: response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ('ubiquity/text/go_back', 'ubiquity/text/continue')) if response is None or response == 'ubiquity/text/continue': self.preseed(question, 'true') else: self.preseed(question, 'false') return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman/free_space': if self.building_cache: state = self.__state[-1] assert state[0] == 'partman/choose_partition' partition = self.partition_cache[state[1]] can_new = False if self.find_script(menu_options, 'new'): can_new = True partition['can_new'] = can_new # Back up to the previous menu. return False elif self.creating_partition: self.preseed_script(question, menu_options, 'new') return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman-partitioning/new_partition_size': if self.creating_partition: if 'bad_size' in self.creating_partition: return False size = self.creating_partition['size'] if re.search(r'^[0-9.]+$', size): # ensure megabytes just in case partman's semantics change size += 'M' self.preseed(question, size) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman-partitioning/new_partition_type': if self.creating_partition: if self.creating_partition['type'] == PARTITION_TYPE_PRIMARY: self.preseed(question, 'Primary') else: self.preseed(question, 'Logical') return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman-partitioning/new_partition_place': if self.creating_partition: if (self.creating_partition['place'] == PARTITION_PLACE_BEGINNING): self.preseed(question, 'Beginning') else: self.preseed(question, 'End') return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman/active_partition': if self.building_cache: state = self.__state[-1] partition = self.partition_cache[state[1]] if state[0] == question: state[2] += 1 if state[2] < len(partition['active_partition_build']): # Move on to the next item. visit = partition['active_partition_build'] self.preseed(question, visit[state[2]][2]) return True else: # Finished building the cache for this submenu; go # back to the previous one. try: del partition['active_partition_build'] except KeyError: pass self.__state.pop() return False assert state[0] == 'partman/choose_partition' os.seteuid(0) parted = parted_server.PartedServer() parted.select_disk(partition['dev']) for entry in ('method', 'filesystem', 'detected_filesystem', 'acting_filesystem', 'existing', 'formatable', 'mountpoint'): if parted.has_part_entry(partition['id'], entry): partition[entry] = \ parted.readline_part_entry(partition['id'], entry) drop_privileges() visit = [] for (script, arg, option) in menu_options: if arg in ('method', 'mountpoint'): visit.append((script, arg, option)) elif arg == 'format': partition['can_activate_format'] = True elif arg == 'resize': visit.append((script, arg, option)) partition['can_resize'] = True if visit: partition['active_partition_build'] = visit self.__state.append([question, state[1], 0]) self.preseed(question, visit[0][2]) return True else: # Back up to the previous menu. return False elif self.creating_partition or self.editing_partition: if self.creating_partition: request = self.creating_partition else: request = self.editing_partition state = self.__state[-1] partition = self.partition_cache[state[1]] if state[0] != question: # Set up our intentions for this menu. visit = [] for item in ('method', 'mountpoint', 'format'): if item in request and request[item] is not None: visit.append(item) if (self.editing_partition and 'size' in request and request['size'] is not None): visit.append('resize') partition['active_partition_edit'] = visit self.__state.append([question, state[1], -1]) state = self.__state[-1] state[2] += 1 while state[2] < len(partition['active_partition_edit']): # Move on to the next item. visit = partition['active_partition_edit'] item = visit[state[2]] scripts = self.find_script(menu_options, None, item) if scripts: self.preseed(question, scripts[0][2]) return True state[2] += 1 # If we didn't find anything to do, finish editing this # partition. try: del partition['active_partition_edit'] except KeyError: pass self.__state.pop() self.preseed_script(question, menu_options, 'finish') return True elif self.deleting_partition: self.preseed_script(question, menu_options, 'delete') self.deleting_partition = None return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman-partitioning/confirm_resize': if self.autopartition_question is not None: if self.auto_state is not None: # Proceed through confirmation question; we'll back up # later. self.preseed(question, 'true') return True else: response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ('ubiquity/text/go_back', 'ubiquity/text/continue')) if (response is None or response == 'ubiquity/text/continue'): self.preseed(question, 'true') else: self.preseed(question, 'false') return True elif self.building_cache: state = self.__state[-1] assert state[0] == 'partman/active_partition' # Proceed through to asking for the size; don't worry, we'll # back up from there. self.preseed(question, 'true') return True elif self.editing_partition: response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ('ubiquity/text/go_back', 'ubiquity/text/continue')) if response is None or response == 'ubiquity/text/continue': self.preseed(question, 'true') else: self.preseed(question, 'false') return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman-partitioning/new_size': if self.autopartition_question is not None: if self.auto_state is not None: self.extra_options[self.auto_state[1]] = \ (self.resize_min_size, self.resize_max_size, self.resize_orig_size, self.resize_path) # Back up to autopartitioning question. self.succeeded = False return False else: assert self.extra_choice is not None if self.bad_auto_size: self.bad_auto_size = False return False self.preseed(question, '%d%%' % self.extra_choice) self.succeeded = True return True elif self.building_cache: # subst() should have gathered the necessary information. # Back up. return False elif self.editing_partition: if 'bad_size' in self.editing_partition: return False size = self.editing_partition['size'] if re.search(r'^[0-9.]+$', size): # ensure megabytes just in case partman's semantics change size += 'M' self.preseed(question, size) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman-target/choose_method': if self.building_cache: state = self.__state[-1] assert state[0] == 'partman/active_partition' partition = self.partition_cache[state[1]] partition['method_choices'] = [] for (script, arg, option) in menu_options: partition['method_choices'].append((script, arg, option)) # Back up to the previous menu. return False elif self.creating_partition or self.editing_partition: if self.creating_partition: request = self.creating_partition else: request = self.editing_partition self.preseed_script(question, menu_options, None, request['method']) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question in ('partman-basicfilesystems/mountpoint', 'partman-basicfilesystems/fat_mountpoint'): if self.building_cache: state = self.__state[-1] assert state[0] == 'partman/active_partition' partition = self.partition_cache[state[1]] partition['mountpoint_choices'] = [] choices_c = self.choices_untranslated(question) choices = self.choices(question) assert len(choices_c) == len(choices) for i in range(len(choices_c)): if choices_c[i].startswith('/'): partition['mountpoint_choices'].append(( choices_c[i].split(' ')[0], choices_c[i], choices[i])) # Back up to the previous menu. return False elif self.creating_partition or self.editing_partition: if self.creating_partition: request = self.creating_partition else: request = self.editing_partition if 'bad_mountpoint' in request: return False mountpoint = request['mountpoint'] if mountpoint == '' or mountpoint is None: self.preseed(question, 'Do not mount it') else: self.preseed(question, 'Enter manually') return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == 'partman-basicfilesystems/mountpoint_manual': if self.creating_partition or self.editing_partition: if self.creating_partition: request = self.creating_partition else: request = self.editing_partition if 'bad_mountpoint' in request: return False self.preseed(question, request['mountpoint']) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question.startswith('partman/confirm'): if question == 'partman/confirm': self.db.set('ubiquity/partman-made-changes', 'true') else: self.db.set('ubiquity/partman-made-changes', 'false') self.preseed(question, 'true') self.succeeded = True self.done = True return True elif question == 'partman/exception_handler': if priority == 'critical' or priority == 'high': response = self.frontend.question_dialog( self.description(question), self.extended_description(question), self.choices(question), use_templates=False) self.preseed(question, response) else: self.preseed(question, 'unhandled') return True elif question == 'partman/exception_handler_note': if priority == 'critical' or priority == 'high': self.frontend.error_dialog(self.description(question), self.extended_description(question)) return FilteredCommand.error(self, priority, question) else: return True elif self.question_type(question) == 'boolean': response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ('ubiquity/text/go_back', 'ubiquity/text/continue')) answer_reversed = False if question in ('partman-jfs/jfs_boot', 'partman-jfs/jfs_root', 'grub-installer/install_to_xfs'): answer_reversed = True if response is None or response == 'ubiquity/text/continue': answer = answer_reversed else: answer = not answer_reversed if answer: self.preseed(question, 'true') else: self.preseed(question, 'false') return True return FilteredCommand.run(self, priority, question)
def run(self, priority, question): if self.done: # user answered confirmation question or backed up return self.succeeded self.current_question = question options = self.snoop() menu_options = self.snoop_menu(options) self.debug("Partman: state = %s", self.__state) self.debug("Partman: auto_state = %s", self.auto_state) if question.endswith("automatically_partition"): self.autopartition_question = question choices = self.choices(question) if self.auto_state is None: self.some_device_desc = self.description("partman-auto/text/use_device") self.resize_desc = self.description("partman-auto/text/resize_use_free") self.manual_desc = self.description("partman-auto/text/custom_partitioning") self.biggest_free_desc = self.description("partman-auto/text/use_biggest_free") self.extra_options = {} if choices: self.auto_state = [0, None] else: self.auto_state[0] += 1 while self.auto_state[0] < len(choices): self.auto_state[1] = choices[self.auto_state[0]] if self.auto_state[1] == self.some_device_desc or self.auto_state[1] == self.resize_desc: break else: self.auto_state[0] += 1 if self.auto_state[0] < len(choices): self.preseed_as_c(question, self.auto_state[1], seen=False) self.succeeded = True return True else: self.auto_state = None if self.resize_desc not in self.extra_options: try: del choices[choices.index(self.resize_desc)] except ValueError: pass regain_privileges() # {'/dev/sda' : ('/dev/sda1', 24973242, '32256-2352430079'), ... # TODO evand 2009-04-16: We should really use named tuples here. parted = parted_server.PartedServer() layout = {} for disk in parted.disks(): parted.select_disk(disk) ret = [] total = 0 for partition in parted.partitions(): size = int(partition[2]) if partition[4] == "free": dev = "free" else: dev = partition[5] ret.append((dev, size, partition[1])) layout[disk] = ret self.frontend.set_disk_layout(layout) drop_privileges() # Set up translation mappings to avoid debian-installer # specific text ('Guided -'). self.translation_mappings = {} def map_trans(di_string, ubiquity_string): ubiquity_string = self.description(ubiquity_string) self.translation_mappings[ubiquity_string] = di_string try: choices[choices.index(di_string)] = ubiquity_string except ValueError: pass if di_string in self.extra_options: t = self.extra_options[di_string] del self.extra_options[di_string] self.extra_options[ubiquity_string] = t return ubiquity_string self.some_device_desc = map_trans(self.some_device_desc, "ubiquity/text/use_device") self.biggest_free_desc = map_trans(self.biggest_free_desc, "ubiquity/text/biggest_free") self.resize_desc = map_trans(self.resize_desc, "ubiquity/text/resize_use_free") self.manual_desc = map_trans(self.manual_desc, "ubiquity/text/custom_partitioning") biggest_free = self.find_script(menu_options, "biggest_free") if biggest_free: biggest_free = biggest_free[0][1] biggest_free = self.split_devpart(biggest_free)[1] self.extra_options[self.biggest_free_desc] = biggest_free self.frontend.set_autopartition_choices( choices, self.extra_options, self.resize_desc, self.manual_desc, self.biggest_free_desc ) elif question == "partman-auto/select_disk": if self.auto_state is not None: self.extra_options[self.auto_state[1]] = self.choices(question) # Back up to autopartitioning question. self.succeeded = False return False else: assert self.extra_choice is not None self.preseed_as_c(question, self.extra_choice, seen=False) self.succeeded = True return True elif question == "partman/choose_partition": self.autopartition_question = None # not autopartitioning any more if not self.building_cache and self.update_partitions: # Rebuild our cache of just these partitions. self.__state = [["", None, None]] self.building_cache = True if "ALL" in self.update_partitions: self.update_partitions = None if self.building_cache: state = self.__state[-1] if state[0] == question: # advance to next partition self.frontend.debconf_progress_step(1) self.frontend.refresh() self.debug("Partman: update_partitions = %s", self.update_partitions) state[1] = None while self.update_partitions: state[1] = self.update_partitions[0] del self.update_partitions[0] if state[1] not in self.partition_cache: self.debug("Partman: %s not found in cache", partition) state[1] = None self.frontend.debconf_progress_step(1) self.frontend.refresh() else: break if state[1] is not None: # Move on to the next partition. partition = self.partition_cache[state[1]] self.debug("Partman: Building cache (%s)", partition["parted"]["path"]) self.preseed(question, partition["display"], seen=False) return True else: # Finished building the cache. self.debug("Partman: Finished building cache") self.__state.pop() self.update_partitions = None self.building_cache = False self.frontend.debconf_progress_stop() self.frontend.refresh() self.frontend.update_partman(self.disk_cache, self.partition_cache, self.cache_order) else: self.debug("Partman: Building cache") regain_privileges() parted = parted_server.PartedServer() matches = self.find_script(menu_options, "partition_tree") # If we're only updating our cache for certain # partitions, then self.update_partitions will be a list # of the partitions to update; otherwise, we build the # cache from scratch. rebuild_all = self.update_partitions is None if rebuild_all: self.disk_cache = {} self.partition_cache = {} self.cache_order = [] # Clear out the partitions we're updating to make sure # stale keys are removed. if self.update_partitions is not None: for devpart in self.update_partitions: if devpart in self.partition_cache: del self.partition_cache[devpart] # Initialise any items we haven't heard of yet. for script, arg, option in matches: dev, part_id = self.split_devpart(arg) if not dev: continue parted.select_disk(dev) self.cache_order.append(arg) if part_id: if rebuild_all or arg not in self.partition_cache: self.partition_cache[arg] = {"dev": dev, "id": part_id, "parent": dev.replace("=", "/")} else: if rebuild_all or arg not in self.disk_cache: device = parted.readline_device_entry("device") self.disk_cache[arg] = {"dev": dev, "device": device} if self.update_partitions is None: self.update_partitions = self.partition_cache.keys() else: self.update_partitions = [ devpart for devpart in self.update_partitions if devpart in self.partition_cache ] # Update the display names of all disks and partitions. for script, arg, option in matches: dev, part_id = self.split_devpart(arg) if not dev: continue parted.select_disk(dev) if part_id: self.partition_cache[arg]["display"] = "%s__________%s" % (script, arg) else: self.disk_cache[arg]["display"] = "%s__________%s" % (script, arg) # Get basic information from parted_server for each # partition being updated. for devpart in self.update_partitions: dev, part_id = self.split_devpart(devpart) if not dev: continue parted.select_disk(dev) info = parted.partition_info(part_id) self.partition_cache[devpart]["parted"] = { "num": info[0], "id": info[1], "size": info[2], "type": info[3], "fs": info[4], "path": info[5], "name": info[6], } drop_privileges() self.frontend.debconf_progress_start( 0, len(self.update_partitions), self.description("partman/progress/init/parted") ) self.frontend.refresh() self.debug("Partman: update_partitions = %s", self.update_partitions) # Selecting a disk will ask to create a new disklabel, # so don't bother with that. devpart = None if self.partition_cache: while self.update_partitions: devpart = self.update_partitions[0] del self.update_partitions[0] if devpart not in self.partition_cache: self.debug("Partman: %s not found in cache", partition) devpart = None self.frontend.debconf_progress_step(1) self.frontend.refresh() else: break if devpart is not None: partition = self.partition_cache[devpart] self.debug("Partman: Building cache (%s)", partition["parted"]["path"]) self.__state.append([question, devpart, None]) self.preseed(question, partition["display"], seen=False) return True else: self.debug("Partman: Finished building cache " "(no partitions to update)") self.update_partitions = None self.building_cache = False self.frontend.debconf_progress_stop() self.frontend.refresh() self.frontend.update_partman(self.disk_cache, self.partition_cache, self.cache_order) elif self.creating_partition: devpart = self.creating_partition["devpart"] if devpart in self.partition_cache: self.frontend.update_partman(self.disk_cache, self.partition_cache, self.cache_order) elif self.editing_partition: devpart = self.editing_partition["devpart"] if devpart in self.partition_cache: self.frontend.update_partman(self.disk_cache, self.partition_cache, self.cache_order) elif self.deleting_partition: raise AssertionError, "Deleting partition didn't rebuild cache?" if self.debug_enabled(): import pprint self.debug("disk_cache:") printer = pprint.PrettyPrinter() for line in printer.pformat(self.disk_cache).split("\n"): self.debug("%s", line) self.debug("disk_cache end") self.debug("partition_cache:") printer = pprint.PrettyPrinter() for line in printer.pformat(self.partition_cache).split("\n"): self.debug("%s", line) self.debug("partition_cache end") self.__state = [["", None, None]] self.creating_label = None self.creating_partition = None self.editing_partition = None self.deleting_partition = None self.undoing = False self.finish_partitioning = False FilteredCommand.run(self, priority, question) if self.finish_partitioning or self.done: if self.succeeded: self.preseed_script(question, menu_options, "finish") return self.succeeded elif self.creating_label: devpart = self.creating_label["devpart"] if devpart in self.disk_cache: disk = self.disk_cache[devpart] # No need to use self.__state to keep track of this. self.preseed(question, disk["display"], seen=False) return True elif self.creating_partition: devpart = self.creating_partition["devpart"] if devpart in self.partition_cache: partition = self.partition_cache[devpart] self.__state.append([question, devpart, None]) self.preseed(question, partition["display"], seen=False) return True elif self.editing_partition: devpart = self.editing_partition["devpart"] if devpart in self.partition_cache: partition = self.partition_cache[devpart] self.__state.append([question, devpart, None]) self.preseed(question, partition["display"], seen=False) return True elif self.deleting_partition: devpart = self.deleting_partition["devpart"] if devpart in self.partition_cache: partition = self.partition_cache[devpart] # No need to use self.__state to keep track of this. self.preseed(question, partition["display"], seen=False) return True elif self.undoing: self.preseed_script(question, menu_options, "undo") return True else: raise AssertionError, ("Returned to %s with nothing to do" % question) elif question == "partman-partitioning/confirm_new_label": if self.creating_label: response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ("ubiquity/text/go_back", "ubiquity/text/continue"), ) if response is None or response == "ubiquity/text/continue": self.preseed(question, "true", seen=False) else: self.preseed(question, "false", seen=False) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman/free_space": if self.building_cache: state = self.__state[-1] assert state[0] == "partman/choose_partition" partition = self.partition_cache[state[1]] can_new = False if self.find_script(menu_options, "new"): can_new = True partition["can_new"] = can_new # Back up to the previous menu. return False elif self.creating_partition: self.preseed_script(question, menu_options, "new") return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman-partitioning/new_partition_size": if self.creating_partition: if "bad_size" in self.creating_partition: return False size = self.creating_partition["size"] if re.search(r"^[0-9.]+$", size): # ensure megabytes just in case partman's semantics change size += "M" self.preseed(question, size, seen=False) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman-partitioning/new_partition_type": if self.creating_partition: if self.creating_partition["type"] == PARTITION_TYPE_PRIMARY: self.preseed(question, "Primary", seen=False) else: self.preseed(question, "Logical", seen=False) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman-partitioning/new_partition_place": if self.creating_partition: if self.creating_partition["place"] == PARTITION_PLACE_BEGINNING: self.preseed(question, "Beginning", seen=False) else: self.preseed(question, "End", seen=False) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman/active_partition": if self.building_cache: state = self.__state[-1] partition = self.partition_cache[state[1]] if state[0] == question: state[2] += 1 if state[2] < len(partition["active_partition_build"]): # Move on to the next item. visit = partition["active_partition_build"] self.preseed_as_c(question, visit[state[2]][2], seen=False) return True else: # Finished building the cache for this submenu; go # back to the previous one. try: del partition["active_partition_build"] except KeyError: pass self.__state.pop() return False assert state[0] == "partman/choose_partition" regain_privileges() parted = parted_server.PartedServer() parted.select_disk(partition["dev"]) for entry in ( "method", "filesystem", "detected_filesystem", "acting_filesystem", "existing", "formatable", "mountpoint", ): if parted.has_part_entry(partition["id"], entry): partition[entry] = parted.readline_part_entry(partition["id"], entry) drop_privileges() visit = [] for (script, arg, option) in menu_options: if arg in ("method", "mountpoint"): visit.append((script, arg, option)) elif arg == "format": partition["can_activate_format"] = True elif arg == "resize": visit.append((script, arg, option)) partition["can_resize"] = True if visit: partition["active_partition_build"] = visit self.__state.append([question, state[1], 0]) self.preseed_as_c(question, visit[0][2], seen=False) return True else: # Back up to the previous menu. return False elif self.creating_partition or self.editing_partition: if self.creating_partition: request = self.creating_partition else: request = self.editing_partition state = self.__state[-1] partition = self.partition_cache[state[1]] if state[0] != question: # Set up our intentions for this menu. visit = [] for item in ("method", "mountpoint", "format"): if item in request and request[item] is not None: visit.append(item) if self.editing_partition and "size" in request and request["size"] is not None: visit.append("resize") partition["active_partition_edit"] = visit self.__state.append([question, state[1], -1]) state = self.__state[-1] state[2] += 1 while state[2] < len(partition["active_partition_edit"]): # Move on to the next item. visit = partition["active_partition_edit"] item = visit[state[2]] scripts = self.find_script(menu_options, None, item) if scripts: self.preseed_as_c(question, scripts[0][2], seen=False) return True state[2] += 1 # If we didn't find anything to do, finish editing this # partition. try: del partition["active_partition_edit"] except KeyError: pass self.__state.pop() self.preseed_script(question, menu_options, "finish") return True elif self.deleting_partition: self.preseed_script(question, menu_options, "delete") self.deleting_partition = None return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman-partitioning/confirm_resize": if self.autopartition_question is not None: if self.auto_state is not None: # Proceed through confirmation question; we'll back up # later. self.preseed(question, "true", seen=False) return True else: response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ("ubiquity/text/go_back", "ubiquity/text/continue"), ) if response is None or response == "ubiquity/text/continue": self.preseed(question, "true", seen=False) else: self.preseed(question, "false", seen=False) return True elif self.building_cache: state = self.__state[-1] assert state[0] == "partman/active_partition" # Proceed through to asking for the size; don't worry, we'll # back up from there. self.preseed(question, "true", seen=False) return True elif self.editing_partition: response = self.frontend.question_dialog( self.description(question), self.extended_description(question), ("ubiquity/text/go_back", "ubiquity/text/continue"), ) if response is None or response == "ubiquity/text/continue": self.preseed(question, "true", seen=False) else: self.preseed(question, "false", seen=False) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman-partitioning/new_size": if self.autopartition_question is not None: if self.auto_state is not None: self.extra_options[self.auto_state[1]] = ( self.resize_min_size, self.resize_max_size, self.resize_orig_size, self.resize_path, ) # Back up to autopartitioning question. self.succeeded = False return False else: assert self.extra_choice is not None if self.bad_auto_size: self.bad_auto_size = False return False self.preseed(question, self.extra_choice, seen=False) self.succeeded = True return True elif self.building_cache: # subst() should have gathered the necessary information. # Back up. return False elif self.editing_partition: if "bad_size" in self.editing_partition: return False size = self.editing_partition["size"] if re.search(r"^[0-9.]+$", size): # ensure megabytes just in case partman's semantics change size += "M" self.preseed(question, size, seen=False) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman-target/choose_method": if self.building_cache: state = self.__state[-1] assert state[0] == "partman/active_partition" partition = self.partition_cache[state[1]] partition["method_choices"] = [] for (script, arg, option) in menu_options: partition["method_choices"].append((script, arg, option)) # Back up to the previous menu. return False elif self.creating_partition or self.editing_partition: if self.creating_partition: request = self.creating_partition else: request = self.editing_partition self.preseed_script(question, menu_options, None, request["method"]) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question in ("partman-basicfilesystems/mountpoint", "partman-basicfilesystems/fat_mountpoint"): if self.building_cache: state = self.__state[-1] assert state[0] == "partman/active_partition" partition = self.partition_cache[state[1]] partition["mountpoint_choices"] = [] choices_c = self.choices_untranslated(question) choices = self.choices(question) assert len(choices_c) == len(choices) for i in range(len(choices_c)): if choices_c[i].startswith("/"): partition["mountpoint_choices"].append((choices_c[i].split(" ")[0], choices_c[i], choices[i])) # Back up to the previous menu. return False elif self.creating_partition or self.editing_partition: if self.creating_partition: request = self.creating_partition else: request = self.editing_partition if "bad_mountpoint" in request: return False mountpoint = request["mountpoint"] if mountpoint == "" or mountpoint is None: self.preseed(question, "Do not mount it", seen=False) else: self.preseed(question, "Enter manually", seen=False) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question == "partman-basicfilesystems/mountpoint_manual": if self.creating_partition or self.editing_partition: if self.creating_partition: request = self.creating_partition else: request = self.editing_partition if "bad_mountpoint" in request: return False self.preseed(question, request["mountpoint"], seen=False) return True else: raise AssertionError, "Arrived at %s unexpectedly" % question elif question.startswith("partman/confirm"): if question == "partman/confirm": self.db.set("ubiquity/partman-made-changes", "true") else: self.db.set("ubiquity/partman-made-changes", "false") self.preseed(question, "true", seen=False) self.succeeded = True self.done = True return True elif question == "partman/exception_handler": if priority == "critical" or priority == "high": response = self.frontend.question_dialog( self.description(question), self.extended_description(question), self.choices(question), use_templates=False, ) self.preseed(question, response, seen=False) else: self.preseed(question, "unhandled", seen=False) return True elif question == "partman/exception_handler_note": if priority == "critical" or priority == "high": self.frontend.error_dialog(self.description(question), self.extended_description(question)) return FilteredCommand.error(self, priority, question) else: return True elif question == "partman/installation_medium_mounted": self.frontend.installation_medium_mounted(self.extended_description(question)) return True elif self.question_type(question) == "boolean": if question == "partman/unmount_active": yes = "ubiquity/imported/yes" no = "ubiquity/imported/no" else: yes = "ubiquity/text/continue" no = "ubiquity/text/go_back" response = self.frontend.question_dialog( self.description(question), self.extended_description(question), (no, yes) ) answer_reversed = False if question in ("partman-jfs/jfs_boot", "partman-jfs/jfs_root", "partman/unmount_active"): answer_reversed = True if response is None or response == yes: answer = answer_reversed else: answer = not answer_reversed if answer: self.preseed(question, "true", seen=False) else: self.preseed(question, "false", seen=False) return True return FilteredCommand.run(self, priority, question)