Skip to main content

validate-platform-config

Validate whether a provisioned platform is correctly configured when run locally on that host, including k3s pod health, binary paths, cloud-init state, network and proxy setup, and device readiness.

Source facts

Repository
open-edge-platform/edge-node-infrastructure-blueprint
Last source activity
August 31, 2026 at 10:32
Detected SKILL.md language
English
Stars
1
Forks
9

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
validate-platform-config
description
Validate whether a provisioned platform is correctly configured when run locally on that host, including k3s pod health, binary paths, cloud-init state, network and proxy setup, and device readiness.
## Trigger Phrases - validate platform config - validate provisioned host - check provisioned node health - validate k3s platform readiness - post provision local validation - host health check ## Required Inputs - enib_home: absolute path to this repository root (default: current workspace root) - kubeconfig_path: expected kubeconfig path (default: `/etc/rancher/k3s/k3s.yaml`) ## Preconditions Run silently without user prompts: - [ ] Skill file exists and is readable: - `test -f <enib_home>/skills/validate-platform-config/SKILL.md` - [ ] Verify this skill is running on the provisioned host (local execution model): - `test -f /etc/cloud/config-file` - [ ] Required local tools exist: - `command -v grep` - `command -v ip` - `command -v systemctl` - `command -v lscpu` - `command -v lspci` - `command -v curl` - [ ] Probe sudo non-interactively before any sudo fallback command: - `sudo -n true` - if exit code is `0`, record `SUDO_NONINTERACTIVE=yes` - if non-zero, record `SUDO_NONINTERACTIVE=no` and skip sudo fallback commands later (do not fail preconditions) Prompt only for missing required inputs: - [ ] Ask only for missing `enib_home` and/or `kubeconfig_path`. ## Steps 1. Detect the `host_type` from local configuration. - command: - `grep -E '^host_type' /etc/cloud/config-file 2>/dev/null || echo 'host_type=unknown'` - parse the output to extract the value (e.g. `kubernetes`, `container`, or `unknown`) - store as `HOST_TYPE` for conditional branching in Steps 2 and 3 2. **If HOST_TYPE=kubernetes**: Validate k3s pods and device plugins. - command (try in order until one succeeds): - `kubectl get pods -A --no-headers` - `KUBECONFIG=~/.kube/config kubectl get pods -A --no-headers` - if `SUDO_NONINTERACTIVE=yes`: `sudo -n kubectl get pods -A --no-headers` - if `SUDO_NONINTERACTIVE=yes`: `sudo -n k3s kubectl get pods -A --no-headers` - required pod name prefixes and expected status: - `intel-gpu-plugin` in `default` namespace, `Running`, `READY 1/1` - `intel-npu-plugin` in `default` namespace, `Running`, `READY 1/1` - `coredns` in `kube-system`, `Running`, `READY 1/1` - `local-path-provisioner` in `kube-system`, `Running`, `READY 1/1` - `metrics-server` in `kube-system`, `Running`, `READY 1/1` - `nfd-gc` in `node-feature-discovery`, `Running`, `READY 1/1` - `nfd-master` in `node-feature-discovery`, `Running`, `READY 1/1` - `nfd-worker` in `node-feature-discovery`, `Running`, `READY 1/1` - also validate binaries: - `command -v kubectl` - `command -v k3s` - `ls -l /usr/local/bin/kubectl /usr/local/bin/k3s 2>/dev/null || true` - `systemctl is-enabled k3s 2>/dev/null || true` - `systemctl is-active k3s 2>/dev/null || true` - expected: - `k3s` found in PATH - `kubectl` found in PATH (binary or symlink) - one of expected locations exists: `/usr/local/bin/kubectl`, `/usr/bin/kubectl` - one of expected locations exists: `/usr/local/bin/k3s`, `/usr/bin/k3s` - k3s service is enabled and active 3. **If HOST_TYPE!=kubernetes** (container or unknown): Validate Docker, Docker Compose, and Container Device Interface (CDI). - commands: - `command -v docker` - `docker --version 2>/dev/null || true` - `docker compose version 2>/dev/null || true` - `ls -l /usr/local/bin/docker /usr/bin/docker 2>/dev/null || true` - `systemctl is-enabled docker 2>/dev/null || true` - `systemctl is-active docker 2>/dev/null || true` - `docker info 2>/dev/null | grep -E 'Server Version|Storage Driver|Cgroup|data-root' || true` - `ls /etc/cdi/ 2>/dev/null || true` - `ls /var/run/cdi/ 2>/dev/null || true` - `cat /etc/cdi/*.json 2>/dev/null | python3 -c "import sys,json; [print(d.get('kind','?')) for d in json.load(sys.stdin).get('cdiDevices',json.load(open('/dev/stdin'))) if isinstance(d,dict)]" 2>/dev/null || ls /etc/cdi/ 2>/dev/null || true` - `docker info 2>/dev/null | grep -i cdi || true` - expected: - `docker` found in PATH - Docker version reported - Docker Compose plugin available (`docker compose version` succeeds) - Docker service is enabled and active - CDI spec files present in `/etc/cdi/` or `/var/run/cdi/` (e.g. `intel-gpu.json`, `intel-npu.json`) - CDI devices exposed to Docker runtime 4. Validate cloud-init completion. - commands: - `cloud-init status --long || true` - `test -f /var/lib/cloud/instance/boot-finished && echo CLOUD_INIT_BOOT_FINISHED=1 || echo CLOUD_INIT_BOOT_FINISHED=0` - `grep -Ei 'error|failed|traceback' /var/log/cloud-init.log | tail -n 20 || true` - expected: - cloud-init reports `status: done` - `/var/lib/cloud/instance/boot-finished` exists - no blocking cloud-init errors relevant to first boot provisioning 5. Validate network connectivity and assigned IP. - commands: - `ip -o -4 addr show scope global` - `ip route show default` - `ping -c 2 -W 2 8.8.8.8 >/dev/null 2>&1 && echo NET_INTERNET=ok || echo NET_INTERNET=fail` - `getent hosts github.com >/dev/null 2>&1 && echo DNS=ok || echo DNS=fail` - `curl -I --max-time 8 https://github.com >/dev/null 2>&1 && echo HTTPS_EGRESS=ok || echo HTTPS_EGRESS=fail` - expected: - at least one global IPv4 address assigned - default route present - connectivity result is classified explicitly: - direct internet OK: `NET_INTERNET=ok` - restricted/proxy-likely: `NET_INTERNET=fail` and `DNS=ok` - DNS/config issue: `DNS=fail` - if `NET_INTERNET=fail` and `DNS=ok`, do not hard-fail validation; report as "likely proxy required" with proxy evidence from Step 6 6. Collect proxy values (brief). - command: - `grep -hsE '^(https?_proxy|no_proxy)=' /etc/environment 2>/dev/null | head -5 || echo 'no proxy configured'` - expected: - report proxy variables from `/etc/environment` if set; otherwise report "no proxy configured" - do NOT dump k3s.service.env or docker proxy.conf unless network checks in Step 6 indicate proxy issues 7. Inventory CPU/GPU/NPU devices. - commands: - `nproc` - `lscpu` - `lscpu | grep -E 'Model name|Vendor ID|CPU family|Model:|Stepping'` - `grep -E '^(model name|flags|cpu cores|siblings)' /proc/cpuinfo | head -20` - `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver 2>/dev/null || true` - `cat /proc/cpuinfo | grep -E 'cpu family|model|stepping|flags' | head -10` - `if ls /sys/devices/system/cpu/cpu*/topology/core_type >/dev/null 2>&1; then for f in /sys/devices/system/cpu/cpu*/topology/core_type; do cat "$f"; done | awk '{c[$1]++} END {for (t in c) printf "CORE_TYPE_RAW_%s_COUNT=%d\n", t, c[t]}' | sort; else echo CORE_TYPE_EXPOSED=no; fi` - `if ls /sys/devices/system/cpu/cpu*/topology/core_type >/dev/null 2>&1; then for f in /sys/devices/system/cpu/cpu*/topology/core_type; do cat "$f"; done | awk '{c[$1]++} END {printf "P_CORE_COUNT=%d\n", c[2]+0; printf "E_CORE_COUNT=%d\n", c[1]+0; printf "LPE_CORE_COUNT=%d\n", c[3]+0}'; else echo "P_CORE_COUNT=unavailable"; echo "E_CORE_COUNT=unavailable"; echo "LPE_CORE_COUNT=unavailable"; fi` - `for cpu in /sys/devices/system/cpu/cpu*/topology/thread_siblings_list; do [ -f "$cpu" ] && echo "$cpu=$(cat $cpu)"; done | head -10` - `lspci -nn | grep -Ei 'vga|3d|display|npu|neural|vpu|accel|intel' || true` - `ls -l /dev/dri 2>/dev/null || true` - expected: - Total CPU core count and logical processors reported - P-core, E-core, and LPE-core counts are reported when `core_type` is exposed - raw `core_type` counts are always reported alongside decoded counts for traceability - if `core_type` is not exposed by the kernel or platform, report P/E/LPE counts as `unavailable` - CPU model, family, stepping, and feature flags documented - CPU codename is reported only when verified from trusted identifiers (family/model/stepping mapping); never infer codename from model name text alone - if codename cannot be verified confidently, report `CPU_CODENAME=unverified` instead of guessing - CPU frequency scaling driver reported - Core type information from `/sys/devices/system/cpu/cpu*/topology/core_type` is decoded using common Linux hybrid mapping (`2=P`, `1=E`, `3=LPE`) and may vary by kernel/platform - Thread siblings mapping for logical CPU layout - GPU presence determined from Peripheral Component Interconnect (PCI) and/or `/dev/dri` - NPU presence determined from PCI scan output 8. If GPU is present, report GPU Virtual Function (VF) counts. - commands: - `for f in /sys/class/drm/card*/device/sriov_numvfs; do [ -f "$f" ] && echo "$f=$(cat $f)"; done` - `for f in /sys/class/drm/card*/device/sriov_totalvfs; do [ -f "$f" ] && echo "$f=$(cat $f)"; done` - expected: - report per-GPU `sriov_numvfs` and `sriov_totalvfs` - if GPU exists but no SR-IOV files are present, report as unsupported/not enabled. 9. Check SR-IOV service if `enable_sriov` is set to true. - first check: - `grep -E '^enable_sriov' /etc/cloud/config-file 2>/dev/null || echo 'enable_sriov=unset'` - if value is `true`, validate: - `systemctl is-enabled intel-sriov-vf.service 2>/dev/null || echo 'not-found'` - expected: - if enabled: report `intel-sriov-vf.service` is enabled — VFs will be preserved across reboots - if disabled/not-found: report service not enabled — VFs will NOT persist across reboots - if `enable_sriov` is not `true`, SKIP this check ## Validation Validation section is criteria-only. Do not render the pass/fail results table here. - `host_type` is detected and reported; conditional checks branch accordingly. - **If kubernetes**: All required k3s pods listed in Step 2 are found in the correct namespaces and are healthy (`Running`, `1/1`); `kubectl` and `k3s` binaries are present. - **If container/unknown**: Docker and Docker Compose are available, Docker service is active, and CDI specification files are present. - cloud-init completion indicators are successful. - Network check reports assigned IP and route; connectivity is classified as direct or proxy/restricted with explicit reason. - Proxy values are collected briefly from `/etc/environment`; expanded only if network issues are detected. - CPU/GPU/NPU inventory is collected with clear present/absent status. - CPU codename labeling is verification-based and avoids false platform naming. - GPU VF data is reported when the GPU exists. - SR-IOV service (`intel-sriov-vf.service`) is validated when `enable_sriov=true` in config-file. ## Rollback This is a read-only validation skill. No rollback required. ## Safety Rules - Prefer read-only commands; do not alter target host configuration in this skill. - Do not use destructive or privileged write operations. - If a check fails, continue collecting remaining checks and return a complete report. ## Expected Result Summary Render the report as the following tables. ### Run Metadata | Field | Value | |---|---| | Preconditions | PASS/FAIL | | Execution mode | `local` | | Host context | `provisioned host` | | Sudo fallback availability | `yes/no` from `sudo -n true` probe | ### Validation Results | Check Area | Status | Evidence | Notes | |---|---|---|---| | host_type detection | PASS/FAIL/WARN | value from `/etc/cloud/config-file` | `kubernetes`, `container`, or `unknown` | | k3s pods (kubernetes only) | PASS/FAIL/WARN/SKIP | key pod states from `kubectl get pods -A` | skipped if host_type!=kubernetes | | k3s binaries (kubernetes only) | PASS/FAIL/WARN/SKIP | `command -v k3s`, `kubectl` | skipped if host_type!=kubernetes | | docker + compose (container only) | PASS/FAIL/WARN/SKIP | `docker --version`, `docker compose version` | skipped if host_type=kubernetes | | CDI specs (container only) | PASS/FAIL/WARN/SKIP | `/etc/cdi/`, `/var/run/cdi/` contents | skipped if host_type=kubernetes | | cloud-init | PASS/FAIL/WARN | `cloud-init status`, `boot-finished` marker | include relevant error lines | | network and IP | PASS/FAIL/WARN | IP/route, `NET_INTERNET`, `DNS`, `HTTPS_EGRESS` | classify restricted/proxy-likely cases | | proxy values | PASS/FAIL/WARN | `/etc/environment` summary | only expanded if network issues detected | | SR-IOV service | PASS/FAIL/WARN/SKIP | `intel-sriov-vf.service` state | skipped if enable_sriov!=true | | CPU/GPU/NPU inventory | PASS/FAIL/WARN | CPU topology, lspci, `/dev/dri` | codename must be verified or `unverified` | | GPU VF counts | PASS/FAIL/WARN | `sriov_numvfs`, `sriov_totalvfs` | unsupported/not-enabled if files missing | ### Observed Proxy Values | Variable | Value |
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub