diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0ce029072928ad5d86de3b9d502f139d353a1d8e..7af0dd3085bf3c2dfb732d0b13df332a9c8e5717 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ stages: variables: BUILD_ENV_DOCKER_IMAGE: docker-registry.ebrains.eu/esd/tmp:latest + build-wheel: stage: build tags: diff --git a/esd/error_handling/exceptions.py b/esd/error_handling/exceptions.py index d6de666bd472555ff75b87166d532cfd4fcc4446..9d11b5fa46e1d87c80e258753dcfa425ea367d34 100644 --- a/esd/error_handling/exceptions.py +++ b/esd/error_handling/exceptions.py @@ -14,13 +14,18 @@ class BashCommandException(SpackException): """ -class NoSpackEnvironmentException(SpackException): +class NoSpackEnvironmentException(BashCommandException): """ To be thrown when an operation on a spack environment is executed without the environment being activated or existent """ -class SpackConcertizeException(SpackException): +class SpackConcertizeException(BashCommandException): """ To be thrown when the spack concretization step fails """ + +class SpackInstallPackagesException(BashCommandException): + """ + To be thrown when the spack fails to install spack packages + """ diff --git a/esd/spack_manager/SpackManager.py b/esd/spack_manager/SpackManager.py index 340b1b9580b4ec4c1829b149a1276f314e3dfbfc..a7f46c2778eeb874a138a01e2c99ed85f7f12e3d 100644 --- a/esd/spack_manager/SpackManager.py +++ b/esd/spack_manager/SpackManager.py @@ -1,10 +1,13 @@ import os +import re from abc import ABC, abstractmethod from pathlib import Path -from esd.error_handling.exceptions import BashCommandException, NoSpackEnvironmentException +from esd.error_handling.exceptions import BashCommandException, NoSpackEnvironmentException, \ + SpackInstallPackagesException from esd.logger.logger_builder import get_logger from esd.model.SpackModel import SpackModel +from esd.spack_manager.wrapper.spack_wrapper import no_spack_env from esd.utils.utils import run_command, git_clone_repo @@ -103,10 +106,10 @@ class SpackManager(ABC): else: if self.spack_env_exists(): result = run_command("bash", "-c", - f'source {self.spack_setup_script} && spack env activate -p {self.env_path} && spack repo list', - check=True, - capture_output=True, text=True, logger=self.logger, - debug_msg=f'Checking if repository {repo_name} was added') + f'source {self.spack_setup_script} && spack env activate -p {self.env_path} && spack repo list', + check=True, + capture_output=True, text=True, logger=self.logger, + debug_msg=f'Checking if repository {repo_name} was added') else: self.logger.debug('No spack environment defined') raise NoSpackEnvironmentException('No spack environment defined') @@ -124,18 +127,35 @@ class SpackManager(ABC): return False return True + @no_spack_env def add_spack_repo(self, repo_path: Path, repo_name: str): """Add the Spack repository if it does not exist.""" - if self.spack_env_exists(): - run_command("bash", "-c", - f'source {self.spack_setup_script} && spack env activate -p {self.env_path} && spack repo add {repo_path}/{repo_name}', - check=True, logger=self.logger, - debug_msg=f"Added {repo_name} to spack environment {self.env.env_name}", - exception_msg=f"Failed to add {repo_name} to spack environment {self.env.env_name}", - exception=BashCommandException) - else: - self.logger.debug('No spack environment defined') - raise NoSpackEnvironmentException('No spack environment defined') + run_command("bash", "-c", + f'source {self.spack_setup_script} && spack env activate -p {self.env_path} && spack repo add {repo_path}/{repo_name}', + check=True, logger=self.logger, + debug_msg=f"Added {repo_name} to spack environment {self.env.env_name}", + exception_msg=f"Failed to add {repo_name} to spack environment {self.env.env_name}", + exception=BashCommandException) + + @no_spack_env + def get_compiler_version(self): + result = run_command("bash", "-c", + f'source {self.spack_setup_script} && spack env activate -p {self.env_path} && spack compiler list', + check=True, logger=self.logger, + capture_output=True, text=True, + debug_msg=f"Checking spack environment compiler version for {self.env.env_name}", + exception_msg=f"Failed to checking spack environment compiler version for {self.env.env_name}", + exception=BashCommandException) + # todo add error handling and tests + if result.stdout is None: + self.logger.debug('No gcc found for {self.env.env_name}') + return None + + # Find the first occurrence of a GCC compiler using regex + match = re.search(r"gcc@([\d\.]+)", result.stdout) + gcc_version = match.group(1) + self.logger.debug(f'Found gcc for {self.env.env_name}: {gcc_version}') + return gcc_version def get_spack_installed_version(self): spack_version = run_command("bash", "-c", f'source {self.spack_setup_script} && spack --version', @@ -147,6 +167,7 @@ class SpackManager(ABC): return spack_version.stdout.strip().split()[0] return None + def install_spack(self, spack_version="v0.21.1", spack_repo='https://github.com/spack/spack'): try: user = os.getlogin() diff --git a/esd/spack_manager/wrapper/__init__.py b/esd/spack_manager/wrapper/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/esd/spack_manager/wrapper/spack_wrapper.py b/esd/spack_manager/wrapper/spack_wrapper.py new file mode 100644 index 0000000000000000000000000000000000000000..d075a317289669d00aa07b086ed78a41922f26fd --- /dev/null +++ b/esd/spack_manager/wrapper/spack_wrapper.py @@ -0,0 +1,15 @@ +import functools + +from esd.error_handling.exceptions import NoSpackEnvironmentException + + +def no_spack_env(method): + @functools.wraps(method) + def wrapper(self, *args, **kwargs): + if self.spack_env_exists(): + return method(self, *args, **kwargs) # Call the method with 'self' + else: + self.logger.debug('No spack environment defined') + raise NoSpackEnvironmentException('No spack environment defined') + + return wrapper