Skip to content
Snippets Groups Projects

Draft: Esd spack installation

Closed Adrian Ciu requested to merge esd-spack-installation into master
Compare and
29 files
+ 1028
45
Compare changes
  • Side-by-side
  • Inline
Files
29
@@ -12,48 +12,51 @@ class BuildCacheManager(BuildCacheManagerInterface):
@@ -12,48 +12,51 @@ class BuildCacheManager(BuildCacheManagerInterface):
This class aims to manage the push/pull/delete of build cache files
This class aims to manage the push/pull/delete of build cache files
"""
"""
def __init__(self, auth_backend='basic', insecure=False):
def __init__(self, registry_host, registry_project, registry_username, registry_password, cache_version='cache',
self.logger = get_logger(__name__, BuildCacheManager.__name__)
auth_backend='basic',
self.home_path = Path(os.environ.get("HOME_PATH", os.getcwd()))
insecure=False):
self.registry_project = os.environ.get("REGISTRY_PROJECT")
self._logger = get_logger(__name__, BuildCacheManager.__name__)
 
self._registry_project = registry_project
self._registry_username = str(os.environ.get("REGISTRY_USERNAME"))
self._registry_username = registry_username
self._registry_password = str(os.environ.get("REGISTRY_PASSWORD"))
self._registry_password = registry_password
self.registry_host = str(os.environ.get("REGISTRY_HOST"))
self._registry_host = registry_host
# Initialize an OrasClient instance.
# Initialize an OrasClient instance.
# This method utilizes the OCI Registry for container image and artifact management.
# This method utilizes the OCI Registry for container image and artifact management.
# Refer to the official OCI Registry documentation for detailed information on the available authentication methods.
# Refer to the official OCI Registry documentation for detailed information on the available authentication methods.
# Supported authentication types may include basic authentication (username/password), token-based authentication,
# Supported authentication types may include basic authentication (username/password), token-based authentication,
self.client = oras.client.OrasClient(hostname=self.registry_host, auth_backend=auth_backend, insecure=insecure)
self._client = oras.client.OrasClient(hostname=self._registry_host, auth_backend=auth_backend,
self.client.login(username=self._registry_username, password=self._registry_password)
insecure=insecure)
self.oci_registry_path = f'{self.registry_host}/{self.registry_project}/cache'
self._client.login(username=self._registry_username, password=self._registry_password)
 
self.cache_version = cache_version
 
self._oci_registry_path = f'{self._registry_host}/{self._registry_project}/{self.cache_version}'
def upload(self, out_dir: Path):
def upload(self, out_dir: Path):
"""
"""
This method pushed all the files from the build cache folder into the OCI Registry
This method pushed all the files from the build cache folder into the OCI Registry
"""
"""
build_cache_path = self.home_path / out_dir
build_cache_path = out_dir.resolve()
# build cache folder must exist before pushing all the artifacts
# build cache folder must exist before pushing all the artifacts
if not build_cache_path.exists():
if not build_cache_path.exists():
self.logger.error(f"Path {build_cache_path} not found.")
self._logger.error(f"Path {build_cache_path} not found.")
for sub_path in build_cache_path.rglob("*"):
for sub_path in build_cache_path.rglob("*"):
if sub_path.is_file():
if sub_path.is_file():
rel_path = str(sub_path.relative_to(build_cache_path)).replace(str(sub_path.name), "")
rel_path = str(sub_path.relative_to(build_cache_path)).replace(str(sub_path.name), "")
target = f"{self.registry_host}/{self.registry_project}/cache:{str(sub_path.name)}"
target = f"{self._registry_host}/{self._registry_project}/{self.cache_version}:{str(sub_path.name)}"
try:
try:
self.logger.info(f"Pushing folder '{sub_path}' to ORAS target '{target}' ...")
self._logger.info(f"Pushing folder '{sub_path}' to ORAS target '{target}' ...")
self.client.push(
self._client.push(
files=[str(sub_path)],
files=[str(sub_path)],
target=target,
target=target,
# save in manifest the relative path for reconstruction
# save in manifest the relative path for reconstruction
manifest_annotations={"path": rel_path},
manifest_annotations={"path": rel_path},
disable_path_validation=True,
disable_path_validation=True,
)
)
self.logger.info(f"Successfully pushed {sub_path.name}")
self._logger.info(f"Successfully pushed {sub_path.name}")
except Exception as e:
except Exception as e:
self.logger.error(
self._logger.error(
f"An error occurred while pushing: {e}")
f"An error occurred while pushing: {e}")
# todo to be discussed hot to delete the build cache after being pushed to the OCI Registry
# todo to be discussed hot to delete the build cache after being pushed to the OCI Registry
# clean_up([str(build_cache_path)], self.logger)
# clean_up([str(build_cache_path)], self.logger)
@@ -63,37 +66,38 @@ class BuildCacheManager(BuildCacheManagerInterface):
@@ -63,37 +66,38 @@ class BuildCacheManager(BuildCacheManagerInterface):
This method retrieves all tags from an OCI Registry
This method retrieves all tags from an OCI Registry
"""
"""
try:
try:
return self.client.get_tags(self.oci_registry_path)
return self._client.get_tags(self._oci_registry_path)
except Exception as e:
except Exception as e:
self.logger.error(f"Failed to list tags: {e}")
self._logger.error(f"Failed to list tags: {e}")
return None
return None
def download(self, in_dir: Path):
def download(self, in_dir: Path):
"""
"""
This method pulls all the files from the OCI Registry into the build cache folder
This method pulls all the files from the OCI Registry into the build cache folder
"""
"""
build_cache_path = self.home_path / in_dir
build_cache_path = in_dir.resolve()
# create the buildcache dir if it does not exist
# create the buildcache dir if it does not exist
os.makedirs(build_cache_path, exist_ok=True)
os.makedirs(build_cache_path, exist_ok=True)
tags = self.list_tags()
tags = self.list_tags()
if tags is not None:
if tags is not None:
for tag in tags:
for tag in tags:
ref = f"{self.registry_host}/{self.registry_project}/cache:{tag}"
ref = f"{self._registry_host}/{self._registry_project}/{self.cache_version}:{tag}"
# reconstruct the relative path of each artifact by getting it from the manifest
# reconstruct the relative path of each artifact by getting it from the manifest
cache_path = \
cache_path = \
self.client.get_manifest(f'{self.registry_host}/{self.registry_project}/cache:{tag}')[
self._client.get_manifest(
 
f'{self._registry_host}/{self._registry_project}/{self.cache_version}:{tag}')[
'annotations'][
'annotations'][
'path']
'path']
try:
try:
self.client.pull(
self._client.pull(
ref,
ref,
# missing dirs to output dir are created automatically by OrasClient pull method
# missing dirs to output dir are created automatically by OrasClient pull method
outdir=str(build_cache_path / cache_path),
outdir=str(build_cache_path / cache_path),
overwrite=True
overwrite=True
)
)
self.logger.info(f"Successfully pulled artifact {tag}.")
self._logger.info(f"Successfully pulled artifact {tag}.")
except Exception as e:
except Exception as e:
self.logger.error(
self._logger.error(
f"Failed to pull artifact {tag} : {e}")
f"Failed to pull artifact {tag} : {e}")
def delete(self):
def delete(self):
@@ -106,8 +110,8 @@ class BuildCacheManager(BuildCacheManagerInterface):
@@ -106,8 +110,8 @@ class BuildCacheManager(BuildCacheManagerInterface):
tags = self.list_tags()
tags = self.list_tags()
if tags is not None:
if tags is not None:
try:
try:
self.client.delete_tags(self.oci_registry_path, tags)
self._client.delete_tags(self._oci_registry_path, tags)
self.logger.info(f"Successfully deleted all artifacts form OCI registry.")
self._logger.info(f"Successfully deleted all artifacts form OCI registry.")
except RuntimeError as e:
except RuntimeError as e:
self.logger.error(
self._logger.error(
f"Failed to delete artifacts: {e}")
f"Failed to delete artifacts: {e}")