nomadctl 0.2.0__tar.gz
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.
- nomadctl-0.2.0/LICENSE +21 -0
- nomadctl-0.2.0/PKG-INFO +268 -0
- nomadctl-0.2.0/README.md +236 -0
- nomadctl-0.2.0/pyproject.toml +187 -0
- nomadctl-0.2.0/src/nd/__init__.py +7 -0
- nomadctl-0.2.0/src/nd/binary/__init__.py +10 -0
- nomadctl-0.2.0/src/nd/binary/env.py +43 -0
- nomadctl-0.2.0/src/nd/binary/runner.py +192 -0
- nomadctl-0.2.0/src/nd/cli.py +97 -0
- nomadctl-0.2.0/src/nd/commands/__init__.py +1 -0
- nomadctl-0.2.0/src/nd/commands/_common.py +101 -0
- nomadctl-0.2.0/src/nd/commands/clean.py +50 -0
- nomadctl-0.2.0/src/nd/commands/exec.py +67 -0
- nomadctl-0.2.0/src/nd/commands/list.py +120 -0
- nomadctl-0.2.0/src/nd/commands/logs.py +76 -0
- nomadctl-0.2.0/src/nd/commands/plan.py +103 -0
- nomadctl-0.2.0/src/nd/commands/run.py +372 -0
- nomadctl-0.2.0/src/nd/commands/status/__init__.py +29 -0
- nomadctl-0.2.0/src/nd/commands/status/command.py +102 -0
- nomadctl-0.2.0/src/nd/commands/status/render.py +172 -0
- nomadctl-0.2.0/src/nd/commands/status/report.py +339 -0
- nomadctl-0.2.0/src/nd/commands/stop.py +412 -0
- nomadctl-0.2.0/src/nd/commands/volume/__init__.py +25 -0
- nomadctl-0.2.0/src/nd/commands/volume/command.py +216 -0
- nomadctl-0.2.0/src/nd/commands/volume/render.py +132 -0
- nomadctl-0.2.0/src/nd/commands/volume/report.py +146 -0
- nomadctl-0.2.0/src/nd/constants.py +43 -0
- nomadctl-0.2.0/src/nd/jobfiles.py +125 -0
- nomadctl-0.2.0/src/nd/nomad/__init__.py +29 -0
- nomadctl-0.2.0/src/nd/nomad/client.py +51 -0
- nomadctl-0.2.0/src/nd/nomad/config.py +156 -0
- nomadctl-0.2.0/src/nd/nomad/errors.py +52 -0
- nomadctl-0.2.0/src/nd/nomad/models/__init__.py +1 -0
- nomadctl-0.2.0/src/nd/nomad/models/agent.py +26 -0
- nomadctl-0.2.0/src/nd/nomad/models/allocation.py +37 -0
- nomadctl-0.2.0/src/nd/nomad/models/deployment.py +40 -0
- nomadctl-0.2.0/src/nd/nomad/models/evaluation.py +21 -0
- nomadctl-0.2.0/src/nd/nomad/models/job.py +51 -0
- nomadctl-0.2.0/src/nd/nomad/models/node.py +41 -0
- nomadctl-0.2.0/src/nd/nomad/models/volume.py +28 -0
- nomadctl-0.2.0/src/nd/nomad/resources/__init__.py +1 -0
- nomadctl-0.2.0/src/nd/nomad/resources/agent.py +25 -0
- nomadctl-0.2.0/src/nd/nomad/resources/allocations.py +24 -0
- nomadctl-0.2.0/src/nd/nomad/resources/base.py +45 -0
- nomadctl-0.2.0/src/nd/nomad/resources/deployments.py +28 -0
- nomadctl-0.2.0/src/nd/nomad/resources/evaluations.py +19 -0
- nomadctl-0.2.0/src/nd/nomad/resources/jobs.py +70 -0
- nomadctl-0.2.0/src/nd/nomad/resources/nodes.py +24 -0
- nomadctl-0.2.0/src/nd/nomad/resources/status.py +14 -0
- nomadctl-0.2.0/src/nd/nomad/resources/system.py +25 -0
- nomadctl-0.2.0/src/nd/nomad/resources/volumes.py +42 -0
- nomadctl-0.2.0/src/nd/nomad/transport.py +141 -0
- nomadctl-0.2.0/src/nd/targets/__init__.py +32 -0
- nomadctl-0.2.0/src/nd/targets/alloc_target.py +166 -0
- nomadctl-0.2.0/src/nd/targets/selection.py +91 -0
- nomadctl-0.2.0/src/nd/ui/__init__.py +1 -0
- nomadctl-0.2.0/src/nd/ui/alloc_rows.py +93 -0
- nomadctl-0.2.0/src/nd/ui/duration.py +44 -0
- nomadctl-0.2.0/src/nd/ui/links.py +22 -0
- nomadctl-0.2.0/src/nd/ui/live_panel.py +199 -0
- nomadctl-0.2.0/src/nd/ui/panels.py +31 -0
- nomadctl-0.2.0/src/nd/ui/prompts.py +46 -0
- nomadctl-0.2.0/src/nd/ui/styles.py +52 -0
- nomadctl-0.2.0/src/nd/volumefiles.py +143 -0
nomadctl-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nathaniel Landau
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
nomadctl-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nomadctl
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A friendly command-line tool for managing a HashiCorp Nomad homelab cluster.
|
|
5
|
+
Keywords: cli,devops,hashicorp,homelab,nomad,orchestration
|
|
6
|
+
Author: Nathaniel Landau
|
|
7
|
+
Author-email: Nathaniel Landau <github@natelandau.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: System Administrators
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: System :: Systems Administration
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Dist: httpx2>=2.4.0,<3.0.0
|
|
21
|
+
Requires-Dist: lark>=1.3.1,<2.0.0
|
|
22
|
+
Requires-Dist: msgspec>=0.21.1
|
|
23
|
+
Requires-Dist: nclutils>=3.4.1,<4.0.0
|
|
24
|
+
Requires-Dist: python-hcl2>=8.1.2,<9.0.0
|
|
25
|
+
Requires-Dist: rich>=15.0.0
|
|
26
|
+
Requires-Dist: typer>=0.26.7
|
|
27
|
+
Requires-Python: >=3.13, <3.15
|
|
28
|
+
Project-URL: Homepage, https://github.com/natelandau/nd
|
|
29
|
+
Project-URL: Issues, https://github.com/natelandau/nd/issues
|
|
30
|
+
Project-URL: Repository, https://github.com/natelandau/nd
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
[](https://github.com/natelandau/nd/actions/workflows/automated-tests.yml) [](https://codecov.io/gh/natelandau/nd)
|
|
34
|
+
|
|
35
|
+
# nd
|
|
36
|
+
|
|
37
|
+
A friendly command-line tool for managing a Nomad cluster.
|
|
38
|
+
|
|
39
|
+
`nd` wraps the Nomad HTTP API and the local `nomad` binary behind a small set of
|
|
40
|
+
task-focused commands. Instead of stitching together multiple nomad commands, you
|
|
41
|
+
get easy to remember commands that marry your on-disk job and volume files and the
|
|
42
|
+
live cluster. No more no more hunting for an allocation ID or task name, just use
|
|
43
|
+
your easy to remember job and volume names and the cli does the rest.
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- A one-screen cluster dashboard covering nodes, jobs, allocations, deployments,
|
|
48
|
+
evaluations, and host volumes.
|
|
49
|
+
- Deploy and stop commands that watch the rollout or drain live and report a clear
|
|
50
|
+
success or failure at the end.
|
|
51
|
+
- Job-file aware commands that discover and work with your local `.hcl` and `.nomad` specs
|
|
52
|
+
- Interactive shell and log streaming for any task, with a prompt to pick the job,
|
|
53
|
+
allocation, and task when the choice is ambiguous.
|
|
54
|
+
- Dynamic host volume management: register, delete, and list host volumes across
|
|
55
|
+
every eligible node.
|
|
56
|
+
- Standard `NOMAD_*` environment variables work out of the box, with an optional
|
|
57
|
+
config file for anything you would rather not retype.
|
|
58
|
+
|
|
59
|
+
## Requirements
|
|
60
|
+
|
|
61
|
+
- Python 3.13 or 3.14.
|
|
62
|
+
- A reachable Nomad cluster.
|
|
63
|
+
- The `nomad` binary on your `PATH`. The `plan`, `run`, `exec`, and `logs` commands
|
|
64
|
+
shell out to it, because the HTTP API cannot parse HCL2 job files and does not own
|
|
65
|
+
the interactive exec protocol. The other commands use the API only.
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
The tool is published to PyPI as `nomadctl`. The installed command is `nd`.
|
|
70
|
+
|
|
71
|
+
Install it as an isolated CLI with [uv](https://docs.astral.sh/uv/):
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
uv tool install nomadctl
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Or with `pipx`:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pipx install nomadctl
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Confirm the install:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
nd --version
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
`nd` reads the standard Nomad environment variables first, then overrides them with
|
|
92
|
+
an optional config file. If you already run `nomad` from your shell, `nd` targets
|
|
93
|
+
the same cluster with no extra setup.
|
|
94
|
+
|
|
95
|
+
### Environment variables
|
|
96
|
+
|
|
97
|
+
| Variable | Purpose | Default |
|
|
98
|
+
| ----------------------- | ---------------------------- | -------------------------- |
|
|
99
|
+
| `NOMAD_ADDR` | Cluster API address | `http://127.0.0.1:4646` |
|
|
100
|
+
| `NOMAD_TOKEN` | ACL token | none |
|
|
101
|
+
| `NOMAD_NAMESPACE` | Default namespace | none |
|
|
102
|
+
| `NOMAD_REGION` | Default region | none |
|
|
103
|
+
| `NOMAD_CACERT` | Path to a CA certificate | none |
|
|
104
|
+
| `NOMAD_CLIENT_CERT` | Path to a client certificate | none |
|
|
105
|
+
| `NOMAD_CLIENT_KEY` | Path to a client key | none |
|
|
106
|
+
| `NOMAD_TLS_SERVER_NAME` | TLS server name override | none |
|
|
107
|
+
| `NOMAD_UI_URL` | Base URL for web UI links | falls back to `NOMAD_ADDR` |
|
|
108
|
+
|
|
109
|
+
### Config file
|
|
110
|
+
|
|
111
|
+
For settings you do not want to export every session, create
|
|
112
|
+
`~/.config/nd/config.toml` (or `$XDG_CONFIG_HOME/nd/config.toml`). Values here
|
|
113
|
+
override the environment.
|
|
114
|
+
|
|
115
|
+
```toml
|
|
116
|
+
[nomad]
|
|
117
|
+
address = "https://nomad.example.com:4646"
|
|
118
|
+
token = "your-acl-token"
|
|
119
|
+
ui_url = "https://nomad.example.com"
|
|
120
|
+
|
|
121
|
+
# Directories nd searches for .hcl and .nomad job files.
|
|
122
|
+
[jobs]
|
|
123
|
+
directories = ["~/homelab/jobs"]
|
|
124
|
+
|
|
125
|
+
# Directories nd searches for host volume spec files.
|
|
126
|
+
[volumes]
|
|
127
|
+
directories = ["~/homelab/volumes"]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The `[jobs]` and `[volumes]` directory lists power the file-aware commands. Without
|
|
131
|
+
them, `list`, `plan`, `run`, and the `volume` commands have nothing to discover.
|
|
132
|
+
|
|
133
|
+
## Quick start
|
|
134
|
+
|
|
135
|
+
Point `nd` at your cluster, then look at it:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
export NOMAD_ADDR="https://nomad.example.com:4646"
|
|
139
|
+
export NOMAD_TOKEN="your-acl-token"
|
|
140
|
+
|
|
141
|
+
nd
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Add a job directory to your config file, then list your specs against the live
|
|
145
|
+
cluster:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
nd list
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Deploy a job that is not yet running and watch it roll out:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
nd run web
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Tail its logs, then open a shell inside it:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
nd logs web
|
|
161
|
+
nd exec web
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Commands
|
|
165
|
+
|
|
166
|
+
Run `nd --help`, or `nd <command> --help`, for the full option list at any time.
|
|
167
|
+
|
|
168
|
+
| Command | What it does |
|
|
169
|
+
| --------------------------- | --------------------------------------------------------------------------------- |
|
|
170
|
+
| `nd status` | Show an at-a-glance overview of the cluster. Also runs when you type `nd` alone. |
|
|
171
|
+
| `nd list` | List discovered job files and whether each is running, dead, or not deployed. |
|
|
172
|
+
| `nd plan [JOB]` | Preview the changes one or more job files would apply, including to running jobs. |
|
|
173
|
+
| `nd run [JOB]` | Deploy not-yet-running job files and watch the rollout. |
|
|
174
|
+
| `nd stop [JOB]` | Stop, and optionally purge, running jobs and watch them drain. |
|
|
175
|
+
| `nd logs [JOB]` | Stream, tail, or export a task's logs. |
|
|
176
|
+
| `nd exec [JOB]` | Open an interactive shell inside a running task. |
|
|
177
|
+
| `nd clean` | Force garbage collection and reconcile job summaries. |
|
|
178
|
+
| `nd volume register [NAME]` | Register host volumes on every eligible node. |
|
|
179
|
+
| `nd volume delete [NAME]` | Delete registered host volumes matching the selected specs. |
|
|
180
|
+
| `nd volume list [NAME]` | List host volume specs and where each is registered. |
|
|
181
|
+
|
|
182
|
+
### Targeting jobs by name
|
|
183
|
+
|
|
184
|
+
Commands that take a `JOB` or `NAME` argument match by case-insensitive name prefix.
|
|
185
|
+
A single match runs straight away; several matches open a prompt. Omit the argument
|
|
186
|
+
to pick from a list of every candidate.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
nd run web # runs the one job whose name starts with "web"
|
|
190
|
+
nd stop # prompts you to choose from all running jobs
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Previewing before you act
|
|
194
|
+
|
|
195
|
+
Lifecycle commands accept `--dry-run` (`-n`) to report their targets without
|
|
196
|
+
touching the cluster:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
nd run --dry-run
|
|
200
|
+
nd stop web --dry-run
|
|
201
|
+
nd volume register --dry-run
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
For `nd run`, a dry run still validates each job file locally, so it catches a
|
|
205
|
+
broken spec without registering anything.
|
|
206
|
+
|
|
207
|
+
### Deploying jobs
|
|
208
|
+
|
|
209
|
+
`nd run` only offers jobs that are not already running. Each selected file is
|
|
210
|
+
validated and registered, then watched live until its deployment or allocations
|
|
211
|
+
settle. Use `--detach` to register and return without watching the rollout.
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
nd run # choose from every deployable job
|
|
215
|
+
nd run web # deploy the job whose name starts with "web"
|
|
216
|
+
nd run web --detach # register and return immediately
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Working with logs
|
|
220
|
+
|
|
221
|
+
`nd logs` streams both stdout and stderr live until you press Ctrl-C. Narrow or
|
|
222
|
+
redirect the output with flags:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
nd logs web # follow stdout and stderr
|
|
226
|
+
nd logs web --stderr # follow stderr only
|
|
227
|
+
nd logs web --tail 100 # print the last 100 lines, no follow
|
|
228
|
+
nd logs web --export run.log # write the current logs to a file
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Stopping jobs
|
|
232
|
+
|
|
233
|
+
`nd stop` confirms before it acts unless you pass `--force`. Use `--purge` to
|
|
234
|
+
garbage-collect the job afterward, `--detach` to return without watching the drain,
|
|
235
|
+
and `--no-shutdown-delay` to skip the configured shutdown delays for an immediate
|
|
236
|
+
teardown.
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
nd stop web # confirm, stop, and watch it drain
|
|
240
|
+
nd stop web --purge --force # purge without a prompt
|
|
241
|
+
nd stop web --detach # request the stop and return immediately
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Verbosity
|
|
245
|
+
|
|
246
|
+
Add `-v` for debug output or `-vv` to trace each API request with timings. The flag
|
|
247
|
+
works before or after the subcommand.
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
nd status -v
|
|
251
|
+
nd -vv run web
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Development
|
|
255
|
+
|
|
256
|
+
The project uses [uv](https://docs.astral.sh/uv/) for dependency management and
|
|
257
|
+
[duty](https://pawamoy.github.io/duty/) as a task runner.
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
uv sync # install dependencies
|
|
261
|
+
uv run nd --help # run the CLI from source
|
|
262
|
+
uv run duty lint # run ruff, ty, typos, and prek
|
|
263
|
+
uv run duty test # run the test suite with coverage
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## License
|
|
267
|
+
|
|
268
|
+
MIT. See [LICENSE](LICENSE).
|
nomadctl-0.2.0/README.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
[](https://github.com/natelandau/nd/actions/workflows/automated-tests.yml) [](https://codecov.io/gh/natelandau/nd)
|
|
2
|
+
|
|
3
|
+
# nd
|
|
4
|
+
|
|
5
|
+
A friendly command-line tool for managing a Nomad cluster.
|
|
6
|
+
|
|
7
|
+
`nd` wraps the Nomad HTTP API and the local `nomad` binary behind a small set of
|
|
8
|
+
task-focused commands. Instead of stitching together multiple nomad commands, you
|
|
9
|
+
get easy to remember commands that marry your on-disk job and volume files and the
|
|
10
|
+
live cluster. No more no more hunting for an allocation ID or task name, just use
|
|
11
|
+
your easy to remember job and volume names and the cli does the rest.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- A one-screen cluster dashboard covering nodes, jobs, allocations, deployments,
|
|
16
|
+
evaluations, and host volumes.
|
|
17
|
+
- Deploy and stop commands that watch the rollout or drain live and report a clear
|
|
18
|
+
success or failure at the end.
|
|
19
|
+
- Job-file aware commands that discover and work with your local `.hcl` and `.nomad` specs
|
|
20
|
+
- Interactive shell and log streaming for any task, with a prompt to pick the job,
|
|
21
|
+
allocation, and task when the choice is ambiguous.
|
|
22
|
+
- Dynamic host volume management: register, delete, and list host volumes across
|
|
23
|
+
every eligible node.
|
|
24
|
+
- Standard `NOMAD_*` environment variables work out of the box, with an optional
|
|
25
|
+
config file for anything you would rather not retype.
|
|
26
|
+
|
|
27
|
+
## Requirements
|
|
28
|
+
|
|
29
|
+
- Python 3.13 or 3.14.
|
|
30
|
+
- A reachable Nomad cluster.
|
|
31
|
+
- The `nomad` binary on your `PATH`. The `plan`, `run`, `exec`, and `logs` commands
|
|
32
|
+
shell out to it, because the HTTP API cannot parse HCL2 job files and does not own
|
|
33
|
+
the interactive exec protocol. The other commands use the API only.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
The tool is published to PyPI as `nomadctl`. The installed command is `nd`.
|
|
38
|
+
|
|
39
|
+
Install it as an isolated CLI with [uv](https://docs.astral.sh/uv/):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv tool install nomadctl
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or with `pipx`:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pipx install nomadctl
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Confirm the install:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
nd --version
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
`nd` reads the standard Nomad environment variables first, then overrides them with
|
|
60
|
+
an optional config file. If you already run `nomad` from your shell, `nd` targets
|
|
61
|
+
the same cluster with no extra setup.
|
|
62
|
+
|
|
63
|
+
### Environment variables
|
|
64
|
+
|
|
65
|
+
| Variable | Purpose | Default |
|
|
66
|
+
| ----------------------- | ---------------------------- | -------------------------- |
|
|
67
|
+
| `NOMAD_ADDR` | Cluster API address | `http://127.0.0.1:4646` |
|
|
68
|
+
| `NOMAD_TOKEN` | ACL token | none |
|
|
69
|
+
| `NOMAD_NAMESPACE` | Default namespace | none |
|
|
70
|
+
| `NOMAD_REGION` | Default region | none |
|
|
71
|
+
| `NOMAD_CACERT` | Path to a CA certificate | none |
|
|
72
|
+
| `NOMAD_CLIENT_CERT` | Path to a client certificate | none |
|
|
73
|
+
| `NOMAD_CLIENT_KEY` | Path to a client key | none |
|
|
74
|
+
| `NOMAD_TLS_SERVER_NAME` | TLS server name override | none |
|
|
75
|
+
| `NOMAD_UI_URL` | Base URL for web UI links | falls back to `NOMAD_ADDR` |
|
|
76
|
+
|
|
77
|
+
### Config file
|
|
78
|
+
|
|
79
|
+
For settings you do not want to export every session, create
|
|
80
|
+
`~/.config/nd/config.toml` (or `$XDG_CONFIG_HOME/nd/config.toml`). Values here
|
|
81
|
+
override the environment.
|
|
82
|
+
|
|
83
|
+
```toml
|
|
84
|
+
[nomad]
|
|
85
|
+
address = "https://nomad.example.com:4646"
|
|
86
|
+
token = "your-acl-token"
|
|
87
|
+
ui_url = "https://nomad.example.com"
|
|
88
|
+
|
|
89
|
+
# Directories nd searches for .hcl and .nomad job files.
|
|
90
|
+
[jobs]
|
|
91
|
+
directories = ["~/homelab/jobs"]
|
|
92
|
+
|
|
93
|
+
# Directories nd searches for host volume spec files.
|
|
94
|
+
[volumes]
|
|
95
|
+
directories = ["~/homelab/volumes"]
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The `[jobs]` and `[volumes]` directory lists power the file-aware commands. Without
|
|
99
|
+
them, `list`, `plan`, `run`, and the `volume` commands have nothing to discover.
|
|
100
|
+
|
|
101
|
+
## Quick start
|
|
102
|
+
|
|
103
|
+
Point `nd` at your cluster, then look at it:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
export NOMAD_ADDR="https://nomad.example.com:4646"
|
|
107
|
+
export NOMAD_TOKEN="your-acl-token"
|
|
108
|
+
|
|
109
|
+
nd
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Add a job directory to your config file, then list your specs against the live
|
|
113
|
+
cluster:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
nd list
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Deploy a job that is not yet running and watch it roll out:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
nd run web
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Tail its logs, then open a shell inside it:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
nd logs web
|
|
129
|
+
nd exec web
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Commands
|
|
133
|
+
|
|
134
|
+
Run `nd --help`, or `nd <command> --help`, for the full option list at any time.
|
|
135
|
+
|
|
136
|
+
| Command | What it does |
|
|
137
|
+
| --------------------------- | --------------------------------------------------------------------------------- |
|
|
138
|
+
| `nd status` | Show an at-a-glance overview of the cluster. Also runs when you type `nd` alone. |
|
|
139
|
+
| `nd list` | List discovered job files and whether each is running, dead, or not deployed. |
|
|
140
|
+
| `nd plan [JOB]` | Preview the changes one or more job files would apply, including to running jobs. |
|
|
141
|
+
| `nd run [JOB]` | Deploy not-yet-running job files and watch the rollout. |
|
|
142
|
+
| `nd stop [JOB]` | Stop, and optionally purge, running jobs and watch them drain. |
|
|
143
|
+
| `nd logs [JOB]` | Stream, tail, or export a task's logs. |
|
|
144
|
+
| `nd exec [JOB]` | Open an interactive shell inside a running task. |
|
|
145
|
+
| `nd clean` | Force garbage collection and reconcile job summaries. |
|
|
146
|
+
| `nd volume register [NAME]` | Register host volumes on every eligible node. |
|
|
147
|
+
| `nd volume delete [NAME]` | Delete registered host volumes matching the selected specs. |
|
|
148
|
+
| `nd volume list [NAME]` | List host volume specs and where each is registered. |
|
|
149
|
+
|
|
150
|
+
### Targeting jobs by name
|
|
151
|
+
|
|
152
|
+
Commands that take a `JOB` or `NAME` argument match by case-insensitive name prefix.
|
|
153
|
+
A single match runs straight away; several matches open a prompt. Omit the argument
|
|
154
|
+
to pick from a list of every candidate.
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
nd run web # runs the one job whose name starts with "web"
|
|
158
|
+
nd stop # prompts you to choose from all running jobs
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Previewing before you act
|
|
162
|
+
|
|
163
|
+
Lifecycle commands accept `--dry-run` (`-n`) to report their targets without
|
|
164
|
+
touching the cluster:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
nd run --dry-run
|
|
168
|
+
nd stop web --dry-run
|
|
169
|
+
nd volume register --dry-run
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
For `nd run`, a dry run still validates each job file locally, so it catches a
|
|
173
|
+
broken spec without registering anything.
|
|
174
|
+
|
|
175
|
+
### Deploying jobs
|
|
176
|
+
|
|
177
|
+
`nd run` only offers jobs that are not already running. Each selected file is
|
|
178
|
+
validated and registered, then watched live until its deployment or allocations
|
|
179
|
+
settle. Use `--detach` to register and return without watching the rollout.
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
nd run # choose from every deployable job
|
|
183
|
+
nd run web # deploy the job whose name starts with "web"
|
|
184
|
+
nd run web --detach # register and return immediately
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Working with logs
|
|
188
|
+
|
|
189
|
+
`nd logs` streams both stdout and stderr live until you press Ctrl-C. Narrow or
|
|
190
|
+
redirect the output with flags:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
nd logs web # follow stdout and stderr
|
|
194
|
+
nd logs web --stderr # follow stderr only
|
|
195
|
+
nd logs web --tail 100 # print the last 100 lines, no follow
|
|
196
|
+
nd logs web --export run.log # write the current logs to a file
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Stopping jobs
|
|
200
|
+
|
|
201
|
+
`nd stop` confirms before it acts unless you pass `--force`. Use `--purge` to
|
|
202
|
+
garbage-collect the job afterward, `--detach` to return without watching the drain,
|
|
203
|
+
and `--no-shutdown-delay` to skip the configured shutdown delays for an immediate
|
|
204
|
+
teardown.
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
nd stop web # confirm, stop, and watch it drain
|
|
208
|
+
nd stop web --purge --force # purge without a prompt
|
|
209
|
+
nd stop web --detach # request the stop and return immediately
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Verbosity
|
|
213
|
+
|
|
214
|
+
Add `-v` for debug output or `-vv` to trace each API request with timings. The flag
|
|
215
|
+
works before or after the subcommand.
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
nd status -v
|
|
219
|
+
nd -vv run web
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Development
|
|
223
|
+
|
|
224
|
+
The project uses [uv](https://docs.astral.sh/uv/) for dependency management and
|
|
225
|
+
[duty](https://pawamoy.github.io/duty/) as a task runner.
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
uv sync # install dependencies
|
|
229
|
+
uv run nd --help # run the CLI from source
|
|
230
|
+
uv run duty lint # run ruff, ty, typos, and prek
|
|
231
|
+
uv run duty test # run the test suite with coverage
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
MIT. See [LICENSE](LICENSE).
|