Example #1
0
 def test_drop_privileges(self, *args):
     with EnvironmentVarGuard() as env:
         env['PKEXEC_UID'] = '1000'
         misc.drop_privileges()
     os.seteuid.assert_called_once_with(1000)
     os.setegid.assert_called_once_with(1000)
     os.setgroups.assert_called_once_with([1234])
Example #2
0
 def test_drop_privileges(self, *args):
     with EnvironmentVarGuard() as env:
         env['PKEXEC_UID'] = '1000'
         misc.drop_privileges()
     os.seteuid.assert_called_once_with(1000)
     os.setegid.assert_called_once_with(1000)
     os.setgroups.assert_called_once_with([1234])
    def filter_parts(self):
        question = 'migration-assistant/partitions'
        from ubiquity.parted_server import PartedServer
        os.seteuid(0)
        parted = PartedServer()

        parts = []
        for disk in parted.disks():
            parted.select_disk(disk)
            for partition in parted.partitions():
                # We check to see if the partition is scheduled to be
                # formatted and if not add it to the list of post-commit
                # available partitions.
                filename = '/var/lib/partman/devices/%s/%s/view' % \
                    (disk, partition[1])
                fd = open(filename)
                pieces = fd.readline().rstrip('\n').split(None, 8)
                fd.close()
                line = [''] * 8
                line[0:len(pieces)] = pieces
                formatted = ['F', 'f', 'swap']
                if not (set(line) & set(formatted)):
                    parts.append(partition[5])
                else:
                    syslog.syslog('filtering out %s as it is to be formatted.' % partition[5])

        drop_privileges()
        ret = []
        for choice in self.choices(question):
            if choice[choice.rfind('(')+1:choice.rfind(')')] in parts:
                ret.append(choice)

        self.preseed(question, ", ".join(ret))
    def prepare(self):
        self.preseed('console-setup/ask_detect', 'false')

        # We need to get rid of /etc/default/console-setup, or console-setup
        # will think it's already configured and behave differently. Try to
        # save the old file for interest's sake, but it's not a big deal if
        # we can't.
        os.seteuid(0)
        try:
            os.unlink('/etc/default/console-setup.pre-ubiquity')
        except OSError:
            pass
        try:
            os.rename('/etc/default/console-setup',
                      '/etc/default/console-setup.pre-ubiquity')
        except OSError:
            try:
                os.unlink('/etc/default/console-setup')
            except OSError:
                pass
        misc.drop_privileges()
        # Make sure debconf doesn't do anything with crazy "preseeded"
        # answers to these questions. If you want to preseed these, use the
        # *code variants.
        self.db.fset('console-setup/layout', 'seen', 'false')
        self.db.fset('console-setup/variant', 'seen', 'false')

        # Technically we should provide a version as the second argument,
        # but that isn't currently needed and it would require querying
        # apt/dpkg for the current version, which would be slow, so we don't
        # bother for now.
        return (['/usr/lib/ubiquity/console-setup/console-setup.postinst',
                 'configure'],
                ['^console-setup/layout', '^console-setup/variant'],
                {'OVERRIDE_ALLOW_PRESEEDING': '1'})
    def prepare(self):
        self.preseed("console-setup/ask_detect", "false")

        # We need to get rid of /etc/default/console-setup, or console-setup
        # will think it's already configured and behave differently. Try to
        # save the old file for interest's sake, but it's not a big deal if
        # we can't.
        os.seteuid(0)
        try:
            os.unlink("/etc/default/console-setup.pre-ubiquity")
        except OSError:
            pass
        try:
            os.rename("/etc/default/console-setup", "/etc/default/console-setup.pre-ubiquity")
        except OSError:
            try:
                os.unlink("/etc/default/console-setup")
            except OSError:
                pass
        misc.drop_privileges()
        # Make sure debconf doesn't do anything with crazy "preseeded"
        # answers to these questions. If you want to preseed these, use the
        # *code variants.
        if not "UBIQUITY_AUTOMATIC" in os.environ:
            self.db.fset("console-setup/layout", "seen", "false")
            self.db.fset("console-setup/variant", "seen", "false")

        # Technically we should provide a version as the second argument,
        # but that isn't currently needed and it would require querying
        # apt/dpkg for the current version, which would be slow, so we don't
        # bother for now.
        return (
            ["/usr/lib/ubiquity/console-setup/console-setup.postinst", "configure"],
            ["^console-setup/layout", "^console-setup/variant"],
        )
 def test_drop_privileges(self, *args):
     with test_support.EnvironmentVarGuard():
         os.environ['SUDO_UID'] = '1000'
         os.environ['SUDO_GID'] = '1000'
         misc.drop_privileges()
     os.seteuid.assert_called_once_with(1000)
     os.setegid.assert_called_once_with(1000)
     os.setgroups.assert_called_once_with([1234])
    def prepare(self):
        # If an old parted_server is still running, clean it up.
        os.seteuid(0)
        if os.path.exists('/var/run/parted_server.pid'):
            try:
                pidline = open('/var/run/parted_server.pid').readline().strip()
                pid = int(pidline)
                os.kill(pid, signal.SIGTERM)
            except Exception:
                pass
            try:
                os.unlink('/var/run/parted_server.pid')
            except OSError:
                pass

        # Force autopartitioning to be re-run.
        shutil.rmtree('/var/lib/partman', ignore_errors=True)
        drop_privileges()

        self.autopartition_question = None
        self.auto_state = None
        self.extra_options = {}
        self.extra_choice = None

        self.update_partitions = None
        self.building_cache = True
        self.__state = [['', None, None]]
        self.disk_cache = {}
        self.partition_cache = {}
        self.cache_order = []
        self.creating_label = None
        self.creating_partition = None
        self.editing_partition = None
        self.deleting_partition = None
        self.undoing = False
        self.finish_partitioning = False
        self.bad_auto_size = False

        questions = ['^partman-auto/.*automatically_partition$',
                     '^partman-auto/select_disk$',
                     '^partman-partitioning/confirm_resize$',
                     '^partman-partitioning/confirm_new_label$',
                     '^partman-partitioning/new_size$',
                     '^partman/choose_partition$',
                     '^partman/confirm.*',
                     '^partman/free_space$',
                     '^partman/active_partition$',
                     '^partman-partitioning/new_partition_(size|type|place)$',
                     '^partman-target/choose_method$',
                     '^partman-basicfilesystems/(fat_mountpoint|mountpoint|mountpoint_manual)$',
                     '^partman/exception_handler$',
                     '^partman/exception_handler_note$',
                     'type:boolean',
                     'ERROR',
                     'PROGRESS']
        return ('/bin/partman', questions,
                {'PARTMAN_NO_COMMIT': '1', 'PARTMAN_SNOOP': '1'})
Example #8
0
    def __init__(self, distro):
        """Frontend initialisation."""
        self.distro = distro
        self.locale = None
        self.dbfilter = None
        self.dbfilter_status = None
        self.current_layout = None
        self.resize_choice = None
        self.manual_choice = None
        self.summary_device = None
        self.popcon = None
        self.http_proxy_host = None
        self.http_proxy_port = 8080

        # Drop privileges so we can run the frontend as a regular user, and
        # thus talk to a11y applications running as a regular user.
        drop_privileges()
        self.oem_config = False
        try:
            if self.debconf_operation('get', 'oem-config/enable') == 'true':
                self.oem_config = True
                # It seems unlikely that anyone will need
                # migration-assistant in the OEM installation process. If it
                # turns out that they do, just delete the following two
                # lines.
                if 'UBIQUITY_MIGRATION_ASSISTANT' in os.environ:
                    del os.environ['UBIQUITY_MIGRATION_ASSISTANT']
        except debconf.DebconfError:
            pass
        
        try:
            self.oem_id = self.debconf_operation('get', 'oem-config/id')
        except debconf.DebconfError:
            self.oem_id = ''

        # set commands
        # Note that this will never work if the database is locked, so you
        # cannot trap that particular error using failure_command.
        self.automation_error_cmd = None
        self.error_cmd = None
        self.success_cmd = None
        try:
            self.automation_error_cmd = self.debconf_operation('get',
                'ubiquity/automation_failure_command')
            self.error_cmd = self.debconf_operation('get',
                'ubiquity/failure_command')
            self.success_cmd = self.debconf_operation('get',
                'ubiquity/success_command')
        except debconf.DebconfError:
            pass
Example #9
0
    def openURL(self, url):
        from PyQt5.QtGui import QDesktopServices
        from PyQt5.QtCore import QUrl
        import shutil
        import os

        # this nonsense is needed because kde doesn't want to be root
        misc.drop_privileges()
        misc.drop_privileges_save()
        # copy over gtkrc-2.0 to get the themeing right
        if os.path.exists("/usr/share/kubuntu-default-settings"):
            shutil.copy(
                "/usr/share/kubuntu-default-settings/" + "dot-gtkrc-2.0-kde4",
                os.getenv("HOME") + "/.gtkrc-2.0")
        QDesktopServices.openUrl(QUrl(url))
        misc.regain_privileges()
        misc.regain_privileges_save()
Example #10
0
    def openURL(self, url):
        from PyQt4.QtGui import QDesktopServices
        from PyQt4.QtCore import QUrl
        import shutil
        import os

        # this nonsense is needed because kde doesn't want to be root
        misc.drop_privileges()
        misc.drop_privileges_save()
        # copy over gtkrc-2.0 to get the themeing right
        if os.path.exists("/usr/share/netrunner-default-settings"):
            shutil.copy("/usr/share/netrunner-default-settings/" +
                        "dot-gtkrc-2.0-kde4",
                        os.getenv("HOME") + "/.gtkrc-2.0")
        QDesktopServices.openUrl(QUrl(url))
        misc.regain_privileges()
        misc.regain_privileges_save()
    def __init__(self, distro):
        """Frontend initialisation."""
        self.distro = distro
        self.db = None
        self.dbfilter = None
        self.dbfilter_status = None
        self.resize_choice = None
        self.manual_choice = None
        self.locale = None
        self.wget_retcode = None
        self.wget_proc = None

        # Drop privileges so we can run the frontend as a regular user, and
        # thus talk to a11y applications running as a regular user.
        drop_privileges()

        self.start_debconf()

        self.oem_user_config = False
        if 'UBIQUITY_OEM_USER_CONFIG' in os.environ:
            self.oem_user_config = True

        try:
            self.custom_title = self.db.get('ubiquity/custom_title_text')
        except debconf.DebconfError:
            self.custom_title = False

        self.oem_config = False
        if not self.oem_user_config:
            try:
                if self.db.get('oem-config/enable') == 'true':
                    self.oem_config = True
            except debconf.DebconfError:
                pass

            if self.oem_config:
                try:
                    self.db.set('passwd/auto-login', 'true')
                    self.db.set('passwd/auto-login-backup', 'oem')
                except debconf.DebconfError:
                    pass

        # set commands
        # Note that this will never work if the database is locked, so you
        # cannot trap that particular error using failure_command.
        self.automation_error_cmd = ''
        self.error_cmd = ''
        self.success_cmd = ''
        try:
            self.automation_error_cmd = self.db.get(
                'ubiquity/automation_failure_command')
            self.error_cmd = self.db.get('ubiquity/failure_command')
            self.success_cmd = self.db.get('ubiquity/success_command')
        except debconf.DebconfError:
            pass

        try:
            self.show_shutdown_button = \
                self.db.get('ubiquity/show_shutdown_button') == 'true'
        except debconf.DebconfError:
            self.show_shutdown_button = False

        self.hide_slideshow = False
        try:
            if self.db.get('ubiquity/hide_slideshow') == 'true':
                self.hide_slideshow = True
        except debconf.DebconfError:
            pass

        # Load plugins
        plugins = plugin_manager.load_plugins()
        modules = plugin_manager.order_plugins(plugins)
        self.modules = []
        for mod in modules:
            comp = Component()
            comp.module = mod
            if hasattr(mod, 'Page'):
                comp.filter_class = mod.Page
            self.modules.append(comp)

        if not self.modules:
            raise ValueError('No valid steps.')

        if 'SUDO_USER' in os.environ:
            os.environ['SCIM_USER'] = os.environ['SUDO_USER']
            os.environ['SCIM_HOME'] = os.path.expanduser(
                '~%s' % os.environ['SUDO_USER'])
Example #12
0
    def __init__(self, distro):
        """Frontend initialisation."""
        self.distro = distro
        self.locale = None
        self.dbfilter = None
        self.dbfilter_status = None
        self.current_layout = None
        self.resize_choice = None
        self.manual_choice = None
        self.summary_device = None
        self.grub_en = None
        self.popcon = None
        self.http_proxy_host = None
        self.http_proxy_port = 8080

        # Drop privileges so we can run the frontend as a regular user, and
        # thus talk to a11y applications running as a regular user.
        drop_privileges()

        # Use a single private debconf-communicate instance for several
        # queries we need to make at startup. While this is less convenient
        # than using debconf_operation, it's significantly faster.
        db = self.debconf_communicator()

        self.oem_config = False
        try:
            if db.get('oem-config/enable') == 'true':
                self.oem_config = True
                # It seems unlikely that anyone will need
                # migration-assistant in the OEM installation process. If it
                # turns out that they do, just delete the following two
                # lines.
                if 'UBIQUITY_MIGRATION_ASSISTANT' in os.environ:
                    del os.environ['UBIQUITY_MIGRATION_ASSISTANT']
        except debconf.DebconfError:
            pass
        
        try:
            self.oem_id = db.get('oem-config/id')
        except debconf.DebconfError:
            self.oem_id = ''

        if self.oem_config:
            try:
                db.set('passwd/auto-login', 'true')
                db.set('passwd/auto-login-backup', 'oem')
            except debconf.DebconfError:
                pass

        # set commands
        # Note that this will never work if the database is locked, so you
        # cannot trap that particular error using failure_command.
        self.automation_error_cmd = None
        self.error_cmd = None
        self.success_cmd = None
        try:
            self.automation_error_cmd = db.get(
                'ubiquity/automation_failure_command')
            self.error_cmd = db.get('ubiquity/failure_command')
            self.success_cmd = db.get('ubiquity/success_command')
        except debconf.DebconfError:
            pass

        self.allow_password_empty = False
        try:
            self.allow_password_empty = db.get('user-setup/allow-password-empty') == 'true'
        except debconf.DebconfError:
            pass

        if 'SUDO_USER' in os.environ:
            os.environ['SCIM_USER'] = os.environ['SUDO_USER']
            os.environ['SCIM_HOME'] = os.path.expanduser(
                '~%s' % os.environ['SUDO_USER'])

        db.shutdown()
Example #13
0
    def __init__(self, distro):
        """Frontend initialisation."""
        self.distro = distro
        self.db = None
        self.dbfilter = None
        self.dbfilter_status = None
        self.resize_choice = None
        self.manual_choice = None
        self.locale = None
        self.wget_retcode = None
        self.wget_proc = None

        # Drop privileges so we can run the frontend as a regular user, and
        # thus talk to a11y applications running as a regular user.
        drop_privileges()

        self.start_debconf()

        self.oem_user_config = False
        if 'UBIQUITY_OEM_USER_CONFIG' in os.environ:
            self.oem_user_config = True

        try:
            self.custom_title = self.db.get('ubiquity/custom_title_text')
        except debconf.DebconfError:
            self.custom_title = False

        self.oem_config = False
        if not self.oem_user_config:
            try:
                if self.db.get('oem-config/enable') == 'true':
                    self.oem_config = True
            except debconf.DebconfError:
                pass

            if self.oem_config:
                try:
                    self.db.set('passwd/auto-login', 'true')
                    self.db.set('passwd/auto-login-backup', 'oem')
                except debconf.DebconfError:
                    pass

        # set commands
        # Note that this will never work if the database is locked, so you
        # cannot trap that particular error using failure_command.
        self.automation_error_cmd = ''
        self.error_cmd = ''
        self.success_cmd = ''
        try:
            self.automation_error_cmd = self.db.get(
                'ubiquity/automation_failure_command')
            self.error_cmd = self.db.get('ubiquity/failure_command')
            self.success_cmd = self.db.get('ubiquity/success_command')
        except debconf.DebconfError:
            pass

        try:
            self.show_shutdown_button = \
                self.db.get('ubiquity/show_shutdown_button') == 'true'
        except debconf.DebconfError:
            self.show_shutdown_button = False

        self.hide_slideshow = False
        try:
            if self.db.get('ubiquity/hide_slideshow') == 'true':
                self.hide_slideshow = True
        except debconf.DebconfError:
            pass

        # Load plugins
        plugins = plugin_manager.load_plugins()
        modules = plugin_manager.order_plugins(plugins)
        self.modules = []
        for mod in modules:
            comp = Component()
            comp.module = mod
            if hasattr(mod, 'Page'):
                comp.filter_class = mod.Page
            self.modules.append(comp)

        if not self.modules:
            raise ValueError('No valid steps.')

        if 'SUDO_USER' in os.environ:
            os.environ['SCIM_USER'] = os.environ['SUDO_USER']
            os.environ['SCIM_HOME'] = os.path.expanduser(
                '~%s' % os.environ['SUDO_USER'])
Example #14
0
    def __init__(self, distro):
        """Frontend initialisation."""
        self.distro = distro
        self.db = None
        self.dbfilter = None
        self.dbfilter_status = None
        self.resize_choice = None
        self.manual_choice = None
        self.grub_en = None
        self.popcon = None
        self.locale = None
        self.http_proxy_host = None
        self.http_proxy_port = 8080

        # Drop privileges so we can run the frontend as a regular user, and
        # thus talk to a11y applications running as a regular user.
        drop_privileges()

        self.start_debconf()

        self.oem_user_config = False
        if 'UBIQUITY_OEM_USER_CONFIG' in os.environ:
          self.oem_user_config = True

        try:
            self.custom_title = self.db.get('ubiquity/custom_title_text')
        except debconf.DebconfError:
            self.custom_title = False

        self.oem_config = False
        if not self.oem_user_config:
            try:
                if self.db.get('oem-config/enable') == 'true':
                    self.oem_config = True
                    # It seems unlikely that anyone will need
                    # migration-assistant in the OEM installation process. If it
                    # turns out that they do, just delete the following two
                    # lines.
                    if 'UBIQUITY_MIGRATION_ASSISTANT' in os.environ:
                        del os.environ['UBIQUITY_MIGRATION_ASSISTANT']
            except debconf.DebconfError:
                pass

            if self.oem_config:
                try:
                    self.db.set('passwd/auto-login', 'true')
                    self.db.set('passwd/auto-login-backup', 'oem')
                except debconf.DebconfError:
                    pass

        # set commands
        # Note that this will never work if the database is locked, so you
        # cannot trap that particular error using failure_command.
        self.automation_error_cmd = ''
        self.error_cmd = ''
        self.success_cmd = ''
        try:
            self.automation_error_cmd = self.db.get(
                'ubiquity/automation_failure_command')
            self.error_cmd = self.db.get('ubiquity/failure_command')
            self.success_cmd = self.db.get('ubiquity/success_command')
        except debconf.DebconfError:
            pass

        # Load plugins
        plugins = plugin_manager.load_plugins()
        modules = plugin_manager.order_plugins(plugins)
        self.modules = []
        for mod in modules:
            if mod.NAME == 'migrationassistant' and \
                'UBIQUITY_MIGRATION_ASSISTANT' not in os.environ:
                    continue
            comp = Component()
            comp.module = mod
            if hasattr(mod, 'Page'):
                comp.filter_class = mod.Page
            self.modules.append(comp)

        if not self.modules:
            raise ValueError, 'No valid steps.'

        if 'SUDO_USER' in os.environ:
            os.environ['SCIM_USER'] = os.environ['SUDO_USER']
            os.environ['SCIM_HOME'] = os.path.expanduser(
                '~%s' % os.environ['SUDO_USER'])
Example #15
0
    def __init__(self, distro):
        """Frontend initialisation."""
        self.distro = distro
        self.db = None
        self.dbfilter = None
        self.dbfilter_status = None
        self.resize_choice = None
        self.manual_choice = None
        self.summary_device = None
        self.grub_en = None
        self.popcon = None
        self.locale = None
        self.http_proxy_host = None
        self.http_proxy_port = 8080

        # Drop privileges so we can run the frontend as a regular user, and
        # thus talk to a11y applications running as a regular user.
        drop_privileges()

        self.start_debconf()

        self.oem_user_config = False
        if 'UBIQUITY_OEM_USER_CONFIG' in os.environ:
            self.oem_user_config = True

        self.oem_config = False
        if not self.oem_user_config:
            try:
                if self.db.get('oem-config/enable') == 'true':
                    self.oem_config = True
                    # It seems unlikely that anyone will need
                    # migration-assistant in the OEM installation process. If it
                    # turns out that they do, just delete the following two
                    # lines.
                    if 'UBIQUITY_MIGRATION_ASSISTANT' in os.environ:
                        del os.environ['UBIQUITY_MIGRATION_ASSISTANT']
            except debconf.DebconfError:
                pass

            if self.oem_config:
                try:
                    self.db.set('passwd/auto-login', 'true')
                    self.db.set('passwd/auto-login-backup', 'oem')
                except debconf.DebconfError:
                    pass

        # set commands
        # Note that this will never work if the database is locked, so you
        # cannot trap that particular error using failure_command.
        self.automation_error_cmd = ''
        self.error_cmd = ''
        self.success_cmd = ''
        try:
            self.automation_error_cmd = self.db.get(
                'ubiquity/automation_failure_command')
            self.error_cmd = self.db.get('ubiquity/failure_command')
            self.success_cmd = self.db.get('ubiquity/success_command')
        except debconf.DebconfError:
            pass

        # Load plugins
        plugins = plugin_manager.load_plugins()
        modules = plugin_manager.order_plugins(plugins)
        self.modules = []
        for mod in modules:
            if mod.NAME == 'migrationassistant' and \
                'UBIQUITY_MIGRATION_ASSISTANT' not in os.environ:
                continue
            comp = Component()
            comp.module = mod
            if hasattr(mod, 'Page'):
                comp.filter_class = mod.Page
            self.modules.append(comp)

        if not self.modules:
            raise ValueError, 'No valid steps.'

        if 'SUDO_USER' in os.environ:
            os.environ['SCIM_USER'] = os.environ['SUDO_USER']
            os.environ['SCIM_HOME'] = os.path.expanduser(
                '~%s' % os.environ['SUDO_USER'])
    def cleanup(self):
        # TODO cjwatson 2006-09-07: I'd use dexconf, but it seems reasonable
        # for somebody to edit /etc/X11/xorg.conf on the live CD and expect
        # that to be carried over to the installed system (indeed, we've
        # always supported that up to now). So we get this horrible mess
        # instead ...

        model = self.db.get("console-setup/modelcode")
        layout = self.db.get("console-setup/layoutcode")
        variant = self.db.get("console-setup/variantcode")
        options = self.db.get("console-setup/optionscode")
        self.apply_real_keyboard(model, layout, variant, options.split(","))

        if layout == "":
            return

        os.seteuid(0)
        oldconfigfile = "/etc/X11/xorg.conf"
        newconfigfile = "/etc/X11/xorg.conf.new"
        try:
            oldconfig = open(oldconfigfile)
        except IOError:
            # Did they remove /etc/X11/xorg.conf or something? Oh well,
            # better to carry on than to crash.
            return
        newconfig = open(newconfigfile, "w")

        re_section_inputdevice = re.compile(r'\s*Section\s+"InputDevice"\s*$')
        re_driver_kbd = re.compile(r'\s*Driver\s+"kbd"\s*$')
        re_endsection = re.compile(r"\s*EndSection\s*$")
        re_option_xkbmodel = re.compile(r'(\s*Option\s*"XkbModel"\s*).*')
        re_option_xkblayout = re.compile(r'(\s*Option\s*"XkbLayout"\s*).*')
        re_option_xkbvariant = re.compile(r'(\s*Option\s*"XkbVariant"\s*).*')
        re_option_xkboptions = re.compile(r'(\s*Option\s*"XkbOptions"\s*).*')
        in_inputdevice = False
        in_inputdevice_kbd = False
        done = {"model": model == "", "layout": False, "variant": variant == "", "options": options == ""}

        for line in oldconfig:
            line = line.rstrip("\n")
            if re_section_inputdevice.match(line) is not None:
                in_inputdevice = True
            elif in_inputdevice and re_driver_kbd.match(line) is not None:
                in_inputdevice_kbd = True
            elif re_endsection.match(line) is not None:
                if in_inputdevice_kbd:
                    if not done["model"]:
                        print >> newconfig, ('\tOption\t\t"XkbModel"\t"%s"' % model)
                    if not done["layout"]:
                        print >> newconfig, ('\tOption\t\t"XkbLayout"\t"%s"' % layout)
                    if not done["variant"]:
                        print >> newconfig, ('\tOption\t\t"XkbVariant"\t"%s"' % variant)
                    if not done["options"]:
                        print >> newconfig, ('\tOption\t\t"XkbOptions"\t"%s"' % options)
                in_inputdevice = False
                in_inputdevice_kbd = False
                done = {"model": model == "", "layout": False, "variant": variant == "", "options": options == ""}
            elif in_inputdevice_kbd:
                match = re_option_xkbmodel.match(line)
                if match is not None:
                    if model == "":
                        # hmm, not quite sure what to do here; guessing that
                        # forcing to pc105 will be reasonable
                        line = match.group(1) + '"pc105"'
                    else:
                        line = match.group(1) + '"%s"' % model
                    done["model"] = True
                else:
                    match = re_option_xkblayout.match(line)
                    if match is not None:
                        line = match.group(1) + '"%s"' % layout
                        done["layout"] = True
                    else:
                        match = re_option_xkbvariant.match(line)
                        if match is not None:
                            if variant == "":
                                continue  # delete this line
                            else:
                                line = match.group(1) + '"%s"' % variant
                            done["variant"] = True
                        else:
                            match = re_option_xkboptions.match(line)
                            if match is not None:
                                if options == "":
                                    continue  # delete this line
                                else:
                                    line = match.group(1) + '"%s"' % options
                                done["options"] = True
            print >> newconfig, line

        newconfig.close()
        oldconfig.close()
        os.rename(newconfigfile, oldconfigfile)
        misc.drop_privileges()
Example #17
0
    def __init__(self, distro):
        """Frontend initialisation."""
        self.distro = distro
        self.db = None
        self.dbfilter = None
        self.dbfilter_status = None
        self.resize_choice = None
        self.manual_choice = None
        self.locale = None
        self.wget_retcode = None
        self.wget_proc = None

        # Drop privileges so we can run the frontend as a regular user, and
        # thus talk to a11y applications running as a regular user.
        drop_privileges()

        self.start_debconf()

        self.oem_user_config = False
        if "UBIQUITY_OEM_USER_CONFIG" in os.environ:
            self.oem_user_config = True

        try:
            self.custom_title = self.db.get("ubiquity/custom_title_text")
        except debconf.DebconfError:
            self.custom_title = False

        self.oem_config = False
        if not self.oem_user_config:
            try:
                if self.db.get("oem-config/enable") == "true":
                    self.oem_config = True
                    # It seems unlikely that anyone will need
                    # migration-assistant in the OEM installation process. If it
                    # turns out that they do, just delete the following two
                    # lines.
                    if "UBIQUITY_MIGRATION_ASSISTANT" in os.environ:
                        del os.environ["UBIQUITY_MIGRATION_ASSISTANT"]
            except debconf.DebconfError:
                pass

            if self.oem_config:
                try:
                    self.db.set("passwd/auto-login", "true")
                    self.db.set("passwd/auto-login-backup", "oem")
                except debconf.DebconfError:
                    pass

        # set commands
        # Note that this will never work if the database is locked, so you
        # cannot trap that particular error using failure_command.
        self.automation_error_cmd = ""
        self.error_cmd = ""
        self.success_cmd = ""
        try:
            self.automation_error_cmd = self.db.get("ubiquity/automation_failure_command")
            self.error_cmd = self.db.get("ubiquity/failure_command")
            self.success_cmd = self.db.get("ubiquity/success_command")
        except debconf.DebconfError:
            pass

        try:
            self.show_shutdown_button = self.db.get("ubiquity/show_shutdown_button") == "true"
        except debconf.DebconfError:
            self.show_shutdown_button = False

        # Load plugins
        plugins = plugin_manager.load_plugins()
        modules = plugin_manager.order_plugins(plugins)
        self.modules = []
        for mod in modules:
            if mod.NAME == "migrationassistant" and "UBIQUITY_MIGRATION_ASSISTANT" not in os.environ:
                continue
            comp = Component()
            comp.module = mod
            if hasattr(mod, "Page"):
                comp.filter_class = mod.Page
            self.modules.append(comp)

        if not self.modules:
            raise ValueError("No valid steps.")

        if "SUDO_USER" in os.environ:
            os.environ["SCIM_USER"] = os.environ["SUDO_USER"]
            os.environ["SCIM_HOME"] = os.path.expanduser("~%s" % os.environ["SUDO_USER"])
Example #18
0
    def __init__(self, distro):
        """Frontend initialisation."""
        self.distro = distro
        self.dbfilter = None
        self.dbfilter_status = None
        self.resize_choice = None
        self.manual_choice = None
        self.summary_device = None
        self.grub_en = None
        self.popcon = None
        self.locale = None
        self.http_proxy_host = None
        self.http_proxy_port = 8080

        # Drop privileges so we can run the frontend as a regular user, and
        # thus talk to a11y applications running as a regular user.
        drop_privileges()

        # Use a single private debconf-communicate instance for several
        # queries we need to make at startup. While this is less convenient
        # than using debconf_operation, it's significantly faster.
        db = self.debconf_communicator()

        self.oem_config = False
        try:
            if db.get('oem-config/enable') == 'true':
                self.oem_config = True
                # It seems unlikely that anyone will need
                # migration-assistant in the OEM installation process. If it
                # turns out that they do, just delete the following two
                # lines.
                if 'UBIQUITY_MIGRATION_ASSISTANT' in os.environ:
                    del os.environ['UBIQUITY_MIGRATION_ASSISTANT']
        except debconf.DebconfError:
            pass

        self.oem_user_config = False
        if 'UBIQUITY_OEM_USER_CONFIG' in os.environ:
          self.oem_user_config = True

        if self.oem_config:
            try:
                db.set('passwd/auto-login', 'true')
                db.set('passwd/auto-login-backup', 'oem')
            except debconf.DebconfError:
                pass

        # set commands
        # Note that this will never work if the database is locked, so you
        # cannot trap that particular error using failure_command.
        self.automation_error_cmd = None
        self.error_cmd = None
        self.success_cmd = None
        try:
            self.automation_error_cmd = db.get(
                'ubiquity/automation_failure_command')
            self.error_cmd = db.get('ubiquity/failure_command')
            self.success_cmd = db.get('ubiquity/success_command')
        except debconf.DebconfError:
            pass

        self.allow_password_empty = False
        try:
            self.allow_password_empty = db.get('user-setup/allow-password-empty') == 'true'
        except debconf.DebconfError:
            pass

        # These step lists are the steps that aren't yet converted to plugins.
        # We just hardcode them here, but they will eventually be dynamic.
        if self.oem_user_config:
            steps = ['UserInfo']
        else:
            use_raid = db.get('ubiquity/use_raid')
            if use_raid == "true":
                steps = ['UserInfo', 'MigrationAssistant', 'Ready']
            else:
                steps = ['Partman', 'UserInfo', 'MigrationAssistant', 'Ready']
        modules = []
        for step in steps:
            if step == 'MigrationAssistant' and \
                'UBIQUITY_MIGRATION_ASSISTANT' not in os.environ:
                continue
            page_module = PAGE_COMPONENTS[step]
            if page_module is not None:
                modules.append(page_module)

        # Load plugins
        plugins = plugin_manager.load_plugins()
        modules = plugin_manager.order_plugins(plugins, modules)
        self.modules = []
        for mod in modules:
            comp = Component()
            comp.module = mod
            if hasattr(mod, 'Page'):
                comp.filter_class = mod.Page
            self.modules.append(comp)

        if not self.modules:
            raise ValueError, 'No valid steps.'

        if 'SUDO_USER' in os.environ:
            os.environ['SCIM_USER'] = os.environ['SUDO_USER']
            os.environ['SCIM_HOME'] = os.path.expanduser(
                '~%s' % os.environ['SUDO_USER'])

        db.shutdown()
    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)