summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cns-libs/cnslibs/common/heketi_version.py116
1 files changed, 103 insertions, 13 deletions
diff --git a/cns-libs/cnslibs/common/heketi_version.py b/cns-libs/cnslibs/common/heketi_version.py
index ccf92d33..d198ebeb 100644
--- a/cns-libs/cnslibs/common/heketi_version.py
+++ b/cns-libs/cnslibs/common/heketi_version.py
@@ -1,9 +1,11 @@
"""
-Use this module for any Heketi client package version comparisons.
+Use this module for any Heketi server and client packages versions comparisons.
Usage example:
- # Assume Heketi version is '7.0.0-3'. Then we have following:
+ # Assume Heketi server version is '7.0.0-3' and client is '7.0.0-5'
+ Then we have following:
+
from cnslibs.common import heketi_version
version = heketi_version.get_heketi_version()
if version < '7.0.0-4':
@@ -12,21 +14,28 @@ Usage example:
# False
if '7.0.0-2' < version <= '7.0.0-3':
# True
+
+ At first step, we compare requested version against the Heketi server
+ version, making sure they are compatible. Then, we make sure, that
+ existing heketi client package has either the same or newer version than
+ server's one.
"""
import re
from glusto.core import Glusto as g
import six
+from cnslibs.common import command
from cnslibs.common import exceptions
HEKETI_VERSION_RE = r"(\d+)(?:\.)(\d+)(?:\.)(\d+)(?:\-)(\d+)$"
-HEKETI_VERSION = None
+HEKETI_CLIENT_VERSION = None
+HEKETI_SERVER_VERSION = None
-def _get_heketi_version_str(hostname=None):
- """Gets Heketi client package version.
+def _get_heketi_client_version_str(hostname=None):
+ """Gets Heketi client package version from heketi client node.
Args:
hostname (str): Node on which the version check command should run.
@@ -42,8 +51,8 @@ def _get_heketi_version_str(hostname=None):
"cut -d '.' -f 1,2,3")
ret, out, err = g.run(hostname, cmd, "root")
if ret != 0:
- msg = "Failed to get heketi version. \n'err': %s\n 'out': %s" % (
- err, out)
+ msg = ("Failed to get heketi client version. "
+ "\n'err': %s\n 'out': %s" % (err, out))
g.log.error(msg)
raise AssertionError(msg)
out = out.strip()
@@ -55,6 +64,49 @@ def _get_heketi_version_str(hostname=None):
return out
+def _get_heketi_server_version_str(ocp_client_node=None):
+ """Gets Heketi server package version from Heketi POD.
+
+ Args:
+ ocp_client_node (str): Node on which the version check command should
+ run.
+ Returns:
+ str : heketi version, i.e. '7.0.0-1'
+ Raises: 'exceptions.ExecutionError' if failed to get version
+ """
+ if not ocp_client_node:
+ ocp_client_node = g.config["ocp_servers"]["client"].keys()[0]
+ get_package_version_cmd = (
+ "rpm -q heketi --queryformat '%{version}-%{release}\n' | "
+ "cut -d '.' -f 1,2,3")
+
+ # NOTE(vponomar): we implement Heketi POD call command here, not in common
+ # module for OC commands just to avoid cross-reference imports.
+ get_pods_cmd = "oc get -o wide --no-headers=true pods --selector heketi"
+ heketi_pods = command.cmd_run(get_pods_cmd, hostname=ocp_client_node)
+
+ err_msg = ""
+ for heketi_pod_line in heketi_pods.split("\n"):
+ heketi_pod_data = heketi_pod_line.split()
+ if ("-deploy" in heketi_pod_data[0] or
+ heketi_pod_data[1].lower() != "1/1" or
+ heketi_pod_data[2].lower() != "running"):
+ continue
+ try:
+ pod_cmd = "oc exec %s -- %s" % (
+ heketi_pod_data[0], get_package_version_cmd)
+ return command.cmd_run(pod_cmd, hostname=ocp_client_node)
+ except Exception as e:
+ err = ("Failed to run '%s' command on '%s' Heketi POD. "
+ "Error: %s\n" % (pod_cmd, heketi_pod_data[0], e))
+ err_msg += err
+ g.log.error(err)
+ if not err_msg:
+ err_msg += "Haven't found 'Running' and 'ready' (1/1) Heketi PODs.\n"
+ err_msg += "Heketi PODs: %s" % heketi_pods
+ raise exceptions.ExecutionError(err_msg)
+
+
def _parse_heketi_version(heketi_version_str):
"""Parses Heketi version str into tuple of 4 values.
@@ -110,32 +162,62 @@ class HeketiVersion(object):
"'%s' type is not supported for Heketi version "
"comparison." % type(other))
+ def _compare_client_and_server_versions(self, client_v, server_v):
+ if client_v < server_v:
+ raise Exception(
+ "Client version (%s) is older than server's (%s)." % (
+ client_v, server_v))
+
def __lt__(self, other):
+ global HEKETI_CLIENT_VERSION
+ global HEKETI_SERVER_VERSION
+ self._compare_client_and_server_versions(
+ HEKETI_CLIENT_VERSION.v, HEKETI_SERVER_VERSION.v)
adapted_other = self._adapt_other(other)
return self.v < adapted_other.v
def __le__(self, other):
+ global HEKETI_CLIENT_VERSION
+ global HEKETI_SERVER_VERSION
+ self._compare_client_and_server_versions(
+ HEKETI_CLIENT_VERSION.v, HEKETI_SERVER_VERSION.v)
adapted_other = self._adapt_other(other)
return self.v <= adapted_other.v
def __eq__(self, other):
+ global HEKETI_CLIENT_VERSION
+ global HEKETI_SERVER_VERSION
+ self._compare_client_and_server_versions(
+ HEKETI_CLIENT_VERSION.v, HEKETI_SERVER_VERSION.v)
adapted_other = self._adapt_other(other)
return self.v == adapted_other.v
def __ge__(self, other):
+ global HEKETI_CLIENT_VERSION
+ global HEKETI_SERVER_VERSION
+ self._compare_client_and_server_versions(
+ HEKETI_CLIENT_VERSION.v, HEKETI_SERVER_VERSION.v)
adapted_other = self._adapt_other(other)
return self.v >= adapted_other.v
def __gt__(self, other):
+ global HEKETI_CLIENT_VERSION
+ global HEKETI_SERVER_VERSION
+ self._compare_client_and_server_versions(
+ HEKETI_CLIENT_VERSION.v, HEKETI_SERVER_VERSION.v)
adapted_other = self._adapt_other(other)
return self.v > adapted_other.v
def __ne__(self, other):
+ global HEKETI_CLIENT_VERSION
+ global HEKETI_SERVER_VERSION
+ self._compare_client_and_server_versions(
+ HEKETI_CLIENT_VERSION.v, HEKETI_SERVER_VERSION.v)
adapted_other = self._adapt_other(other)
return self.v != adapted_other.v
-def get_heketi_version(hostname=None):
+def get_heketi_version(hostname=None, ocp_client_node=None):
"""Cacher of the Heketi client package version.
Version of Heketi client package is constant value. So, we call API just
@@ -146,11 +228,19 @@ def get_heketi_version(hostname=None):
If not specified, then first key
from 'openshift.heketi_config.heketi_client_node' config option
will be picked up.
+ ocp_client_node (str): a node with the 'oc' client,
+ where Heketi POD command will run.
+ If not specified, then first key
+ from 'ocp_servers.client' config option will be picked up.
Returns:
HeketiVersion object instance.
"""
- global HEKETI_VERSION
- if not HEKETI_VERSION:
- version_str = _get_heketi_version_str(hostname=hostname)
- HEKETI_VERSION = HeketiVersion(version_str)
- return HEKETI_VERSION
+ global HEKETI_CLIENT_VERSION
+ global HEKETI_SERVER_VERSION
+ if not (HEKETI_SERVER_VERSION and HEKETI_CLIENT_VERSION):
+ client_version_str = _get_heketi_client_version_str(hostname=hostname)
+ server_version_str = _get_heketi_server_version_str(
+ ocp_client_node=ocp_client_node)
+ HEKETI_CLIENT_VERSION = HeketiVersion(client_version_str)
+ HEKETI_SERVER_VERSION = HeketiVersion(server_version_str)
+ return HEKETI_SERVER_VERSION