feat(zfs): enhance command handling with run_zfs and run_zpool functions
treefmt / nix fmt (pull_request) Successful in 6s
pytest / pytest (pull_request) Successful in 30s
test ebook search / test-ebook-search (pull_request) Successful in 36s
build_systems / build-brain (pull_request) Successful in 46s
build_systems / build-bob (pull_request) Successful in 47s
build_systems / build-rhapsody-in-green (pull_request) Successful in 58s
build_systems / build-jeeves (pull_request) Successful in 2m23s
pytest / pytest (push) Successful in 33s
test ebook search / test-ebook-search (push) Successful in 42s
build_systems / build-jeeves (push) Successful in 2m26s
treefmt / nix fmt (push) Successful in 5s
build_systems / build-brain (push) Successful in 9s
build_systems / build-bob (push) Successful in 40s
build_systems / build-rhapsody-in-green (push) Successful in 53s
treefmt / nix fmt (pull_request) Successful in 6s
pytest / pytest (pull_request) Successful in 30s
test ebook search / test-ebook-search (pull_request) Successful in 36s
build_systems / build-brain (pull_request) Successful in 46s
build_systems / build-bob (pull_request) Successful in 47s
build_systems / build-rhapsody-in-green (pull_request) Successful in 58s
build_systems / build-jeeves (pull_request) Successful in 2m23s
pytest / pytest (push) Successful in 33s
test ebook search / test-ebook-search (push) Successful in 42s
build_systems / build-jeeves (push) Successful in 2m26s
treefmt / nix fmt (push) Successful in 5s
build_systems / build-brain (push) Successful in 9s
build_systems / build-bob (push) Successful in 40s
build_systems / build-rhapsody-in-green (push) Successful in 53s
This commit was merged in pull request #48.
This commit is contained in:
1 parent
cc166df90f
commit
48a7e3a54c
5 files changed
+606
-25
No files matched your search
+87
-3
@@ -8,6 +8,7 @@ from datetime import UTC, datetime
|
||||
from typing import Any
|
||||
|
||||
from python.common import bash_wrapper
|
||||
from python.zfs.command import run_zfs
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -207,8 +208,91 @@ def get_datasets() -> list[Dataset]:
|
||||
"""
|
||||
logger.info("Getting zfs list")
|
||||
|
||||
dataset_names, _ = bash_wrapper("zfs list -Hp -t filesystem -o name")
|
||||
return [Dataset(dataset_name) for dataset_name in list_dataset_names() if "/" in dataset_name]
|
||||
|
||||
cleaned_datasets = dataset_names.strip().split("\n")
|
||||
|
||||
return [Dataset(dataset_name) for dataset_name in cleaned_datasets if "/" in dataset_name]
|
||||
def get_properties(name: str) -> dict[str, tuple[str, str]]:
|
||||
"""Get every property of a dataset along with where its value came from.
|
||||
|
||||
The source is what distinguishes a property that was deliberately set on
|
||||
this dataset from one that is merely inherited or left at its default.
|
||||
|
||||
Args:
|
||||
name (str): The name of the dataset.
|
||||
|
||||
Returns:
|
||||
dict[str, tuple[str, str]]: A mapping of property name to (value, source).
|
||||
"""
|
||||
result = run_zfs("get", "-Hp", "-o", "property,value,source", "all", name)
|
||||
if not result.ok:
|
||||
error = f"Failed to get properties for {name}: {result.message}"
|
||||
raise RuntimeError(error)
|
||||
|
||||
properties = {}
|
||||
for line in result.stdout.strip().splitlines():
|
||||
if not line:
|
||||
continue
|
||||
prop, value, source = line.split("\t")
|
||||
properties[prop] = (value, source)
|
||||
|
||||
return properties
|
||||
|
||||
|
||||
def create_dataset(name: str, properties: dict[str, str]) -> str | None:
|
||||
"""Create a dataset with the given properties.
|
||||
|
||||
Args:
|
||||
name (str): The name of the dataset.
|
||||
properties (dict[str, str]): The properties to create the dataset with.
|
||||
|
||||
Returns:
|
||||
str | None: An error message on failure, None on success.
|
||||
"""
|
||||
options = [argument for key, value in sorted(properties.items()) for argument in ("-o", f"{key}={value}")]
|
||||
logger.debug(f"creating {name} with {properties}")
|
||||
|
||||
result = run_zfs("create", *options, name)
|
||||
if not result.ok:
|
||||
return f"Failed to create {name}: {result.message}"
|
||||
return None
|
||||
|
||||
|
||||
def set_property(name: str, key: str, value: str) -> str | None:
|
||||
"""Set a single property on a dataset.
|
||||
|
||||
Args:
|
||||
name (str): The name of the dataset.
|
||||
key (str): The property to set.
|
||||
value (str): The value to set the property to.
|
||||
|
||||
Returns:
|
||||
str | None: An error message on failure, None on success.
|
||||
"""
|
||||
logger.debug(f"setting {key}={value} on {name}")
|
||||
|
||||
result = run_zfs("set", f"{key}={value}", name)
|
||||
if not result.ok:
|
||||
return f"Failed to set {key}={value} on {name}: {result.message}"
|
||||
return None
|
||||
|
||||
|
||||
def list_dataset_names() -> list[str]:
|
||||
"""List every zfs filesystem name, including pool root filesystems.
|
||||
|
||||
Unlike get_datasets this does not build Dataset objects and does not filter
|
||||
out pool roots, which makes it usable for existence checks.
|
||||
|
||||
Returns:
|
||||
list[str]: The names of every zfs filesystem.
|
||||
|
||||
Raises:
|
||||
RuntimeError: If zfs list fails. Never returns a partial or error
|
||||
derived list, since treating stderr as dataset names would make
|
||||
the reconciler think every dataset is missing.
|
||||
"""
|
||||
result = run_zfs("list", "-Hp", "-t", "filesystem", "-o", "name")
|
||||
if not result.ok:
|
||||
error = f"Failed to list ZFS datasets: {result.message}"
|
||||
raise RuntimeError(error)
|
||||
|
||||
return [name for name in result.stdout.strip().splitlines() if name]
|
||||
Reference in new issue
Block a user