From f7f12480d05101f0f3fdc3ad36559892d19a6bd0 Mon Sep 17 00:00:00 2001 From: Eric Wendland Date: Sun, 5 Jul 2026 22:40:27 +0200 Subject: [PATCH] docs: add automation examples --- README.md | 3 + docs/automation-examples.md | 128 +++++++++++++++++++++++++++ docs/production-readiness-roadmap.md | 10 +-- 3 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 docs/automation-examples.md diff --git a/README.md b/README.md index 17fa515..46bbaaf 100644 --- a/README.md +++ b/README.md @@ -443,6 +443,9 @@ not reachable. It checks config parsing, local daemon socket health, validity, and representative peer grants when local metadata is available. Use `--json` for scripts. +See `docs/automation-examples.md` for shell, Python JSON, and user-service +automation examples. + ## Owner And Node Management The intended owner setup is SSH-admin-rooted: diff --git a/docs/automation-examples.md b/docs/automation-examples.md new file mode 100644 index 0000000..c17fe90 --- /dev/null +++ b/docs/automation-examples.md @@ -0,0 +1,128 @@ +# Automation Examples + +These examples are intended as starting points for local scripts and +infrastructure automation. They assume the single `geth` executable is on +`PATH`. + +## Shell + +Initialize a home, start the daemon in a user-owned process, wait for control, +and read stable JSON status: + +```sh +#!/usr/bin/env sh +set -eu + +export GETH_HOME="${GETH_HOME:-$HOME/.local/share/geth/geth}" + +geth init +geth daemon run >"$GETH_HOME/daemon.log" 2>&1 & +daemon_pid=$! + +geth wait daemon --timeout-ms 30000 +geth doctor --json +geth status --json + +trap 'kill "$daemon_pid" 2>/dev/null || true' EXIT +``` + +Create a backup into a separate directory and validate that it can restore to a +new home: + +```sh +#!/usr/bin/env sh +set -eu + +backup_dir="${1:?backup dir required}" +restore_home="$(mktemp -d)" + +geth backup create --out "$backup_dir" +geth backup restore "$backup_dir" --target-home "$restore_home" +GETH_HOME="$restore_home" geth doctor --json || true +``` + +## Python JSON + +Use CLI JSON output without parsing human text: + +```python +#!/usr/bin/env python3 +import json +import os +import subprocess +import sys + + +def geth(*args, check=True): + proc = subprocess.run( + ["geth", "--json", *args], + check=False, + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=os.environ.copy(), + ) + if check and proc.returncode != 0: + raise RuntimeError(proc.stderr or proc.stdout) + return json.loads(proc.stdout) + + +doctor = geth("doctor", check=False) +for check in doctor["checks"]: + print(check["status"], check["code"], check["message"]) + +status = geth("status") +print(status["node_id"], status.get("endpoint_id")) +``` + +Wait for a known peer before pulling sync status: + +```python +#!/usr/bin/env python3 +import json +import subprocess +import sys + +node = sys.argv[1] + +wait = subprocess.run( + ["geth", "--json", "wait", "peer", node, "--timeout-ms", "30000"], + text=True, + stdout=subprocess.PIPE, +) +report = json.loads(wait.stdout) +if not report["ready"]: + raise SystemExit(report["reason"]) + +sync = subprocess.check_output(["geth", "--json", "sync", "status"], text=True) +print(sync) +``` + +## User Service + +Install and operate the daemon through the current user's service manager. These +commands do not install a system service and do not require privileged service +manager mutation: + +```sh +geth daemon service print +geth daemon service install --start +geth wait daemon --timeout-ms 30000 +geth daemon service status +geth daemon service stop +geth daemon service uninstall +``` + +Admin SSH keys remain outside geth state. Automation should pass public admin +keys with `--admin-key` and use the matching private key only as an argument to +the explicit signing command when an admin operation is intended: + +```sh +geth init \ + --admin-key "$HOME/.ssh/id_ed25519.pub" \ + --signing-key "$HOME/.ssh/id_ed25519" \ + --node-name "$(hostname)" +``` + +Do not copy private SSH admin keys into `GETH_HOME`, backups, service +definitions, or shared project repositories. diff --git a/docs/production-readiness-roadmap.md b/docs/production-readiness-roadmap.md index 9e6e6ed..63e2193 100644 --- a/docs/production-readiness-roadmap.md +++ b/docs/production-readiness-roadmap.md @@ -258,12 +258,12 @@ Goal: make `geth` ergonomic and stable as a base layer for custom automation. - `[ ]` Grant creation supports deterministic caller-provided IDs. - `[ ]` Repeated sync and import commands report no-op state clearly. -- `[ ]` Publish automation examples. +- `[x]` Publish automation examples. Acceptance criteria: - - `[ ]` Docs include shell examples. - - `[ ]` Docs include Python examples using CLI JSON. - - `[ ]` Docs include user-service automation examples. - - `[ ]` Examples avoid private-key copying and privileged service mutation. + - `[x]` Docs include shell examples. + - `[x]` Docs include Python examples using CLI JSON. + - `[x]` Docs include user-service automation examples. + - `[x]` Examples avoid private-key copying and privileged service mutation. ## Phase 8: Observability And Operations