proto-lpm-cli (0.3.206)
Installation
pip install --index-url proto-lpm-cliAbout this package
TEST VERSION of lpm-cli, a command-line client for Live Platform Manager, derived from its OpenAPI document
lpm-cli
NOTE: NOT TO BE USED FOR ANY PURPOSE OTHER THAN DEV TESTING OF A FEATURE. This branch exists purely for testing the auto-update feature. We needed a downloadable branch whose git release tag can be updated at the repo.
Command-line client for Live Platform Manager.
The command tree is not written by hand: it is derived at runtime from the backend's OpenAPI
document, so every endpoint the server offers is reachable, and a new endpoint appears without a
CLI release. lpm --help shows what the server in force offers; what a browser cookie owns —
login, single sign-on, scoreboard, SOL console — is absent from the tree and reachable only with
lpm raw.
Answers arrive as a table in a terminal and as the server's own JSON anywhere else. --json asks
for the whole document, wherever on the line it is written.
Two documents in Outline go further than this file: LPM CLI walks through logging in, reading, writing and what to do when a call fails, and LPM Patch Notes records what each LPM release brought.
Install
uv tool install git+ssh://git@source.ultrascale-svc.com/UltrascaleDI/lpm-cli.git
lpm login
That is the whole of it if your SSH key is on source.ultrascale-svc.com. lpm login asks for an
API key made in the LPM web UI. No uv yet? curl -LsSf https://astral.sh/uv/install.sh | sh, then
open a new terminal — it brings its own Python.
- Add
@v0.1.0to the repository to follow a release rather thanmain. - The key is stored in
~/.config/lpm/config.tomlwith mode0600, never as a command-line argument. One too long for a terminal line goes in withlpm login --api-key-file <path>. - Windows is not supported, and is not planned: the config file's permissions are POSIX modes.
lpm cli updatefetches the current version from wherever this copy came from — a repository install reinstalled, an index install upgraded with the index named, a checkout left togit pull.uv tool upgradeis no substitute: it treats a Git source as settled and reports nothing to upgrade however many commits have landed.
Without an SSH key, or in CI
The registry is private, so this needs a Forgejo token (Settings → Applications). It goes in
~/.netrc, which keeps it out of the index URL; the chmod is not optional.
printf 'machine source.ultrascale-svc.com login USERNAME password TOKEN\n' >> ~/.netrc
chmod 600 ~/.netrc
uv tool install lpm-cli \
--index https://source.ultrascale-svc.com/api/packages/UltrascaleDI/pypi/simple
The forge is asked first, so lpm-cli comes from there whenever it is reachable — but the name is
one the public index could carry one day, and there it would be someone else's package. If that
matters more than convenience, install from the repository. Dependencies come from the public
index either way, which is why it stays in the list.
Driving a BMC
What LPM does over IPMI sits under lpm bmc. Every command there names its devices with
--device-ids, repeated once per device — as the id lpm dcim devices list gives, or as the
machine's name with an @ in front of it:
lpm bmc power-status list --device-ids @node-17 --device-ids @node-18
lpm bmc power create --device-ids @node-17 --action graceful_restart
lpm bmc logs list --device-ids 42 --limit 20 # ids still work, everywhere
A name is looked up before the call goes out, and has to fit one machine exactly: @node-1 does
not reach node-17, and a name two machines carry is refused with both of them named rather than
acted on. Where several are given and one of them cannot be pinned down, none of the call runs.
The mark is what makes a name a name — without it 42 is an id, even where a machine is called
that. This works wherever a command takes a device id, lpm bmc included but not only.
| Command | What it reaches |
|---|---|
bmc ipmi-commands list |
which IPMI actions this backend offers |
bmc power-status list |
the power state, per device |
bmc power create --action <a> |
on, off, restart, reset, graceful_shutdown, graceful_restart |
bmc reset create |
resets the BMC itself, not the host |
bmc info list, bmc health list |
identity, and the health the BMC reports |
bmc logs list --limit <n> |
the event log |
bmc memory-modules list |
the DIMMs as the BMC sees them |
bmc task-list list, bmc tasks-clear create |
tasks the BMC is holding, and a way to drop them |
bmc media-mount create --image-url <u> |
virtual media; bmc media-eject create takes it back off |
bmc firmware list, bmc firmware-flash create |
the BMC's own firmware, with bios- and gpu- siblings for the rest |
bmc bios-settings list, bmc bios-settings create -d @file |
BIOS attributes, written as one document |
bmc fan-profiles list, bmc fan-profile activate create |
the fan policy in force, and how to change it |
The actions — power, reset, media, the flashes, tasks-clear — take --scheduled-at, an ISO 8601
time with a zone: left out, the action runs now and the answer holds the outcome per device; set to
a future time, it is deferred and the answer holds only the action ids to poll. lpm bmc <command> --help names the endpoint behind the command, the capability it needs, and every flag it takes.
Completion
There is nothing to install. Every run drops the completion where fish and bash read one by
themselves and keeps it in step with the version running; a file at that place the tool did not
write is left where it is. zsh has no such place — nothing takes effect there without an entry in
.zshrc, and that file is yours — so the tool writes what it can and names the line, which goes
above compinit:
fpath=(~/.local/share/lpm/completions $fpath)
What completes is the tool's own commands. The tree derived from the server would cost a round trip for every keystroke, so a name only the backend knows completes to nothing at all.
Working against more than one LPM
lpm login --url https://lab.example --profile lab
lpm cli profile list # which profiles exist, and which is in force
lpm cli profile use lab # switch for the next commands
lpm --profile lab dcim devices list # or just for this one call
lpm cli profile remove lab # take it back off this machine
lpm logout # the same, for whichever is in force
lpm whoami # the server, and what this key may do
LPM_URL and LPM_API_KEY work too, for CI jobs with no config file. What is typed on the
command line wins over the environment, and both win over the file.
An address must be an address: https://name:secret@lpm.example is refused wherever it turns up,
because a name and password in a URL replace the API key as the credential for every call — the
key then never sent, and nothing saying so. For the same reason lpm raw takes a path, not a
whole address.
The address from the browser works. LPM answers on lpm.<env> with the web UI and on
lpm-api.<env> with the API, so where a page comes back instead of JSON, the tool retries against
the lpm-api sibling of that name, says so on stderr, and login stores the address that
answered. No other host is rewritten: guessing more freely means sending the key to one nobody
named.
Removing the profile in force leaves none chosen rather than quietly falling back to another — the next command says so and lists what is left. What removal takes away is the copy stored here; the key itself keeps working until it is revoked in the web UI.