예제 #1
0
    def progress_loop(self):
        """prepare, copy and config the system in the core install process."""

        self.start_debconf()
        dbfilter = partman_commit.PartmanCommit(self)
        if dbfilter.run_command(auto_process=True) != 0:
            print >> self.console, '\nUnable to commit the partition table, exiting.'
            return

        self.start_debconf()
        dbfilter = install.Install(self)
        ret = dbfilter.run_command(auto_process=True)
        if ret == 0:
            dbfilter = plugininstall.Install(self)
            ret = dbfilter.run_command(auto_process=True)
        if ret == 0:
            self.run_success_cmd()
            print >> self.console, 'Installation complete.'
            if self.get_reboot():
                misc.execute("reboot")
        if ret != 0:
            if ret == 3:
                # error already handled by Install
                sys.exit(ret)
            elif (os.WIFSIGNALED(ret) and os.WTERMSIG(ret)
                  in (signal.SIGINT, signal.SIGKILL, signal.SIGTERM)):
                sys.exit(ret)
            elif os.path.exists('/var/lib/ubiquity/install.trace'):
                tbfile = open('/var/lib/ubiquity/install.trace')
                realtb = tbfile.read()
                tbfile.close()
                raise RuntimeError("Install failed with exit code %s\n%s" %
                                   (ret, realtb))
예제 #2
0
    def progress_loop(self):
        """prepare, copy and config the system in the core install process."""
        syslog.syslog('progress_loop()')

        self.current_page = None

        slideshow_dir = '/usr/share/ubiquity-slideshow'
        slideshow_locale = self.slideshow_get_available_locale(slideshow_dir, self.locale)
        slideshow_main = slideshow_dir + '/slides/index.html'

        s = self.app.desktop().availableGeometry()
        fail = None
        if os.path.exists(slideshow_main):
            if s.height >= 600 and s.width >= 800:
                slides = 'file://' + slideshow_main
                if slideshow_locale != 'c': #slideshow will use default automatically
                    slides += '#?locale=' + slideshow_locale
                    ltr = i18n.get_string('default-ltr', slideshow_locale, 'ubiquity/imported')
                    if ltr == 'default:RTL':
                        slides += '?rtl'
                try:
                    from PyQt4.QtWebKit import QWebView
                    from PyQt4.QtWebKit import QWebPage

                    def openLink(qUrl):
                        QDesktopServices.openUrl(qUrl)

                    webView = QWebView()

                    webView.linkClicked.connect(openLink)

                    webView.setContextMenuPolicy(Qt.NoContextMenu)
                    webView.page().setLinkDelegationPolicy(QWebPage.DelegateExternalLinks)
                    webView.page().mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
                    webView.page().mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)
                    webView.setFixedSize(700,420)

                    webView.load(QUrl(slides))

                    #add the webview to the extra frame of the progress dialog
                    self.progressDialog.extraFrame.layout().addWidget(webView)
                    self.progressDialog.extraFrame.setVisible(True)
                except ImportError:
                    fail = 'Webkit not present.'
            else:
                fail = 'Display < 800x600 (%sx%s).' % (s.width, s.height)
        else:
            fail = 'No slides present for %s.' % slideshow_dir
        if fail:
            syslog.syslog('Not displaying the slideshow: %s' % fail)

        self.progressDialog.show()

        self.debconf_progress_start(
            0, 100, self.get_string('ubiquity/install/title'))
        self.debconf_progress_region(0, 15)

        if not self.oem_user_config:
            self.start_debconf()
            dbfilter = partman_commit.PartmanCommit(self)
            if dbfilter.run_command(auto_process=True) != 0:
                while self.progress_position.depth() != 0:
                    self.debconf_progress_stop()
                self.progressDialog.hide()
                self.return_to_partitioning()
                return

        # No return to partitioning from now on
        self.installing_no_return = True

        self.debconf_progress_region(15, 100)

        self.start_debconf()
        dbfilter = install.Install(self)
        ret = dbfilter.run_command(auto_process=True)
        if ret != 0:
            self.installing = False
            if ret == 3:
                # error already handled by Install
                sys.exit(ret)
            elif (os.WIFSIGNALED(ret) and
                  os.WTERMSIG(ret) in (signal.SIGINT, signal.SIGKILL,
                                       signal.SIGTERM)):
                sys.exit(ret)
            elif os.path.exists('/var/lib/ubiquity/install.trace'):
                tbfile = open('/var/lib/ubiquity/install.trace')
                realtb = tbfile.read()
                tbfile.close()
                raise RuntimeError, ("Install failed with exit code %s\n%s" %
                                     (ret, realtb))
            else:
                raise RuntimeError, ("Install failed with exit code %s; see "
                                     "/var/log/syslog" % ret)

        while self.progress_position.depth() != 0:
            self.debconf_progress_stop()

        # just to make sure
        self.progressDialog.hide()

        self.installing = False
        quitText = '<qt>%s</qt>' % self.get_string("finished_label")
        rebootButtonText = self.get_string("reboot_button")
        quitButtonText = self.get_string("quit_button")
        titleText = self.get_string("finished_dialog")

        ##FIXME use non-stock messagebox to customise button text
        #quitAnswer = QMessageBox.question(self.ui, titleText, quitText, rebootButtonText, quitButtonText)
        self.run_success_cmd()
        if self.oem_user_config:
            self.quit()
        elif not self.get_reboot_seen():
            if ('UBIQUITY_ONLY' in os.environ or
                'UBIQUITY_GREETER' in os.environ):
                quitText = self.get_string('ubiquity/finished_restart_only')
            messageBox = QMessageBox(QMessageBox.Question, titleText, quitText, QMessageBox.NoButton, self.ui)
            messageBox.addButton(rebootButtonText, QMessageBox.AcceptRole)
            if ('UBIQUITY_ONLY' not in os.environ and
                'UBIQUITY_GREETER' not in os.environ):
                messageBox.addButton(quitButtonText, QMessageBox.RejectRole)
            messageBox.setWindowFlags(messageBox.windowFlags() | Qt.WindowStaysOnTopHint)
            quitAnswer = messageBox.exec_()

            if quitAnswer == 0:
                self.reboot()
        elif self.get_reboot():
            self.reboot()
예제 #3
0
    def run_install(self,
                    target,
                    hostname,
                    adminuser,
                    adminpassword,
                    recovery_data=None,
                    large_install=False):
        """Perform normal product install."""
        try:
            # Set umask to be the same as normal ubuntu user umask (0022) that ubuquity install assumes
            # instead of default root umask (0066) that we are otherwise using.
            posix.umask(022)

            self.prepare()
            self.hostname = hostname
            self.large_install = large_install

            self.install_stage_set('Preparing target disk')
            self.debconf_progress_start(0, 100, '')
            self.debconf_progress_set(0)

            self.debconf_progress_region(0, 4)
            self.create_filesystems(target)
            self.setup_fat_partition('/target-fat')
            self.debconf_progress_set(4)

            # Copy recovery data for the first time, to ensure that the data is available
            # in case this recovery fails
            self.copy_recovery_data(recovery_data)

            self.install_stage_set('Copying files')

            # Note: resume partition setup is not a problem
            # because we do not use swap in live-cd => ubiquity
            # cannot find a swap partition to use for resume..

            # Set configuration values to the debconf database so that
            # Ubiquity can find them.

            # Grub boot device
            self.set_debconf_variable('grub-installer/bootdev', target)

            # Disable os-prober so that grub installer will not find other
            # devices to boot from. This is not configurable from debconf
            # and requires this hack (or menu.lst cleanup afterwards).
            os_prober = '/usr/bin/os-prober'
            os_prober_orig = '/usr/bin/os-prober.orig'

            # Note: first move command in unionfs system changes the directory permissions,
            # avoiding this by doing a copy/delete instead of move.
            run_command([constants.CMD_CP, '-f', os_prober, os_prober_orig],
                        retval=runcommand.FAIL)
            run_command([constants.CMD_RM, '-f', os_prober],
                        retval=runcommand.FAIL)

            helpers.write_file(os_prober,
                               '#!/bin/sh\nexit 0\n',
                               append=False,
                               perms=0755)

            # Admin user and passwd
            self.set_debconf_variable('passwd/username', adminuser)
            self.set_debconf_variable('passwd/user-fullname', 'Administrator')
            self.set_debconf_variable('passwd/user-uid', '999')

            # Note: here we could use real password received from UI (currently cleartext)
            # eg.: self.set_debconf_variable('passwd/user-password', adminpassword)
            # For now the admin password is disabled.
            self.set_debconf_variable('passwd/user-password-crypted', '*')

            # Set root password disabled.
            self.set_debconf_variable('passwd/root-password-crypted', '*')

            # Disable unwanted parts of Ubiquity
            # 1. language_apply (first two)
            # 2. apt_setup
            # 3. timezone_apply (zone and clock)
            # 4. keyboard_chooser
            for i in [
                    '/usr/lib/ubiquity/localechooser/post-base-installer',
                    '/usr/lib/ubiquity/localechooser/prebaseconfig',
                    '/usr/share/ubiquity/apt-setup',
                    '/usr/lib/ubiquity/tzsetup/prebaseconfig',
                    '/usr/share/ubiquity/clock-setup',
                    '/usr/lib/ubiquity/kbd-chooser/prebaseconfig'
            ]:
                helpers.write_file(
                    i,
                    textwrap.dedent("""\
                #!/bin/sh
                exit 0
                """))

            # Run Ubiquity to do the main part of installation
            self.debconf_progress_region(4, 97)
            if install.Install(self).run_command():
                raise Exception('Ubiquity installer failed')

            # Set back os-prober
            # Note: first move command in unionfs system changes the directory permissions,
            # avoiding this by doing a delete/copy/delete instead of move.
            run_command([constants.CMD_RM, '-f', os_prober],
                        retval=runcommand.FAIL)
            run_command([constants.CMD_CP, '-f', os_prober_orig, os_prober],
                        retval=runcommand.FAIL)
            run_command([constants.CMD_RM, '-f', os_prober_orig],
                        retval=runcommand.FAIL)

            # Clear debconf database
            for i in [
                    'grub-installer/bootdev', 'passwd/user-password',
                    'passwd/user-password-crypted',
                    'passwd/root-password-crypted', 'passwd/username',
                    'passwd/user-fullname', 'passwd/user-uid'
            ]:
                self.set_debconf_variable(i, None)

            # Ensure that the default user has sudo rights because
            # user-setup-apply fails when username is "admin".
            helpers.write_file('/target/etc/sudoers',
                               textwrap.dedent("""\
            # Ensure that the default user has admin rights always.
            %s ALL=(ALL) NOPASSWD: ALL
            """ % adminuser),
                               append=True,
                               perms=None)

            # Add GRUB options to /boot/grub/menu.lst:
            #   * recover from kernel panic (panic=60)
            #   * force a 16-bit VESA mode for Virtual PC 2007 compatibility
            #     (affects only startup)

            f = open('/target/boot/grub/menu.lst')
            grub_menu = f.read()
            f.close()

            def_re = re.compile(r'^# defoptions=')
            alt_re = re.compile(r'^# altoptions=')

            updated_grub_menu = ''
            for l in grub_menu.split('\n'):
                if (def_re.match(l) is not None) or (alt_re.match(l)
                                                     is not None):
                    updated_grub_menu += '%s panic=60 vga=785' % l
                else:
                    updated_grub_menu += l

                updated_grub_menu += '\n'

            f = open('/target/boot/grub/menu.lst', 'wb')
            f.write(updated_grub_menu)
            f.close()

            run_command(['/usr/sbin/chroot', '/target', '/sbin/update-grub'],
                        retval=runcommand.FAIL)

            # Fix permissions of all ubiquity-created files on target system.
            # These permissions are broken because of root umask (0066) is used
            # when running installer instead of ubuntu-user umask (0022))
            #
            # Files affected include at least: /etc/hosts, /etc/iftab, /etc/kernel-img.conf, /boot/grub, /boot/grub/*
            #
            # The following files already have proper permissions (files do exist before write),
            # but setting anyways: /etc/hostname, /etc/network/interfaces
            #
            # Note: this is still in place as a safeguard even when the umask is now set
            # in script start.

            for f, p in [['etc/hosts', 0644], ['etc/iftab', 0644],
                         ['etc/hostname', 0644],
                         ['etc/network/interfaces', 0644],
                         ['etc/kernel-img.conf', 0644]]:
                os.chmod(os.path.join('/target', f), p)

            for r, d, files in os.walk('/target/boot/grub'):
                os.chmod(r, 0755)
                for f in files:
                    os.chmod(os.path.join(r, f), 0644)

            # Note: Use this if the login stuff gets broken again and
            # debugging is required.
            # helpers.write_file('/target/etc/sudoers', textwrap.dedent("""\
            # debug ALL=(ALL) NOPASSWD: ALL
            # """), append=True, perms=None)
            # run_command(['/usr/sbin/chroot', '/target', 'adduser', '--disabled-password', '--gecos', 'Debug', '--uid', '1020', 'debug'])
            # run_command(['/usr/sbin/chroot', '/target', 'chpasswd'], stdin='debug:debug\n')

            self.install_stage_set('Finishing installation')

            if not os.path.exists(constants.LOWMEM_MARKER_FILE):
                # XXX: database stuff: (when testusage is implemented)
                # - stop database
                # - stop cron scripts from accessing database
                # - copy database to installed system
                # - copy marker files to installed system?
                #   - configured marker, other marker files
                #   - whole /var/lib/l2tpgw/ ?
                # - copy uuid file to installed system?
                # - copy logfiles to installed system
                # - remove/nocopy: fastboot marker
                pass

            self.debconf_progress_region(97, 99)

            # Recreate ssh keys
            for f, t in [['/etc/ssh/ssh_host_rsa_key', 'rsa'],
                         ['/etc/ssh/ssh_host_dsa_key', 'dsa']]:
                run_command(
                    ['/usr/sbin/chroot', '/target', '/bin/rm', '-f', f],
                    retval=runcommand.FAIL)
                run_command([
                    '/usr/sbin/chroot', '/target', '/usr/bin/ssh-keygen', '-q',
                    '-N', '', '-f', f, '-t', t, '-C',
                    'root@%s' % self.hostname
                ],
                            retval=runcommand.FAIL)

            # Copy recovery data (again)
            self.copy_recovery_data(recovery_data)

            self.copy_debconf()
            self.cleanup()
            self.debconf_progress_set(100)

            self.write_status('success\nInstall completed')
            self.info('installation success')
        except:
            self.cleanup()
            self.write_status('failure\nInstall failed')
            self.error('installation failed')
            raise
예제 #4
0
    def run(self):
        if os.getuid() != 0:
            print >>sys.stderr, textwrap.fill(
                'This program must be run with administrative privileges, and '
                'cannot continue without them.')
            sys.exit(1)

        self.pagesindex = 0
        self.pageslen = 0
        self.pages = []
        for mod in self.modules:
            if hasattr(mod.module, 'PageDebconf'):
                mod.ui_class = mod.module.PageDebconf
                mod.controller = Controller(self)
                mod.ui = mod.ui_class(mod.controller)
                title = mod.ui.get('plugin_title')
                if title:
                    mod.title = title
                    self.pageslen += 1
                    self.pages.append(mod)

        while(self.pagesindex >= 0 and self.pagesindex < self.pageslen):
            step = self.pages[self.pagesindex]

            self.db.settitle(step.title)

            if issubclass(self.pages[self.pagesindex].filter_class, Plugin):
                ui = self.pages[self.pagesindex].ui
            else:
                ui = None
            dbfilter = self.pages[self.pagesindex].filter_class(self,
                                                                db=self.db,
                                                                ui=ui)
            ret = dbfilter.run_unfiltered()

            if ret == 10:
                self.pagesindex -= 1
            else:
                self.pagesindex += 1

        # TODO: handle errors
        if self.pagesindex == self.pageslen:
            dbfilter = install.Install(self, db=self.db)
            ret = dbfilter.run_unfiltered()
            if ret != 0:
                self.installing = False
                if ret == 3:
                    # error already handled by Install
                    sys.exit(ret)
                elif (os.WIFSIGNALED(ret) and
                      os.WTERMSIG(ret) in (signal.SIGINT, signal.SIGKILL,
                                           signal.SIGTERM)):
                    sys.exit(ret)
                elif os.path.exists('/var/lib/ubiquity/install.trace'):
                    tbfile = open('/var/lib/ubiquity/install.trace')
                    realtb = tbfile.read()
                    tbfile.close()
                    raise RuntimeError, ("Install failed with exit code %s\n%s" %
                                         (ret, realtb))
                else:
                    raise RuntimeError, ("Install failed with exit code %s; see "
                                         "/var/log/syslog" % ret)

            return 0
        else:
            return 10