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
101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
"""zpool."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from python.zfs.command import run_zpool
|
|
|
|
|
|
def _zpool_list(*args: str) -> dict[str, Any]:
|
|
"""Run a zpool list and check the output is a format we understand.
|
|
|
|
Args:
|
|
*args: The arguments to pass to zpool.
|
|
|
|
Returns:
|
|
dict[str, Any]: The decoded output.
|
|
|
|
Raises:
|
|
RuntimeError: If zpool fails, or reports a format this does not parse.
|
|
Never decodes a partial or error derived payload.
|
|
"""
|
|
result = run_zpool(*args)
|
|
if not result.ok:
|
|
error = f"Failed to run zpool {' '.join(args)}: {result.message}"
|
|
raise RuntimeError(error)
|
|
|
|
zpool_data = json.loads(result.stdout)
|
|
|
|
vers_major = zpool_data["output_version"]["vers_major"]
|
|
vers_minor = zpool_data["output_version"]["vers_minor"]
|
|
command = zpool_data["output_version"]["command"]
|
|
|
|
if vers_major != 0 or vers_minor != 1 or command != "zpool list":
|
|
error = f"Datasets are not in the correct format {vers_major=} {vers_minor=} {command=}"
|
|
raise RuntimeError(error)
|
|
|
|
return zpool_data
|
|
|
|
|
|
class Zpool:
|
|
"""Zpool."""
|
|
|
|
def __init__(
|
|
self,
|
|
name: str,
|
|
) -> None:
|
|
"""__init__."""
|
|
zpool_data = _zpool_list("list", name, "-pHj", "-o", "all")
|
|
|
|
properties = zpool_data["pools"][name]["properties"]
|
|
|
|
self.name = name
|
|
|
|
self.allocated = int(properties["allocated"]["value"])
|
|
self.altroot = properties["altroot"]["value"]
|
|
self.ashift = int(properties["ashift"]["value"])
|
|
self.autoexpand = properties["autoexpand"]["value"]
|
|
self.autoreplace = properties["autoreplace"]["value"]
|
|
self.autotrim = properties["autotrim"]["value"]
|
|
self.capacity = int(properties["capacity"]["value"])
|
|
self.comment = properties["comment"]["value"]
|
|
self.dedupratio = properties["dedupratio"]["value"]
|
|
self.delegation = properties["delegation"]["value"]
|
|
self.expandsize = properties["expandsize"]["value"]
|
|
self.failmode = properties["failmode"]["value"]
|
|
self.fragmentation = int(properties["fragmentation"]["value"])
|
|
self.free = properties["free"]["value"]
|
|
self.freeing = int(properties["freeing"]["value"])
|
|
self.guid = int(properties["guid"]["value"])
|
|
self.health = properties["health"]["value"]
|
|
self.leaked = int(properties["leaked"]["value"])
|
|
self.readonly = properties["readonly"]["value"]
|
|
self.size = int(properties["size"]["value"])
|
|
|
|
def __repr__(self) -> str:
|
|
"""__repr__."""
|
|
return (
|
|
f"{self.name=}\n"
|
|
f"{self.allocated=}\n"
|
|
f"{self.altroot=}\n"
|
|
f"{self.ashift=}\n"
|
|
f"{self.autoexpand=}\n"
|
|
f"{self.autoreplace=}\n"
|
|
f"{self.autotrim=}\n"
|
|
f"{self.capacity=}\n"
|
|
f"{self.comment=}\n"
|
|
f"{self.dedupratio=}\n"
|
|
f"{self.delegation=}\n"
|
|
f"{self.expandsize=}\n"
|
|
f"{self.failmode=}\n"
|
|
f"{self.fragmentation=}\n"
|
|
f"{self.freeing=}\n"
|
|
f"{self.guid=}\n"
|
|
f"{self.health=}\n"
|
|
f"{self.leaked=}\n"
|
|
f"{self.readonly=}\n"
|
|
f"{self.size=}"
|
|
)
|