hostctl 0.1.41 → 0.1.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,30 +1,63 @@
1
1
  # hostctl
2
2
 
3
- `hostctl` is a modern task runner for managing fleets of hosts. It makes it easy to execute TypeScript or JavaScript automations locally or over SSH while keeping secrets, inventories, and host metadata in one place.
3
+ `hostctl` is a modern task runner for managing fleets of hosts. It executes TypeScript or JavaScript automations locally or over SSH while keeping inventories, tags, and secrets in one place.
4
4
 
5
5
  ## Why hostctl
6
- - Treat remote automation like regular code: tasks are modules with strong typing and rich logging.
6
+
7
+ - Treat remote automation like regular code: tasks are modules with strong typing and structured logging.
7
8
  - First-class inventory and secrets management built around [AGE](https://age-encryption.org/).
8
- - Layered runtime isolates CLI parsing, orchestration, and local/remote execution for easy extension.
9
+ - Layered runtime cleanly separates CLI parsing, orchestration, and execution for easy extension.
9
10
 
10
- ## Quick Start
11
- 1. **Install dependencies**
12
- - Node.js 24+ (the CLI runs through `tsx` to execute TypeScript directly)
13
- - `age`: `brew install age` (macOS) or follow <https://age-encryption.org>.
14
- 2. **Clone and bootstrap**
15
- ```bash
16
- git clone https://github.com/monopod/hostctl.git
17
- cd hostctl
18
- npm install
19
- ```
20
- 3. **Generate AGE identities**
11
+ ## System Requirements
12
+
13
+ - Node.js **24+** (CLI runs through `tsx`).
14
+ - [`age`](https://age-encryption.org) for encrypting secrets.
15
+ - Git (recommended) for cloning packages and publishing tasks.
16
+
17
+ Check your toolchain:
18
+
19
+ ```bash
20
+ node -v
21
+ npm -v
22
+ age --version
23
+ ```
24
+
25
+ ## Install hostctl
26
+
27
+ ### Clone & Develop
28
+
29
+ ```bash
30
+ git clone https://github.com/monopod/hostctl.git
31
+ cd hostctl
32
+ npm install
33
+ ```
34
+
35
+ Use `./hostctl` during development or `npm run build && ./dist/bin/hostctl.js ...` to test the bundled CLI.
36
+
37
+ ### Global CLI
38
+
39
+ ```bash
40
+ npm install -g hostctl
41
+ hostctl --help
42
+ ```
43
+
44
+ ### One-off Execution
45
+
46
+ Run straight from npm without installing globally:
47
+
48
+ ```bash
49
+ npx hostctl run core.echo message:hello
50
+ ```
51
+
52
+ ## Bootstrap identities, inventory, and secrets
53
+
54
+ 1. **Generate AGE identities**
21
55
  ```bash
22
56
  mkdir -p ~/.hostctl/age
23
- age-keygen -o ~/.hostctl/age/jane.priv
24
- age-keygen -y ~/.hostctl/age/jane.priv > ~/.hostctl/age/jane.pub
57
+ age-keygen -o ~/.hostctl/age/you.priv
58
+ age-keygen -y ~/.hostctl/age/you.priv > ~/.hostctl/age/you.pub
25
59
  ```
26
- 4. **Author an inventory**
27
- Create `~/.hostctl/hostctl.yaml`:
60
+ 2. **Author an inventory** at `~/.hostctl/hostctl.yaml`:
28
61
  ```yaml
29
62
  hosts:
30
63
  ubuntu-vm:
@@ -34,59 +67,162 @@
34
67
  tags: [ubuntu, testvm]
35
68
  secrets:
36
69
  vagrant-password:
37
- ids: jane
70
+ ids: you
38
71
  value: vagrant
39
72
  ids:
40
- jane: age1...
73
+ you: age1...
74
+ ```
75
+ 3. **Manage the file**
76
+ ```bash
77
+ hostctl inventory encrypt # wrap with AGE recipients
78
+ hostctl inventory decrypt # view/edit locally
79
+ hostctl inventory list # inspect hosts & tags
41
80
  ```
42
- See `docs/system_management.md` for more host examples and encryption workflows.
43
- 5. **Run an example task**
81
+ Set `AGE_IDS="~/.hostctl/age/*.priv"` before running commands if the file is encrypted.
82
+
83
+ ## Running tasks
84
+
85
+ - **Local script**
44
86
  ```bash
45
87
  npm run build
46
88
  ./dist/bin/hostctl.js run example/echo.ts args:hello
47
89
  ```
48
- Use `AGE_IDS="~/.hostctl/age/*.priv"` to point at custom identities.
49
-
50
- 6. **Target remote hosts by tag**
51
- ```bash
52
- ./dist/bin/hostctl.js run -r -t xcpng-lab --json core.net.interfaces
53
- ```
54
- Flags:
55
- - `-r` executes the task against matching remote hosts from your inventory.
56
- - `-t <tag>` narrows the target set; multiple tags may be comma-separated.
57
- - `--json` emits machine-readable results per host.
90
+ - **Local package**
91
+ ```bash
92
+ hostctl run ./my-package hello name:Sam
93
+ ```
94
+ Local directories are executed directly and are not installable via `hostctl pkg install`.
95
+ - **Remote orchestration**
96
+ ```bash
97
+ hostctl run -r -t ubuntu core.net.interfaces --json
98
+ ```
58
99
 
59
- ## Install via npm
60
- - Global CLI:
100
+ - `-r/--remote` targets hosts selected by tags via SSH.
101
+ - `-t/--tag` is greedy; use `--` before positional args when needed.
102
+ - **From npm or git**
103
+ ```bash
104
+ hostctl run hostctl-hello greet name:Phil
105
+ hostctl run https://github.com/monopod/hostctl-example echo args:hello,world
106
+ ```
107
+ - **Install Docker anywhere**
61
108
  ```bash
62
- npm install -g hostctl
63
- hostctl run example/echo.ts args:hello
109
+ hostctl run -r -t ubuntu core.docker.install users:hostctl
64
110
  ```
65
- - One-off execution:
111
+ The task follows Docker’s official installation guides for Ubuntu/Debian and Fedora/RHEL/Rocky (matching the current `xcpng-e2e` templates), so the same invocation works across your lab images.
112
+ - **Run containers**
66
113
  ```bash
67
- npx hostctl run core.echo message:hello
114
+ hostctl run core.docker.run-container image:alpine command:'["/bin/sh","-c","echo from container"]'
115
+ hostctl run core.docker.run-container-detached image:redis name:ci-cache
68
116
  ```
69
- The published binary keeps its `tsx`-based runtime so TypeScript scripts can execute without pre-compilation; ensure your runtime Node version is 24 or newer.
70
-
71
- ## Documentation Map
72
- - **Architecture & Design**: [ARCHITECTURE.md](ARCHITECTURE.md) captures module boundaries, runtime flows, and design principles.
73
- - **Operational Guides**: User-facing how‑tos live in `docs/` (e.g., `docs/process_management.md`, `docs/package_management.md`, `docs/system_management.md`).
74
- - **Detailed Onboarding**: [docs/user-onboarding.md](docs/user-onboarding.md) preserves the full setup, CLI, and task catalog reference.
75
- - **XCP-ng Provisioning**: [docs/xcp-ng-operations.md](docs/xcp-ng-operations.md) covers the emerging hypervisor-native testing workflow.
76
- - **LLM Contributor Guide**: See [AGENTS.md](AGENTS.md) for automated contributors.
77
- - **Community Standards**: [CONTRIBUTING.md](CONTRIBUTING.md) outlines coding standards, issue triage, and release process.
78
-
79
- ## Developer Workflow
80
- - Format & typing: `npm run format` (Prettier) and `npm run lint` (TypeScript no-emit).
81
- - Build artifacts: `npm run build` (tsup) produces `dist/` bundles consumed by the CLI and published package.
117
+ The first task streams container output back to the CLI; the detached variant returns the created container ID/name so you can manage it later.
118
+
119
+ **Passing parameters**
120
+
121
+ - `key:value` pairs after the task name.
122
+ - `--params '{"key":"value"}'` for JSON blobs.
123
+ - `--file params.json` to load structured arguments.
124
+
125
+ ## Managing task packages
126
+
127
+ `hostctl pkg` commands wrap the npm-only package manager:
128
+
129
+ ```bash
130
+ hostctl pkg create my-task --lang typescript
131
+ hostctl pkg install hostctl-hello
132
+ hostctl pkg list
133
+ hostctl pkg remove hostctl-hello
134
+ ```
135
+
136
+ Installed packages live under `~/.hostctl/packages` and can be run offline once cached.
137
+ Use `pkg install` for npm registry names (scoped + versioned) or git URLs. Local directories should be run directly without installing (`hostctl run ./path/to/pkg task args`); this avoids polluting the manifest with workstation paths and keeps the install story aligned with reproducible npm/git sources.
138
+
139
+ ## Designing tasks
140
+
141
+ Define tasks with the `task` helper and a typed `TaskContext`:
142
+
143
+ ```ts
144
+ import { task, type TaskContext } from 'hostctl';
145
+
146
+ interface EchoParams {
147
+ message: string;
148
+ }
149
+ interface EchoResult {
150
+ repeated: string;
151
+ }
152
+
153
+ async function run(context: TaskContext<EchoParams>): Promise<EchoResult> {
154
+ const { params, info } = context;
155
+ info(`Echo: ${params.message}`);
156
+ return { repeated: params.message };
157
+ }
158
+
159
+ export default task(run, { name: 'echo', description: 'Prints a message' });
160
+ ```
161
+
162
+ Export one default task per file. Qualified task names come from a registry when present; otherwise they are derived from the task file path relative to the package root.
163
+
164
+ Key `TaskContext` capabilities (see [`docs/task-api.md`](docs/task-api.md) for details):
165
+
166
+ - Structured logging via `info`, `warn`, `error`, `debug`, or `log(level, ...)`.
167
+ - Command execution with `exec(command, { sudo, env, cwd, stdin, pty })`.
168
+ - Remote fan-out using `ssh(tags, remoteFn)`.
169
+ - Subtask orchestration with `run(otherTask(params))`.
170
+ - Secrets & credentials via `getSecret(name)` and `getPassword()`.
171
+ - Inventory helpers: `inventory(tags)` and `selectedInventory(tags?)`.
172
+ - File helpers: `file.read`, `file.write`, `file.exists`, `file.mkdir`, `file.rm` that respect local vs. remote runtime.
173
+
174
+ ## Building & testing task packages
175
+
176
+ 1. Scaffold: `hostctl pkg create awesome-firewall --lang typescript`.
177
+ 2. Install deps: `cd awesome-firewall && npm install`.
178
+ 3. Build: `npm run build` (defaults to `tsc`).
179
+ 4. Test locally without publishing: `npx hostctl run . args:foo`.
180
+ 5. Add unit tests with Vitest if needed, or invoke tasks directly in scripts.
181
+
182
+ ## Publishing task packages
183
+
184
+ 1. Update `package.json` metadata (`name`, `version`, `description`, `files`).
185
+ 2. Build artifacts (`npm run build` or rely on `prepublishOnly`).
186
+ 3. Authenticate with npm (`npm login` or `NPM_TOKEN`).
187
+ 4. Publish:
188
+ ```bash
189
+ npm version patch # or minor/major
190
+ npm publish --access public
191
+ ```
192
+ 5. Tag releases in git or automate with tools like `release-it` (this repo ships `release.sh` as an example flow).
193
+ 6. Verify: `npm info your-package version`.
194
+
195
+ ## Consuming published packages
196
+
197
+ - One-off: `npx hostctl run your-package taskName param:value`.
198
+ - Cache locally: `hostctl pkg install your-package@1.2.3` then run offline.
199
+ - Compose in other codebases by adding the package to `dependencies` and importing its exported tasks.
200
+
201
+ ## Troubleshooting
202
+
203
+ - **Task not found**: confirm the package exports the task name and that `exports` exposes it.
204
+ - **Version mismatch**: keep `package.json`, `src/version.ts`, and `jsr.json` in sync before releasing.
205
+ - **SSH failures**: verify inventory entries (hostname, user, auth) and only pass `-r` when you intend remote execution.
206
+ - **Secrets**: when inventories are encrypted, ensure `AGE_IDS` includes the private keys so `hostctl` can decrypt secrets.
207
+ - **Environment drift**: run `hostctl runtime` to inspect prerequisites or `hostctl runtime install` to bootstrap them.
208
+
209
+ ## Developer workflow
210
+
211
+ - Format & typing: `npm run format` (Prettier) and `npm run lint` (`tsc --noEmit`).
212
+ - Build artifacts: `npm run build` (tsup) produces `dist/` bundles for the CLI and published package.
82
213
  - Tests:
83
214
  - `npm run test` → unit + functional suites.
84
215
  - `npm run test:unit`, `npm run test:functional`, `npm run test:e2e` for focused runs.
85
- - VM-backed runs currently lean on legacy Vagrant boxes. Those helpers (`npm run vm:*`) remain for continuity but are **deprecated** while we shift to provisioning test VMs directly on XCP-ng hypervisors. See [docs/xcp-ng-operations.md](docs/xcp-ng-operations.md) for the in-progress workflow and contribute new test setups there.
86
- - Release scripts rely on `npm run release` and accompanying tooling described in `NPM_MIGRATION_PLAN.md`.
87
-
88
- ## Next Steps
89
- - Explore bundled examples under `example/` to learn the task API.
90
- - Review [ARCHITECTURE.md](ARCHITECTURE.md) for runtime internals and extension guidelines.
91
- - Familiarise yourself with the new XCP-ng task suite to help migrate integration tests off the Vagrant stack.
92
- - Join discussions or open issues at <https://github.com/monopod/hostctl/issues>.
216
+ - VM helpers (`npm run vm:*`) are legacy while XCP-ng provisioning matures; see `docs/xcp-ng-operations.md`.
217
+ - Releases rely on `npm run release` + `release-it`; see `NPM_MIGRATION_PLAN.md` for npm-only context.
218
+
219
+ ## Documentation map
220
+
221
+ - **Task API reference**: [`docs/task-api.md`](docs/task-api.md).
222
+ - **Task package authoring**: [`docs/task-package-authoring.md`](docs/task-package-authoring.md).
223
+ - **Operational guides**: `docs/*.md` (process, package, system management, etc.).
224
+ - **Architecture & design**: [`ARCHITECTURE.md`](ARCHITECTURE.md) and supporting design docs.
225
+ - **Contributor guide**: [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`AGENTS.md`](AGENTS.md).
226
+ - **Issue tracking**: <https://github.com/monopod/hostctl/issues>.
227
+
228
+ Explore the examples under `example/`, get familiar with the task API, and share automations with the community via npm-compatible packages.