142 lines
3.3 KiB
Bash
Executable File
142 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
STATE_DIR="${TDC114_WSL_MAINTENANCE_STATE_DIR:-$ROOT_DIR/.tmp}"
|
|
STATE_FILE="${TDC114_WSL_MAINTENANCE_STATE_FILE:-$STATE_DIR/wsl-maintenance-last-check.txt}"
|
|
ANCHOR_DATE="${TDC114_WSL_MAINTENANCE_ANCHOR_DATE:-2026-07-16}"
|
|
INTERVAL_DAYS="${TDC114_WSL_MAINTENANCE_INTERVAL_DAYS:-14}"
|
|
MODE="${1:-status}"
|
|
TODAY="${TDC114_WSL_MAINTENANCE_TODAY:-$(date +%F)}"
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $0 [status|record|reset]
|
|
|
|
status : print whether the recurring WSL maintenance check is due
|
|
record : mark today's date as the completed maintenance date
|
|
reset : remove the stored completion date
|
|
EOF
|
|
}
|
|
|
|
require_date() {
|
|
local value="$1"
|
|
if ! date -d "$value" +%F >/dev/null 2>&1; then
|
|
echo "Invalid date: $value" >&2
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
require_non_negative_integer() {
|
|
local value="$1"
|
|
case "$value" in
|
|
''|*[!0-9]*)
|
|
echo "Interval must be a non-negative integer: $value" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
}
|
|
|
|
days_since() {
|
|
local from_date="$1"
|
|
local to_date="$2"
|
|
local from_epoch
|
|
local to_epoch
|
|
|
|
from_epoch="$(date -d "$from_date" +%s)"
|
|
to_epoch="$(date -d "$to_date" +%s)"
|
|
echo $(((to_epoch - from_epoch) / 86400))
|
|
}
|
|
|
|
print_due_message() {
|
|
local base_date="$1"
|
|
local elapsed_days="$2"
|
|
local next_due_date
|
|
|
|
next_due_date="$(date -d "$base_date + $INTERVAL_DAYS days" +%F)"
|
|
|
|
cat <<EOF
|
|
WSL maintenance reminder: DUE
|
|
Base date: $base_date
|
|
Days elapsed: $elapsed_days
|
|
Due date: $next_due_date
|
|
|
|
General PowerShell:
|
|
1. Close VS Code, WSL terminals, Docker Desktop, and any \\\\wsl$ Explorer windows.
|
|
2. Run: wsl --shutdown
|
|
|
|
Administrator PowerShell:
|
|
1. Run: diskpart
|
|
2. Then run:
|
|
select vdisk file="%LOCALAPPDATA%\\Packages\\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\\LocalState\\ext4.vhdx"
|
|
attach vdisk readonly
|
|
compact vdisk
|
|
detach vdisk
|
|
exit
|
|
|
|
After maintenance is complete, record it with:
|
|
./scripts/check-wsl-maintenance.sh record
|
|
EOF
|
|
}
|
|
|
|
print_not_due_message() {
|
|
local base_date="$1"
|
|
local elapsed_days="$2"
|
|
local remaining_days
|
|
local next_due_date
|
|
|
|
remaining_days=$((INTERVAL_DAYS - elapsed_days))
|
|
next_due_date="$(date -d "$base_date + $INTERVAL_DAYS days" +%F)"
|
|
|
|
cat <<EOF
|
|
WSL maintenance reminder: OK
|
|
Base date: $base_date
|
|
Days elapsed: $elapsed_days
|
|
Next due date: $next_due_date
|
|
Days remaining: $remaining_days
|
|
EOF
|
|
}
|
|
|
|
require_date "$ANCHOR_DATE"
|
|
require_date "$TODAY"
|
|
require_non_negative_integer "$INTERVAL_DAYS"
|
|
mkdir -p "$STATE_DIR"
|
|
|
|
case "$MODE" in
|
|
status)
|
|
base_date="$ANCHOR_DATE"
|
|
if [ -f "$STATE_FILE" ] && [ -s "$STATE_FILE" ]; then
|
|
base_date="$(tr -d '[:space:]' < "$STATE_FILE")"
|
|
require_date "$base_date"
|
|
fi
|
|
|
|
elapsed_days="$(days_since "$base_date" "$TODAY")"
|
|
if [ "$elapsed_days" -lt 0 ]; then
|
|
echo "Stored date is in the future: $base_date" >&2
|
|
exit 2
|
|
fi
|
|
|
|
if [ "$elapsed_days" -ge "$INTERVAL_DAYS" ]; then
|
|
print_due_message "$base_date" "$elapsed_days"
|
|
else
|
|
print_not_due_message "$base_date" "$elapsed_days"
|
|
fi
|
|
;;
|
|
record)
|
|
printf '%s\n' "$TODAY" > "$STATE_FILE"
|
|
echo "Recorded WSL maintenance date: $TODAY"
|
|
;;
|
|
reset)
|
|
rm -f "$STATE_FILE"
|
|
echo "Removed recorded WSL maintenance date: $STATE_FILE"
|
|
;;
|
|
--help|-h|help)
|
|
usage
|
|
;;
|
|
*)
|
|
echo "Unknown mode: $MODE" >&2
|
|
usage >&2
|
|
exit 2
|
|
;;
|
|
esac
|