One binary. Every node. No surprises. clusterctl selects nodes with ClusterShell syntax, fans out commands, drives service processors, reinstalls nodes and administers Slurm, and asks before it changes anything.
$ clusterctl node select '@slurm:main&@rack:R02'
exe[0004-0009]
$ clusterctl exec -n '@slurm:main' --dedup -- uname -r
exe[0001-0009] (9): ok
5.14.0-570.el9.x86_64
exe0010 (1): ok
4.18.0-553.el8.x86_64
$ clusterctl slurm node drain 'ticket 4711: failing DIMM' -n exe0007
About to drain 1 host: exe0007
reason: ticket 4711: failing DIMM
Continue? [y/N] y
drained exe0007
$ clusterctl provision reinstall -n '@rack:R02' --dry-run
Would reinstall 10 hosts: exe[0001-0010]
everything on these machines is lostWith mise, which pins a version per project and verifies the download:
$ mise use -g github:GSI-HPC/clusterctl
$ clusterctl versionOr take the binary for your platform from the releases:
$ curl -fsSL -o clusterctl.tar.gz \
https://github.com/GSI-HPC/clusterctl/releases/latest/download/clusterctl_linux_amd64.tar.gz
$ tar xzf clusterctl.tar.gz
$ install -m 0755 clusterctl ~/.local/bin/Or build it:
$ go install github.com/GSI-HPC/clusterctl/cmd/clusterctl@latestGo 1.26 or newer. The toolchain downloads itself if yours is older.
$ clusterctl config init --site lab --cluster alpha --domain hpc.example.org
$ $EDITOR ~/.config/clusterctl/*.yaml # the files it listed; fill in what they ask
$ clusterctl config validate
$ clusterctl doctor
$ clusterctl node listconfig init writes the least configuration that resolves, and only into an
empty directory, and prints the path of every file it writes. On macOS that
directory is ~/Library/Application Support/clusterctl, not
~/.config/clusterctl. examples/site/ is a complete configuration to take
further settings from. The
manual walks through both, and
doc/migration.md maps every command and setting of the
shell toolkit clusterctl replaces to its counterpart.
$ clusterctl completion bash > /etc/bash_completion.d/clusterctl
$ clusterctl completion zsh > "${fpath[1]}/_clusterctl"Node set completion offers the configured groups, and --context offers the
configured contexts.
| Code | Meaning |
|---|---|
| 0 | Everything succeeded |
| 1 | At least one target failed |
| 2 | Usage or configuration error |
| 3 | A host could not be reached |
| 130 | Interrupted, or a confirmation declined |
clusterctl's node set engine is a library of its own, go-nodeset, because the Go ecosystem had none:
import "github.com/GSI-HPC/go-nodeset"
ns, err := nodeset.Parse("exe[0001-0010]!exe0003")
fmt.Println(ns) // exe[0001-0002,0004-0010]
fmt.Println(ns.Len()) // 9Its language reference
describes the language and the rules chosen where it differs from ClusterShell;
doc/nodeset.md says what clusterctl adds to it.
The repository carries a mise.toml, so the toolchain comes from
mise if you use it:
$ mise install # Go, golangci-lint, sops and sind, at the versions CI uses$ make test # unit and command tests
$ make lint # vet and formatting
$ make cover # coverage
$ make build # bin/clusterctlThe end-to-end tests run the binary against a Slurm cluster in Docker, which
sind creates; they need Linux with Docker,
and mise install installs sind:
$ make e2e-up # create the cluster
$ make e2e # run the tests against it
$ make e2e-down # delete itThe documentation site needs Hugo extended; see site/README.md.
Commits are Conventional Commits.
Design notes and the decision records are in doc/; a change that
takes a decision gets a record.
Copyright (C) 2026 GSI Helmholtz Centre for Heavy Ion Research GmbH http://www.gsi.de
LGPL-3.0-or-later. See COPYING and
COPYING.LESSER.