Olares Cluster (olares-cli cluster)

Operations
DeploymentKubernetesPrompt

Olares ControlHub view (olares-cli cluster) — per-Olares-ID command-line mirror of the Olares ControlHub SPA's Cluster page, the Kubernetes view of an Olares instance. Reads pods, containers, workloads (Deployment / StatefulSet / DaemonSet), application spaces (KubeSphere-grouped namespaces), namespaces, nodes, jobs, cronjobs, and Olares-managed middleware (databases, queues, object stores) that the active Olares ID is allowed to see. Mutating verbs (scale / restart / stop / start / delete on workloads, delete / restart on pods, suspend / resume on cronjobs, rerun on jobs) all go through a confirmation prompt that --yes skips. Watch verbs (pod get -w, workload rollout-status -w, application status -w, pod / container logs -f) poll on --interval. Use when the user mentions Olares, Olares ID, Olares ControlHub, olares-cli cluster, or asks 'what's running on my Olares', 'tail logs of <pod>', 'restart / scale / delete this workload', 'who am I on this ControlHub', 'suspend this cronjob', or 'rerun this job'. Do NOT use for Olares app-store lifecycle (use olares-cli market) or host-side install / node join / OS upgrade (use olares-cli node / os / gpu).

Install

openclaw skills install @olares/olares-cluster

cluster (per-user K8s view)

CRITICAL — before doing anything, MUST use the Read tool to read ../olares-shared/SKILL.md for the profile model, login flow, automatic token refresh, and the auth-error recovery table.

Source of truth for flags & wire shapes is always olares-cli cluster <noun> <verb> --help. This file only carries what --help cannot give: routing, the mental model of nouns, the identity-vs-server principle, the mutating-verb safety contract, cross-verb output conventions, and the common-errors → fix table.

When to use this skill

Against the cluster the active profile can see:

  • "What pods / containers / workloads / jobs / cronjobs / namespaces / nodes are running?"
  • "Tail / show logs of <pod> (or <container> of <pod>)"
  • "Restart / scale / stop / start / delete <workload>" — the K8s controller, not the Olares app
  • "Suspend / resume <cronjob>" or "rerun <job>"
  • "Who am I on this cluster, what's my role?" (cluster context)
  • "What does this object's YAML look like?" (cluster <noun> yaml)

When NOT to use — route to a sibling skill

User intentUse insteadWhy
Install / uninstall / upgrade / start / stop an Olares appolares-marketApp-store lifecycle, not K8s object lifecycle
Edit app entrances / domains / env / policy / ACL from the user perspectiveolares-settingsThe settings UI mirror, scoped to the user's apps
Browse / sync drive filesolares-filesFile API, not K8s
Cluster install / node join / OS upgrade / GPU driversolares-cli node, olares-cli os, olares-cli gpuKubeconfig-based host maintenance, NOT profile-based
Profile management, login, token refresholares-sharedAuth lives there

Mental model: if the question is runtime state of an existing cluster, you are here. If it's lifecycle of an Olares app or day-zero host setup, you are not.

Core concepts

NounIdentifier grammarWhat it is
Pod<ns>/<pod> (or -n NS <pod>)One running pod with one or more containers
Container<ns>/<pod>/<container> (or -n NS <pod> -c NAME)A single container inside a pod (logs / env target)
Workload<ns>/<name> + --kind deployment|statefulset|daemonsetThe controller that owns pods. Subject of scale / restart / stop / start / rollout-status
Application space<namespace>A KubeSphere-grouped K8s namespace; the "Olares Application Space" framing groups namespaces by workspace
Namespace<name>The same K8s namespace, kubectl-style framing (no workspace grouping)
Node<name>A K8s node visible to the active profile. Different from olares-cli node (host maintenance)
Job<ns>/<name>A one-shot batch run (apis/batch/v1)
CronJob<ns>/<name>A scheduled Job template (apis/batch/v1)
Middleware--type T --name N --namespace NSAn Olares-managed database / queue / object store; NOT a K8s native resource (separate /middleware/v1/* aggregator)

Resource relationships

Application space (namespace)
├── Workload  (Deployment | StatefulSet | DaemonSet)
│   └── Pod
│       └── Container       (logs | env)
├── Job
│   └── Pod
└── CronJob
    └── Job
        └── Pod

Cluster
├── Node                    (per-user view, not host maintenance)
└── Middleware              (DB / queue / object store, separate aggregator)

cluster context             (identity / role / accessible workspaces)

The identity-vs-server-decides principle (cross-cutting)

  1. Identity = the currently-selected profile. Switch with olares-cli profile use <name> ahead of time. There is no per-invocation --profile override — agents must commit to one role up-front.
  2. The server decides what the active profile can see; the CLI never preflights. Pass the request, render whatever the server returns. A 403 is the authoritative "no" — surface it. Never gate a call against the locally cached cluster context; that cache is for display only.
  3. All requests go through https://control-hub.<terminus> and ride the active profile's access_token via the auto-refreshing transport. See ../olares-shared/SKILL.md for refresh mechanics and ErrTokenInvalidated recovery.
  4. The same nginx fans out four prefixes: /capi/* (Olares aggregator), /api/v1/* + /apis/<g>/<v>/* (K8s native), /kapis/* (KubeSphere paginated), /middleware/v1/* (Olares middleware aggregator). The right helper is picked per-call by the CLI.

cluster context is identity-only — it does NOT own resources. Use it once at the start of a session to confirm "I am <id>, role <X>, can see <workspaces>". Never gate other verbs on its cached value.

Verb index

For flags, examples, and wire shapes, always start with olares-cli cluster <noun> <verb> --help.

NounVerbs--help first, then...
context(single verb)olares-cli cluster context --help
podlist, get, yaml, events, logs, delete, restartreferences/olares-cluster-pod.md
containerlist, env, logsolares-cli cluster container --help
workload (alias wl)list, get, yaml, rollout-status, scale, restart, stop, start, deletereferences/olares-cluster-workload.md
application (alias app)list, get, workloads, pods, statusreferences/olares-cluster-application.md
namespace (alias ns)list, getolares-cli cluster namespace --help
node (alias nodes)list, getolares-cli cluster node --help
job (alias jobs)list, get, yaml, pods, events, rerunreferences/olares-cluster-job.md
cronjob (aliases cronjobs / cj)list, get, yaml, jobs, suspend, resumereferences/olares-cluster-cronjob.md
middleware (alias mw)listreferences/olares-cluster-middleware.md

Mutating verb safety contract (cross-cutting)

Every mutating verb — pod delete / pod restart, all of workload scale|restart|stop|start|delete, cronjob suspend, job rerun — follows the same contract:

  1. Wrapped in a ConfirmDestructive y/N prompt. Even for "reversible" changes — the prompt is the safety net. --yes / -y opts out for scripts.
  2. No client-side authorization preflight — server is the only authority. A 403 surfaces; the CLI does not gate against cluster context.
  3. Stable JSON summary on success, not the apiserver's response. JSON consumers care whether the change took, not every field of the object.

Non-destructive verbs (cronjob resume, workload start, pod logs) are NOT wrapped. Confirm intent with the user BEFORE invoking any destructive verb, even when scripts pass --yes.

Output conventions

  • -o table (default): tabwriter columns. List verbs add a NAMESPACE column when scope is cross-namespace; get verbs render a vertical key/value layout. Paginated lists print (showing X of Y total — pass --limit Y to see more) to stderr when truncated.
  • -o json: pretty-printed JSON. List/get verbs decode through minimal typed structs and re-emit only the fields the CLI knows about. The four * yaml verbs forward server bytes verbatim through JSON→YAML.
  • -q / --quiet: suppress all stdout; exit code carries success/failure.
  • --no-headers: omit table headers (handy for shell pipelines).

Pagination (--page N / --all)

Every list verb under pod / cronjob / job / namespace / node / workload (and the application pods / application workloads wrappers) supports pagination. Defaults: --limit 100, --page 1. Pass --page N to walk pages, or --all to drain every page.

--watch / --follow semantics (uniform)

pod get -w, workload rollout-status -w, application status -w, pod logs -f, container logs -f all share the same plumbing:

  • Polling, never streaming. Avoids chunked transfer encoding; matches olares-cli market --watch.
  • signal.NotifyContext(os.Interrupt, SIGTERM) for graceful Ctrl-C; exits nil on voluntary stop.
  • Tolerates up to 5 consecutive transient errors (network blips, 5xx) before aborting. Terminal 4xx responses short-circuit immediately — a NotFound / Forbidden / Unauthorized won't fix itself on the next poll. 408 and 429 are still retried.
  • TTY detection: clear-screen-redraw for table, raw stream for piped output, JSONL for -o json.
  • --interval D / --timeout D are rejected with an error when their gate flag (-w or -f) isn't also set — don't silently waste a flag.

Common errors → fixes

Error message starts withMeaningFix
server rejected the request (HTTP 401: ...); please run: olares-cli profile login --olares-id <id>Auto-refresh failed, OR refreshed token still rejectedRun the suggested profile login
server rejected the request (HTTP 403: ...)The active profile's role can't perform thiscluster context --refresh to confirm the cached role matches the server. If still 403, the user genuinely lacks permission
... HTTP 404 (NotFound): ... on a list verbNamespace doesn't exist OR the user can't see it (KubeSphere often returns 404 instead of 403 for "no access")cluster application list to see what the server thinks is visible
--field-selector: field "..." is not supported (supported: ...) (from cluster pod list)The pod list --field-selector accepts only a translatable subset of kubectl selectors (KubeSphere doesn't speak the raw fieldSelector= wire syntax)Use one of the supported fields (status.phase, spec.nodeName, metadata.name, metadata.namespace), or drop --field-selector and filter client-side
--field-selector: "..." uses the '!=' operator which the upstream KubeSphere pods endpoint does not supportKubeSphere only matches equalityRephrase as a positive match, or filter the output through jq
aborted by user / stdin is not a terminal — pass --yes to confirm: ...Destructive prompt rejected, or non-TTY context without --yesInteractive: answer y. Scripted: add --yes
--interval requires --follow / --interval requires --watch / --timeout requires --watchPolling cadence flags set without their gate flagAdd -f / -w, or drop the offending flag
decode ... response: ...Endpoint returned something we couldn't parseRe-run with -o json to see the raw shape; may indicate a server-side schema change
refresh token for ... became invalid at ... (typed *credential.ErrTokenInvalidated)The refresh_token itself is dead — auto-refresh can't recoverolares-cli profile login

For the full auth-error matrix see ../olares-shared/SKILL.md.