From ac5f39f68569deb90a63acfdf962f29a46e7971f Mon Sep 17 00:00:00 2001 From: Chris Berry Date: Sun, 16 Aug 2026 20:39:45 -0700 Subject: [PATCH] Support system-wide home-ops installs --- .secrets.baseline | 2 +- AGENTS.md | 2 +- README.md | 17 ++++++++--------- poolctl/config.py | 2 +- script/install | 17 +++++++++++++---- tests/test_config.py | 6 +++++- 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 186f6c2..6bcffdf 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -135,5 +135,5 @@ } ], "results": {}, - "generated_at": "2026-08-16T20:10:38Z" + "generated_at": "2026-08-17T03:33:54Z" } diff --git a/AGENTS.md b/AGENTS.md index e4b8fa1..cfe4fa8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,6 @@ the installed CLI useful without requiring repository knowledge. ## Development -Prefer `pipx` for daily installed use and `.venv` for development. Run the full +Use the private home-ops bootstrap for installed use and `.venv` for development. Run the full format, lint, secret-scan, and test sequence documented in `README.md` before publishing. Never make a live hardware write as part of an automated test. diff --git a/README.md b/README.md index 569b306..7fb6abe 100644 --- a/README.md +++ b/README.md @@ -29,15 +29,14 @@ Python 3.11 or newer is required. ## Install ```bash -git clone https://github.com/cnberry/poolctl.git -cd poolctl -./script/install +cd /path/to/private/home-ops +./bin/bootstrap-ctls poolctl ``` -`script/install` is the stable repository contract used by private deployment -automation. Today it installs the Python package with `pipx`; it can be replaced -by a Rust or binary installer later without changing callers. `just install` -uses the same contract. +The private `home-ops` bootstrap is the canonical installer: it populates the +real adapter inventory, calls this repository's stable `script/install` +contract, and creates `/usr/local/bin/poolctl` backed by an isolated system +environment under `/usr/local/lib/home-ops/ctls`. ## Configure private adapter data @@ -47,7 +46,7 @@ Run discovery once on the same LAN as the ScreenLogic adapter: poolctl discover ``` -The selected adapter is saved to `~/.config/poolctl/config.json` with mode +The selected adapter is saved to `/usr/local/config/poolctl/config.json` with mode `0600`. Set `POOLCTL_CONFIG=/path/to/config.json` to use another private file, or pass `--host 192.0.2.10` before a command for a one-off host override. @@ -87,7 +86,7 @@ full behavior and safety boundary. | Data | Default path | Git policy | | --- | --- | --- | -| Adapter cache | `~/.config/poolctl/config.json` | Private config repo only | +| Adapter cache | `/usr/local/config/poolctl/config.json` | Private config repo only | | Raw status output | Standard output only | Review before sharing | `poolctl` does not require a cloud username, password, or token. diff --git a/poolctl/config.py b/poolctl/config.py index 1495c65..ad906cb 100644 --- a/poolctl/config.py +++ b/poolctl/config.py @@ -6,7 +6,7 @@ from typing import Any ENV_CONFIG_PATH = "POOLCTL_CONFIG" -CONFIG_DIR = Path.home() / ".config" / "poolctl" +CONFIG_DIR = Path("/usr/local/config/poolctl") CONFIG_PATH = CONFIG_DIR / "config.json" diff --git a/script/install b/script/install index 9b4253a..bac752c 100755 --- a/script/install +++ b/script/install @@ -2,11 +2,20 @@ set -eu repo_root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) +name=poolctl +install_prefix=${CTL_INSTALL_PREFIX:-/usr/local} +venv_root=${CTL_VENV_ROOT:-$install_prefix/lib/home-ops/ctls} +bin_dir=${CTL_BIN_DIR:-$install_prefix/bin} +venv="$venv_root/$name" +python=${PYTHON:-python3} -if ! command -v pipx >/dev/null 2>&1; then - echo "poolctl: the current Python implementation requires pipx" >&2 - echo "poolctl: install pipx, or replace script/install when a binary implementation ships" >&2 +if ! command -v "$python" >/dev/null 2>&1; then + echo "$name: Python 3 is required" >&2 exit 1 fi -exec pipx install --force "$repo_root" +install -d -m 755 "$install_prefix/lib" "$install_prefix/lib/home-ops" "$venv_root" "$bin_dir" +"$python" -m venv --clear "$venv" +"$venv/bin/python" -m pip install --disable-pip-version-check "$repo_root" +chmod -R a+rX "$venv" +ln -sfn "$venv/bin/$name" "$bin_dir/$name" diff --git a/tests/test_config.py b/tests/test_config.py index c62796f..f9c3a35 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,6 +1,10 @@ import stat -from poolctl.config import get_adapter_config, load_config, set_adapter_config +from poolctl.config import CONFIG_PATH, get_adapter_config, load_config, set_adapter_config + + +def test_system_config_path_is_the_default(): + assert CONFIG_PATH.as_posix() == "/usr/local/config/poolctl/config.json" def test_load_config_missing(monkeypatch, tmp_path):