/install olares-cluster
\r \r
cluster (per-user K8s view)\r
\r
CRITICAL — before doing anything, MUST use the Read tool to read ../olares-shared/SKILL.md. It owns the profile model, login flow, automatic token refresh, and the auth-error recovery table that every command here depends on.\r
\r
When to use this skill\r
\r
Use olares-cli cluster ... when the user asks, against the cluster the active profile can see:\r
\r
- "What pods / containers / workloads / jobs / cronjobs / namespaces / nodes are running?"\r
- "Tail / show logs of
\x3Cpod>(or\x3Ccontainer>of\x3Cpod>)"\r - "Restart / scale / stop / start / delete
\x3Cworkload>" — the K8s controller, not the Olares app\r - "Suspend / resume
\x3Ccronjob>" or "rerun\x3Cjob>"\r - "What workspaces / application spaces can I see?"\r
- "Who am I on this cluster, what's my role?" (
cluster context)\r - "Rotate the admin password on this
\x3Cmiddleware>"\r - "What does this object's YAML look like?" (
cluster \x3Cnoun> yaml)\r \r
When NOT to use — route to a sibling skill\r
\r
| User intent | Use instead | Why |\r
|---|---|---|\r
| Install / uninstall / upgrade / start / stop an Olares app | olares-market | App-store lifecycle, not K8s object lifecycle |\r
| Edit app entrances / domains / env / policy / ACL from the user perspective | olares-settings | The settings UI mirror, scoped to the user's apps |\r
| Browse / sync drive files | olares-files | File API, not K8s |\r
| Cluster install / node join / OS upgrade / GPU drivers | olares-cli node, olares-cli os, olares-cli gpu | Kubeconfig-based host maintenance, NOT profile-based |\r
| Profile management, login, token refresh | olares-shared | Auth lives there |\r
\r
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.\r \r
Core concepts\r
\r
| Noun | Identifier grammar | What it is |\r
|---|---|---|\r
| Pod | \x3Cns>/\x3Cpod> (or -n NS \x3Cpod>) | One running pod with one or more containers. |\r
| Container | \x3Cns>/\x3Cpod>/\x3Ccontainer> (or -n NS \x3Cpod> -c NAME) | A single container inside a pod (logs / env target). |\r
| Workload | \x3Cns>/\x3Cname> + --kind deployment\|statefulset\|daemonset | The controller that owns pods. Subject of scale / restart / stop / start / rollout-status. |\r
| Application space | \x3Cnamespace> | A KubeSphere-grouped K8s namespace. The "Olares Application Space" framing groups namespaces by workspace so the user sees apps, not raw K8s. |\r
| Namespace | \x3Cname> | The same K8s namespace, but with kubectl-style framing (no workspace grouping). |\r
| Node | \x3Cname> | A K8s node visible to the active profile. Different from olares-cli node (host maintenance). |\r
| Job | \x3Cns>/\x3Cname> | A one-shot batch run (apis/batch/v1). |\r
| CronJob | \x3Cns>/\x3Cname> | A scheduled Job template (apis/batch/v1beta1). |\r
| Middleware | --type T --name N --namespace NS | An Olares-managed database / queue / object store. NOT a K8s native resource — uses a separate /middleware/v1/* aggregator. |\r
\r
Resource relationships\r
\r
Application space (namespace)\r
├── Workload (Deployment | StatefulSet | DaemonSet)\r
│ └── Pod\r
│ └── Container (logs | env)\r
├── Job\r
│ └── Pod\r
└── CronJob\r
└── Job\r
└── Pod\r
\r
Cluster\r
├── Node (per-user view, not host maintenance)\r
└── Middleware (DB / queue / object store, separate aggregator)\r
\r
cluster context (identity / role / accessible workspaces)\r
```\r
\r
`cluster context` is identity-only; it does not own resources. Use it once at the start of a session to confirm "I am `\x3Cid>`, role `\x3CX>`, can see `\x3Cworkspaces>`" — never to gate other verbs (see "Server decides" below).\r
\r
## Prerequisites and invariants\r
\r
1. **Identity = the currently-selected profile.** Switch with `olares-cli profile use \x3Cname>` ahead of time. There is intentionally no per-invocation `--profile` override — agents must commit to one role up-front. See [`olares-shared`](../olares-shared/SKILL.md).\r
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.\r
3. All requests go through `https://control-hub.\x3Cterminus>` and ride the active profile's `access_token` via `refreshingTransport`, which auto-rotates on 401/403 (full mechanics in [`olares-shared`](../olares-shared/SKILL.md) under "Automatic token refresh"). **Do not write retry loops on top of `*credential.ErrTokenInvalidated` / `*credential.ErrNotLoggedIn`** — once you see one, only `profile login` / `profile import` will help.\r
4. The same nginx fans out four prefixes: `/capi/*` (Olares custom aggregator), `/api/v1/*` and `/apis/\x3Cgroup>/\x3Cversion>/*` (K8s native proxy), `/kapis/*` (KubeSphere paginated), `/middleware/v1/*` (Olares middleware aggregator). The right helper is picked per-call in [`cli/pkg/clusterclient/`](cli/pkg/clusterclient) — verbs do not auto-detect.\r
\r
## Identity (`cluster context`)\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster context [--refresh] [-o table\|json]` | `GET /capi/app/detail` | Identity + global role + accessible workspaces / system namespaces / granted clusters. Cache-first; `--refresh` forces a roundtrip and updates the cache. |\r
\r
> Cached `ClusterContext` exists ONLY so this verb can render without a roundtrip and so error helpers can include the cached role in messages. Never gate other verbs on it.\r
\r
## Pods (`cluster pod ...`)\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster pod list [-n NS] [-l SEL] [--field-selector S] [--page N\|--all]` | `GET /kapis/resources.kubesphere.io/v1alpha3/[namespaces/\x3Cns>/]pods` | Lists pods. Cross-namespace by default; `NAMESPACE` column appears when scope is wider than one namespace. |\r
| `cluster pod get \x3Cns/name> [-w] [--interval D]` | `GET /api/v1/namespaces/\x3Cns>/pods/\x3Cname>` | Vertical summary + per-container table. With `-w`: clear-screen-redraw on TTY (table) / JSONL (json). |\r
| `cluster pod yaml \x3Cns/name>` | same | JSON-to-YAML round-trip via `sigs.k8s.io/yaml`; faithful to every server field. |\r
| `cluster pod events \x3Cns/name> [--limit N]` | `GET /api/v1/namespaces/\x3Cns>/events` | Server returns every event in the namespace; CLI filters client-side to `involvedObject.kind=Pod, name=\x3Cpod>`. Sorted oldest-first. |\r
| `cluster pod logs \x3Cns/pod> [-c NAME] [--tail N] [--since D] [-f] [--interval D] [--previous] [--timestamps]` | `GET /api/v1/.../pods/\x3Cname>/log?container=\x3Cc>` | Plain-text body forwarded to stdout. Multi-container pods require `-c`. `--follow` is poll-based (`sinceTime` advances each tick). `--previous` reads the prior instance's buffer (mutually exclusive with `--follow`). |\r
| `cluster pod delete \x3Cns/name> [--yes] [--grace-period N]` | `DELETE /api/v1/namespaces/\x3Cns>/pods/\x3Cname>` | Wrapped in `ConfirmDestructive`. `--grace-period -1` (default) honors the pod's `terminationGracePeriodSeconds`; `0` forces immediate kill. Controller-managed pods will be recreated. |\r
| `cluster pod restart \x3Cns/name> [--yes] [--grace-period N]` | (same DELETE) | Alias verb — wire-identical to `pod delete`. The SPA pairs them so we do too. |\r
\r
## Containers (`cluster container ...`)\r
\r
Per-pod projection over the same `/api/v1/.../pods/\x3Cname>` body — no new HTTP surface.\r
\r
| Command | What it does |\r
|---|---|\r
| `cluster container list \x3Cns/pod>` | One row per `spec.containers[*]` fused with the matching `status.containerStatuses[*]`: CONTAINER \| IMAGE \| READY \| RESTARTS \| STATE \| PORTS. |\r
| `cluster container env \x3Cns/pod> [--container NAME]` | Lists explicit `env: [...]` per container. `valueFrom` renders as `(from configMapKey/secretKey/fieldRef ...)` — values are NOT resolved. `envFrom` is intentionally not enumerated. JSON mode always emits a `{containers: [...]}` envelope (parseable even when empty). |\r
| `cluster container logs \x3Cns/pod/container \| ns/pod \| pod> [-c NAME] [--tail N] [--since D] [-f] [--interval D] [--previous] [--timestamps]` | Same wire endpoint as `pod logs`, plus an extra 3-segment positional `\x3Cns>/\x3Cpod>/\x3Ccontainer>` so users who already know the container name can skip `-c`. |\r
\r
## Workloads (`cluster workload ...`, alias `wl`)\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster workload list [-n NS] [--kind all\|deployment\|statefulset\|daemonset] [-l SEL] [--page N\|--all]` | `GET /kapis/resources.kubesphere.io/v1alpha3/[namespaces/\x3Cns>/]\x3Ckind>` | `--kind=all` (default) fans out one request per kind and merges into one table with a `KIND` column. Single-kind drops `KIND`. Singular / plural / short forms accepted (`deploy`, `sts`, `ds`). |\r
| `cluster workload get \x3Cns/name> --kind X` | `GET /apis/apps/v1/namespaces/\x3Cns>/\x3Ckind>/\x3Cname>` | `--kind` REQUIRED (no `all`). Vertical summary with kind-aware READY (`readyReplicas/replicas` or `numberReady/desiredNumberScheduled`), Availability, UpdateStrategy, Selector. |\r
| `cluster workload yaml \x3Cns/name> --kind X` | same | JSON-to-YAML round-trip. |\r
| `cluster workload rollout-status \x3Cns/name> --kind X [-w] [--interval D] [--timeout D]` | same | Reports whether the rollout has converged (kind-aware, mirrors `kubectl rollout status`). Without `-w`: one GET, exits 0 if converged or 2 if not. With `-w`: re-poll on `--interval` until converged, `--timeout` (default 10m), or Ctrl-C. Only emits on state change. |\r
| `cluster workload scale \x3Cns/name> --kind X --replicas N [-w] [--interval D] [--timeout D] [--yes]` | `PATCH /apis/apps/v1/namespaces/\x3Cns>/\x3Ckind>/\x3Cname>` body `{"spec":{"replicas":N}}` Content-Type `application/merge-patch+json` | DaemonSet rejected (no replicas). `--replicas=0` triggers `ConfirmDestructive`. With `-w` chains into `rollout-status -w`. |\r
| `cluster workload restart \x3Cns/name> --kind X [--yes] [--concurrency N]` | (1) GET selector; (2) GET pods by selector; (3) parallel DELETE pods | SPA-aligned. The controller recreates each pod from the workload template. `--concurrency` (default 5) bounds parallel deletes. NOT the kubectl `restartedAt` annotation trick. |\r
| `cluster workload stop \x3Cns/name> --kind X [-w] [--yes]` | (alias for `scale --replicas=0`) | DaemonSet rejected (delete the workload instead). Justified verb because the SPA exposes a labeled "STOP". |\r
| `cluster workload start \x3Cns/name> --kind X --replicas N [-w]` | (alias for `scale --replicas=N`) | `--replicas` REQUIRED (no cached previous count). No `--yes` (non-destructive). |\r
| `cluster workload delete \x3Cns/name> --kind X [--yes] [--propagation foreground\|background\|orphan]` | `DELETE /apis/apps/v1/namespaces/\x3Cns>/\x3Ckind>/\x3Cname>?propagationPolicy=\x3CP>` | CLI-original (the SPA has no direct workload-delete button). `Foreground` (default) waits for the cascade. |\r
\r
## Application spaces (`cluster application ...`, alias `app`)\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster application list` | `GET /capi/namespaces/group` | One row per Namespace, grouped by KubeSphere workspace. |\r
| `cluster application get \x3Cnamespace>` | `GET /api/v1/namespaces/\x3Cns>` | Vertical detail with KubeSphere-flavored labels (workspace, alias, creator) lifted to the top. |\r
| `cluster application workloads \x3Cnamespace> [...]` | (delegates to `workload list -n \x3Cns>`) | Pivot from "what app spaces?" → "what workloads here?". |\r
| `cluster application pods \x3Cnamespace> [...]` | (delegates to `pod list -n \x3Cns>`) | Symmetric pivot for pods. |\r
| `cluster application status \x3Cnamespace> [-w] [--interval D] [--events N]` | parallel fan-out over `/kapis/.../{deployments,statefulsets,daemonsets,pods}` + `/api/v1/.../events` | **CLI-original aggregation** — three sections: workload READY counts per kind, pod phase buckets, recent events (default 5, newest-first). Per-lane errors render as `(failed: ...)`; one section's failure does not blackout the rest. |\r
\r
## Namespaces (`cluster namespace ...`, alias `ns`)\r
\r
K8s framing of the same resource the application tree exposes.\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster namespace list [-l SEL] [--page N\|--all]` | `GET /kapis/resources.kubesphere.io/v1alpha3/namespaces` | kubectl-style table: NAME / PHASE / WORKSPACE / AGE. WORKSPACE comes from the `kubesphere.io/workspace` label. |\r
| `cluster namespace get \x3Cname>` | `GET /api/v1/namespaces/\x3Cns>` | Vertical K8s-style detail with full labels + annotations blocks. |\r
\r
## Nodes (`cluster node ...`, alias `nodes`)\r
\r
Per-user K8s view; **not** the host-side `olares-cli node` tree.\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster node list [-l SEL] [--page N\|--all]` | `GET /kapis/resources.kubesphere.io/v1alpha3/nodes` | kubectl-shaped: NAME / STATUS / ROLES / AGE / VERSION / INTERNAL-IP. STATUS = Ready / `Ready,SchedulingDisabled` / NotReady / Unknown. |\r
| `cluster node get \x3Cname>` | same `/\x3Cnode>` | Vertical detail with Capacity / Allocatable, Conditions, Taints, Addresses, full labels. |\r
\r
## Jobs (`cluster job ...`, alias `jobs`)\r
\r
K8s Jobs (`apis/batch/v1`).\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster job list [-n NS] [-l SEL] [--page N\|--all]` | `GET /kapis/resources.kubesphere.io/v1alpha3/[namespaces/\x3Cns>/]jobs` | NAMESPACE / NAME / COMPLETIONS / STATUS (Complete/Failed/Suspended/Running/...) / DURATION / AGE. |\r
| `cluster job get \x3Cns/name>` | `GET /apis/batch/v1/namespaces/\x3Cns>/jobs/\x3Cname>` | Vertical summary + Conditions + `Controlled By: CronJob/\x3Cname>` if present. |\r
| `cluster job yaml \x3Cns/name>` | same | JSON-to-YAML round-trip. |\r
| `cluster job pods \x3Cns/name> [-l ADDITIONAL] [...]` | (1) `job.Get` for `metadata.uid`; (2) `pod list` with `controller-uid=\x3Cuid>` | Two-step. `--label` is ANDed onto the controller-uid clause server-side. |\r
| `cluster job events \x3Cns/name> [--limit N]` | `GET /api/v1/namespaces/\x3Cns>/events` | Same shape as `pod events`, filtered to `involvedObject.kind=Job`. Shares `clusteropts.Event` + render/sort/URL helpers with `pod events` and `application status`. |\r
| `cluster job rerun \x3Cns/name> [--yes]` | (1) `job.Get` for `resourceVersion`; (2) `POST /kapis/operations.kubesphere.io/v1alpha2/namespaces/\x3Cns>/jobs/\x3Cname>?action=rerun&resourceVersion=\x3Crv>` | KubeSphere operations action; server spawns a new pod attempt. `ConfirmDestructive`-wrapped. |\r
\r
## CronJobs (`cluster cronjob ...`, aliases `cronjobs` / `cj`)\r
\r
K8s CronJobs (`apis/batch/v1beta1` — different from Jobs).\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster cronjob list [-n NS] [-l SEL] [--page N\|--all]` | `GET /kapis/resources.kubesphere.io/v1alpha3/[namespaces/\x3Cns>/]cronjobs` | NAMESPACE / NAME / SCHEDULE / SUSPEND / ACTIVE / LAST-SCHEDULE / AGE. |\r
| `cluster cronjob get \x3Cns/name>` | `GET /apis/batch/v1beta1/namespaces/\x3Cns>/cronjobs/\x3Cname>` | Vertical summary + ConcurrencyPolicy + Active Jobs + Job Template Selector. |\r
| `cluster cronjob yaml \x3Cns/name>` | same | JSON-to-YAML round-trip. |\r
| `cluster cronjob jobs \x3Cns/name> [--limit N]` | (1) `cronjob.Get` for `spec.jobTemplate.metadata.labels`; (2) `GET /apis/batch/v1/.../jobs?labelSelector=\x3Cderived>` | Two-step. Errors clearly if the jobTemplate carries no labels (rather than fanning to "every job in the namespace"). |\r
| `cluster cronjob suspend \x3Cns/name> [--yes]` | `PATCH /apis/batch/v1beta1/.../cronjobs/\x3Cname>` body `{"spec":{"suspend":true}}` Content-Type `application/merge-patch+json` | `ConfirmDestructive`. No-op short-circuit when already suspended. |\r
| `cluster cronjob resume \x3Cns/name>` | same path body `{"spec":{"suspend":false}}` | NO `--yes` (re-enabling is non-destructive). No-op short-circuit when already active. |\r
\r
## Middleware (`cluster middleware ...`, alias `mw`)\r
\r
Olares-managed databases / queues / object stores via the `/middleware/v1/*` aggregator. NOT a K8s native resource.\r
\r
| Command | Endpoint | What it does |\r
|---|---|---|\r
| `cluster middleware list [-t TYPE] [--show-passwords]` | `GET /middleware/v1/list` | Custom envelope `{code, data:[...]}` — NOT K8s. TYPE / NAME / NAMESPACE / NODES / ADMIN-USER. **Admin password is never printed in table mode**; in `-o json` it's `\x3Credacted>` unless `--show-passwords` is explicitly set. |\r
| `cluster middleware password set --type X --name N --namespace NS --user U [--password P] [--yes]` | `POST /middleware/v1/\x3Ctype>/password` | Sub-noun `password` (future-proof for `password rotate` / `reveal`). **`--password` is OPTIONAL and SHOULD usually be omitted** — when not provided, the verb prompts twice (no echo, must match). Passing it on the command line leaks the secret into shell history. `ConfirmDestructive`-wrapped. JSON output never echoes the password. |\r
\r
## Output conventions\r
\r
Same `-o table | json` flag set as `settings` and `market`.\r
\r
- `-o table` (default): tabwriter columns. List verbs add a `NAMESPACE` column when scope is cross-namespace; `get` verbs use a vertical key/value layout plus secondary tables; paginated lists print `(showing X of Y total — pass --limit Y to see more)` to stderr when truncated.\r
- `-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 are the exception — they forward server bytes verbatim through JSON→YAML.\r
- `-q` / `--quiet`: suppress all stdout; exit code carries success/failure. Useful for `cluster pod get foo/bar -q && echo ok`.\r
- `--no-headers`: omit table headers (handy for shell pipelines).\r
- **Mutating verbs synthesize a stable JSON summary** (e.g. `{operation, kind, namespace, name, replicas}`) rather than forwarding the apiserver's post-write response — JSON consumers care about whether the change took, not about every field of the object.\r
\r
### Pagination (`--page N` / `--all`)\r
\r
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. Helper lives in [`cli/cmd/ctl/cluster/internal/clusteropts/pagination.go`](cli/cmd/ctl/cluster/internal/clusteropts/pagination.go).\r
\r
### `--watch` / `--follow` semantics (uniform)\r
\r
`pod get -w`, `workload rollout-status -w`, `application status -w`, `pod logs -f`, `container logs -f` all share the same plumbing:\r
\r
- **Polling, never streaming.** Avoids chunked transfer encoding and matches `olares-cli market --watch`.\r
- `signal.NotifyContext(os.Interrupt, SIGTERM)` for graceful Ctrl-C; exits nil so scripts don't get a non-zero from a voluntary stop.\r
- Tolerates up to 5 consecutive transient errors before aborting; auth failures propagate immediately.\r
- TTY detection (`golang.org/x/term.IsTerminal`): clear-screen-redraw for table, raw stream for piped output, JSONL for `-o json`.\r
- `--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.\r
\r
## Mutating verb safety contract\r
\r
Every mutating verb (`pod delete` / `pod restart`, all of `workload scale|restart|stop|start|delete`, `cronjob suspend`, `job rerun`, `middleware password set`) follows the same contract:\r
\r
1. **Wrapped in `ConfirmDestructive`.** Even for "reversible" changes — the prompt is the safety net, not the apiserver's typed error. `--yes` / `-y` opts out so scripts work non-interactively. `cronjob resume`, `workload start`, and `pod logs` are NOT wrapped (non-destructive).\r
2. **No client-side authorization.** Server is the only authority. A 403 from the server is the answer; surface it. Never preflight against the cached cluster context.\r
3. **Stable JSON summary**, not the apiserver's response (see "Output conventions" above).\r
\r
## Common errors → fixes\r
\r
| Error message starts with | Meaning | Fix |\r
|---|---|---|\r
| `server rejected the request (HTTP 401: ...); please run: olares-cli profile login --olares-id \x3Cid>` | Auto-refresh failed, OR refreshed token still rejected. | Run the suggested `profile login`. |\r
| `server rejected the request (HTTP 403: ...)` | The active profile's role can't perform this. | Try `cluster context --refresh` to confirm the cached role matches the server. If still 403, the user genuinely lacks permission. |\r
| `... HTTP 404 (NotFound): ...` on a list verb | Namespace 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. |\r
| `aborted by user` / `stdin is not a terminal — pass --yes to confirm: ...` | Destructive prompt rejected, or non-TTY context without `--yes`. | Interactive: answer `y`. Scripted: add `--yes`. |\r
| `passwords do not match` (from `middleware password set`) | The two no-echo prompts disagreed. | Re-run. |\r
| `--interval requires --follow` / `--interval requires --watch` / `--timeout requires --watch` | Polling cadence flags set without their gate flag. | Add `-f` / `-w`, or drop the offending flag. |\r
| `decode ... response: ...` | Endpoint returned something we couldn't parse. | Re-run with `-o json` to see the raw shape. May indicate a server-side schema change. |\r
| `refresh token for ... became invalid at ...` (typed `*credential.ErrTokenInvalidated`) | The refresh_token itself is dead — auto-refresh can't recover. | `olares-cli profile login`. See [`olares-shared`](../olares-shared/SKILL.md). |\r
\r
For the full auth-error matrix (`no access token for \x3Cid>`, `already authenticated`, `two-factor authentication required`, etc.) see [`olares-shared`](../olares-shared/SKILL.md).\r
\r
## What's NOT here yet\r
\r
| Want to ... | Status |\r
|---|---|\r
| Resolve `valueFrom` env refs to actual ConfigMap / Secret values | Not yet — `container env` shows the reference (`secretKey foo/k`) but does not GET the target. Future `--resolve` flag. |\r
| Enumerate `envFrom` (implicit configMapRef / secretRef sets) | Not yet — only explicit `env: [...]` declarations are listed. |\r
| Bulk verbs (e.g. `pod delete --all -l X`, `workload delete --all`) | Not yet — pattern from `workload restart` (bounded concurrency + `ConfirmDestructive` showing the count) would slot straight in. |\r
| `cronjob trigger-now` — fire a CronJob's job template once on demand | Not yet — the SPA has no dedicated endpoint; would need to clone `spec.jobTemplate` into a fresh Job ourselves. |\r
\r
## Source layout (developer orientation)\r
\r
For agents this is reference material, not a routing aid; skim only when modifying the verb implementation.\r
\r
- [`cli/cmd/ctl/cluster/internal/clusteropts/`](cli/cmd/ctl/cluster/internal/clusteropts) — shared `ClusterOptions` (output flags + `Prepare()` factory), `ConfirmDestructive`, `SplitNsName`, `Age` / `DashIfEmpty`, `JSONToYAML`, `SleepContext`, `PaginationOptions` + `FetchAllKubeSphere`, and the unified `Event` type + `RenderEventsTable` + `EventsListPath` shared across `pod` / `job` / `application` events.\r
- [`cli/cmd/ctl/cluster/{pod,container,workload,application,namespace,node,job,cronjob,middleware}/`](cli/cmd/ctl/cluster) — one package per noun. Cross-package exports: `pod.RunList` / `pod.RunLogs` / `pod.RunDelete` / `pod.Get`, `job.Get`, `cronjob.Get`, `workload.RunScale` / `RunList` / `NormalizeKind`. Wrapper verbs (`application pods` / `application workloads`, `job pods`, `cronjob jobs`, `container logs`) reuse those exports rather than re-implementing the wire calls.\r
- [`cli/pkg/clusterclient/`](cli/pkg/clusterclient) — `Client`, `DoJSON`, `DoJSONWithContentType`, `DoRaw`, plus envelope decoders: `GetKubeSphereList[T]` (`/kapis/*` `{items, totalItems}`), `GetK8sList[T]` / `GetK8sObject` (`/api/v1/*`, `/apis/*` native), `GetRaw` (raw bytes for logs / yaml), `Patch[T]`. Per-call typed structs live in each verb's `types.go` — we do NOT vendor `k8s.io/api`.\r
- [`cli/pkg/clusterctx/`](cli/pkg/clusterctx) — `cluster context` business logic; mirrors [`cli/pkg/whoami`](cli/pkg/whoami).\r
- [`cli/pkg/credential/default_provider.go`](cli/pkg/credential/default_provider.go), [`cli/pkg/olares/id.go`](cli/pkg/olares/id.go) — `ResolvedProfile.ControlHubURL` derivation from OlaresID.\r
\r
## See also\r
\r
- [`olares-shared`](../olares-shared/SKILL.md) — profile model, login, automatic token refresh, full auth-error recovery table. **Read this one first.**\r
- [`olares-market`](../olares-market/SKILL.md) — Olares app lifecycle (install / uninstall / upgrade / start / stop / cancel / clone).\r
- [`olares-settings`](../olares-settings/SKILL.md) — settings UI mirror (users, appearance, vpn, network, gpu, video, search, backup, restore, advanced, integration, apps).\r
- [`olares-files`](../olares-files/SKILL.md) — drive / sync file browser.\r
- [`olares-dashboard`](../olares-dashboard/SKILL.md) — dashboard SPA proxy.\r
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install olares-cluster - 安装完成后,直接呼叫该 Skill 的名称或使用
/olares-cluster触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
Olares Cluster (olares-cli cluster) 是什么?
Per-user Kubernetes view of an Olares cluster via olares-cli cluster — the ControlHub-backed CLI mirror of what the active Olares profile is allowed to see.... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 37 次。
如何安装 Olares Cluster (olares-cli cluster)?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install olares-cluster」即可一键安装,无需额外配置。
Olares Cluster (olares-cli cluster) 是免费的吗?
是的,Olares Cluster (olares-cli cluster) 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。
Olares Cluster (olares-cli cluster) 支持哪些平台?
Olares Cluster (olares-cli cluster) 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 Olares Cluster (olares-cli cluster)?
由 Peng Peng(@pengpeng)开发并维护,当前版本 v0.5.0。