Templates: migrate clan templates to flake identifiers
This commit is contained in:
@@ -99,3 +99,73 @@ def machine_template(
|
||||
finally:
|
||||
# If no error occurred, the machine directory is kept
|
||||
pass
|
||||
|
||||
|
||||
@contextmanager
|
||||
def clan_template(flake: Flake, template_ident: str, dst_dir: Path) -> Iterator[Path]:
|
||||
"""
|
||||
Create a clan from a template.
|
||||
This function will copy the template files to a new clan directory
|
||||
|
||||
:param flake: The flake to create the machine in.
|
||||
:param template_ident: The identifier of the template to use. Example ".#template_name"
|
||||
:param dst: The name of the directory to create.
|
||||
|
||||
|
||||
Example usage:
|
||||
|
||||
>>> with clan_template(
|
||||
... Flake("/home/johannes/git/clan-core"), ".#new-machine", "my-machine"
|
||||
... ) as clan_dir:
|
||||
... # Use `clan_dir` here if you want to access the created directory
|
||||
|
||||
... The directory is removed if the context raised any errors.
|
||||
... Only if the context is exited without errors, it is kept.
|
||||
"""
|
||||
|
||||
# Get the clan template from the specifier
|
||||
[flake_ref, template_selector] = transform_url("clan", template_ident, flake=flake)
|
||||
# For pretty error messages
|
||||
printable_template_ref = f"{flake_ref}#{template_selector}"
|
||||
|
||||
template_flake = Flake(flake_ref)
|
||||
|
||||
try:
|
||||
template = template_flake.select(template_selector)
|
||||
except ClanError as e:
|
||||
msg = f"Failed to select template '{template_ident}' from flake '{flake_ref}' (via attribute path: {printable_template_ref})"
|
||||
raise ClanError(msg) from e
|
||||
|
||||
src = template.get("path")
|
||||
if not src:
|
||||
msg = f"Malformed template: {printable_template_ref} does not have a 'path' attribute"
|
||||
raise ClanError(msg)
|
||||
|
||||
src_path = Path(src).resolve()
|
||||
|
||||
realize_nix_path(template_flake, str(src_path))
|
||||
|
||||
if not src_path.exists():
|
||||
msg = f"Template {printable_template_ref} does not exist at {src_path}"
|
||||
raise ClanError(msg)
|
||||
|
||||
if not src_path.is_dir():
|
||||
msg = f"Template {printable_template_ref} is not a directory at {src_path}"
|
||||
raise ClanError(msg)
|
||||
|
||||
if dst_dir.exists():
|
||||
msg = f"Destination directory {dst_dir} already exists"
|
||||
raise ClanError(msg)
|
||||
|
||||
copy_from_nixstore(src_path, dst_dir)
|
||||
|
||||
try:
|
||||
yield dst_dir
|
||||
except Exception as e:
|
||||
log.error(f"An error occurred inside the 'clan_template' context: {e}")
|
||||
log.info(f"Removing left-over directory: {dst_dir}")
|
||||
shutil.rmtree(dst_dir, ignore_errors=True)
|
||||
raise
|
||||
finally:
|
||||
# If no error occurred, the directory is kept
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user