hostctl 0.1.41 → 0.1.42

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,55 @@
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
+ - Treat remote automation like regular code: tasks are modules with strong typing and structured logging.
7
7
  - 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.
8
+ - Layered runtime cleanly separates CLI parsing, orchestration, and execution for easy extension.
9
9
 
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**
10
+ ## System Requirements
11
+ - Node.js **24+** (CLI runs through `tsx`).
12
+ - [`age`](https://age-encryption.org) for encrypting secrets.
13
+ - Git (recommended) for cloning packages and publishing tasks.
14
+
15
+ Check your toolchain:
16
+
17
+ ```bash
18
+ node -v
19
+ npm -v
20
+ age --version
21
+ ```
22
+
23
+ ## Install hostctl
24
+
25
+ ### Clone & Develop
26
+ ```bash
27
+ git clone https://github.com/monopod/hostctl.git
28
+ cd hostctl
29
+ npm install
30
+ ```
31
+ Use `./hostctl` during development or `npm run build && ./dist/bin/hostctl.js ...` to test the bundled CLI.
32
+
33
+ ### Global CLI
34
+ ```bash
35
+ npm install -g hostctl
36
+ hostctl --help
37
+ ```
38
+
39
+ ### One-off Execution
40
+ Run straight from npm without installing globally:
41
+ ```bash
42
+ npx hostctl run core.echo message:hello
43
+ ```
44
+
45
+ ## Bootstrap identities, inventory, and secrets
46
+ 1. **Generate AGE identities**
21
47
  ```bash
22
48
  mkdir -p ~/.hostctl/age
23
- age-keygen -o ~/.hostctl/age/jane.priv
24
- age-keygen -y ~/.hostctl/age/jane.priv > ~/.hostctl/age/jane.pub
49
+ age-keygen -o ~/.hostctl/age/you.priv
50
+ age-keygen -y ~/.hostctl/age/you.priv > ~/.hostctl/age/you.pub
25
51
  ```
26
- 4. **Author an inventory**
27
- Create `~/.hostctl/hostctl.yaml`:
52
+ 2. **Author an inventory** at `~/.hostctl/hostctl.yaml`:
28
53
  ```yaml
29
54
  hosts:
30
55
  ubuntu-vm:
@@ -34,59 +59,139 @@
34
59
  tags: [ubuntu, testvm]
35
60
  secrets:
36
61
  vagrant-password:
37
- ids: jane
62
+ ids: you
38
63
  value: vagrant
39
64
  ids:
40
- jane: age1...
65
+ you: age1...
66
+ ```
67
+ 3. **Manage the file**
68
+ ```bash
69
+ hostctl inventory encrypt # wrap with AGE recipients
70
+ hostctl inventory decrypt # view/edit locally
71
+ hostctl inventory list # inspect hosts & tags
41
72
  ```
42
- See `docs/system_management.md` for more host examples and encryption workflows.
43
- 5. **Run an example task**
73
+ Set `AGE_IDS="~/.hostctl/age/*.priv"` before running commands if the file is encrypted.
74
+
75
+ ## Running tasks
76
+ - **Local script**
44
77
  ```bash
45
78
  npm run build
46
79
  ./dist/bin/hostctl.js run example/echo.ts args:hello
47
80
  ```
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.
58
-
59
- ## Install via npm
60
- - Global CLI:
81
+ - **Local package**
82
+ ```bash
83
+ hostctl run ./my-package hello name:Sam
84
+ ```
85
+ - **Remote orchestration**
86
+ ```bash
87
+ hostctl run -r -t ubuntu core.net.interfaces --json
88
+ ```
89
+ - `-r/--remote` targets hosts selected by tags via SSH.
90
+ - `-t/--tag` is greedy; use `--` before positional args when needed.
91
+ - **From npm or git**
61
92
  ```bash
62
- npm install -g hostctl
63
- hostctl run example/echo.ts args:hello
93
+ hostctl run hostctl-hello greet name:Phil
94
+ hostctl run https://github.com/monopod/hostctl-example echo args:hello,world
64
95
  ```
65
- - One-off execution:
96
+ - **Install Docker anywhere**
66
97
  ```bash
67
- npx hostctl run core.echo message:hello
98
+ hostctl run -r -t ubuntu core.docker.install users:hostctl
68
99
  ```
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.
100
+ 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.
101
+ - **Run containers**
102
+ ```bash
103
+ hostctl run core.docker.run-container image:alpine command:'["/bin/sh","-c","echo from container"]'
104
+ hostctl run core.docker.run-container-detached image:redis name:ci-cache
105
+ ```
106
+ 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.
107
+
108
+ **Passing parameters**
109
+ - `key:value` pairs after the task name.
110
+ - `--params '{"key":"value"}'` for JSON blobs.
111
+ - `--file params.json` to load structured arguments.
112
+
113
+ ## Managing task packages
114
+ `hostctl pkg` commands wrap the npm-only package manager:
115
+ ```bash
116
+ hostctl pkg create my-task --lang typescript
117
+ hostctl pkg install hostctl-hello
118
+ hostctl pkg list
119
+ hostctl pkg remove hostctl-hello
120
+ ```
121
+ Installed packages live under `~/.hostctl/packages` and can be run offline once cached.
122
+
123
+ ## Designing tasks
124
+ Define tasks with the `task` helper and a typed `TaskContext`:
125
+
126
+ ```ts
127
+ import { task, type TaskContext } from 'hostctl';
128
+
129
+ interface EchoParams { message: string }
130
+ interface EchoResult { repeated: string }
131
+
132
+ async function run(context: TaskContext<EchoParams>): Promise<EchoResult> {
133
+ const { params, info } = context;
134
+ info(`Echo: ${params.message}`);
135
+ return { repeated: params.message };
136
+ }
137
+
138
+ export default task(run, { name: 'example.echo', description: 'Prints a message' });
139
+ ```
140
+
141
+ Key `TaskContext` capabilities (see [`docs/task-api.md`](docs/task-api.md) for details):
142
+ - Structured logging via `info`, `warn`, `error`, `debug`, or `log(level, ...)`.
143
+ - Command execution with `exec(command, { sudo, env, cwd, stdin, pty })`.
144
+ - Remote fan-out using `ssh(tags, remoteFn)`.
145
+ - Subtask orchestration with `run(otherTask(params))`.
146
+ - Secrets & credentials via `getSecret(name)` and `getPassword()`.
147
+ - Inventory helpers: `inventory(tags)` and `selectedInventory(tags?)`.
148
+ - File helpers: `file.read`, `file.write`, `file.exists`, `file.mkdir`, `file.rm` that respect local vs. remote runtime.
149
+
150
+ ## Building & testing task packages
151
+ 1. Scaffold: `hostctl pkg create awesome-firewall --lang typescript`.
152
+ 2. Install deps: `cd awesome-firewall && npm install`.
153
+ 3. Build: `npm run build` (defaults to `tsc`).
154
+ 4. Test locally without publishing: `npx hostctl run . args:foo`.
155
+ 5. Add unit tests with Vitest if needed, or invoke tasks directly in scripts.
156
+
157
+ ## Publishing task packages
158
+ 1. Update `package.json` metadata (`name`, `version`, `description`, `files`).
159
+ 2. Build artifacts (`npm run build` or rely on `prepublishOnly`).
160
+ 3. Authenticate with npm (`npm login` or `NPM_TOKEN`).
161
+ 4. Publish:
162
+ ```bash
163
+ npm version patch # or minor/major
164
+ npm publish --access public
165
+ ```
166
+ 5. Tag releases in git or automate with tools like `release-it` (this repo ships `release.sh` as an example flow).
167
+ 6. Verify: `npm info your-package version`.
168
+
169
+ ## Consuming published packages
170
+ - One-off: `npx hostctl run your-package taskName param:value`.
171
+ - Cache locally: `hostctl pkg install your-package@1.2.3` then run offline.
172
+ - Compose in other codebases by adding the package to `dependencies` and importing its exported tasks.
173
+
174
+ ## Troubleshooting
175
+ - **Task not found**: confirm the package exports the task name and that `exports` exposes it.
176
+ - **Version mismatch**: keep `package.json`, `src/version.ts`, and `jsr.json` in sync before releasing.
177
+ - **SSH failures**: verify inventory entries (hostname, user, auth) and only pass `-r` when you intend remote execution.
178
+ - **Secrets**: when inventories are encrypted, ensure `AGE_IDS` includes the private keys so `hostctl` can decrypt secrets.
179
+ - **Environment drift**: run `hostctl runtime` to inspect prerequisites or `hostctl runtime install` to bootstrap them.
180
+
181
+ ## Developer workflow
182
+ - Format & typing: `npm run format` (Prettier) and `npm run lint` (`tsc --noEmit`).
183
+ - Build artifacts: `npm run build` (tsup) produces `dist/` bundles for the CLI and published package.
82
184
  - Tests:
83
185
  - `npm run test` → unit + functional suites.
84
186
  - `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>.
187
+ - VM helpers (`npm run vm:*`) are legacy while XCP-ng provisioning matures; see `docs/xcp-ng-operations.md`.
188
+ - Releases rely on `npm run release` + `release-it`; see `NPM_MIGRATION_PLAN.md` for npm-only context.
189
+
190
+ ## Documentation map
191
+ - **Task API reference**: [`docs/task-api.md`](docs/task-api.md).
192
+ - **Operational guides**: `docs/*.md` (process, package, system management, etc.).
193
+ - **Architecture & design**: [`ARCHITECTURE.md`](ARCHITECTURE.md) and supporting design docs.
194
+ - **Contributor guide**: [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`AGENTS.md`](AGENTS.md).
195
+ - **Issue tracking**: <https://github.com/monopod/hostctl/issues>.
196
+
197
+ Explore the examples under `example/`, get familiar with the task API, and share automations with the community via npm-compatible packages.
@@ -4044,7 +4044,7 @@ var ParamMap = class _ParamMap {
4044
4044
  };
4045
4045
 
4046
4046
  // src/version.ts
4047
- var version = "0.1.41";
4047
+ var version = "0.1.42";
4048
4048
 
4049
4049
  // src/app.ts
4050
4050
  import { retryUntilDefined } from "ts-retry";