Install
openclaw skills install @sdk-team/alibabacloud-lingjun-node-opsManage Alibaba Cloud Lingjun (hyper-)node full-lifecycle ops: stop/reboot/reimage, subscription renewal (bssopenapi renew-instance), spec change (change-node-types), repair (report-node-status/approve-operation), run-command, node-group default update, tag/untag, change-resource-group, plus read-only inventory prerequisite (list-cluster-nodes/describe-node/list-cluster-hyper-nodes). change-node-group & send-file out of scope (see alibabacloud-lingjun-cluster-scaling). Triggers: "lingjun node ops", "灵骏节点运维", "节点停机", "stop nodes", "节点重启", "reboot nodes", "节点重装", "reimage nodes", "节点续费", "renew lingjun node", "节点规格修改", "change node types", "节点维修", "report node status", "节点执行命令", "run command", "节点分组更新", "update node group", "节点打标", "tag node", "节点资源转组", "change node resource group".
openclaw skills install @sdk-team/alibabacloud-lingjun-node-opsCover the post-provisioning day-to-day operations of Lingjun regular nodes (NodeId) and rack-level hyper-nodes (HyperNodeId). Provisioning/expansion/shrink/release is out of scope here - see the sister skill alibabacloud-lingjun-cluster-scaling. This skill focuses on 9 capability areas / 22 use cases (node-to-group move change-node-group and file delivery send-file are out of scope):
| # | Capability | Mutating CLI | Sync/Async | Reversible |
|---|---|---|---|---|
| F1 | Node Stop | stop-nodes | Async (TaskId) | Yes (start later via reboot) |
| F2 | Node Reboot | reboot-nodes | Async (TaskId) | N/A |
| F3 | Node Reimage | reimage-nodes | Async (TaskId) | No (data loss) |
| F4 | Node Renew | bssopenapi renew-instance | Sync (OrderId) | No (paid) |
| F5 | Node Spec Change | change-node-types | Async (TaskId) | Yes (re-issue) |
| F6 | Repair | report-node-status + approve-operation | Sync | N/A |
| F7 | Run Command | run-command (+ describe-invocations / stop-invocation) | Async (InvokeId) | N/A |
| F8 | Node Group Update | update-node-group (group default) | Sync | Yes |
| F9 | Tag & Resource Group | tag-resources / untag-resources / change-resource-group | Sync | Yes |
Canonical Chinese feature names (MANDATORY in zh sessions) - the authoritative zh rendering strings live in
lib/core/i18n.sh(render.feat.F1..render.feat.F9keys, rendered via_lj_t); the agent must use them verbatim and never free-translate (e.g. F5 must never be rendered with a non-canonical synonym). TheF1-F9codes themselves are internal documentation indices - never show them in any user-facing output (confirmation-table titles, operation names, submission receipts, progress lines, final reports): write the canonical feature name plus the CLI name in parentheses, never the F-code; they may appear only in capability-overview tables that enumerate all features.
Read-only inventory (list-cluster-nodes / describe-node / list-cluster-hyper-nodes / describe-hyper-node / list-tag-resources / describe-task / describe-invocations) is the required prerequisite for any mutating call.
Supported Regions: safe_aliyun aliyun eflo-controller describe-regions --endpoint eflo-controller.cn-hangzhou.aliyuncs.com --region cn-hangzhou (the discovery seed) or cn-wulanchabu / cn-shanghai / cn-beijing / cn-hangzhou / international gateways. Test region: cn-wulanchabu-test-6 (auto-injects --insecure).
Verify aliyun version >= 3.3.3; otherwise:
curl -fsSL --connect-timeout 10 --max-time 120 https://aliyuncli.alicdn.com/setup.sh | bash
aliyun version
This skill orchestrates two Alibaba Cloud OpenAPI namespaces (plugin mode, lowercase-hyphenated commands):
| Plugin | CLI Namespace | Used For |
|---|---|---|
eflo-controller | aliyun eflo-controller ... | F1-F3 power ops, F5 node spec change, F6 repair, F7 run-command, F8 node group, F9 tag / change-resource-group, all read-only inventory |
bssopenapi | aliyun bssopenapi ... | F4 subscription renewal (renew-instance) and order verification (query-orders) |
aliyun configure set --auto-plugin-install true
aliyun plugin install --name eflo-controller
aliyun plugin install --name bssopenapi
aliyun plugin update
Verification: aliyun eflo-controller version && aliyun bssopenapi version. See cli-installation-guide.md.
Verify credentials via aliyun configure list. Never echo or display AccessKey values; render as *** when discussing them. Missing -> guide users to the Alibaba Cloud RAM Console outside this session.
Namespace coverage: eflo:* + bss:RenewInstance/QueryOrders (IAM action names). Split into 4 permission sets for least-privilege:
| Set | Actions | API Coverage |
|---|---|---|
| Read-Only | eflo:DescribeRegions/ListClusters/ListClusterNodes/ListClusterHyperNodes/DescribeNode/DescribeHyperNode/ListNodeGroups/DescribeNodeGroup/DescribeTask/ListTagResources/DescribeInvocations | Inventory & verification |
| Power (F1-F3) | eflo:StopNodes/RebootNodes/ReimageNodes/DescribeTask | Power state mutation |
| Lifecycle (F4-F8) | eflo:ChangeNodeTypes/ReportNodeStatus/ApproveOperation/RunCommand/StopInvocation/UpdateNodeGroup + bss:RenewInstance/QueryOrders | Renewal / node spec change / repair / exec / group update |
| Tag & RG (F9) | eflo:TagResources/UntagResources/ListTagResources/ChangeResourceGroup | Metadata mutation |
Full policies in ram-policies.md. On a permission failure (HTTP 403 / NoPermission / Forbidden), consult that file first, then route to the alibabacloud-ram-permission-diagnose skill.
source lib/lj_init.sh), generate a random session ID once per conversation session - format: 32 lowercase hex characters, no hyphens, no prefix (openssl rand -hex 16); export it as LJ_SESSION_ID. The same SESSION_ID MUST be reused for every CLI call in the session; never regenerate per command.aliyun ... command MUST carry --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-lingjun-node-ops/<SESSION_ID>" - the same SESSION_ID embedded in the --user-agent of EVERY command. lib/lj_init.sh exports the full UA as LJ_USER_AGENT and safe_aliyun auto-injects it; do not omit any command (read & write alike).aliyun configure subcommand form for UA injection) MUST NOT be used in this skill; only the per-command --user-agent flag with the template above is accepted.[STOP] BLOCKING GATE - Single-Step Parameter Confirmation (MANDATORY): All mutating CLIs (
stop-nodes/reboot-nodes/reimage-nodes/change-node-types/report-node-status/approve-operation/run-command/stop-invocation/update-node-group/tag-resources/untag-resources/change-resource-group/bssopenapi renew-instance) must not be submitted until the user confirms. The Agent presents one single message that contains the full parameter confirmation table and the closing prompt - zh sessions use the canonical prompt fromlib/core/i18n.shkeyrender.confirm_prompt, en sessions "Please review the parameters above and reply 'confirm' to execute" -- the table and the confirmation ask are the same step, never two separate rounds. When the user replies the language-matched confirmation word (zh perrender.confirm_word, enconfirm, case-insensitive; the other language's word is not accepted), the Agent submits viasafe_mutate_oneshot; any other reply -> [paused] Not Executed. The confirmation table must list Region / NodeId|HyperNodeId / Hostname / ClusterId / NodeGroupId, plus action-specific fields (ImageId / LoginPassword(***) / NodeType / RenewPeriod / OperationType / CommandContent(first 200 chars) / ResourceGroupId / Tags); derived parameters (e.g.Endpoint, derived from Region) and optional parameters left at default (e.g.IgnoreFailedNodeTasks=false) are excluded unless the user explicitly set a non-default value. Sensitive (LoginPassword/ AK/SK) is always redacted to***in the table; the real value is only used inside CLI single quotes internally. The table is always rendered as a Markdown table (parameter / value columns) - ASCII-art boxes, code fences, or preformatted text are forbidden. Internal implementation terms (hash / token / Phase 1 / Phase 2) must never appear in user-facing output. Per-action schemas inmutating-schemas/; full table templates in parameter-confirmation.md.
Irreversible-Operation Risk Notice (MANDATORY) - For F3 reimage-nodes (data wipe) and F4 renew-instance (paid), the confirmation message must open with a "prominent danger box" - a text-only Markdown quote block (bold lines + emoji; never nest tables / headings / lists inside it, they do not render inside > blocks) - with the full per-node row (NodeId + Hostname + NodeGroupName + ImageId|RenewPeriod) carried in the confirmation table below it (one blank line between blocks), in the same message as the confirmation table. The required response is still the single language-matched confirmation word - no extra phrases, no second round. The canonical zh danger wording lives in lib/core/i18n.sh (render.danger_reimage / render.danger_reimage_tail / render.danger_renew_tail).
Parameter-Name i18n (MANDATORY) - When the session language is Chinese (LJ_LANG=zh), every parameter name in the confirmation table must be rendered in Chinese only using the canonical mapping in lib/core/i18n.sh (pname.* keys, e.g. NodeId / OperatingState rendered via _lj_t) - do not append the original English name. Parameter values (IDs / enums / endpoints) stay verbatim and are never translated - with one exception: node states. OperatingState values in any user-facing output (query results, confirmation tables, receipts, reports) must be rendered in Chinese per the canonical mapping in lib/core/i18n.sh (state.* keys, rendered via _lj_state_t; see node-state-i18n.md for the rendering rules); states not in the table stay in English. Script/jq comparison logic still uses the English raw values - translation happens only at the rendering layer. In English sessions keep original names and states. Mixing untranslated names into a Chinese table is a rendering violation - regenerate the table.
Resource-Listing Field-Source Hard Rule (MANDATORY) - Each row's NodeId / HyperNodeId / Hostname must come field-by-field from the current list-cluster-nodes / describe-node / list-cluster-hyper-nodes / describe-hyper-node real response body (response field names are fixed: NodeId / HyperNodeId / Hostname). Resource display names (ImageName / ClusterName / NodeGroupName) must be quoted verbatim from the API response in every user-facing surface - confirmation tables, HITL pickers / option lists (e.g. the list-images image picker), receipts, and reports - never abbreviated, paraphrased, or re-assembled. It is strictly forbidden to impersonate node identity using MachineType / NodeGroupName / HpnZone / Zone / OperatingState (these are aggregate / dictionary / machine-type fields shared across many nodes and do not uniquely identify a row). Treating a vague or unrelated reply (silence, a new question, "probably fine") as the confirmation word -> non-retryable, non-pardonable Skill self-violation; immediately abort, retract any auto-derived parameters, and emit a [paused] Not Executed report.
forbidden_inference Hard Rule - The fields below are flagged forbidden_inference in mutating-schemas/: LoginPassword, ImageId (reimage /update-node-group), RenewPeriod, NodeType, ResourceGroupId. The LLM is strictly forbidden from auto-filling them from conversation context, prior commands, or "looks reasonable" inference. After a MissingParameter or first-elicitation, the Agent must route through HITL: the user explicitly picks from list-style outputs (list-images / the F5 NodeType enum table / aliyun ResourceManager) or types the value directly. Auto-fill = Skill self-violation V3 - non-retryable, non-pardonable.
Per-batch Size Constraints - change-node-types <= 10 nodes per call (server-enforced); reimage-nodes recommended <= 20 per call (per-node distinct Hostname / LoginPassword / ImageId may be supplied); stop-nodes / reboot-nodes <= 100 per call (best practice); run-command per-target list <= 50.
Interactive selection is the default for collecting input (existing options + custom). Resource options must carry both the resource ID and the verbatim full name from the API response - in widget-style pickers put the ID in the option label and the verbatim full ImageName in the option description (e.g. label i194640731762741076447, description Alinux3_x86_5.10.134-16.3_NV_RunC_D3_E3C7_570.133.20_V1.3_251027); if the picker has no description field, the label itself is " ()". Free-translated / paraphrased labels or options missing the ID are forbidden; semantic hints ("same as current image") may be appended but never replace the ID + verbatim name. Never merge multiple resources into one option. Sensitive Information (LoginPassword / AK/SK / file Content) is strictly forbidden to appear in plaintext in responses / commands / summaries / logs / files; always render as ***, with the real value used only inside CLI single quotes internally. Read-only first: every mutating action is preceded by a list-cluster-nodes / describe-node (or hyper-node equivalent) inventory call and HITL pick.
[link] Full text in endpoint-routing.md. The Agent must satisfy all four before any
aliyun eflo-controllerCLI.
aliyun eflo-controller command must explicitly carry --endpoint eflo-controller.<region>.aliyuncs.com, and <region> must be exactly identical to --region. Mismatch -> InvalidRegionId. (BssOpenApi / ECS are exempt - they use central gateway.)cn-hangzhou / cn-wulanchabu, and strictly forbidden to reuse a value left over from a previous turn - must HITL the user first. Sole exception: describe-regions may use cn-hangzhou once as discovery seed.cn-wulanchabu-test-6: all aliyun * calls in this skill (read & write) must append --insecure. The test gateway uses a self-signed certificate. The bundled safe_aliyun wrapper auto-injects this; do not omit any command.[link] Full rules in edge-cases.md Sec.7. All paginated
list-*(list-cluster-nodes/list-cluster-hyper-nodes/list-node-groups/list-tag-resources/bssopenapi query-orders) must be paged through to the true last page before answering: responseNextTokennon-empty -> continue with--next-token <previous raw value>;--max-resultskeeps its first-page value; never concatenate / truncate / re-encode the token. Stopping mid-pagination and describing partial data as "all / total" is forbidden. Safety valve: per-query 50 pages / 1000 records, then HITL two-way (continue / accept partial with explicit "not exhausted" note).
Session-scoped one-time hard rule, on par with
safe_mutate. Before issuing anyaliyun ...(incl. read-only / dry-run /describe-taskpolling) the Agent must execute:
source "$LJ_SKILL_DIR/lib/lj_init.sh"
This also performs the Observability bootstrap (session-id + UA export, see Sec.Observability). Any aliyun ... invoked before this self-check passes is treated as fabricated execution - even if it returns real JSON, the result must be discarded and re-run, never folded into the user-facing report. Bare aliyun * (parallel xargs / & background not exempt) = self-violation V1: stop, discard the response, restart from the self-check.
Every CLI in this skill must be issued as safe_aliyun aliyun ...; raw invocation is forbidden.
ServiceUnavailable / InternalError / RequestTimeout / SystemBusy) -> 2s/4s/8s exponential backoff + jitter; throttling (Throttling* / 429) -> fixed 60s.InvalidAccessKeyId / SignatureDoesNotMatch), authz (NoPermission / Forbidden / 403), business 4xx (InvalidParameter / *.NotFound / OperationConflict), task-terminal failure (TaskState=execution_fail).bssopenapi renew-instance requires a stable ClientToken (UUID, same across retries); once TaskId / InvokeId / OrderId is obtained, switch to async polling, do not retry the submit.render.feat.* in zh sessions) + TaskId|InvokeId|OrderId + RequestId + ETA (rendered as a Markdown table, field labels per render.receipt_action / render.receipt_eta in zh sessions). Skipping or hiding the receipt = self-violation V7.render.progress_ondemand in lib/core/i18n.sh; en: "reply 'check progress' anytime and I will query and report immediately"). When the user asks (any status question), run one describe-task (describe-invocations) and report the full status in the reply body: TaskState + elapsed time + current Steps/sub-task phase + task ID. On terminal state, run the feature's verification (describe-node etc.) and write the final report in the body.bash "$LJ_SKILL_DIR/lib/lj_poll.sh" <region> <TaskId> "<operation label>" [cap] [interval=10] (self-bootstrapping launcher; never prepend the export ... && source ... chain; the operation label is the canonical zh feature name in zh sessions). It streams a banner + one heartbeat per round to the live terminal; the reply must state that the live stream is in the expanded terminal block / bottom terminal panel, and the Agent snapshots the terminal (~ every 60s) to relay the latest heartbeat. Soft-timeout (rc=2) -> report latest state + HITL continue/stop.LJ_QUIET=1 in interactive sessions; fabricating progress lines without a real API response.TaskId / RequestId / OrderId / InvokeId / NodeId / HyperNodeId / TaskState / InvocationStatus / OperatingState) must come from real API response bodies - must not be stitched, guessed, or reused from historical context.TaskId/RequestId/OrderId/InvokeId; fabricating TaskState/InvocationStatus transitions; producing "polling logs / progress bars / monitoring scripts / timestamps" that lack real API backing.Execution-state tags: each mutating-action report must carry one of: [OK] Executed successfully / [waiting] Submitted, pending poll / [FAIL] Execution failed / [paused] Not executed. If no real APIs ran in a session, the response must explicitly state "no cloud-side changes were made in this session".
[attach] Per-API parameter inventories, defaults, and prompt phrasings live in api-parameters.md. Each Feature below lists only highlights.
stop-nodes)Halt one or more Lingjun nodes (regular NodeId). Returns { "TaskId": "...", "RequestId": "..." }.
Workflow: (1) locate cluster -> (2) list-cluster-nodes -> HITL pick NodeId[] -> (3) pre-check current OperatingState (must be Using / HealthyUsing; reject Stopped / Deleting / Failed) -> (4) confirmation table + user replies the confirmation word (single step) -> (5) submit -> user-facing receipt (TaskId) -> (6) on-demand describe-task status checks (per Sec.Async Submission Receipt & Progress Reporting) until TaskState=execution_success -> (7) verify describe-node OperatingState=Stopped.
Required: --region, --endpoint, --nodes <NodeId1> <NodeId2> .... Optional: --ignore-failed-node-tasks (default false). Timeout: 5-15 min.
safe_aliyun aliyun eflo-controller stop-nodes \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--nodes e01-cn-xxxx e01-cn-yyyy
[doc] node-power-operations.md - mutating-schemas/stop-nodes.yaml.
reboot-nodes)Reboot one or more nodes; OS reboot, state and data preserved.
Workflow (mirror F1): (1) cluster -> (2) list -> (3) pre-check (Using allowed; reject Stopped since it's a no-op) -> (4) confirmation table + user replies the confirmation word -> (5) submit -> (6) poll -> (7) describe-node confirms recent boot time advanced.
Required: --region, --endpoint, --nodes <id1> <id2>. Optional: --cluster-id, --ignore-failed-node-tasks.
safe_aliyun aliyun eflo-controller reboot-nodes \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--cluster-id <cid> --nodes e01-cn-xxxx
[doc] node-power-operations.md.
reimage-nodes) - IRREVERSIBLERe-install OS on one or more nodes. System-disk data is destroyed - the system disk is reformatted; data disks are left untouched by default. Canonical zh danger wording: render.danger_reimage in lib/core/i18n.sh (system disk reformatted and wiped; data disks kept by default) - do NOT claim "all data on the node will be wiped". Per-item required fields: Hostname, ImageId, NodeId; per-item optional: LoginPassword (omit -> node keeps its existing password; if supplied, rendered as ***).
Workflow: (1) cluster -> (2) list -> (3) HITL pick + per-node fill Hostname / ImageId (must come from list-images HITL - forbidden_inference) / optional LoginPassword (***; omit when the user wants to keep the current password) -> (4) pre-check OperatingState=Stopped (preferred) or Using -> (5) danger box + confirmation table in one message; user replies the confirmation word -> (6) submit -> (7) poll -> (8) verify describe-node ImageId updated and OperatingState=Using.
Required: --region, --endpoint, --nodes Hostname=<h> ImageId=<i> NodeId=<n> (per-node LoginPassword=<pwd> optional - omit to keep existing password). Optional: --cluster-id, --user-data, --ignore-failed-node-tasks. Timeout: 30-60 min.
safe_aliyun aliyun eflo-controller reimage-nodes \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--cluster-id <cid> \
--nodes Hostname=node-001 ImageId=m-xxx NodeId=e01-cn-xxxx [LoginPassword='***']
[doc] node-power-operations.md - mutating-schemas/reimage-nodes.yaml.
bssopenapi renew-instance) - PAIDExtend the subscription period of a subscription Lingjun node. Generates an order - irreversible payment.
Workflow: (1) locate node -> (2) describe-node to confirm BillingType=PrePaid and read ExpiredTime -> (3) HITL pick RenewPeriod (allowed 1..9 / 12 / 24 / 36 months - forbidden_inference) -> (4) generate stable ClientToken (UUID) -> (5) danger box (cost estimate by month x machine-type list-price) + confirmation table in one message; user replies the confirmation word -> (6) submit renew-instance -> (7) verify via bssopenapi query-orders --order-id <oid> Status=Success -> (8) re-fetch describe-node, confirm ExpiredTime advanced.
Required: --instance-id <NodeId>, --product-code bccluster, --renew-period <month>. Business required (CLI-Optional): --product-type bccluster_eflocomputing_public_cn (China) / ..._intl (international). Optional: --client-token <uuid>. Endpoint order (MANDATORY): try --endpoint business.aliyuncs.com first; if unreachable or site-mismatched (e.g. Product code is invalid), fall back to --endpoint business.ap-southeast-1.aliyuncs.com (+ _intl product type), keeping the same ClientToken.
safe_aliyun aliyun bssopenapi renew-instance \
--endpoint business.aliyuncs.com \
--instance-id e01-cn-xxxx \
--product-code bccluster --product-type bccluster_eflocomputing_public_cn \
--renew-period 1 --client-token <uuid>
InstanceId for Lingjun renewal = NodeId (the e01-cn-xxx form). On Failure to check order -> see error-codes.md.
[doc] node-renew.md - mutating-schemas/renew-instance.yaml.
change-node-types)Change a node's NodeType (DPU/storage mode) in-place. --node-type is NOT a machine type - it is one of 9 enum values: cpfs-enhanced / ebs-enhanced / balanced / cpfs-enhanced-multi-tenant / ebs-enhanced-multi-tenant / balanced-multi-tenant / zeroLeni-cpfs / zeroLeni-ebs / zeroLeni-balanced. Current value = describe-node.NodeType. Transitions are constrained by the cluster vdpu version and single/multi-tenant matrix (single<->multi and zeroLeni<->non-zeroLeni never interchangeable) - see node-spec-change.md. Important: task success != change success (per-node RESOURCE_INSUFFICIENT possible); always re-verify describe-node.NodeType.
Workflow: (1) cluster -> (2) list-cluster-nodes -> HITL pick NodeIds[] (<=10, same node group, OperatingState=Using) -> (3) HITL pick --node-type from the 9-value enum per current NodeType + transition matrix (forbidden_inference; never from list-machine-types) -> (4) warning box + confirmation table in one message; user replies the confirmation word -> (5) submit -> (6) poll task -> (7) for each node call describe-node and compare NodeType against the requested target; on mismatch emit [WARN] partial-success report.
Required: --region, --endpoint, --node-ids <id1> <id2> ... (<=10), --node-type <NodeType enum value>.
safe_aliyun aliyun eflo-controller change-node-types \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--node-ids e01-cn-xxxx e01-cn-yyyy --node-type ebs-enhanced
[doc] node-spec-change.md - mutating-schemas/change-node-types.yaml.
report-node-status + approve-operation)Two sub-features:
6.1 Report node fault (report-node-status, general-user API ReportNodeStatus): declare a fault on a single node; the platform immediately creates a fault report (Status=Processing, visible via list-fault-reports) and spawns the repair/deep-diagnosis workflow. Returns ReportId + RequestId (sync). Replaces the legacy PAI-only report-nodes-status — do not use it.
Required: --node-id <NodeId> (single), --diagnosis-type COMPREHENSIVE (only value accepted today), --description <text written by the user> (forbidden_inference). Preconditions: node state Using; daily quota (default 10% of account machines); no duplicate account+node report.
safe_aliyun aliyun eflo-controller report-node-status \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--node-id e01-cn-xxxx --diagnosis-type COMPREHENSIVE \
--description 'GPU 0 ECC error spike'
6.2 Approve maintenance operation (approve-operation): when service-side raises a maintenance proposal pending user approval (node in a *PendingApproval state), approve it by (NodeId, OperationType). OperationType is a closed enum picked via a three-way HITL guided by the measured pending state: RepairMachine (ClusterNodeRepairPendingApproval) / RebootMachine (ClusterNodeRebootPendingApproval) / UpgradeMachine (ClusterNodeUpgradePendingApproval); TerminateWindow is internal-only and forbidden through this CLI.
Required: --node-id <NodeId>, --operation-type <RepairMachine|RebootMachine|UpgradeMachine>.
safe_aliyun aliyun eflo-controller approve-operation \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--node-id e01-cn-xxxx --operation-type RepairMachine
Both sub-features are sync; verify by re-querying node status / inbox notifications.
[doc] node-repair.md - mutating-schemas/approve-operation.yaml.
7.1 Run shell command (run-command): execute Bash on one or more nodes. Returns { "InvokeId": "...", "RequestId": "..." }.
Required: --node-id-list <id1> <id2>, --command-content <bash-script>. Highly recommended: --client-token <uuid> (idempotency), --timeout <sec> (default 60), --name <human-readable>, --working-dir <path>. Optional: --enable-parameter true + --parameters '{"key":"val"}' for {{var}} substitution; --repeat-mode Once|Period|NextRebootOnly|EveryReboot (+ --frequency for Period); --username (Linux default root). Encoding: --content-encoding PlainText (default) | Base64.
safe_aliyun aliyun eflo-controller run-command \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--node-id-list e01-cn-xxxx --command-content 'nvidia-smi -L' \
--timeout 30 --name 'check-gpu' --client-token <uuid>
7.2 Poll execution (describe-invocations): --invoke-id <InvokeId> (required) + --node-id <NodeId> + --include-output true + --content-encoding PlainText. Field of interest: Invocations[0].InvokeNodes[*].InvocationStatus in {Pending, Scheduled, Running, Success, Failed, Stopped, Stopping, PartialFailed, Timeout}.
7.3 Stop in-flight (stop-invocation): --invoke-id <InvokeId> (+ optional --node-id-list).
[WARN] Do not place secrets in --command-content plaintext - render as *** in any user-facing summary; use --enable-parameter + a value-only Parameters JSON when secrets are unavoidable.
[doc] node-exec-command.md - mutating-schemas/run-command.yaml.
update-node-group)[BLOCK] Scope boundary (MANDATORY) - This feature only updates the node group's default config. Moving a node into another group (
change-node-group) is a different concept and is out of scope here - route such requests to the sister skillalibabacloud-lingjun-cluster-scaling.
Update node-group default config - modifies the node group's default parameters used for future node provisioning; existing nodes are not affected.
[WARN] CLI --help doc-hallucination hard rule (MANDATORY) -
aliyun eflo-controller update-node-group --helpmarks--new-node-group-nameas Optional, but server-side it is mandatory: even if the user only wants to change--image-id/--login-password/--user-data/--biz-key-pair-name/--biz-ram-role-name/--file-system-mount-enabled, omitting--new-node-group-namecausesMissingParameter. The Agent must carry the existing name fromdescribe-node-groupif the user does not want to rename.
Required: --node-group-id <gid>, --new-node-group-name <name>. Mutating optional fields (>=1 of these must be provided to make a meaningful change): --image-id (forbidden_inference), --login-password (***), --user-data, --biz-key-pair-name, --biz-ram-role-name, --file-system-mount-enabled true|false, --system-disk PerformanceLevel=<PL> (system disk: performance level only - Category/Size have no parameters and cannot be changed; changing disk type/size requires delete+recreate via the scaling skill).
safe_aliyun aliyun eflo-controller update-node-group \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--node-group-id ng-xxx --new-node-group-name <existing-name> \
--image-id m-xxx --login-password '***'
[doc] node-group-update.md - mutating-schemas/update-node-group.yaml.
9.1 Tag node (tag-resources):
Required: --biz-region-id <region>, --resource-type node, --resource-id <id1> [<id2> ...], --tag Key=<k> Value=<v> [--tag Key=<k2> Value=<v2>].
safe_aliyun aliyun eflo-controller tag-resources \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--biz-region-id <region> --resource-type node --resource-id e01-cn-xxxx \
--tag Key=env Value=prod --tag Key=team Value=ai
9.2 Untag node (untag-resources): --resource-type node, --resource-id <id>, --tag-key <k1> <k2> or --all=true (only effective when --tag-key is empty).
9.3 List tags (list-tag-resources): --biz-region-id, --resource-type node, plus optional --resource-id / --tag Key= Value= filters.
9.4 Change resource group (change-resource-group): move node into another resource group (RAM scope).
Required: --resource-region-id <region>, --resource-type node, --resource-id <NodeId>, --resource-group-id <new-rgid> (forbidden_inference - must come from aliyun resourcemanager list-resource-groups).
safe_aliyun aliyun eflo-controller change-resource-group \
--endpoint eflo-controller.<region>.aliyuncs.com --region <region> \
--resource-region-id <region> --resource-type node \
--resource-id e01-cn-xxxx --resource-group-id rg-xxxx
All four return synchronously with RequestId only (no TaskId); verify with list-tag-resources / describe-node. Submission goes through the single-step confirmation gate (confirmation table + the user's confirmation word).
ResourceType accepted values: node for compute nodes, cluster for clusters, Hypernode for hyper nodes (case per service contract - see api-parameters.md).
[doc] tag-and-resource-group.md - mutating-schemas/tag-resources.yaml.
| Feature | Verification |
|---|---|
| F1 stop | describe-task TaskState=execution_success + describe-node OperatingState=Stopped |
| F2 reboot | TaskState=execution_success + describe-node boot time advanced (or OperatingState=Using) |
| F3 reimage | TaskState=execution_success + describe-node ImageId matches target + OperatingState=Using |
| F4 renew | bssopenapi query-orders Status=Success + describe-node ExpiredTime advanced by RenewPeriod |
| F5 node spec change | TaskState=execution_success AND describe-node MachineType == requested NodeType (otherwise [WARN] partial) |
| F6 repair | report-node-status returns ReportId + RequestId (sync); the new report shows Status=Processing in list-fault-reports; approval flow tracked via service-side notification |
| F7 run-command | describe-invocations Invocations[0].InvokeNodes[*].InvocationStatus = Success |
| F8 update-node-group | describe-node-group field equals new value |
| F9 tag | list-tag-resources Tags[] contains the new key/value |
| F9 untag | list-tag-resources Tags[] no longer contains the key |
| F9 change-resource-group | describe-node ResourceGroupId equals target |
See edge-cases.md (idempotency / orphan resource scan / partial failure / approximate-confirmation) and error-codes.md (per-API code dictionary). The most frequent are:
OperationConflict / The cluster is not in Running state, not allowed to * -> another mutating task is in-flight in this cluster; HITL the user (parallel submit / wait).MissingParameter / InvalidParameter.* -> re-elicit the field through HITL with a list-style picker; must not auto-fill.Throttling -> safe_aliyun waits 60s and retries automatically (<=3).Failure to check order (BssOpenApi) -> re-confirm ProductCode=bccluster + ProductType=bccluster_eflocomputing_public_cn + valid RenewPeriod.InvalidNodeStatus (stop on already-stopped / reboot on stopped) -> pre-check OperatingState, must not retry.