Add cn doctor with mirror auto-failover and restore commands
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QKxGW1raAWaqeU8WdHsMsp
This commit is contained in:
Executable
+91
@@ -0,0 +1,91 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# omarchy:summary=Check network, pacman mirror, and dev registries; --fix fails over mirrors
|
||||||
|
# omarchy:args=[network|mirror|dev-mirror] [--fix]
|
||||||
|
# omarchy:examples=omarchycn doctor | omarchycn doctor mirror --fix
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
source "$OMARCHY_PATH/cn/lib/mirror.sh"
|
||||||
|
|
||||||
|
module="all"
|
||||||
|
fix="false"
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
network | mirror | dev-mirror) module="$arg" ;;
|
||||||
|
--fix) fix="true" ;;
|
||||||
|
*)
|
||||||
|
echo "Unknown argument: $arg" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
failures=0
|
||||||
|
|
||||||
|
check_network() {
|
||||||
|
local host
|
||||||
|
for host in mirrors.tuna.tsinghua.edu.cn archlinux.org; do
|
||||||
|
if getent hosts "$host" > /dev/null 2>&1; then
|
||||||
|
echo "PASS network: DNS resolves $host"
|
||||||
|
else
|
||||||
|
echo "FAIL network: cannot resolve $host"
|
||||||
|
failures=$((failures + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if curl -sSf -o /dev/null -m 8 --connect-timeout 5 https://www.baidu.com 2>/dev/null; then
|
||||||
|
echo "PASS network: HTTPS reachable (baidu.com)"
|
||||||
|
else
|
||||||
|
echo "FAIL network: HTTPS unreachable (baidu.com)"
|
||||||
|
failures=$((failures + 1))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_mirror() {
|
||||||
|
local primary speed ttfb age
|
||||||
|
|
||||||
|
primary=$(grep -sE '^Server' "$CN_MIRRORLIST" | head -1 | sed -E 's/^Server = //; s|/\$repo/os/\$arch/?$||')
|
||||||
|
if [[ -z $primary ]]; then
|
||||||
|
echo "FAIL mirror: no Server entries in $CN_MIRRORLIST"
|
||||||
|
failures=$((failures + 1))
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "INFO mirror: primary $primary"
|
||||||
|
read -r speed ttfb age < <(cn_mirror_probe "$primary")
|
||||||
|
if (( speed > 0 )) && [[ $age != "stale" ]]; then
|
||||||
|
echo "PASS mirror: primary healthy ($((speed / 1024)) KB/s, sync age ${age}s)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "FAIL mirror: primary unhealthy (speed=$speed age=$age)"
|
||||||
|
failures=$((failures + 1))
|
||||||
|
|
||||||
|
if [[ $fix == "true" && -f $CN_PROFILE_FILE && $(<"$CN_PROFILE_FILE") == "china" ]]; then
|
||||||
|
echo "INFO mirror: re-applying china profile (auto-failover)"
|
||||||
|
if omarchy-cn-mirror-apply china; then
|
||||||
|
failures=$((failures - 1))
|
||||||
|
omarchy-notification-send "OmarchyCN" "pacman 镜像已自动切换" || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_dev_mirror() {
|
||||||
|
omarchy-cn-dev-mirror-doctor || failures=$((failures + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$module" in
|
||||||
|
network) check_network ;;
|
||||||
|
mirror) check_mirror ;;
|
||||||
|
dev-mirror) check_dev_mirror ;;
|
||||||
|
all)
|
||||||
|
check_network
|
||||||
|
check_mirror
|
||||||
|
check_dev_mirror
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if (( failures > 0 )); then
|
||||||
|
echo "Doctor: $failures failure(s)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Doctor: all checks passed"
|
||||||
Executable
+33
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# omarchy:summary=Restore development registry configs from a backup stamp
|
||||||
|
# omarchy:args=<stamp>
|
||||||
|
# omarchy:examples=omarchycn restore config 20260824-184243
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
source "$OMARCHY_PATH/cn/lib/dev-mirror.sh"
|
||||||
|
|
||||||
|
stamp="${1:?usage: omarchycn restore config <stamp> (see: omarchycn restore list)}"
|
||||||
|
dir="$CN_DM_BACKUP_ROOT/$stamp"
|
||||||
|
|
||||||
|
if [[ ! -d $dir ]]; then
|
||||||
|
echo "No backup at $dir" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
restored=0
|
||||||
|
for target in "${CN_DM_TARGETS[@]}"; do
|
||||||
|
dest=$(cn_dm_config_file "$target")
|
||||||
|
src="$dir/${dest##*/}"
|
||||||
|
if [[ -f $src && $dest != /etc/* ]]; then
|
||||||
|
mkdir -p "${dest%/*}"
|
||||||
|
cp "$src" "$dest"
|
||||||
|
echo "restored $target: $dest"
|
||||||
|
restored=$((restored + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( restored == 0 )); then
|
||||||
|
echo "Nothing restored from $dir (system files like docker are not auto-restored)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Executable
+31
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# omarchy:summary=List OmarchyCN configuration backups
|
||||||
|
# omarchy:examples=omarchycn restore list
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
source "$OMARCHY_PATH/cn/lib/dev-mirror.sh"
|
||||||
|
|
||||||
|
echo "Dev-mirror backups ($CN_DM_BACKUP_ROOT):"
|
||||||
|
if [[ -d $CN_DM_BACKUP_ROOT ]]; then
|
||||||
|
for dir in "$CN_DM_BACKUP_ROOT"/*/; do
|
||||||
|
[[ -d $dir ]] || continue
|
||||||
|
stamp="${dir%/}"
|
||||||
|
stamp="${stamp##*/}"
|
||||||
|
echo " $stamp: $(ls "$dir" | tr '\n' ' ')"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo " (none)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Mirrorlist backups (/etc/pacman.d):"
|
||||||
|
found="false"
|
||||||
|
for f in /etc/pacman.d/mirrorlist.omarchycn-bak-*; do
|
||||||
|
if [[ -e $f ]]; then
|
||||||
|
echo " ${f##*/}"
|
||||||
|
found="true"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ $found == "false" ]]; then
|
||||||
|
echo " (none)"
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user