Bug 2066 fixed
[osm/N2VC.git] / n2vc / k8s_helm_base_conn.py
index e494a76..6ddf118 100644 (file)
@@ -404,9 +404,9 @@ class K8sHelmBaseConnector(K8sConnector):
         # version
         kdu_model, version = self._split_version(kdu_model)
 
-        repo = self._split_repo(kdu_model)
+        _, repo = self._split_repo(kdu_model)
         if repo:
-            self.repo_update(cluster_id, repo)
+            await self.repo_update(cluster_id, repo)
 
         command = self._get_install_command(
             kdu_model,
@@ -508,9 +508,9 @@ class K8sHelmBaseConnector(K8sConnector):
         # version
         kdu_model, version = self._split_version(kdu_model)
 
-        repo = self._split_repo(kdu_model)
+        _, repo = self._split_repo(kdu_model)
         if repo:
-            self.repo_update(cluster_uuid, repo)
+            await self.repo_update(cluster_uuid, repo)
 
         command = self._get_upgrade_command(
             kdu_model,
@@ -742,7 +742,7 @@ class K8sHelmBaseConnector(K8sConnector):
             raise K8sException("kdu_instance {} not found".format(kdu_instance))
 
         # init env, paths
-        paths, env = self._init_paths_env(
+        paths, _ = self._init_paths_env(
             cluster_name=cluster_uuid, create_if_not_exist=True
         )
 
@@ -753,8 +753,15 @@ class K8sHelmBaseConnector(K8sConnector):
             resource_name=resource_name,
         )
 
+        self.log.debug(
+            f"Number of replicas of the KDU instance {kdu_instance} and resource {resource_name} obtained: {replicas}"
+        )
+
         # Get default value if scale count is not found from provided values
-        if not replicas:
+        # Important note: this piece of code shall only be executed in the first scaling operation,
+        # since it is expected that the _get_replica_count_instance is able to obtain the number of
+        # replicas when a scale operation was already conducted previously for this KDU/resource!
+        if replicas is None:
             repo_url = await self._find_repo(
                 kdu_model=kdu_model, cluster_uuid=cluster_uuid
             )
@@ -762,10 +769,15 @@ class K8sHelmBaseConnector(K8sConnector):
                 kdu_model=kdu_model, repo_url=repo_url, resource_name=resource_name
             )
 
-        if not replicas:
-            msg = "Replica count not found. Cannot be scaled"
-            self.log.error(msg)
-            raise K8sException(msg)
+            self.log.debug(
+                f"Number of replicas of the Helm Chart package for KDU instance {kdu_instance} and resource "
+                f"{resource_name} obtained: {replicas}"
+            )
+
+            if replicas is None:
+                msg = "Replica count not found. Cannot be scaled"
+                self.log.error(msg)
+                raise K8sException(msg)
 
         return int(replicas)
 
@@ -1547,6 +1559,9 @@ class K8sHelmBaseConnector(K8sConnector):
             return output, return_code
 
         except asyncio.CancelledError:
+            # first, kill the process if it is still running
+            if process.returncode is None:
+                process.kill()
             raise
         except K8sException:
             raise
@@ -1586,7 +1601,7 @@ class K8sHelmBaseConnector(K8sConnector):
         try:
             async with self.cmd_lock:
                 read, write = os.pipe()
-                await asyncio.create_subprocess_exec(
+                process_1 = await asyncio.create_subprocess_exec(
                     *command1, stdout=write, env=environ
                 )
                 os.close(write)
@@ -1622,6 +1637,10 @@ class K8sHelmBaseConnector(K8sConnector):
 
             return output, return_code
         except asyncio.CancelledError:
+            # first, kill the processes if they are still running
+            for process in (process_1, process_2):
+                if process.returncode is None:
+                    process.kill()
             raise
         except K8sException:
             raise
@@ -1708,10 +1727,8 @@ class K8sHelmBaseConnector(K8sConnector):
         if repo_url:
             repo_str = " --repo {}".format(repo_url)
 
-        idx = kdu_model.find("/")
-        if idx >= 0:
-            idx += 1
-            kdu_model = kdu_model[idx:]
+            # Obtain the Chart's name and store it in the var kdu_model
+            kdu_model, _ = self._split_repo(kdu_model=kdu_model)
 
         kdu_model, version = self._split_version(kdu_model)
         if version:
@@ -1720,10 +1737,13 @@ class K8sHelmBaseConnector(K8sConnector):
             version_str = ""
 
         full_command = self._get_inspect_command(
-            inspect_command, kdu_model, repo_str, version_str
+            show_command=inspect_command,
+            kdu_model=kdu_model,
+            repo_str=repo_str,
+            version=version_str,
         )
 
-        output, _rc = await self._local_async_exec(command=full_command)
+        output, _ = await self._local_async_exec(command=full_command)
 
         return output
 
@@ -1732,7 +1752,7 @@ class K8sHelmBaseConnector(K8sConnector):
         kdu_model: str,
         repo_url: str = None,
         resource_name: str = None,
-    ):
+    ) -> (int, str):
         """Get the replica count value in the Helm Chart Values.
 
         Args:
@@ -1741,7 +1761,9 @@ class K8sHelmBaseConnector(K8sConnector):
             resource_name: Resource name
 
         Returns:
-            True if replicas, False replicaCount
+            A tuple with:
+            - The number of replicas of the specific instance; if not found, returns None; and
+            - The string corresponding to the replica count key in the Helm values
         """
 
         kdu_values = yaml.load(
@@ -1749,6 +1771,8 @@ class K8sHelmBaseConnector(K8sConnector):
             Loader=yaml.SafeLoader,
         )
 
+        self.log.debug(f"Obtained the Helm package values for the KDU: {kdu_values}")
+
         if not kdu_values:
             raise K8sException(
                 "kdu_values not found for kdu_model {}".format(kdu_model)
@@ -1769,10 +1793,10 @@ class K8sHelmBaseConnector(K8sConnector):
         replica_str = ""
         replicas = None
 
-        if kdu_values.get("replicaCount", None):
+        if kdu_values.get("replicaCount") is not None:
             replicas = kdu_values["replicaCount"]
             replica_str = "replicaCount"
-        elif kdu_values.get("replicas", None):
+        elif kdu_values.get("replicas") is not None:
             duplicate_check = True
             replicas = kdu_values["replicas"]
             replica_str = "replicas"
@@ -1811,7 +1835,7 @@ class K8sHelmBaseConnector(K8sConnector):
         namespace: str,
         kubeconfig: str,
         resource_name: str = None,
-    ):
+    ) -> int:
         """Get the replica count value in the instance.
 
         Args:
@@ -1821,7 +1845,7 @@ class K8sHelmBaseConnector(K8sConnector):
             resource_name: Resource name
 
         Returns:
-            True if replicas, False replicaCount
+            The number of replicas of the specific instance; if not found, returns None
         """
 
         kdu_values = yaml.load(
@@ -1829,23 +1853,23 @@ class K8sHelmBaseConnector(K8sConnector):
             Loader=yaml.SafeLoader,
         )
 
+        self.log.debug(f"Obtained the Helm values for the KDU instance: {kdu_values}")
+
         replicas = None
 
         if kdu_values:
             resource_values = (
                 kdu_values.get(resource_name, None) if resource_name else None
             )
-            replicas = (
-                (
-                    resource_values.get("replicaCount", None)
-                    or resource_values.get("replicas", None)
-                )
-                if resource_values
-                else (
-                    kdu_values.get("replicaCount", None)
-                    or kdu_values.get("replicas", None)
-                )
-            )
+
+            for replica_str in ("replicaCount", "replicas"):
+                if resource_values:
+                    replicas = resource_values.get(replica_str)
+                else:
+                    replicas = kdu_values.get(replica_str)
+
+                if replicas is not None:
+                    break
 
         return replicas
 
@@ -1992,12 +2016,27 @@ class K8sHelmBaseConnector(K8sConnector):
                 kdu_model = parts[0]
         return kdu_model, version
 
-    async def _split_repo(self, kdu_model: str) -> str:
+    def _split_repo(self, kdu_model: str) -> (str, str):
+        """Obtain the Helm Chart's repository and Chart's names from the KDU model
+
+        Args:
+            kdu_model (str): Associated KDU model
+
+        Returns:
+            (str, str): Tuple with the Chart name in index 0, and the repo name
+                        in index 2; if there was a problem finding them, return None
+                        for both
+        """
+
+        chart_name = None
         repo_name = None
+
         idx = kdu_model.find("/")
         if idx >= 0:
+            chart_name = kdu_model[idx + 1 :]
             repo_name = kdu_model[:idx]
-        return repo_name
+
+        return chart_name, repo_name
 
     async def _find_repo(self, kdu_model: str, cluster_uuid: str) -> str:
         """Obtain the Helm repository for an Helm Chart
@@ -2010,12 +2049,15 @@ class K8sHelmBaseConnector(K8sConnector):
             str: the repository URL; if Helm Chart is a local one, the function returns None
         """
 
+        _, repo_name = self._split_repo(kdu_model=kdu_model)
+
         repo_url = None
-        idx = kdu_model.find("/")
-        if idx >= 0:
-            repo_name = kdu_model[:idx]
+        if repo_name:
             # Find repository link
             local_repo_list = await self.repo_list(cluster_uuid)
             for repo in local_repo_list:
-                repo_url = repo["url"] if repo["name"] == repo_name else None
+                if repo["name"] == repo_name:
+                    repo_url = repo["url"]
+                    break  # it is not necessary to continue the loop if the repo link was found...
+
         return repo_url