コード例 #1
0
ファイル: status_page.py プロジェクト: fabiand/ovirt-node
    def on_merge(self, changes):
        # Handle button presses
        number_of_vm = "There are %s Virtual Machines running." \
            % (virt.number_of_domains())
        if "action.lock" in changes:
            self.logger.info("Locking screen")
            self._lock_dialog = LockDialog()
            self.application.ui.hotkeys_enabled(False)
            self.widgets.add(self._lock_dialog)
            return self._lock_dialog

        elif "action.unlock" in changes and "password" in changes:
            self.logger.info("UnLocking screen")
            pam = security.PAM()
            if pam.authenticate(os.getlogin(), changes["password"]):
                self._lock_dialog.close()
                self.application.ui.hotkeys_enabled(True)
            else:
                self.application.notice("The provided password was incorrect.")
                self.widgets["password"].text("")

        elif "action.logoff" in changes:
            self.logger.info("Logging off")
            self.application.quit()

        elif "action.restart" in changes:
            self.logger.info("Restarting")
            return ui.ConfirmationDialog(
                "confirm.reboot", "Confirm System Restart",
                number_of_vm + "\nThis will restart the system,"
                "proceed?")

        elif "confirm.reboot.yes" in changes:
            self.logger.info("Confirm Restarting")
            self.dry_or(lambda: system.reboot())

        elif "action.poweroff" in changes:
            self.logger.info("Shutting down")
            return ui.ConfirmationDialog(
                "confirm.shutdown", "Confirm System Poweroff",
                number_of_vm + "\nThis will shut down the system,"
                "proceed?")

        elif "confirm.shutdown.yes" in changes:
            self.logger.info("Confirm Shutting down")
            self.dry_or(lambda: system.poweroff())

        elif "action.hostkey" in changes:
            self.logger.info("Showing hostkey")
            return HostkeyDialog("dialog.hostkey", "Host Key")

        elif "action.cpu_details" in changes:
            self.logger.info("Showing CPU details")
            return CPUFeaturesDialog("dialog.cpu_details", "CPU Details")

        elif "_save" in changes:
            self.widgets["dialog.hostkey"].close()
コード例 #2
0
def quit(instance):
    def ui_quit(dialog, changes):
        instance.ui.quit()

    txt = "Are you sure you want to quit?"
    dialog = ui.ConfirmationDialog("dialog.exit", "Exit", txt, [
        ui.Button("dialog.exit.yes", "Yes"),
        ui.CloseButton("dialog.exit.close", "No")
    ])

    dialog.buttons[0].on_activate.clear()
    dialog.buttons[0].on_activate.connect(ui.CloseAction())
    dialog.buttons[0].on_activate.connect(ui_quit)
    instance.show(dialog)
コード例 #3
0
def quit(instance):
    def ui_quit(dialog, changes):
        utils.system.reboot()
        instance.ui.quit()

    txt = "Are you sure you want to quit? The system will be rebooted."
    dialog = ui.ConfirmationDialog("dialog.exit", "Exit", txt, [
        ui.Button("dialog.exit.yes", "Reboot"),
        ui.CloseButton("dialog.exit.close", "Cancel")
    ])

    dialog.buttons[0].on_activate.clear()
    dialog.buttons[0].on_activate.connect(ui.CloseAction())
    dialog.buttons[0].on_activate.connect(ui_quit)
    instance.show(dialog)
コード例 #4
0
    def __drop_to_shell(self):
        def open_console():
            utils.process.call("bash", shell=True)

        def return_ok(dialog, changes):
            with self.ui.suspended():
                utils.console.reset()
                utils.console.writeln("Dropping to rescue shell...")
                open_console()

        try:
            txt = "Making changes in the rescue shell is unsupported. Do not "
            txt += "use this without guidance from support representatives"
            dialog = ui.ConfirmationDialog("dialog.shell", "Rescue Shell", txt)

            dialog.buttons[0].on_activate.clear()
            dialog.buttons[0].on_activate.connect(ui.CloseAction())
            dialog.buttons[0].on_activate.connect(return_ok)
            self.show(dialog)

        except:
            # Error when the UI is not running
            open_console()
コード例 #5
0
    def on_merge(self, effective_changes):
        self.logger.info("Saving network stuff")
        changes = Changeset(self.pending_changes(False))
        effective_model = Changeset(self.model())
        effective_model.update(effective_changes)

        self.logger.debug("Changes: %s" % changes)
        self.logger.info("Effective changes %s" % effective_changes)
        self.logger.debug("Effective Model: %s" % effective_model)

        # This object will contain all transaction elements to be executed
        txs = utils.Transaction(_("Network Interface Configuration"))

        # Special case: A NIC was selected, display that dialog!
        if "nics" in changes and len(changes) == 1:
            iface = changes["nics"]
            self.logger.debug("Opening NIC Details dialog for '%s'" % iface)
            self._model_extra["dialog.nic.ifname"] = iface
            self._nic_dialog = NicDetailsDialog(self, iface)

            if network.NodeNetwork().is_configured():
                txt = "Network Configuration detected an already configured "
                txt += "NIC. The configuration for that NIC is "
                txt += "going to be removed if changes are made. Proceed?"
                self._confirm_dialog = ui.ConfirmationDialog("dialog.confirm",
                                                             "Confirm Network "
                                                             "Settings", txt,
                                                             )
                return self._confirm_dialog
            else:
                return self._nic_dialog

        if "dialog.confirm.yes" in changes:
            self._confirm_dialog.close()
            return self._nic_dialog

        if "dialog.nic.close" in changes:
            self._nic_dialog.close()
            return

        if "button.toggle_bond" in changes:
            m_bond = defaults.NicBonding()
            mnet = defaults.Network()
            if m_bond.retrieve()["slaves"]:
                if mnet.retrieve()["iface"] == m_bond.retrieve()["name"]:
                    # Remove network config if primary devce was this
                    # bond
                    mnet.configure_no_networking()
                m_bond.configure_no_bond()
                txs += m_bond.transaction()
                txs += mnet.transaction()
            else:
                self._bond_dialog = CreateBondDialog("dialog.bond")
                self.widgets.add(self._bond_dialog)
                return self._bond_dialog

        if "button.ping" in changes:
            self.logger.debug("Opening ping page")
            self.application.switch_to_plugin(
                ping.Plugin)
            return

        if "dialog.nic.identify" in changes:
            ifname = self._model_extra["dialog.nic.ifname"]
            nic = utils.network.NodeNetwork().build_nic_model(ifname)
            nic.identify()
            self.application.notice("Flashing lights of '%s'" % nic.ifname)
            return

        nameservers = []
        dns_keys = ["dns[0]", "dns[1]"]
        if effective_changes.contains_any(dns_keys):
            nameservers += effective_model.values_for(dns_keys)
        if nameservers:
            self.logger.info("Setting new nameservers: %s" % nameservers)
            model = defaults.Nameservers()
            model.update(nameservers)
            txs += model.transaction()

        timeservers = []
        ntp_keys = ["ntp[0]", "ntp[1]"]
        if effective_changes.contains_any(ntp_keys):
            timeservers += effective_model.values_for(ntp_keys)
        if timeservers:
            self.logger.info("Setting new timeservers: %s" % timeservers)
            model = defaults.Timeservers()
            model.update(timeservers)
            txs += model.transaction()

        hostname_keys = ["hostname"]
        if effective_changes.contains_any(hostname_keys):
            value = effective_model.values_for(hostname_keys)
            self.logger.info("Setting new hostname: %s" % value)
            model = defaults.Hostname()
            model.update(*value)
            txs += model.transaction()

        # For the NIC details dialog:
        if effective_changes.contains_any(self._nic_details_group):
            # If any networking related key was changed, reconfigure networking
            # Fetch the values for the nic keys, they are used as arguments
            args = effective_model.values_for(self._nic_details_group)
            txs += self._configure_nic(*args)

        if effective_changes.contains_any(self._bond_group):
            mb = defaults.NicBonding()
            mnet = defaults.Network()
            args = effective_model.values_for(["bond.name",
                                               "bond.slaves.selected",
                                               "bond.options"])
            self.logger.debug("args: %s" % args)
            mb.update(*args)
            txs += mb.transaction()
            txs += mnet.transaction()
            self._bond_dialog.close()

        progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs, self)
        progress_dialog.run()

        if "dialog.nic.save" in changes:
            # Close the remaing details dialog
            self._nic_dialog.close()

        # Behaves like a page reload
        return self.ui_content()
コード例 #6
0
    def show_dialog(self):
        def open_console():
            if self.temp_cfg_file and os.path.isfile(self.temp_cfg_file):
                try:
                    utils.process.call("reset; screen " +
                                       "ovirt-node-hosted-engine-setup" +
                                       " --config-append=%s" %
                                       self.temp_cfg_file, shell=True)
                    self.__persist_configs()
                except:
                    self.logger.exception("hosted-engine failed to deploy!",
                                          exc_info=True)

            else:
                self.logger.error("Cannot trigger ovirt-hosted-engine-setup" +
                                  " because the configuration file was not " +
                                  "generated, please check the location " +
                                  "referenced in /var/log/ovirt-node.log")
            self.application.show(self.ui_content())

        def return_ok(dialog, changes):
            self.application.ui.close_dialog("Begin Hosted Engine Setup")
            with self.application.ui.suspended():
                open_console()

        if self.application.current_plugin() is self:
            try:
                # if show_progressbar is not set, the download process has
                # never started (PXE) or it finished
                if self._show_progressbar:
                    # Clear out the counters once we're done, and hide the
                    # progress bar
                    self.widgets["download.progress"].current(0)
                    self.widgets["download.status"].text("")
                    self._show_progressbar = False

                    self._model["download.progress"] = 0
                    self._model["download.status"] = ""

                # if the temp config file is empty, we removed it in the model
                # because there was an exception, so don't do anything
                if self.temp_cfg_file and not os.path.isfile(
                        self.temp_cfg_file):
                    self.logger.debug("The temporary config file %s does not"
                                      "exist. Not running screen")
                    return

                if self._install_ready:
                    utils.console.writeln("Beginning Hosted Engine Setup ...")
                    txt = "Setup will be ran with screen enabled that can be "
                    txt += "reconnected in the event of a timeout or "
                    txt += "connection failure.\n"
                    txt += "\nIt can be reconnected by running 'screen -d -r'"

                    dialog = ui.ConfirmationDialog("dialog.shell",
                                                   "Begin Hosted Engine Setup",
                                                   txt
                                                   )
                    dialog.buttons[0].on_activate.clear()
                    dialog.buttons[0].on_activate.connect(ui.CloseAction())
                    dialog.buttons[0].on_activate.connect(return_ok)
                    self.application.show(dialog)
                else:
                    if self._model['display_message']:
                        msg = self._model['display_message']
                        self._model['display_message'] = ''
                    else:
                        msg = "\n\nError Downloading ISO/OVA Image!"

                    dialog = ui.InfoDialog("dialog.notice",
                                           "Hosted Engine Setup",
                                           msg)

                self.application.show(dialog)

            except:
                # Error when the UI is not running
                self.logger.info("Exception on TUI!", exc_info=True)
                open_console()

        self.application.show(self.ui_content())
コード例 #7
0
    def on_merge(self, effective_changes):
        def close_dialog():
            if self._dialog:
                self._dialog.close()
                self._dialog = None
        self._install_ready = False
        self._invalid_download = False
        self.temp_cfg_file = False

        effective_changes = Changeset(effective_changes)
        changes = Changeset(self.pending_changes(False))
        effective_model = Changeset(self.model())
        effective_model.update(effective_changes)

        self.logger.debug("Changes: %s" % changes)
        self.logger.debug("Effective Model: %s" % effective_model)

        if "button.dialog" in effective_changes:
            self._dialog = DeployDialog("Deploy Hosted Engine", self)
            self.widgets.add(self._dialog)
            return self._dialog

        if "button.status" in effective_changes:
            try:
                contents = utils.process.check_output(
                    ["hosted-engine",
                     "--vm-status"],
                    stderr=utils.process.STDOUT
                )
            except utils.process.CalledProcessError:
                contents = "\nFailed to collect hosted engine vm status, " \
                           "check ovirt-ha-broker logs."

            self.application.show(self.ui_content())
            return ui.TextViewDialog("output.dialog", "Hosted Engine VM "
                                     "Status", contents)

        if "button.maintenance" in effective_changes:
            self._dialog = MaintenanceDialog("Hosted Engine Maintenance", self)
            self.widgets.add(self._dialog)
            return self._dialog

        if "maintenance.confirm" in effective_changes:
            close_dialog()
            if "maintenance.level" in effective_changes:
                level = effective_changes["maintenance.level"]
                try:
                    utils.process.check_call(["hosted-engine",
                                              "--set-maintenance",
                                              "--mode=%s" % level])
                except:
                    self.logger.exception("Couldn't set maintenance level "
                                          "to %s" % level, exc_info=True)
                    return ui.InfoDialog("dialog.error", "An error occurred",
                                         "Couldn't set maintenance level to "
                                         "%s. Check the logs" % level)

        if "deploy.additional" in effective_changes:
            close_dialog()

            def run_additional(*args):
                with self.application.ui.suspended():
                    try:
                        utils.process.call(
                            "reset; screen hosted-engine --deploy",
                            shell=True)
                        sys.stdout.write("Press <Return> to return to the TUI")
                        console.wait_for_keypress()
                        self.__persist_configs()
                    except:
                        self.logger.exception("hosted-engine failed to "
                                              "deploy!", exc_info=True)

            txt = ("Please set a password on the RHEV-M page of a host "
                   "which has previously deployed hosted engine before "
                   "continuing. This is required to retrieve the setup "
                   "answer file")
            dialog = ui.ConfirmationDialog("dialog.add",
                                           "Prepare remote host", txt)

            yes_btn, cncl_btn = dialog.buttons
            yes_btn.label("Proceed")
            yes_btn.on_activate.connect(run_additional)
            return dialog
        if effective_changes.contains_any(["deploy.confirm"]):
            close_dialog()

            def make_tempfile():
                if not os.path.exists(config.HOSTED_ENGINE_SETUP_DIR):
                    os.makedirs(config.HOSTED_ENGINE_SETUP_DIR)

                if not os.path.exists(config.HOSTED_ENGINE_TEMPDIR):
                    os.makedirs(config.HOSTED_ENGINE_TEMPDIR)

                temp_fd, temp_cfg_file = tempfile.mkstemp()
                os.close(temp_fd)
                return temp_cfg_file

            imagepath = effective_model["hosted_engine.diskpath"]
            pxe = effective_model["hosted_engine.pxe"]
            localpath = None

            # FIXME: dynamically enable the fields so we can't get into
            # this kind of situation. Selection should be ui.Options, not
            # a checkbox and a blank entry field
            #
            # Check whether we have unclear conditions
            if not imagepath and not pxe:
                self._model['display_message'] = "\n\nYou must enter a URL" \
                    " or choose PXE to install the Engine VM"
                return self.show_dialog()
            elif imagepath and pxe:
                self._model['display_message'] = "\n\nPlease choose either " \
                                                 "PXE or an image to " \
                                                 "retrieve, not both"
                return self.show_dialog()

            self.temp_cfg_file = make_tempfile()

            engine_keys = ["hosted_engine.diskpath", "hosted_engine.pxe"]

            txs = utils.Transaction("Setting up hosted engine")

            # FIXME: The "None" is for force_enable
            # Why are we setting force_enable? It clutters the code. We should
            # move force enabling it to checking for --dry instead
            model = HostedEngine()
            args = tuple(effective_model.values_for(engine_keys)) + (None,)
            model.update(*args)

            if "file://" in imagepath:
                localpath = imagepath[7:]
            elif imagepath:
                localpath = os.path.join(config.HOSTED_ENGINE_SETUP_DIR,
                                         os.path.basename(imagepath))

            # Check whether we have enough conditions to run it right now
            if pxe or os.path.exists(localpath):
                def console_wait(event):
                    event.wait()
                    self._install_ready = True
                    self.show_dialog()

                txs += model.transaction(self.temp_cfg_file)
                progress_dialog = ui.TransactionProgressDialog("dialog.txs",
                                                               txs, self)

                t = threading.Thread(target=console_wait,
                                     args=(progress_dialog.event,))
                t.start()

                progress_dialog.run()

                # The application doesn't wait until the progressdialog is
                # done, and it ends up being called asynchronously. Calling
                # in a thread and waiting to set threading.Event
                # time.sleep(5)

            # Otherwise start an async download
            else:
                path_parsed = urlparse(imagepath)

                if not path_parsed.scheme:
                    self._model['display_message'] = ("\nCouldn't parse "
                                                      "URL. please check "
                                                      "it manually.")

                elif path_parsed.scheme == 'http' or \
                        path_parsed.scheme == 'https':
                    self._show_progressbar = True
                    self.application.show(self.ui_content())
                    self._image_retrieve(imagepath,
                                         config.HOSTED_ENGINE_SETUP_DIR)

        return self.ui_content()