End-to-end smoke
A walkthrough of every operator-facing surface. Each section is self-contained — run them in any order. Good as a release smoke test (mark each section ✓ / ✗ in your release notes) and as a guided tour.
Nomenclature
| Term | What it means |
|---|---|
| Provider | A recipe for reaching compute — an SSH config, an AWS region + credentials, a Slurm cluster. |
| Instance | One live cloud resource (EC2 VM, GCE VM, Kube pod) launched from a Provider. |
| Daemon | A nymph process registered with the control plane. One Worker row. |
| Mode | A named RunConfig — runner, image, env, resources. |
| Queue | A named pipe of pending Invocations that daemons subscribe to. |
| Invocation | One unit of work dispatched to a daemon. |
| ExecJob | An ad-hoc shell command run on a daemon, outside the Invocation path. |
1. Provider lifecycle
Expect: every step exits 0; show reflects the latest state.
The name is a positional, and the flag is --launcher — one of
SSH, SLURM, EC2, GCE, Kube, capitalized exactly like that.
There is no --name and no --type. --launcher is immutable:
supplying it to providers update is an error.
2. Soft delete, restore, and hide
Expect: a soft delete renames the row with a [deleted <iso>]
suffix so the (namespace, name) unique index stays intact; restore
matches both the plain and the tombstoned name. Hidden rows survive but
stay out of default listings. providers edit refetches between actions
so the visible state always reflects what just happened.
3. Cloud-config auto-detect
Pre: ~/.aws/credentials and/or a gcloud configuration.
Expect: every discover is read-only and makes no cloud API calls —
--json is their only flag. --from-aws-profile implies
--launcher EC2 and --from-gcloud-config implies --launcher GCE, so
you do not pass --launcher alongside them.
4. SSH discover and the interactive picker
Pre: at least two entries in ~/.ssh/config.
Expect: --filter takes all | new | existing and exits 2 on
anything else. Local-only directives are stripped silently, and the
picker groups rows into "new" and "existing".
5. Daemon install over SSH
Pre: an SSH alias you can reach, and LAKESHORE_ADMIN_TOKEN exported.
Expect: the CLI SSHes in, drops the binary and config, and waits for
the Worker row to register. --no-wait skips the wait — there is no
positive --wait on install. --binary <path> rsyncs a local nymph
instead of downloading; --slurm wraps the launch in an sbatch
heredoc.
Note --keep-alive-s <n> here (-1 = pool, 0 = single job, N =
seconds), which is spelled --keep-alive <seconds> on daemon launch
and keep_alive_s in YAML.
6. Cloud launch
Expect: --name gpu --count 2 produces labels gpu-00, gpu-01 and
sets the cloud Name tag to match. launch-log fetches the cloud serial
console (EC2 only today). daemon launch reads project defaults from
.lakeshore / .lakeshore.local — pass --no-config to ignore them.
7. Kill, cleanup, hibernate, reset
Expect: kill terminates the cloud instance by default —
--no-terminate is the opt-out. cleanup defaults to 24h and caps at
168h (one week); values outside that range are a 400. --until
accepts a relative duration (+30s, +5m, +1h, +3d) or an ISO-8601
timestamp; a past deadline is a 400. reset queues a reset_backoff
command so a daemon stuck in exponential backoff retries promptly.
8. Queues
Expect: ls and rm are the irregular verbs — list and remove
do not exist in this group. The default queue is auto-created on first
list and refuses both archive and rm with a 409.
9. Jobs
Expect: a queued invocation flips to killed; a running one
returns 409 with the claiming worker id, because there is no daemon-side
cancel signal in the wire protocol yet. bulk-cancel touches only
state=queued rows.
10. Exec on a daemon
Expect: both exec commands use pass-through options, so CLI flags
must precede the command and no -- separator is used. lakeshore exec
with no --queue pops an interactive picker. lakeshore run is
Python-only: it pipes the file bytes to a remote python3 - and writes
nothing to disk on the daemon.
11. Secrets, storage, and code
Expect: secrets add --kind is required and accepts ssh_key,
aws_keypair, gcp_sa_json, opaque; with no --from-file, the
plaintext is read from stdin. Plaintext is AES-256-GCM encrypted and is
never returned by any GET. code push defaults to the storage named
code-staging.
12. Tunnels and mounts (metadata only)
Expect: both round-trip cleanly with no side effects on running daemons. Neither is activated by the runner yet — see Tunnels and Mounts.
13. Admin tokens and namespaces
Requires LAKESHORE_ADMIN_TOKEN; the group exits 1 without it.
Expect: the minted plaintext (dlk_…) is shown exactly once.
tokens list ≡ ls; namespace ≡ ns, with ls and rm aliases.
Revocation is a tombstone — the row stays listable and the auth hook
returns 403.
14. Shell completion
Expect: completion accepts bash, zsh, or fish and exits 2 on
anything else. Server-backed values are cached for 30 s under
$XDG_CACHE_HOME/lakeshore/; local lookups (SSH aliases, AWS profiles,
gcloud configs, kube and docker contexts) are instant and uncached.
15. Dashboard
Expect: --tab takes workers, queues, invocations, or
storage; an unknown value warns and falls back to workers. It exits 2
with a friendly message when stdout is not a TTY or no control plane is
configured.
The CLI defines no .version(), so --version is rejected as an unknown
option. Check the installed version with npm ls -g @dreamlake/lakeshore.
Read next
- CLI — the full command reference.
- CLI examples — runnable snippets per verb group.
- Daemon lifecycle — what the daemon does between install and kill.
- Providers — per-launcher configuration.