User Guide

Command reference. For a hands-on path, use First Steps (Requirements → Prepare → Demo), or start on a queue host at Prepare the machine, then First job.

Full flag lists: julia --project=. -m DistSSHKit {cmd} --help. Each command page starts with Flags for that command.

Prepare hosts

Shared by a job you start here and a job you leave on a queue host.

  • setup: check hosts, clone / rsync / sync, instantiate, prune, cleanup
  • up: the same Julia channel on each machine

This machine

Start a job here. The SSH connection stays open until it finishes. The machine the run starts from is this machine.

  • go: standalone script as-is; one full run per slot (--repeat N = N runs, spread across listed hosts)
  • ride: experimental auto-split of map / filter (parent or SSH workers)
  • drive: master + Distributed workers; driver farms work
  • plan: inspect a script; suggest go / ride / drive (does not run)
  • size: estimate worker counts from RAM / CPU
  • pool: cluster cores / health; no job
  • paths: stored_path / content-hash cache / push_cache!
  • demo: install or list bundled example scripts

progress has no page of its own. julia -m DistSSHKit progress DIR reprints the last phase seconds from a job you started here.

Always-on machine

A queue host is an always-on machine. Leave jobs there. They run one at a time. The machine the run starts from is the queue host.

go vs drive (pick one)

Both share host tokens (parent:N, child:NAME:N) and optional --sync / --rsync. The difference is what the script is:

  • Script: go is ordinary .jl (the job file does not call DistSSHKit). Drive is a driver with init_output_dir! / main.
  • child:NAME:N: go is N concurrent full script runs. Omit :N only with --repeat (uncapped). Drive is N Distributed workers; omit :N is an error. Estimate with size.
  • Collect: go is slot-overwrite after remotes. Drive is post-run-new after main(); optional collect-only flags.
  • Success: go requires every listed slot to run (ok=false if one does not). Drive requires listed parent / child to join, stay, and collect (default). --best-effort allows a partial run.
  • Git parity: go has no --require-git. Drive has opt-in --require-git.
  • --output-dir: go is batch root (PATH/{slot}/). Drive is result root (DISTRIBUTED_OUTPUT_DIR).

If you want “run this job on a few machines,” start with go. If you want one master farming work with pmap (and friends), use drive.

Flag consistency (read once)

Same names are shared on purpose; a few meanings differ by command:

  • --sync / --rsync: same git vs rsync idea on setup (mode) and go / drive (optional pre-run). On each command, pick at most one. go / drive --rsync instantiates if deps are missing.
  • Default pre-run sync: go and drive: none (run setup yourself, or pass --sync / --rsync).
  • Git parity (drive): off by default. Opt-in: --require-git. Compat: --skip-git-guard (no-op; may combine with --sync / --rsync).
  • Host reliability (drive): on by default (--require-all-hosts). Opt out: --best-effort / DISTSSHKIT_BEST_EFFORT.
  • Skip pre-run (go): compat --skip-sync / --skip-git-guard (already the default; exclusive with --sync / --rsync on go).
  • --output-dir: go is batch root (PATH/{slot}/). drive is result root (DISTRIBUTED_OUTPUT_DIR). Different on purpose.
  • --hosts: CSV tokens. setup / size / pool strip :N from parent / child:NAME[:N]. go / ride / drive require :N on listed tokens.
  • --hosts-file: same as --hosts for that command.
  • Shared flags: -q/--quiet, --progress, --verbose, -y/--yes, --hosts, --hosts-file, -v/--version — same on setup / go / drive / size / pool.

Shared concepts

Hosts. Sources, in the order they append after positional tokens:

  • CLI tokens: setup / size / pool may omit :N; go / ride / drive need parent:N / child:NAME:N
  • --hosts (CSV)
  • DISTSSHKIT_HOSTS (comma-separated)
  • --hosts-file (default path from DISTSSHKIT_HOSTS_FILE)

setup / size / pool strip :N and use host names only. Bare SSH names are not accepted on setup (use child:NAME). On setup, parent / parent:N are only for up; other modes take child:NAME only.

Jobs. DISTSSHKIT_JOBS (default 1) is the max concurrent SSH host jobs for setup --rsync, drive post-run collect, and size Julia detection. Worker addprocs stays sequential.

Quiet / progress.

  • Default: --progress (live status) on a TTY; full detail when piped or NO_COLOR
  • -q hides terminal detail; --verbose forces full detail — at most one (DISTSSHKIT_QUIET / DISTSSHKIT_PROGRESS / DISTSSHKIT_VERBOSE)
  • Slot logs still write regardless; fatals stay on the terminal
  • Confirm prompts always print (-y / DISTSSHKIT_YES skips them). setup --delete, setup --prune, and teardown ignore that skip and need --confirm-path

Stale workers.

  • Local drive workers are torn down with rmprocs, not a pattern pkill
  • drive does not pkill -f julia --worker on remotes. With job_id / DISTSSHKIT_JOB_ID it pkills argv distsshkit-job:<id>. Skip that leftover pkill with DISTSSHKIT_SKIP_GLOBAL_WORKER_PKILL=1; rmprocs still runs
  • setup --prune removes .distsshkit/{go,drive,setup,runs} leaves (not the deploy). --cleanup kills stale workers (untagged julia --worker / --bind-to on localhost and remotes; other Distributed jobs on the same login can match). --delete removes the remote project tree
  • Detached execute!(…; job_id=) is a different contract: pkill only argv containing distsshkit-job:<id> (terminate!). Go slots -L a no-op file of that name so the script still runs; drive workers get --eval=#distsshkit-job:<id>

Files on disk. Setup logs: {project}/.distsshkit/setup/ (or the current run dir when DISTSSHKIT_RUN_DIR is set). Artifacts: go {script}/.distsshkit/go/{stem}_{UTC}/; drive (no --output-dir and no init_output_dir!): {script}/.distsshkit/drive/{stem}_{UTC}/. Sidecars (run.toml, pid, stdio): {script}/.distsshkit/runs/<kind>/{stem}_{UTC}/ (if that tree is not writable: {project}/.distsshkit/runs/…, then tempdir()/distsshkit-runs/…). Add .distsshkit/ to the job project's .gitignore — DistSSHKit's own repo already ignores it, but Pkg.add does not. Otherwise go/drive output can show up as untracked files, including under drive --require-git.

Collect modes:

ModeWhere
slot-overwritego after each remote slot (whole slot dir)
post-run-newdrive after main() (newer than run-start sentinel)
collect-missingdrive --collect-missing / collect!(merge=false)
collect-overwritedrive --collect-overwrite / collect!(merge=true)