Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve compare #16

Merged
merged 9 commits into from
Feb 20, 2025
12 changes: 11 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"request": "launch",
"justMyCode": false,
"program": "/venv/bin/deploy-tools",
"args": "compare ${input:deploy-folder}",
"args": "compare ${input:use-previous} ${input:deploy-folder}",
"console": "integratedTerminal",
"env": {
// Enable break on exception when debugging tests (see: tests/conftest.py)
Expand Down Expand Up @@ -101,5 +101,15 @@
"default": "--no-from-scratch",
"type": "pickString"
},
{
"id": "use-previous",
"description": "Compare against previous Deployment snapshot",
"options": [
"--use-previous",
"--no-use-previous"
],
"default": "--no-use-previous",
"type": "pickString"
},
]
}
12 changes: 11 additions & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
{
"label": "Compare deployment to snapshot",
"type": "shell",
"command": "deploy-tools compare ${input:deploy-folder}",
"command": "deploy-tools compare ${input:use-previous} ${input:deploy-folder}",
"problemMatcher": []
},
],
Expand Down Expand Up @@ -72,5 +72,15 @@
"default": "--no-from-scratch",
"type": "pickString"
},
{
"id": "use-previous",
"description": "Compare against previous Deployment snapshot",
"options": [
"--use-previous",
"--no-use-previous"
],
"default": "--no-use-previous",
"type": "pickString"
},
]
}
36 changes: 18 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,21 @@ The equivalent CLI commands are included for reference, but it is recommended th

## Glossary

| **Term** | **Definition** |
|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Environment Modules | A [standard package for Linux](https://modules.readthedocs.io/en/latest/) that provides definitions for loading and unloading 'Environment Modules'. Note that while we are using this system, our definition of Module is separate. If we are referring to an Environment Module, we will use the full name |
| Modulefile | Used by the Environment Modules package to specify all details of an Environment Module. This can include executables to add to the path, environment variables to set, etc. |
| Module | A set of files that can be used to provide applications on your path, provide configuration, and set environment variables. We do this using the Environment Modules system by providing a Modulefile with the relevant configuration |
| Application | Each Module can be configured with multiple Applications, each one providing one or more executables. As of writing, there are 3 types of Application: `Apptainer`, `Shell` (script) and (Bash) `Command` |
| Deployment Area | The filesystem location where all Modules are to be deployed. This is typically a shared filesystem location for general use by multiple people |
| Deployment Root | Refers to the filesystem path at the root of the Deployment Area. The term 'Root' is used similarly for other directories |
| Build (verb) | Generate entrypoint scripts, configuration files and environment variables for a given Module. These are output to the Build Area |
| Build Area | The filesystem location used for building modules. This should ideally be on the same filesystem as the Deployment area to ensure that later move operations are atomic, so by default it is the `build` subdirectory of the Deployment Root. We use a different location when testing builds |
| Deploy | Act of moving built Modules from the Build Area into the Modules Area. A copy of the modulefile is moved to either the Modulefiles Folder or Deprecated Folder, depending on its deprecation status. The Module can then be used by the End User |
| Modules Area | Refers to the `modules` folder under the Deployment Root. The final location for files built for a particular Module configuration |
| Modulefiles Folder | Refers to the `modulefiles` folder under the Deployment Root. When this path is added to the MODULEPATH environment variable, all modulefiles can then be accessed by the End User using the standard Environment Modules interface (`module avail`, etc.) |
| Deprecate | Moving a modulefile to the separate Deprecated Folder, to indicate that its use should be discouraged |
| Deprecated Folder | The folder used to contain Modulefiles for Modules that have been deprecated. By adding this folder to your MODULEPATH environment variable, you then have the ability to use any deprecated Module as normal. Where possible, the use of deprecated modules by the End User should be avoided |
| Release (noun) | A Module, including version, alongside its lifecycle (i.e. deprecation) status |
| Deployment | The sum total of all releases (deprecated or not) that are to be maintained in the deployment area |
| End User | Refers to anybody who is intended to make use of a deployed Module. This can include the people modifying configuration themselves |
|**Term** |**Definition** |
|-------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|Environment Modules|A [standard package for Linux](https://modules.readthedocs.io/en/latest/) that provides definitions for loading and unloading 'Environment Modules'. Note that while we are using this system, our definition of Module is separate. If we are referring to an Environment Module, we will use the full name |
|Modulefile |Used by the Environment Modules package to specify all details of an Environment Module. This can include executables to add to the path, environment variables to set, etc. |
|Module |A set of files that can be used to provide applications on your path, provide configuration, and set environment variables. We do this using the Environment Modules system by providing a Modulefile with the relevant configuration |
|Application |Each Module can be configured with multiple Applications, each one providing one or more executables. As of writing, there are 2 types of Application: `Apptainer` and `Shell` (Bash script) |
|Deployment Area |The filesystem location where all Modules are to be deployed. This is typically a shared filesystem location for general use by multiple people |
|Deployment Root |Refers to the filesystem path at the root of the Deployment Area. The term 'Root' is used similarly for other directories |
|Build (verb) |Generate entrypoint scripts, configuration files and environment variables for a given Module. These are output to the Build Area |
|Build Area |The filesystem location used for building modules. This should ideally be on the same filesystem as the Deployment area to ensure that later move operations are atomic, so by default it is the `build` subdirectory of the Deployment Root. We use a different location when testing builds |
|Deploy |Act of moving built Modules from the Build Area into the Modules Area. A copy of the modulefile is moved to either the Modulefiles Folder or Deprecated Folder, depending on its deprecation status. The Module can then be used by the End User |
|Modules Area |Refers to the `modules` folder under the Deployment Root. The final location for files built for a particular Module configuration |
|Modulefiles Folder |Refers to the `modulefiles` folder under the Deployment Root. When this path is added to the MODULEPATH environment variable, all modulefiles can then be accessed by the End User using the standard Environment Modules interface (`module avail`, etc.) |
|Deprecate |Moving a modulefile to the separate Deprecated Folder, to indicate that its use should be discouraged |
|Deprecated Folder |The folder used to contain Modulefiles for Modules that have been deprecated. By adding the modulefiles subdirectory to your MODULEPATH environment variable, you then have the ability to use any deprecated Module as normal. Where possible, the use of deprecated modules by the End User should be avoided|
|Release (noun) |A Module, including version, alongside its lifecycle (i.e. deprecation) status |
|Deployment |The sum total of all releases (deprecated or not) that are to be maintained in the deployment area |
|End User |Refers to anybody who is intended to make use of a deployed Module. This can include the people modifying configuration themselves |
3 changes: 2 additions & 1 deletion src/deploy_tools/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,15 @@
writable=True,
),
],
use_previous: Annotated[bool, typer.Option()] = False,
) -> None:
"""Compare the deployment snapshot to deployed modules in the deployment root.

This allows us to identify any discrepancies. If there was an error during the
deploy step, we can use this function to determine any required steps for fixing
files in the deployment root.
"""
compare_to_snapshot(deployment_root)
compare_to_snapshot(deployment_root, use_previous)

Check warning on line 94 in src/deploy_tools/__main__.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/__main__.py#L94

Added line #L94 was not covered by tests


@app.command(no_args_is_help=True)
Expand Down
27 changes: 18 additions & 9 deletions src/deploy_tools/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,37 @@
from .models.load import load_from_yaml
from .models.module import Module, Release
from .modulefile import get_default_modulefile_version, is_modulefile_deployed
from .snapshot import load_snapshot
from .snapshot import load_previous_snapshot, load_snapshot
from .validate import validate_default_versions


class ComparisonError(Exception):
pass


def compare_to_snapshot(deployment_root: Path) -> None:
def compare_to_snapshot(deployment_root: Path, use_previous: bool = False) -> None:
"""Compare deployment area to deployment configuration snapshot.

This enables us to identify broken environment modules. Note that this does not
This helps us to identify broken environment modules. Note that this does not
exclude the possibility of all types of issues.

The `use_previous` argument can be used to provide a comparison with the previous
Deployment configuration. This is taken as a backup at the very start of the Deploy
step.

Args:
deployment_root: The root folder of the Deployment Area.
use_previous: If True, compare to the previous snapshot taken as backup at start
of the Deploy step.
"""
layout = Layout(deployment_root)

deployment_snapshot = load_snapshot(layout)
actual_deployment = _reconstruct_deployment_config_from_modules(layout)
if use_previous:
deployment_snapshot = load_previous_snapshot(layout)

Check warning on line 40 in src/deploy_tools/compare.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/compare.py#L39-L40

Added lines #L39 - L40 were not covered by tests
else:
deployment_snapshot = load_snapshot(layout)

Check warning on line 42 in src/deploy_tools/compare.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/compare.py#L42

Added line #L42 was not covered by tests

actual_deployment = _reconstruct_deployment_config_from_modules(layout)

Check warning on line 44 in src/deploy_tools/compare.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/compare.py#L44

Added line #L44 was not covered by tests
_compare_snapshot_to_actual(snapshot=deployment_snapshot, actual=actual_deployment)


Expand Down Expand Up @@ -66,16 +78,13 @@
"""

modules: list[Module] = []
build_layout = layout.build_layout

for name_path in layout.modules_root.glob("*"):
for version_path in name_path.glob("*"):
name = name_path.name
version = version_path.name
modules.append(
load_from_yaml(
Module, build_layout.get_module_snapshot_path(name, version)
)
load_from_yaml(Module, layout.get_module_snapshot_path(name, version))
)

return modules
Expand Down
8 changes: 4 additions & 4 deletions src/deploy_tools/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@

for release in to_deploy:
module = release.module
built_module_folder = build_layout.get_module_build_folder(
built_module_folder = build_layout.get_module_folder(

Check warning on line 72 in src/deploy_tools/deploy.py

View check run for this annotation

Codecov / codecov/patch

src/deploy_tools/deploy.py#L72

Added line #L72 was not covered by tests
module.name, module.version
)
final_module_folder = layout.get_module_folder(module.name, module.version)
Expand All @@ -84,9 +84,9 @@
def _deprecate_releases(to_deprecate: list[Release], layout: Layout) -> None:
"""Deprecate a list of modules.

For each module, this will move the modulefile link to a 'deprecated' directory. If
the user's MODULEPATH is set up to include the 'deprecated' directory, all
modules should be available as before.
For each module, this will move the modulefile link to the 'deprecated' directory
under the Deployment Area. If the user's MODULEPATH is set to include the
'deprecated/modulefiles' directory, all modules should be available as before.
"""
for release in to_deprecate:
deprecate_modulefile_link(release.module.name, release.module.version, layout)
Expand Down
Loading
Loading