if self._stable_repo_url == "None":
self._stable_repo_url = None
+ # Lock to avoid concurrent execution of helm commands
+ self.cmd_lock = asyncio.Lock()
+
def _get_namespace(self, cluster_uuid: str) -> str:
"""
Obtains the namespace used by the cluster with the uuid passed by argument
# 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,
# 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,
environ.update(env)
try:
- process = await asyncio.create_subprocess_exec(
- *command,
- stdout=asyncio.subprocess.PIPE,
- stderr=asyncio.subprocess.PIPE,
- env=environ,
- )
+ async with self.cmd_lock:
+ process = await asyncio.create_subprocess_exec(
+ *command,
+ stdout=asyncio.subprocess.PIPE,
+ stderr=asyncio.subprocess.PIPE,
+ env=environ,
+ )
- # wait for command terminate
- stdout, stderr = await process.communicate()
+ # wait for command terminate
+ stdout, stderr = await process.communicate()
- return_code = process.returncode
+ return_code = process.returncode
output = ""
if stdout:
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
environ.update(env)
try:
- read, write = os.pipe()
- await asyncio.create_subprocess_exec(*command1, stdout=write, env=environ)
- os.close(write)
- process_2 = await asyncio.create_subprocess_exec(
- *command2, stdin=read, stdout=asyncio.subprocess.PIPE, env=environ
- )
- os.close(read)
- stdout, stderr = await process_2.communicate()
+ async with self.cmd_lock:
+ read, write = os.pipe()
+ process_1 = await asyncio.create_subprocess_exec(
+ *command1, stdout=write, env=environ
+ )
+ os.close(write)
+ process_2 = await asyncio.create_subprocess_exec(
+ *command2, stdin=read, stdout=asyncio.subprocess.PIPE, env=environ
+ )
+ os.close(read)
+ stdout, stderr = await process_2.communicate()
- return_code = process_2.returncode
+ return_code = process_2.returncode
output = ""
if stdout:
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
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:
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
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
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