Douglas Schilling Landgraf has uploaded a new change for review. Change subject: engine_page: vdsm-tool register verb integration ......................................................................
engine_page: vdsm-tool register verb integration vdsm-reg will be deprecated. This patch switch the plugin to the new vdsm-tool register verb and make the cleanup/refactor needed. For reference, this patch requires: vdsm-tool: Add register verb: https://gerrit.ovirt.org/#/c/40966/ Change-Id: Iffcbc036369a9c52b7ccb41653dbe254b403af60 Signed-off-by: Douglas Schilling Landgraf <[email protected]> --- M src/config.py.in M src/engine_page.py 2 files changed, 56 insertions(+), 321 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-node-plugin-vdsm refs/changes/81/41081/1 diff --git a/src/config.py.in b/src/config.py.in index 25798d2..eb7d5a5 100644 --- a/src/config.py.in +++ b/src/config.py.in @@ -20,7 +20,3 @@ PACKAGE_VERSION = '@PACKAGE_VERSION@' engine_name = '@ENGINENAME@' ENGINE_PORT = '443' - -# Configuration Files -VDSM_CONFIG = '/etc/vdsm/vdsm.conf' -VDSM_REG_CONFIG = '/etc/vdsm-reg/vdsm-reg.conf' diff --git a/src/engine_page.py b/src/engine_page.py index 719c246..271b318 100644 --- a/src/engine_page.py +++ b/src/engine_page.py @@ -1,8 +1,9 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # -# engine_page.py - Copyright (C) 2012 Red Hat, Inc. +# engine_page.py - Copyright (C) 2012-2015 Red Hat, Inc. # Written by Fabian Deutsch <[email protected]> +# Douglas Schilling Landgraf <[email protected]> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -19,22 +20,16 @@ # MA 02110-1301, USA. A copy of the GNU General Public License is # also available at http://www.gnu.org/copyleft/gpl.html. import augeas -import ConfigParser import errno -import httplib -import os import subprocess import shlex -import sys -import traceback from . import config from socket import error as socket_error from ovirt.node import plugins, valid, ui, utils, log -from ovirt.node.config.defaults import NodeConfigFileSection, SSH, Management +from ovirt.node.config.defaults import NodeConfigFileSection, SSH from ovirt.node.plugins import Changeset -from ovirt.node.utils.fs import Config from vdsm import vdscli @@ -47,50 +42,24 @@ def execute_cmd(cmd, env_shell=False): - cmd = subprocess.Popen(shlex.split(cmd), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=env_shell) - - output, err = cmd.communicate() - if cmd.returncode != 0: - LOGGER.debug("Cannot execute cmd [%s]" % cmd) - - return cmd.returncode - -def update_conf(conf_file, session, option, value): - """ - Update configuration file - - Args: - conf_file -- Configuration file - session -- Session in the configuration file - option -- option to be updated - value -- value to be updated in the option value - - Returns: True or False - """ - - if not os.path.exists(conf_file): - raise IOError('Cannot find file to be updated.') - try: - cfg = ConfigParser.RawConfigParser() - cfg.read(conf_file) - cfg.set(session, option, value) + cmd = subprocess.Popen(shlex.split(cmd), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=env_shell) - with open(conf_file, 'w+') as configfile: - cfg.write(configfile) - except ConfigParser.Error: - LOGGER.debug("Cannot write into file!", exc_info=True) - raise + output, err = cmd.communicate() - return True + except OSError: + LOGGER.debug("Cannot execute cmd {c}, err {e}".format(c=cmd, e=err)) + + return output, cmd.returncode def validate_server(server): """Validate server str if user provided ':' port schema""" return True if ":" in server else False + def sync_mgmt(): """Guess mgmt interface and update TUI config @@ -132,7 +101,9 @@ if cfg["server"] is not None and cfg["server"] != "None" and \ cfg["server"] != "": - server_url = [unicode(info) for info in [cfg["server"], cfg["port"]] if info] + server_url = [unicode(info) for info in [cfg["server"], + cfg["port"]] if info] + port, sslPort = compatiblePort(cfg["port"]) if sslPort: proto = "https" @@ -145,8 +116,10 @@ ":".join(server_url) ) - if cfg['server'] == 'None' or cfg['server'] is None: cfg['server'] = "" - if cfg['port'] == 'None': cfg['port'] = config.ENGINE_PORT + if cfg['server'] == 'None' or cfg['server'] is None: + cfg['server'] = "" + if cfg['port'] == 'None': + cfg['port'] = config.ENGINE_PORT ag = augeas.Augeas() ag.set("/augeas/save/copy_if_rename_fails", "") @@ -185,9 +158,8 @@ model = { "vdsm_cfg.address": cfg["server"] or "", "vdsm_cfg.port": cfg["port"] or config.ENGINE_PORT, - "vdsm_cfg.cert": "Verified" - if utils.fs.Config().exists(cfg["cert_path"]) else "N/A", "vdsm_cfg.password": "", + "check.fqdn": True } return model @@ -226,9 +198,9 @@ header_menu ), ui.Entry("vdsm_cfg.address", - str(config.engine_name) + " Address(or ip:port):"), + str(config.engine_name) + " FQDN (or fqdn:port):"), ui.Divider("divider[0]"), - ui.KeywordLabel("vdsm_cfg.cert", "Certificate Status: "), + ui.Checkbox("check.fqdn", "Check Engine FQDN?", state=True), ui.Divider("divider[1]"), ui.Label("vdsm_cfg.password._label", "Optional password for adding Node through " + @@ -256,7 +228,6 @@ def on_merge(self, effective_changes): model = VDSM() - self.logger.info("Saving engine stuff") changes = Changeset(self.pending_changes(False)) effective_model = Changeset(self.model()) effective_model.update(effective_changes) @@ -264,91 +235,25 @@ self.logger.debug("Changes: %s" % changes) self.logger.debug("Effective Model: %s" % effective_model) - if validate_server(effective_model["vdsm_cfg.address"]): - self._server, self._port = effective_model["vdsm_cfg.address"].split(":") - else: - self._server = effective_model["vdsm_cfg.address"] - self._port = config.ENGINE_PORT - - buttons = [ui.Button("action.cert.accept", "Accept"), - ui.Button("action.cert.reject", "Reject & Remove")] - - txs = utils.Transaction( - "Configuring {engine_name}".format( - engine_name=config.engine_name - ) - ) - - compat, ssl_port = compatiblePort(self._port) - if self._server and effective_model["action.register"]: - title_msg = "\n" - try: - self.logger.debug("find port %s %s" % (self._server, self._port)) - self._port = findPort(self._server, self._port) - - if ssl_port: - self._cert_path, fingerprint = retrieveCetrificate( - self._server, - self._port - ) - if changes.contains_any(["vdsm_cfg.password"]): - title_msg = "\nSetting root password and starting sshd\n\n" - SetRootPassword( - password=effective_model["vdsm_cfg.password"] - ).commit() - - if ssl_port: - title_msg += "Please review the following SSL fingerprint" \ - " from Engine:\n" - except Exception as e: - if ssl_port: - fingerprint = str(e) - title_msg = "\n" - buttons = [ui.Button("action.cert.reject", "Close")] - txs += [CannotFindEngine()] - self._server = "" - - if ssl_port: - self._fp_dialog = ui.Dialog("dialog.engine.fp", "{engine_name} " - "Fingerprint".format( - engine_name=config.engine_name - ), - [ui.Label( - "dialog.label[0]", - title_msg), - ui.Label("dialog.fp", fingerprint)]) - - self._fp_dialog.buttons = buttons - return self._fp_dialog - - if effective_model["action.cert.accept"]: - self._fp_dialog.close() - model.update(self._server, self._port, self._cert_path) - if self._cert_path is not None and \ - os.path.exists(self._cert_path): - utils.fs.Config().persist(self._cert_path) - - if effective_model["action.cert.reject"]: - model.update(cert_path=None) - if self._cert_path is not None and \ - os.path.exists(self._cert_path): - utils.fs.Config().unpersist(self._cert_path) - os.unlink(self._cert_path) - return self._fp_dialog.close() + txs = utils.Transaction("Configuring {engine_name}".format( + engine_name=config.engine_name)) if changes.contains_any(["vdsm_cfg.password"]): txs += [SetRootPassword( password=effective_model["vdsm_cfg.password"] )] - if self._server is not None and self._server != "": - try: - txs += [ActivateVDSM(self._server, self._port)] - except Exception as e: - txs += [CannotFindEngine()] + if effective_model["vdsm_cfg.address"]: + if validate_server(effective_model["vdsm_cfg.address"]): + self._server, self._port = \ + effective_model["vdsm_cfg.address"].split(":") + else: + self._server = effective_model["vdsm_cfg.address"] + self._port = config.ENGINE_PORT - if self._server is None: - txs += [CannotFindEngine()] + cfqdn = effective_model["check.fqdn"] + self.logger.debug("DOUG cfqdn %s" % cfqdn) + txs += [NodeRegister(self._server, self._port, cfqdn)] model.update(server=self._server, port=self._port) @@ -362,56 +267,6 @@ # Acts like a page reload return self.ui_content() - - -def findPort(engineServer, enginePort): - """Function to find the correct port for a given server - """ - _TIMEOUT_FIND_HOST_SEC = 5 - - # pylint: disable-msg=E0611,F0401 - sys.path.append('/usr/share/vdsm-reg') - import deployUtil # @UnresolvedImport - - compatPort, sslPort = compatiblePort(enginePort) - - LOGGER.debug("Finding port %s:%s with compat %s ssl %s" % - (engineServer, enginePort, compatPort, sslPort)) - - deployUtil.nodeCleanup() - - # Build port list to try - port_cfgs = [(enginePort, sslPort)] - if compatPort: - port_cfgs += [(compatPort, sslPort)] - else: - port_cfgs += [(enginePort, False)] - - LOGGER.debug("Port configuratoins for engine: %s" % port_cfgs) - - for try_port, use_ssl in port_cfgs: - LOGGER.debug("Trying to reach engine %s via %s %s" % - (engineServer, try_port, "SSL" if use_ssl else "")) - - is_reachable = False - - try: - is_reachable = isHostReachable(host=engineServer, - port=try_port, ssl=use_ssl, - timeout=_TIMEOUT_FIND_HOST_SEC) - except Exception: - LOGGER.debug("Failed to reach engine: %s" % traceback.format_exc()) - - if is_reachable: - LOGGER.debug("Reached engine") - enginePort = try_port - break - - if not is_reachable: - raise RuntimeError("Can't connect to {engine_name}".format( - engine_name=config.engine_name)) - - return enginePort def compatiblePort(portNumber): @@ -436,43 +291,8 @@ return compatPort.get(portNumber, (None, False)) -def isHostReachable(host, port, ssl, timeout): - """Check if a host is reachable on a given port via HTTP/HTTPS - """ - if ssl: - Connection = httplib.HTTPSConnection - else: - Connection = httplib.HTTPConnection - Connection(str(host), port=int(port), timeout=timeout).request("HEAD", "/") - return True - - -def retrieveCetrificate(engineServer, enginePort): - """Function to retrieve and store the certificate from an Engine - """ - fingerprint = None - - # pylint: disable-msg=E0611,F0401 - sys.path.append('/usr/share/vdsm-reg') - import deployUtil # @UnresolvedImport - # pylint: enable-msg=E0611,F0401 - - if deployUtil.getRhevmCert(engineServer, enginePort): - _, _, path = deployUtil.certPaths('') - fingerprint = deployUtil.generateFingerPrint(path) - else: - msgCert = "Failed downloading " \ - "{engine_name} certificate".format( - engine_name=config.engine_name) - raise RuntimeError(msgCert) - - return path, fingerprint - - -# # # Functions and classes to support the UI -# # class VDSM(NodeConfigFileSection): """Class to handle VDSM configuration in /etc/default/ovirt file @@ -500,15 +320,29 @@ (valid.Empty(or_none=True) | valid.Port())(port) -class CannotFindEngine(utils.Transaction.Element): - title = "Trying to connect with {engine_name}..".format( - engine_name=config.engine_name - ) +class NodeRegister(utils.Transaction.Element): + title = "Registering oVirt Node..." + + def __init__(self, engine, port, check_fqdn): + super(NodeRegister, self).__init__() + self.engine = engine + self.port = port + + if check_fqdn: + self.check_fqdn = True + else: + self.check_fqdn = False def commit(self): - raise RuntimeError( - "Cannot connect with management system!" - ) + out, ret = execute_cmd("vdsm-tool register --engine-fqdn {e} " + "--engine-https-port {p} " + "--check-fqdn {c}".format(e=self.engine, + p=self.port, + c=self.check_fqdn)) + if ret != int("0"): + msg = "{t}\n{l}".format(t=out.split("Traceback")[0], + l="Full log: /var/log/vdsm/register.log") + raise Exception(msg) class SetRootPassword(utils.Transaction.Element): @@ -525,98 +359,3 @@ sshcfg = SSH() sshcfg.update(pwauth=True) sshcfg.commit() - - -class ActivateVDSM(utils.Transaction.Element): - title = "Activating VDSM" - - def __init__(self, server, port): - super(ActivateVDSM, self).__init__() - - if not os.path.exists(config.VDSM_CONFIG): - self.create_vdsm_conf() - self.logger.info("Agent configuration files created.") - - if validate_server(server): - self.server, self.port = server.split(":") - else: - self.server = server - self.port = port - - def cert_validator(self): - cert_path = VDSM().retrieve()["cert_path"] - cert_exists = cert_path and os.path.exists(cert_path) - - return cert_exists - - def create_vdsm_conf(self): - cfg = ConfigParser.RawConfigParser() - - cfg.add_section('addresses') - cfg.set('addresses', 'management_port', '54321') - - cfg.add_section('vars') - cfg.set('vars', 'trust_store_path', '/etc/pki/vdsm/') - cfg.set('vars', 'ssl', 'true') - - with open(config.VDSM_CONFIG, 'w') as configfile: - cfg.write(configfile) - - Config().persist(config.VDSM_CONFIG) - - def commit(self): - _LOCK_FILE_VDSM_REG = "/var/lock/subsys/vdsm-reg" - self.logger.info("Connecting to VDSM server") - - if not self.cert_validator(): - self.logger.info("Trying register without validating cert..") - - # pylint: disable-msg=E0611,F0401 - sys.path.append('/usr/share/vdsm-reg') - import deployUtil # @UnresolvedImport - - sys.path.append('/usr/share/vdsm') - from vdsm import constants - - cfg = VDSM().retrieve() - - # Stopping vdsm-reg may fail but its ok - its in the case when the - # menus are run after installation - self.logger.info("Stopping vdsm-reg service") - if os.path.exists(_LOCK_FILE_VDSM_REG): - os.remove(_LOCK_FILE_VDSM_REG) - execute_cmd('killall -9 vdsm-reg-setup') - - try: - update_conf( - config.VDSM_REG_CONFIG, - "vars", - "vdc_host_name", - cfg["server"] - ) - - update_conf( - config.VDSM_REG_CONFIG, - "vars", - "vdc_host_port", - cfg["port"] - ) - except (ConfigParser.Error, IOError): - mgmt = Management() - mgmt.clear() - - msgConf = "{engine_name} Configuration Failed".format( - engine_name=config.engine_name - ) - self.logger.info(msgConf, exc_info=True) - raise RuntimeError(msgConf) - - self.logger.info("Starting vdsm-reg service") - execute_cmd("/usr/share/vdsm-reg/vdsm-reg-setup") - execute_cmd("touch %s" % _LOCK_FILE_VDSM_REG) - sync_mgmt() - - msgConf = "{engine_name} Configuration Successfully Updated".format( - engine_name=config.engine_name - ) - self.logger.debug(msgConf) -- To view, visit https://gerrit.ovirt.org/41081 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Iffcbc036369a9c52b7ccb41653dbe254b403af60 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-node-plugin-vdsm Gerrit-Branch: master Gerrit-Owner: Douglas Schilling Landgraf <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
