def on_merge(self, changes): if changes.contains_any(["diagnostic.logfiles", "diagnostic.tools"]): cmds = {} changed_field = changes.keys()[0] if "diagnostic.tools" in changed_field: cmds = dict((name, cmd) for (name, cmd) in self.__diagnostics()) cmd = cmds.get(changes[changed_field], None) if cmd: contents = process.check_output(cmd, stderr=process.STDOUT) return ui.TextViewDialog("output.dialog", "Command Output", contents)
def on_merge(self, changes): if changes.contains_any(["support.logfile"]): logfile = changes["support.logfile"] cmds = { "node": "cat /var/log/ovirt.log | less", "ui": "cat /tmp/ovirt.debug.log | less", "messages": "cat /var/log/messages | less", "audit": "cat /var/log/audit/audit.log | less", "dmesg": "dmesg | less", "journal": "journalctl --all --catalog --full" } cmd = cmds[logfile] if logfile in cmds else None if cmd: contents = process.check_output(cmd, stderr=process.STDOUT) return ui.TextViewDialog("output.dialog", "Logfile", contents)
def on_merge(self, changes): p_manifests_dir = "/etc/ovirt-plugins-manifests.d" p_name = self._model["plugin"] fn = None if "button.drpm" in changes: fn = glob.glob("%s/delta-*-manifest-rpm-%s.txt" % (p_manifests_dir, p_name))[0] elif "button.dsrpm" in changes: fn = glob.glob("%s/delta-*-manifest-srpm-%s.txt" % (p_manifests_dir, p_name))[0] elif "button.dfile" in changes: fn = glob.glob("%s/delta-*-manifest-file-%s.txt" % (p_manifests_dir, p_name))[0] if fn: self.logger.debug("Reading manifest from: %s" % fn) with open(fn) as src: contents = src.read() return ui.TextViewDialog("output.dialog", "Manifest", contents)
def on_merge(self, changes): manifest_keys = ["button.drpm", "button.dsrpm", "button.dfile"] p_manifests_dir = "/etc/ovirt-plugins-manifests.d" fn = None for k in manifest_keys: pfix = k.split(".")[1].lstrip("d") if k in changes: fn = glob.glob("%s/delta-manifest-%s.txt" % (p_manifests_dir, pfix)) try: fn = fn[0] # grabs plain text and not gzipped self.logger.debug("Reading manifest from: %s" % fn) with open(fn) as src: contents = src.read() return ui.TextViewDialog("output.dialog", "Manifest", contents) except: self.logger.debug("Error retrieving manifest:", exc_info=True) return InfoDialog("dialog.info", "An Error Occured", "No manifest found")
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()