Douglas Schilling Landgraf has uploaded a new change for review.

Change subject: engine_page: rewrite register
......................................................................

engine_page: rewrite register

Node registrations with engine >= 3.2 should not use vdsm-reg.

Change-Id: I38f3b800c445f8dbb0fa0e89d128cea1e3407798
Signed-off-by: Douglas Schilling Landgraf <[email protected]>
---
M ovirt-node-plugin-vdsm.spec.in
M src/Makefile.am
A src/cert.py
M src/config.py.in
M src/engine_page.py
A src/misc.py
A src/ovirt-node-plugin-vdsm_autoinstall.py
7 files changed, 710 insertions(+), 50 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node-plugin-vdsm 
refs/changes/82/17682/8

diff --git a/ovirt-node-plugin-vdsm.spec.in b/ovirt-node-plugin-vdsm.spec.in
index d5a38ce..1023fd3 100644
--- a/ovirt-node-plugin-vdsm.spec.in
+++ b/ovirt-node-plugin-vdsm.spec.in
@@ -47,7 +47,8 @@
 %install
 %{__rm} -rf %{buildroot}
 make install DESTDIR=%{buildroot}
-
+install -Dm 0644 src/ovirt-node-plugin-vdsm_autoinstall.py \
+       
%{buildroot}%{_sysconfdir}/ovirt-config-boot.d/ovirt-node-plugin-vdsm_autoinstall.py
 
 %clean
 %{__rm} -rf %{buildroot}
@@ -87,6 +88,7 @@
 
 %files
 %{python_sitelib}/ovirt/node/setup/vdsm
+%{_sysconfdir}/ovirt-config-boot.d/ovirt-node-plugin-vdsm_autoinstall.py*
 %{_sysconfdir}/ovirt-plugins.d
 
 %changelog
diff --git a/src/Makefile.am b/src/Makefile.am
index f24622c..cf4e1ea 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,9 +23,12 @@
 #
 pyovirtsetupdir = $(pythondir)/ovirt/node/setup/vdsm
 pyovirtsetup_PYTHON = \
-  engine_page.py \
-  __init__.py \
-  config.py
+       engine_page.py \
+       __init__.py \
+       cert.py \
+       misc.py \
+       ovirt-node-plugin-vdsm_autoinstall.py \
+       config.py
 
 # Requires python-pep8 package (Fedora)
 check-local: check-local-pep8
diff --git a/src/cert.py b/src/cert.py
new file mode 100644
index 0000000..e8f4949
--- /dev/null
+++ b/src/cert.py
@@ -0,0 +1,202 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# cert.py - Copyright (C) 2013 Red Hat, Inc.
+#
+# 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from M2Crypto import X509
+from misc import *
+from ovirtnode.ovirtfunctions import ovirt_store_config
+from ovirtnode.ovirtfunctions import ovirt_safe_delete_config
+
+import logging
+import datetime
+import os
+import re
+import pwd
+import ssl
+import shutil
+
+
+class Cert(object):
+
+    _LOG_PREFIX = 'ovirt-node-plugin-vdsm.'
+    _REMOTE_SSH_KEY_FILE = (
+        '/engine.ssh.key.txt', '/rhevm.ssh.key.txt'
+    )
+    _HTTP_TIMEOUT = 30
+    _P_ROOT_SSH = pwd.getpwnam('root').pw_dir + '/.ssh'
+    _P_ROOT_AUTH_KEYS = _P_ROOT_SSH + '/authorized_keys'
+    _HTTP_SUCCESS_CODE = 200
+
+    # Regular expression used to validate content of SSH public keys:
+    _SSH_PUBLIC_KEY_RE = re.compile(flags=re.VERBOSE, pattern=r"""
+      ^
+      \s*
+      ssh-(rsa|dss)
+      \s+
+      ([A-Za-z0-9+/]+={0,2})
+      (\s+[^\s]+)?
+      \s*
+      $
+    """)
+
+    def __init__(self):
+        prefix = ''
+        if not self.__module__.startswith(self._LOG_PREFIX):
+            prefix = self._LOG_PREFIX
+
+        self.logger = logging.getLogger(prefix + self.__module__)
+        self.misc = Misc()
+
+    def cert_paths(self):
+        pkiDir = VDSM_PKI_DIR
+
+        VDSMCERT = pkiDir + "/certs/vdsmcert.pem"
+        CACERT = pkiDir + "/certs/cacert.pem"
+
+        engineWebCACert = pkiDir + "/certs/engine_web_ca.pem"
+
+        return CACERT, VDSMCERT, engineWebCACert
+
+    def generate_fingerprint(self, path):
+
+        fp = None
+
+        with open(path, 'r') as f:
+            pem_file = f.read()
+
+        x509 = X509.load_cert_string(pem_file, X509.FORMAT_PEM)
+        fp = x509.get_fingerprint('sha1')
+        fp = ':'.join(fp[pos:pos + 2] for pos in xrange(0, len(fp), 2))
+
+        return fp
+
+    def get_http_ca_cert(self, host, port):
+
+        cert_downloaded = False
+
+        try:
+            cert_pem = ssl.get_server_certificate((host, int(port)))
+            _, _, engineWebCACert = self.cert_paths()
+
+            with open(engineWebCACert, "w+") as f:
+                f.write(cert_pem)
+
+            cert_downloaded = True
+        except Exception, e:
+            logging.debug("Cannot download CA cert %s", str(e))
+
+        return cert_downloaded
+
+    def get_authkeys_file(self, IP, port):
+        """
+        This functions returns the public ssh key
+        """
+        _, _, engineWebCACert = self.cert_paths()
+        data = None
+
+        for key in self._REMOTE_SSH_KEY_FILE:
+            tmp = self.misc.get_remote_file(
+                IP, port, key, timeout=self._HTTP_TIMEOUT,
+                certPath=engineWebCACert
+            )
+            if tmp is not None and \
+                    self._SSH_PUBLIC_KEY_RE.match(tmp) is not None:
+                data = tmp
+                break
+
+        return data
+
+    def add_ssh_key(self, path, strKey):
+        resKeys = []
+
+        try:
+            for key in file(path):
+                if not key.endswith('\n'):  # make sure we have complete lines
+                    key += '\n'
+                if key != '\n' and not key.endswith(" ovirt-engine\n") or \
+                        key.startswith("#"):
+                    resKeys.append(key)
+        except IOError:
+            logging.debug("Failed to read %s", path)
+
+        if not strKey.endswith('\n'):
+            strKey += '\n'
+
+        resKeys.append(strKey)
+
+        with open(engineWebCACert, "w") as f:
+            f.write(''.join(resKeys))
+
+    def handle_ssh_key(self, strKey):
+        """
+            This functions appends key to the root's authorized_keys file.
+        """
+        logging.debug('handle_ssh_key start')
+        if not os.path.exists(self._P_ROOT_SSH):
+            logging.debug("handle_ssh_key: creating .ssh dir.")
+            try:
+                os.mkdir(self._P_ROOT_SSH, 0700)
+                self.misc.silent_restorecon(self._P_ROOT_SSH)
+            except OSError:
+                logging.debug("handle_ssh_key: failed to create ssh dir!")
+
+        try:
+            self.add_ssh_key(self._P_ROOT_AUTH_KEYS, strKey)
+        except:
+            logging.debug(
+                "handle_ssh_key: failed to write authorized_keys!",
+                exc_info=True
+            )
+
+        try:
+            os.chmod(self._P_ROOT_AUTH_KEYS, 0644)
+            self.misc.silent_restorecon(self._P_ROOT_AUTH_KEYS)
+        except:
+            logging.debug(
+                "handle_ssh_key: failed to chmod authorized_keys",
+                exc_info=True
+            )
+
+        # persist authorized_keys
+        logging.debug("handle_ssh_key: persist authorized_keys")
+        ovirt_store_config(self._P_ROOT_AUTH_KEYS)
+        logging.debug('handle_ssh_key end')
+
+    def _node_backup_certs(self, certs):
+        dt = datetime.datetime.now()
+        backupTime = dt.strftime("%Y-%m-%d_%H%M%S")
+
+        for pemFile in certs:
+            if os.path.exists(pemFile):
+                certName = os.path.basename(pemFile)
+                dirName = os.path.dirname(pemFile)
+
+                bkpCertName = dirName + "/bkp-" + backupTime + '_' + certName
+
+                shutil.copy2(pemFile, bkpCertName)
+                st = os.stat(pemFile)
+                os.chown(bkpCertName, st.st_uid, st.st_gid)
+                ovirt_store_config(bkpCertName)
+
+    def node_cleanup_certs(self):
+        CACERT, VDSMCERT, engineWebCACert = self.cert_paths()
+
+        self._node_backup_certs([CACERT, VDSMCERT, engineWebCACert])
+        if os.path.exists(engineWebCACert):
+            ovirt_safe_delete_config(engineWebCACert)
diff --git a/src/config.py.in b/src/config.py.in
index 958666a..6b65524 100644
--- a/src/config.py.in
+++ b/src/config.py.in
@@ -17,4 +17,8 @@
 
 PACKAGE_NAME = '@PACKAGE_NAME@'
 PACKAGE_VERSION = '@PACKAGE_VERSION@'
-engine_name = '@ENGINENAME@'
+ENGINE_NAME = '@ENGINENAME@'
+ENGINE_URI = '/OvirtEngineWeb/register:RHEVManagerWeb/VdsAutoRegistration.aspx'
+REGISTER_TIMEOUT_SEC = 10
+VDSM_PKI_DIR = '/etc/pki/vdsm'
+DEFAULT_SSL_PORT = 443
diff --git a/src/engine_page.py b/src/engine_page.py
index f437661..304c77c 100644
--- a/src/engine_page.py
+++ b/src/engine_page.py
@@ -18,10 +18,13 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.  A copy of the GNU General Public License is
 # also available at http://www.gnu.org/copyleft/gpl.html.
-from ovirt.node import plugins, valid, ui, utils, app, exceptions
+from ovirt.node import plugins, valid, ui, utils, app
 from ovirt.node.config.defaults import NodeConfigFileSection
 from ovirt.node.plugins import Changeset
+from misc import *
+from cert import *
 from . import config
+
 import logging
 import os
 import sys
@@ -47,7 +50,7 @@
         self._model = {}
 
     def name(self):
-        return config.engine_name
+        return config.ENGINE_NAME
 
     def rank(self):
         return 100
@@ -60,6 +63,7 @@
             "vdsm_cfg.cert": "Verified"
             if utils.fs.Config().exists(cfg["cert_path"]) else "N/A",
             "vdsm_cfg.password": "",
+            "engine.newreg": True,
         }
         return model
 
@@ -73,9 +77,10 @@
     def ui_content(self):
         ws = [ui.Header("header[0]",
               "{engine_name} Configuration".format(
-                  engine_name=config.engine_name)),
+                  engine_name=config.ENGINE_NAME)),
               ui.Entry("vdsm_cfg.address", "Management Server:"),
               ui.Entry("vdsm_cfg.port", "Management Server Port:"),
+              ui.Checkbox("engine.newreg", "Engine version >= 3.2", True),
               ui.Divider("divider[0]"),
               ui.SaveButton("action.fetch_cert", "Retrieve Certificate"),
               ui.KeywordLabel("vdsm_cfg.cert", "Certificate Status: "),
@@ -118,8 +123,8 @@
             try:
                 server = effective_model["vdsm_cfg.address"]
                 port = findPort(server, effective_model["vdsm_cfg.port"])
-                self._cert_path, fingerprint = retrieveCetrificate(server,
-                                                                   port)
+                self._cert_path, fingerprint = retrieve_certificate(
+                    server, port)
                 self._server, self._port = server, port
             except Exception as e:
                 fingerprint = str(e)
@@ -127,7 +132,7 @@
 
             self._fp_dialog = ui.Dialog("dialog.engine.fp",
                                         "{engine_name} Fingerprint".format(
-                                            engine_name=config.engine_name),
+                                            engine_name=config.ENGINE_NAME),
                                         [ui.Label("dialog.label[0]", "TBD"),
                                          ui.Label("dialog.fp", fingerprint)])
             self._fp_dialog.buttons = buttons
@@ -141,13 +146,14 @@
 
         elif changes.contains_any(["action.cert.reject"]):
             model.update(cert_path=None)
-            utils.fs.Config().unpersist(self._cert_path)
-            os.unlink(self._cert_path)
+            if self._cert_path is not None:
+                utils.fs.Config().unpersist(self._cert_path)
+                os.unlink(self._cert_path)
             self._fp_dialog.close()
             self._server, self._port, self._cert_path = None, None, None
 
         txs = utils.Transaction("Configuring {engine_name}".format(
-            engine_name=config.engine_name))
+            engine_name=config.ENGINE_NAME))
 
         if changes.contains_any(["vdsm_cfg.password"]):
             self.logger.debug("Setting engine password")
@@ -160,7 +166,9 @@
                          port=effective_model["vdsm_cfg.port"])
             self.logger.debug("Connecting to engine")
             txs += [ActivateVDSM(effective_model["vdsm_cfg.address"],
-                                 effective_model["vdsm_cfg.port"])]
+                                 effective_model["vdsm_cfg.port"],
+                                 effective_model["engine.newreg"]
+                                 )]
 
         if len(txs) > 0:
             progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs,
@@ -177,10 +185,6 @@
 def findPort(engineServer, enginePort):
     """Function to find the correct port for a given server
     """
-    # pylint: disable-msg=E0611,F0401
-    sys.path.append('/usr/share/vdsm-reg')
-    import deployUtil  # @UnresolvedImport
-
     from ovirt_config_setup.engine import \
         TIMEOUT_FIND_HOST_SEC  # @UnresolvedImport
     from ovirt_config_setup.engine import \
@@ -192,7 +196,8 @@
     LOGGER.debug("Finding port %s:%s with compat %s ssl %s" %
                  (engineServer, enginePort, compatPort, sslPort))
 
-    deployUtil.nodeCleanup()
+    cert = Cert()
+    cert.node_cleanup_certs()
 
     # Build port list to try
     port_cfgs = [(enginePort, sslPort)]
@@ -223,7 +228,7 @@
 
     if not is_reachable:
         raise RuntimeError("Can't connect to {engine_name}".format(
-            engine_name=config.engine_name))
+            engine_name=config.ENGINE_NAME))
 
     return enginePort
 
@@ -239,23 +244,20 @@
     return True
 
 
-def retrieveCetrificate(engineServer, enginePort):
+def retrieve_certificate(engineServer, enginePort):
     """Function to retrieve and store the certificate from an Engine
     """
     fingerprint = None
+    path = 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)
+    cert = Cert()
+    if cert.get_http_ca_cert(engineServer, enginePort):
+        _, _, path = cert.cert_paths()
+        fingerprint = cert.generate_fingerprint(path)
     else:
         msgCert = "Failed downloading " \
             "{engine_name} certificate".format(
-                engine_name=config.engine_name)
+                engine_name=config.ENGINE_NAME)
         raise RuntimeError(msgCert)
 
     return path, fingerprint
@@ -306,10 +308,13 @@
 class ActivateVDSM(utils.Transaction.Element):
     title = "Activating VDSM"
 
-    def __init__(self, server, port):
+    def __init__(self, server, port, newreg):
         super(ActivateVDSM, self).__init__()
         self.server = server
         self.port = port
+        self.newreg = newreg
+        self.misc = Misc()
+        self.cert = Cert()
 
     def cert_validator(self):
         cert_path = VDSM().retrieve()["cert_path"]
@@ -323,10 +328,6 @@
         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  # @UnresolvedImport
 
@@ -336,19 +337,37 @@
 
         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")
-        deployUtil._logExec([constants.EXT_SERVICE, 'vdsm-reg', 'stop'])
-        if write_vdsm_config(cfg["server"], cfg["port"]):
-            self.logger.info("Starting vdsm-reg service")
-            deployUtil._logExec([constants.EXT_SERVICE, 'vdsm-reg', 'start'])
+        if self.misc.get_uuid() is None:
+            raise RuntimeError("Cannot proceed without uuid request")
 
-            msgConf = "{engine_name} Configuration Successfully " \
-                " Updated".format(
-                    engine_name=config.engine_name)
-            self.logger.debug(msgConf)
+        kparams = self.misc.get_ovirtnode_kernel_params()
+
+        if "management_server_url" not in kparams or \
+                not self.newreg:
+            self.logger.info("VDSM-reg registering..")
+            # 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")
+            self.misc.execute([constants.EXT_SERVICE, 'vdsm-reg', 'stop'])
+            if write_vdsm_config(cfg["server"], cfg["port"]):
+                self.logger.info("Starting vdsm-reg service")
+                self.misc.execute([constants.EXT_SERVICE, 'vdsm-reg', 'start'])
+
+                msgConf = "{engine_name} Configuration Successfully " \
+                    " Updated".format(
+                        engine_name=config.ENGINE_NAME)
+                self.logger.debug(msgConf)
+            else:
+                msgConf = "{engine_name} Configuration Failed".format(
+                    engine_name=config.ENGINE_NAME)
+                raise RuntimeError(msgConf)
         else:
-            msgConf = "{engine_name} Configuration Failed".format(
-                engine_name=config.engine_name)
-            raise RuntimeError(msgConf)
+            keys = self.cert.get_authkeys_file(self.server, self.port)
+            if keys is not None:
+                self.cert.handle_ssh_key(keys)
+                self.misc.register_node(self.server, self.port)
+            else:
+                msgConf = "Cannot get public ssh key on" \
+                    " server: {server} port {port}".format(
+                    server=self.server, port=self.port)
+                raise RuntimeError(msgConf)
diff --git a/src/misc.py b/src/misc.py
new file mode 100644
index 0000000..1bc8bfc
--- /dev/null
+++ b/src/misc.py
@@ -0,0 +1,402 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# misc.py - Copyright (C) 2013 Red Hat, Inc.
+#
+# 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+import os
+import platform
+import logging
+import subprocess
+import uuid
+import urllib
+import socket
+import httplib
+
+from config import *
+from ovirt.node import utils
+
+
+class Misc(object):
+
+    _EX_DMIDECODE = '/usr/sbin/dmidecode'
+    _P_VDSM_NODE_ID = '/etc/vdsm/vdsm.id'
+    _LOG_PREFIX = 'ovirt-node-plugin-vdsm.'
+    _OVIRTNODE_KERNEL_OPTS = '/etc/default/ovirt'
+    _HTTP_SUCCESS_CODE = 200
+    _IP = '/usr/sbin/ip'
+
+    def __init__(self):
+
+        prefix = ''
+        if not self.__module__.startswith(self._LOG_PREFIX):
+            prefix = self._LOG_PREFIX
+
+        self.logger = logging.getLogger(prefix + self.__module__)
+
+    def executeRaw(
+        self,
+        args,
+        executable=None,
+        stdin=None,
+        cwd=None,
+        env=None,
+        envAppend=None,
+    ):
+        """Execute a process.
+
+         Keyword arguments:
+         args -- a list of command arguments.
+         executable -- executable name.
+         stdin -- binary blob.
+         cwd -- working directory.
+         env -- environment dictionary.
+         envAppend -- append environment.
+
+         Returns:
+         (rc, stdout, stderr)
+
+         stdour, stderr binary blobs.
+         """
+        try:
+            if envAppend is not None:
+                if env is None:
+                    env = os.environ
+                env = env.copy()
+                env.update(envAppend)
+
+            self.logger.debug(
+                "execute: %s, executable='%s', cwd='%s', env=%s",
+                args,
+                executable,
+                cwd,
+                env,
+            )
+            p = subprocess.Popen(
+                args,
+                executable=executable,
+                stdin=subprocess.PIPE if stdin is not None else None,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE,
+                close_fds=True,
+                cwd=cwd,
+                env=env,
+            )
+            stdout, stderr = p.communicate(input=stdin)
+            rc = p.returncode
+            self.logger.debug(
+                'execute-result: %s, rc=%s',
+                args,
+                rc,
+            )
+        except:
+            self.logger.debug(
+                'execute-result: %s, exception',
+                args,
+                exc_info=True
+            )
+            raise
+
+        return (rc, stdout, stderr)
+
+    def execute(
+        self,
+        args,
+        raiseOnError=True,
+        logStreams=True,
+        stdin=None,
+        *eargs,
+        **kwargs
+    ):
+        """Execute system command.
+
+        Keyword arguments:
+        args -- a list of command arguments.
+        raiseOnError -- raise exception if an error.
+        logStreams -- log streams' content.
+        stdin -- a list of lines.
+        eargs -- extra args to subprocess.Popen.
+        kwargs - extra kwargs to subprocess.Popen.
+
+        Returns:
+        (rc, stdout, stderr)
+
+        stdour, stderr are list of lines.
+        """
+        if logStreams and stdin is not None:
+            self.logger.debug(
+                'execute-input: %s stdin:\n%s\n',
+                args,
+                '\n'.join(stdin)
+            )
+        (rc, stdout, stderr) = self.executeRaw(
+            args=args,
+            stdin=(
+                '\n'.join(stdin).encode('utf-8')
+                if stdin is not None else None
+            ),
+            *eargs,
+            **kwargs
+        )
+        # warning: python-2.6 does not have kwargs for decode
+        stdout = stdout.decode('utf-8', 'replace').splitlines()
+        stderr = stderr.decode('utf-8', 'replace').splitlines()
+        if logStreams:
+            self.logger.debug(
+                'execute-output: %s stdout:\n%s\n',
+                args,
+                '\n'.join(stdout)
+            )
+            self.logger.debug(
+                'execute-output: %s stderr:\n%s\n',
+                args,
+                '\n'.join(stderr)
+            )
+        if rc != 0 and raiseOnError:
+            raise RuntimeError(
+                _("Command '{command}' failed to execute").format(
+                    command=args[0],
+                )
+            )
+        return (rc, stdout, stderr)
+
+    def get_uuid(self):
+        vdsmId = None
+
+        arch = platform.machine()
+        if arch in ('x86_64', 'i686'):
+            (rc, stdout, stderr) = self.execute(
+                (
+                    self._EX_DMIDECODE,
+                    '-s',
+                    'system-uuid'
+                ),
+                raiseOnError=False
+            )
+            if rc != 0 or len(stdout) != 1:
+                self.logger.warning('Invalid dmidecode output')
+            elif stdout[0].startswith('Not '):
+                self.logger.warning('No system uuid')
+            else:
+                vdsmId = stdout[0]
+        elif arch in ('ppc', 'ppc64'):
+            #eg. output IBM,03061C14A
+            if os.path.exists('/proc/device-tree/system-id'):
+                with open('/proc/device-tree/system-id') as f:
+                    vdsmId = f.readline().rstrip('\0').replace(',', '')
+
+        if vdsmId is None:
+            vdsmId = str(uuid.uuid4())
+            with open(self._P_VDSM_NODE_ID, 'w') as f:
+                f.write(vdsmId)
+            utils.fs.Config().persist(self._P_VDSM_NODE_ID)
+
+        return vdsmId
+
+    def get_ovirtnode_kernel_params(self):
+        kparams = {}
+        try:
+            with open(self._OVIRTNODE_KERNEL_OPTS, 'r') as configfile:
+                for line in configfile:
+                    if "OVIRT_BOOTPARAMS" in line:
+                        for item in line.split("\"")[1].split(" "):
+                            if "=" in item:
+                                kflag = item.split("=")
+                                kparams.update({kflag[0]: kflag[1]})
+                            else:
+                                kparams.update({item: ''})
+        except Exception as e:
+            logging.debug(
+                "Cannot get kernel params %s error %s",
+                self._OVIRTNODE_KERNEL_OPTS,
+                e
+            )
+
+        return kparams
+
+    def silent_restorecon(self, path):
+        """silently ignore restorecon exceptios, when SELinux is disabled"""
+        import selinux
+        try:
+            return selinux.restorecon(path)
+        except:
+            logging.error('restorecon %s failed', path, exc_info=True)
+
+    def register_node(self, engine, port):
+
+        (rc, stdout, stderr) = self.execute(
+            (
+                self._IP,
+                'route',
+                'get',
+                engine
+            ),
+            raiseOnError=True
+        )
+
+        node_address = stdout[0].split(" ")[5]
+        if node_address == '':
+            return
+
+        uuid = self.get_uuid()
+        host = socket.gethostname()
+        timeout = REGISTER_TIMEOUT_SEC
+
+        params = {
+            'vds_ip': node_address,
+            'vds_name': host,
+            'vds_unique_id': uuid,
+            'port': port,
+        }
+
+        for uri in ENGINE_URI.split(":"):
+            http_uri = uri + '?' + urllib.urlencode(params)
+
+            if uuid == "None" and "localhost.localdomain" in self.ovirtName:
+                logging.warn(
+                    "WARNING! node with no UUID and no unique host-name!"
+                )
+
+            ret = False
+            http_res = None
+
+            system_timeout = socket.getdefaulttimeout()
+            socket.setdefaulttimeout(timeout)
+            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+
+            try:
+                sock.connect((engine, int(port)))
+                conn = httplib.HTTPSConnection(engine + ":" + port)
+                conn.sock = ssl.wrap_socket(sock)
+                conn.request("GET", http_uri)
+                http_res = conn.getresponse()
+            except:
+                logging.debug(
+                    "register_node failed in HTTPS. Retrying using HTTP."
+                )
+                try:
+                    conn = None
+                    conn = httplib.HTTPConnection(engine + ":" + port)
+                    conn.request("GET", http_uri)
+                    http_res = conn.getresponse()
+                    logging.debug("register_node succeeded using HTTP.")
+                except:
+                    logging.error(
+                        "register_node failed using HTTP!",
+                        exc_info=True
+                    )
+            else:
+                logging.debug(
+                    "register_node status: %d reason: %s",
+                    http_res.status,
+                    res.reason
+                )
+
+            if http_res.status == self._HTTP_SUCCESS_CODE:
+                ret = True
+                break
+
+        if conn is not None:
+            conn.close()
+
+        socket.setdefaulttimeout(system_timeout)
+        logging.debug("register_node end. return %s", ret)
+
+        return ret
+
+    def get_remote_file(self, IP, port, fileName, timeout=None, certPath=None):
+        logging.debug(
+            "get_remote_file start. IP = %s port = %s fileName = \"%s\"" %
+            (IP, port, fileName)
+        )
+
+        data = None
+        response = None
+        conn = None
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.settimeout(timeout)
+
+        try:
+            connection_port = DEFAULT_SSL_PORT
+            if port is not connection_port:
+                connection_port = int(port)
+
+            sock.connect((IP, connection_port))
+            conn = httplib.HTTPSConnection(IP, connection_port)
+            conn.sock = getSSLSocket(sock, certPath)
+            conn.request("GET", fileName)
+            response = conn.getresponse()
+        except:
+            logging.debug(
+                "%s failed in HTTPS. Retrying using HTTP.",
+                fileName,
+                exc_info=True
+            )
+
+            strPort = ":"
+            if port is None:
+                strPort += "80"
+            else:
+                strPort += port
+
+            try:
+                conn = httplib.HTTPConnection(IP + strPort)
+                conn.request("GET", fileName)
+                response = conn.getresponse()
+            except:
+                logging.error(
+                    "Failed to fetch %s using http.",
+                    fileName,
+                    exc_info=True
+                )
+        else:
+            logging.debug(
+                "%s status: %s reason: %s",
+                fileName,
+                str(response.status),
+                response.reason
+            )
+
+        if response is None or response.status != self._HTTP_SUCCESS_CODE:
+            status = ""
+            if response is not None:
+                status = str(response.status)
+
+            if conn is not None:
+                conn.close()
+
+            logging.error(
+                "Failed to fetch %s status %s",
+                fileName,
+                status
+            )
+        else:
+            try:
+                data = str(response.read())
+            except:
+                logging.error(
+                    "Failed to read %s",
+                    fileName,
+                    exc_info=True
+                )
+            finally:
+                if conn is not None:
+                    conn.close()
+
+        logging.debug('get_remote_file end.')
+
+        return data
diff --git a/src/ovirt-node-plugin-vdsm_autoinstall.py 
b/src/ovirt-node-plugin-vdsm_autoinstall.py
new file mode 100644
index 0000000..8fa1902
--- /dev/null
+++ b/src/ovirt-node-plugin-vdsm_autoinstall.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# ovirt-node-plugin-vdsm_autoinstall.py - Copyright (C) 2013 Red Hat, Inc.
+#
+# 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+import ovirtnode.ovirtfunctions as _functions
+from ovirt.node.setup.vdsm import engine_page
+
+if __name__ == "__main__":
+    args = _functions.get_cmdline_args()
+    if "management_server_url" in args:
+        addr, port = args["management_server_url"].split(":")
+        engine_page.ActivateVDSM(addr, port, True).commit()


-- 
To view, visit http://gerrit.ovirt.org/17682
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I38f3b800c445f8dbb0fa0e89d128cea1e3407798
Gerrit-PatchSet: 8
Gerrit-Project: ovirt-node-plugin-vdsm
Gerrit-Branch: master
Gerrit-Owner: Douglas Schilling Landgraf <[email protected]>
Gerrit-Reviewer: Alon Bar-Lev <[email protected]>
Gerrit-Reviewer: Antoni Segura Puimedon <[email protected]>
Gerrit-Reviewer: Barak Azulay <[email protected]>
Gerrit-Reviewer: Dan Kenigsberg <[email protected]>
Gerrit-Reviewer: Douglas Schilling Landgraf <[email protected]>
Gerrit-Reviewer: Joey Boggs <[email protected]>
Gerrit-Reviewer: Michael Burns <[email protected]>
Gerrit-Reviewer: oVirt Jenkins CI Server
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to