-
Notifications
You must be signed in to change notification settings - Fork 0
feat(k3s): harden Kyber storage lifecycle #2134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| [Journal] | ||
| Storage=persistent | ||
| SystemMaxUse=2G | ||
| SystemKeepFree=10G | ||
| RuntimeMaxUse=256M | ||
| MaxRetentionSec=7day | ||
| MaxFileSec=1day |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,20 @@ | ||
| apiVersion: kubelet.config.k8s.io/v1beta1 | ||
| kind: KubeletConfiguration | ||
| # Keep limited parallelism for faster cold starts without allowing a full-node | ||
| # restart to saturate containerd, disk I/O, and CRI request deadlines. | ||
| serializeImagePulls: false | ||
| maxParallelImagePulls: 2 | ||
| # Make the single-node disk contract explicit. The ext4 root reserve is managed | ||
| # by the Kyber activation script, keeping ordinary usage below the low watermark | ||
| # while kubelet remains the sole owner of image and container garbage collection. | ||
| # These are kubelet's defaults, pinned here so the host headroom contract is visible. | ||
| imageGCHighThresholdPercent: 85 | ||
| imageGCLowThresholdPercent: 80 | ||
| # Serialize image pulls on the single Kyber containerd SSD. A broad restart must | ||
| # not fan out concurrent downloads, unpacking, and snapshot writes. | ||
| serializeImagePulls: true | ||
| # Start image garbage collection early and preserve enough space for image | ||
| # unpacking before kubelet reaches an eviction threshold. | ||
| imageGCHighThresholdPercent: 70 | ||
| imageGCLowThresholdPercent: 60 | ||
| # Keep at least twenty percent free on both the root/control-plane filesystem | ||
| # and the dedicated image filesystem. Kubelet remains the sole CRI collector. | ||
| evictionHard: | ||
| memory.available: "500Mi" | ||
| nodefs.available: "20%" | ||
| imagefs.available: "20%" | ||
| nodefs.inodesFree: "10%" | ||
| imagefs.inodesFree: "10%" | ||
| # Bound the CRI-managed container log files using kubelet's native rotation. | ||
| containerLogMaxSize: 10Mi | ||
| containerLogMaxFiles: 3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| source_name="${1:-${SMARTD_DEVICE:-kyber-host-health}}" | ||
| message="${2:-${SMARTD_MESSAGE:-Kyber host reliability alert}}" | ||
| alert="${source_name}: ${message}" | ||
|
|
||
| logger --priority daemon.alert --tag kyber-host-health -- "$alert" | ||
| printf 'KYBER ALERT: %s\n' "$alert" | wall --nobanner || true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| [Unit] | ||
| Description=Check Kyber storage and CRI reliability | ||
| After=var-lib-rancher-k3s-agent-containerd.mount k3s.service | ||
|
|
||
| [Service] | ||
| Type=oneshot | ||
| ExecStart=@healthCheckScript@/bin/kyber-host-health |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,121 @@ | ||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| readonly EXPECTED_CONTAINERD_UUID="90f29a7b-38ff-460b-b534-92a02f1412ec" | ||||||||||||||||||||||||||||||||||||
| readonly CONTAINERD_MOUNT="/var/lib/rancher/k3s/agent/containerd" | ||||||||||||||||||||||||||||||||||||
| readonly STATE_DIR="/run/kyber-host-health" | ||||||||||||||||||||||||||||||||||||
| readonly D_STATE_THRESHOLD=3 | ||||||||||||||||||||||||||||||||||||
| readonly D_STATE_SUSTAINED_SAMPLES=5 | ||||||||||||||||||||||||||||||||||||
| readonly IO_SOME_AVG300_THRESHOLD=20 | ||||||||||||||||||||||||||||||||||||
| readonly IO_FULL_AVG300_THRESHOLD=10 | ||||||||||||||||||||||||||||||||||||
| readonly IMAGEFS_USAGE_THRESHOLD=70 | ||||||||||||||||||||||||||||||||||||
| readonly CRI_LATENCY_THRESHOLD_SECONDS=5 | ||||||||||||||||||||||||||||||||||||
| readonly CRI_ERROR_THRESHOLD=5 | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| install -d --mode 0755 "$STATE_DIR" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| set_alert() { | ||||||||||||||||||||||||||||||||||||
| local key="$1" | ||||||||||||||||||||||||||||||||||||
| local message="$2" | ||||||||||||||||||||||||||||||||||||
| local marker="$STATE_DIR/${key}.alerted" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if [ ! -e "$marker" ]; then | ||||||||||||||||||||||||||||||||||||
| kyber-host-alert "$key" "$message" | ||||||||||||||||||||||||||||||||||||
| : >"$marker" | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| clear_alert() { | ||||||||||||||||||||||||||||||||||||
| local key="$1" | ||||||||||||||||||||||||||||||||||||
| local marker="$STATE_DIR/${key}.alerted" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if [ -e "$marker" ]; then | ||||||||||||||||||||||||||||||||||||
| logger --priority daemon.notice --tag kyber-host-health -- "$key recovered" | ||||||||||||||||||||||||||||||||||||
| rm -f "$marker" | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| check_io_pressure() { | ||||||||||||||||||||||||||||||||||||
| local some_avg300 full_avg300 | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| # shellcheck disable=SC2016 | ||||||||||||||||||||||||||||||||||||
| some_avg300="$(awk '$1 == "some" { for (i = 1; i <= NF; i++) if ($i ~ /^avg300=/) { sub(/^avg300=/, "", $i); print $i } }' /proc/pressure/io)" | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Guard Prompt for AI agents |
||||||||||||||||||||||||||||||||||||
| # shellcheck disable=SC2016 | ||||||||||||||||||||||||||||||||||||
| full_avg300="$(awk '$1 == "full" { for (i = 1; i <= NF; i++) if ($i ~ /^avg300=/) { sub(/^avg300=/, "", $i); print $i } }' /proc/pressure/io)" | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Gracefully handle missing PSI file to prevent premature script failure. If the system lacks PSI capabilities or Add a readability check to return early if the file does not exist. 🛠️ Proposed fix check_io_pressure() {
+ if [ ! -r /proc/pressure/io ]; then
+ return 0
+ fi
local some_avg300 full_avg300
# shellcheck disable=SC2016📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if awk -v some="$some_avg300" -v full="$full_avg300" -v some_limit="$IO_SOME_AVG300_THRESHOLD" -v full_limit="$IO_FULL_AVG300_THRESHOLD" 'BEGIN { exit !(some >= some_limit || full >= full_limit) }'; then | ||||||||||||||||||||||||||||||||||||
| set_alert "io-pressure" "sustained I/O PSI is elevated (some avg300=${some_avg300}, full avg300=${full_avg300})" | ||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||
| clear_alert "io-pressure" | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| check_d_state() { | ||||||||||||||||||||||||||||||||||||
| local count_file="$STATE_DIR/d-state.samples" | ||||||||||||||||||||||||||||||||||||
| local d_state_count previous_samples=0 samples=0 | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| d_state_count="$(ps --no-headers -eo stat= | awk '$1 ~ /^D/ { count++ } END { print count + 0 }')" | ||||||||||||||||||||||||||||||||||||
| if [ -r "$count_file" ]; then | ||||||||||||||||||||||||||||||||||||
| read -r previous_samples <"$count_file" || previous_samples=0 | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if [ "$d_state_count" -ge "$D_STATE_THRESHOLD" ]; then | ||||||||||||||||||||||||||||||||||||
| samples=$((previous_samples + 1)) | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Latent: corrupted state file crashes the health check.
A one-line guard makes this resilient: if [ -r "$count_file" ]; then
read -r previous_samples <"$count_file" || previous_samples=0
[[ "$previous_samples" =~ ^[0-9]+$ ]] || previous_samples=0
fi
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: Validate Prompt for AI agents |
||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| printf '%s\n' "$samples" >"$count_file" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if [ "$samples" -ge "$D_STATE_SUSTAINED_SAMPLES" ]; then | ||||||||||||||||||||||||||||||||||||
| set_alert "d-state" "${d_state_count} processes have remained in uninterruptible sleep for ${samples} consecutive samples" | ||||||||||||||||||||||||||||||||||||
| elif [ "$samples" -eq 0 ]; then | ||||||||||||||||||||||||||||||||||||
| clear_alert "d-state" | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| check_image_filesystem() { | ||||||||||||||||||||||||||||||||||||
| local mounted_source mounted_uuid usage_percent | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if ! findmnt --mountpoint "$CONTAINERD_MOUNT" >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||||||||
| set_alert "image-filesystem" "$CONTAINERD_MOUNT is not mounted" | ||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| mounted_source="$(findmnt --noheadings --output SOURCE --target "$CONTAINERD_MOUNT")" | ||||||||||||||||||||||||||||||||||||
| mounted_uuid="$(blkid --match-tag UUID --output value "$mounted_source")" | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: An unreadable or unsupported mounted source makes Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||||||
| if [ "$mounted_uuid" != "$EXPECTED_CONTAINERD_UUID" ]; then | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+82
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Prevent script termination if the filesystem lacks a UUID. If the mounted device lacks a UUID (e.g., due to corruption or unexpected filesystem type), Append 🛠️ Proposed fix mounted_source="$(findmnt --noheadings --output SOURCE --target "$CONTAINERD_MOUNT")"
- mounted_uuid="$(blkid --match-tag UUID --output value "$mounted_source")"
+ mounted_uuid="$(blkid --match-tag UUID --output value "$mounted_source" || true)"
if [ "$mounted_uuid" != "$EXPECTED_CONTAINERD_UUID" ]; then📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| set_alert "image-filesystem" "$CONTAINERD_MOUNT has UUID $mounted_uuid, expected $EXPECTED_CONTAINERD_UUID" | ||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+82
to
+87
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using We can retrieve the UUID directly and robustly using
Suggested change
References
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| usage_percent="$(df --output=pcent "$CONTAINERD_MOUNT" | tail -n 1 | tr -cd '0-9')" | ||||||||||||||||||||||||||||||||||||
| if [ "$usage_percent" -ge "$IMAGEFS_USAGE_THRESHOLD" ]; then | ||||||||||||||||||||||||||||||||||||
| set_alert "image-filesystem" "containerd image filesystem usage is ${usage_percent}% (threshold ${IMAGEFS_USAGE_THRESHOLD}%)" | ||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||
| clear_alert "image-filesystem" | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| check_cri() { | ||||||||||||||||||||||||||||||||||||
| local started_at finished_at latency_seconds error_count | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| started_at="$(date +%s)" | ||||||||||||||||||||||||||||||||||||
| if ! timeout 15 k3s crictl info >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: A hung Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||||||
| set_alert "cri-health" "k3s crictl info failed or exceeded 15 seconds" | ||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| finished_at="$(date +%s)" | ||||||||||||||||||||||||||||||||||||
| latency_seconds=$((finished_at - started_at)) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| error_count="$(journalctl --unit k3s --since '5 minutes ago' --no-pager --quiet 2>/dev/null | | ||||||||||||||||||||||||||||||||||||
| grep -Eci 'DeadlineExceeded|deadline exceeded|FailedPrecondition|failed precondition|reserved (container )?name|failed to (create|stop|remove).*(sandbox|container)|cgroup.*(busy|failed)' || true)" | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if [ "$latency_seconds" -ge "$CRI_LATENCY_THRESHOLD_SECONDS" ] || [ "$error_count" -ge "$CRI_ERROR_THRESHOLD" ]; then | ||||||||||||||||||||||||||||||||||||
| set_alert "cri-health" "CRI latency was ${latency_seconds}s with ${error_count} lifecycle errors in the last five minutes" | ||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||
| clear_alert "cri-health" | ||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| check_io_pressure | ||||||||||||||||||||||||||||||||||||
| check_d_state | ||||||||||||||||||||||||||||||||||||
| check_image_filesystem | ||||||||||||||||||||||||||||||||||||
| check_cri | ||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| [Unit] | ||
| Description=Run Kyber storage and CRI reliability checks | ||
|
|
||
| [Timer] | ||
| OnBootSec=5min | ||
| OnUnitActiveSec=1min | ||
| RandomizedDelaySec=15s | ||
| Persistent=true | ||
| Unit=kyber-host-health.service | ||
|
|
||
| [Install] | ||
| WantedBy=timers.target |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Monitor all SMART-capable host disks. The filesystem UUID pin remains the | ||
| # authoritative identity for the containerd mount; smartd monitors physical | ||
| # devices because SMART data belongs to the whole SSD, not its partition. | ||
| DEVICESCAN -a -n standby,q -s (S/../.././02|L/../01/./03) -W 4,50,60 -m <nomailer> -M exec @alertScript@/bin/kyber-host-alert |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| [Unit] | ||
| Description=SMART monitoring for Kyber disks | ||
| Documentation=man:smartd(8) man:smartd.conf(5) | ||
| Wants=var-lib-rancher-k3s-agent-containerd.mount | ||
| After=var-lib-rancher-k3s-agent-containerd.mount | ||
|
|
||
| [Service] | ||
| Type=simple | ||
| ExecStart=@smartd@ --no-fork --quit=never --configfile=@smartdConfig@ | ||
| Restart=on-failure | ||
| RestartSec=30s | ||
|
|
||
| [Install] | ||
| WantedBy=multi-user.target |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,9 +6,18 @@ set -euo pipefail | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SERVICE_FILE="$1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| KUBE_DIR="$2" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MOUNT_FILE="$3" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| JOURNALD_FILE="$4" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HEALTH_SERVICE_FILE="$5" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HEALTH_TIMER_FILE="$6" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SMARTD_SERVICE_FILE="$7" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SYSTEM_SERVICE="/etc/systemd/system/k3s.service" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SYSTEM_MOUNT="/etc/systemd/system/var-lib-rancher-k3s-agent-containerd.mount" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SYSTEM_JOURNALD="/etc/systemd/journald.conf.d/10-kyber-limits.conf" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SYSTEM_HEALTH_SERVICE="/etc/systemd/system/kyber-host-health.service" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SYSTEM_HEALTH_TIMER="/etc/systemd/system/kyber-host-health.timer" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SYSTEM_SMARTD_SERVICE="/etc/systemd/system/kyber-smartd.service" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MOUNT_POINT="/var/lib/rancher/k3s/agent/containerd" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EXPECTED_CONTAINERD_UUID="90f29a7b-38ff-460b-b534-92a02f1412ec" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| K3S_KUBECONFIG="/etc/rancher/k3s/k3s.yaml" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sudo_cmd=() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -41,6 +50,20 @@ require_sudo() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sync_root_file() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local source="$1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local target="$2" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ ! -f "$source" ] || @diff@ -q "$source" "$target" >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| require_sudo || return 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo mkdir -p "$(dirname "$target")" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: A failed privileged copy is reported as success, so activation can reload and enable stale or missing K3s/health/SMART units after a disk-full or permission failure. Make each install command terminate the activation on failure rather than falling through to Prompt for AI agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo cp -f "$source" "$target" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+53
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Propagate command failures in Because Append 🐛 Proposed fix require_sudo || return 1
- run_sudo mkdir -p "$(dirname "$target")"
- run_sudo cp -f "$source" "$target"
- return 0
+ run_sudo mkdir -p "$(dirname "$target")" || return 1
+ run_sudo cp -f "$source" "$target" || return 1
+ return 0
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| configure_root_ext4_reserve() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local root_source root_fs_type filesystem_info block_count reserved_blocks target_reserved_blocks | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| local target_reserved_percent=1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -84,6 +107,16 @@ configure_root_ext4_reserve() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| configure_root_ext4_reserve | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if @findmnt@ --mountpoint "$MOUNT_POINT" >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mounted_source="$(@findmnt@ --noheadings --output SOURCE --target "$MOUNT_POINT")" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mounted_uuid="$(@blkid@ --match-tag UUID --output value "$mounted_source")" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+111
to
+112
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Running Using
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bare On Ubuntu the containerd block device ( The same script already reaches for if @findmnt@ --mountpoint "$MOUNT_POINT" >/dev/null 2>&1; then
mounted_source="$(@findmnt@ --noheadings --output SOURCE --target "$MOUNT_POINT")"
require_sudo || exit 0
mounted_uuid="$(run_sudo @blkid@ --match-tag UUID --output value "$mounted_source")"
...
fiThe existing spec assertion
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: This UUID probe uses Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$mounted_uuid" != "$EXPECTED_CONTAINERD_UUID" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Refusing to run k3s with unexpected containerd filesystem UUID: $mounted_uuid" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Expected $EXPECTED_CONTAINERD_UUID at $MOUNT_POINT" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+110
to
+119
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Run By default, reading block device attributes with 🐛 Proposed fix to use `run_sudo` if `@findmnt`@ --mountpoint "$MOUNT_POINT" >/dev/null 2>&1; then
mounted_source="$(`@findmnt`@ --noheadings --output SOURCE --target "$MOUNT_POINT")"
- mounted_uuid="$(`@blkid`@ --match-tag UUID --output value "$mounted_source")"
+ mounted_uuid="$(run_sudo `@blkid`@ --match-tag UUID --output value "$mounted_source")"
if [ "$mounted_uuid" != "$EXPECTED_CONTAINERD_UUID" ]; then📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$MOUNT_FILE" ] && ! @findmnt@ --mountpoint "$MOUNT_POINT" >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if @systemctl@ is-active --quiet k3s; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Refusing to mount the containerd SSD while k3s is running" >&2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -105,22 +138,27 @@ if [ -f "$MOUNT_FILE" ] && ! @findmnt@ --mountpoint "$MOUNT_POINT" >/dev/null 2> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| systemd_changed=0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$MOUNT_FILE" ] && ! @diff@ -q "$MOUNT_FILE" "$SYSTEM_MOUNT" >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| require_sudo || exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo cp -f "$MOUNT_FILE" "$SYSTEM_MOUNT" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| systemd_changed=1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$SERVICE_FILE" ] && ! @diff@ -q "$SERVICE_FILE" "$SYSTEM_SERVICE" >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| require_sudo || exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo cp -f "$SERVICE_FILE" "$SYSTEM_SERVICE" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| systemd_changed=1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for systemd_file_pair in \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$MOUNT_FILE:$SYSTEM_MOUNT" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$SERVICE_FILE:$SYSTEM_SERVICE" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$HEALTH_SERVICE_FILE:$SYSTEM_HEALTH_SERVICE" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$HEALTH_TIMER_FILE:$SYSTEM_HEALTH_TIMER" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$SMARTD_SERVICE_FILE:$SYSTEM_SMARTD_SERVICE"; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| source_file="${systemd_file_pair%%:*}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| target_file="${systemd_file_pair#*:}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if sync_root_file "$source_file" "$target_file"; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| systemd_changed=1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$systemd_changed" -eq 1 ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo @systemctl@ daemon-reload | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+141
to
156
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win Initialize If none of the systemd files require synchronization, the 🐛 Proposed fix+systemd_changed=0
for systemd_file_pair in \
"$MOUNT_FILE:$SYSTEM_MOUNT" \📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if sync_root_file "$JOURNALD_FILE" "$SYSTEM_JOURNALD"; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo @systemctl@ try-restart systemd-journald.service | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$MOUNT_FILE" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| require_sudo || exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo mkdir -p "$MOUNT_POINT" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -129,6 +167,14 @@ fi | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo @systemctl@ enable --now k3s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$SMARTD_SERVICE_FILE" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo @systemctl@ enable --now kyber-smartd.service | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Updated SMART monitoring configuration never takes effect while Prompt for AI agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$HEALTH_TIMER_FILE" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run_sudo @systemctl@ enable --now kyber-host-health.timer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$K3S_KUBECONFIG" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run mkdir -p "$KUBE_DIR" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| require_sudo || exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
/proc/pressure/iodoes not exist (e.g., on kernels where PSI is disabled or unsupported), theawkcommand will fail. Becauseset -eis enabled, this failure will prematurely abort the entire health check script, preventing subsequent checks from running.Adding a guard to check for the existence of
/proc/pressure/ioensures the script handles this state gracefully.References