Add private asset backup inventory

This commit is contained in:
2026-03-08 17:46:23 +08:00
parent 3483e0a826
commit fdc0b35c13
6 changed files with 182 additions and 0 deletions
+6
View File
@@ -50,6 +50,8 @@ Initialize the local secrets skeleton with:
- `Brewfile` rebuilds the Homebrew toolchain baseline.
- `config/homebrew/Brewfile.lock.json` captures installed package versions as a
lock-style recovery snapshot.
- `config/recovery/private-assets.tsv` tracks the non-versioned local assets
that still need private backup handling.
- `config/clash/config.public.yaml` preserves the ClashX base port/controller
settings that make the local mixed proxy port stay on `7890`.
- `config/clash/clashx.public.yaml` is a sanitized export of the live Clash
@@ -57,6 +59,10 @@ Initialize the local secrets skeleton with:
- `scripts/brew/export-brewfile.sh` refreshes `Brewfile` from the current
machine state.
- `scripts/brew/export-lockfile.rb` refreshes the Homebrew version snapshot.
- `scripts/backup/check-private-assets.sh` verifies that local critical assets
exist before a rebuild or migration.
- `scripts/backup/create-private-backup.sh` packages non-versioned private
assets into a sensitive local archive.
- `scripts/clash/export-public-config.rb` refreshes the sanitized Clash template
from the live local config.
+19
View File
@@ -49,6 +49,21 @@ tar czf ~/Desktop/recovery-secrets-$(date +%Y%m%d).tgz \
- Clash 订阅来源或脱敏后的基础配置
- Keychain 里关键 token 是否有外部保存方案
系统重装前,先跑一遍:
```bash
./scripts/backup/check-private-assets.sh
```
如果要生成本机私有归档:
```bash
./scripts/backup/create-private-backup.sh
```
注意:这个归档会包含 SSH、GPG、kube、Docker、Clash 私有配置等敏感内容,
必须只放在受控位置。
## 恢复顺序
### 1. 系统初始化
@@ -130,6 +145,10 @@ mkdir -p ~/.config/secrets
- `~/.docker/config.json`
- Keychain 中的登录项、API token、证书
这些项目的标准清单已经记录在:
- `config/recovery/private-assets.tsv`
如果你要继续使用本机特有变量,复制本地覆盖文件:
```bash
+28
View File
@@ -0,0 +1,28 @@
# Private Asset Recovery
This directory tracks the inventory of machine-local assets that are critical
for recovery but should not be committed to git with real content.
## Files
- `private-assets.tsv`: backup inventory for non-versioned local assets
## Recommended usage
Check the inventory before major system changes:
```bash
./scripts/backup/check-private-assets.sh
```
Create a private encrypted or access-controlled backup archive when needed:
```bash
./scripts/backup/create-private-backup.sh
```
## Important note
The backup script can package local secret material such as SSH keys, GPG
material, kube config, Docker auth, and private Clash configs. Treat the output
archive as highly sensitive.
+13
View File
@@ -0,0 +1,13 @@
# kind required path_or_label archive_path note
dir true ~/.ssh Users/brunogao/.ssh SSH keys and client config
dir true ~/.gnupg Users/brunogao/.gnupg GPG keys, trustdb, and agent state
dir true ~/.config/secrets Users/brunogao/.config/secrets Local secret env files and private overrides
file true ~/.kube/config Users/brunogao/.kube/config Kubernetes contexts and auth
file true ~/.docker/config.json Users/brunogao/.docker/config.json Docker registry auth and CLI config
file true ~/.config/clash/config.yaml Users/brunogao/.config/clash/config.yaml ClashX base config with effective local port settings
file true ~/.config/clash/clashx.yaml Users/brunogao/.config/clash/clashx.yaml Live Clash config with private node credentials
file true ~/.config/clash/s.trojanflare.com.yaml Users/brunogao/.config/clash/s.trojanflare.com.yaml Provider Clash config or duplicate live config
manual true macOS Keychain - Export or verify API tokens, certs, and login items via Keychain Access or security CLI
manual false Browser profiles - Export browser state if login sessions or bookmarks matter
manual false OrbStack volumes - Backup container volumes or VM state if local runtime data matters
manual false Local model/data dirs - Backup Ollama models, downloads, and other large local state only if worth the size
1 # kind required path_or_label archive_path note
2 dir true ~/.ssh Users/brunogao/.ssh SSH keys and client config
3 dir true ~/.gnupg Users/brunogao/.gnupg GPG keys, trustdb, and agent state
4 dir true ~/.config/secrets Users/brunogao/.config/secrets Local secret env files and private overrides
5 file true ~/.kube/config Users/brunogao/.kube/config Kubernetes contexts and auth
6 file true ~/.docker/config.json Users/brunogao/.docker/config.json Docker registry auth and CLI config
7 file true ~/.config/clash/config.yaml Users/brunogao/.config/clash/config.yaml ClashX base config with effective local port settings
8 file true ~/.config/clash/clashx.yaml Users/brunogao/.config/clash/clashx.yaml Live Clash config with private node credentials
9 file true ~/.config/clash/s.trojanflare.com.yaml Users/brunogao/.config/clash/s.trojanflare.com.yaml Provider Clash config or duplicate live config
10 manual true macOS Keychain - Export or verify API tokens, certs, and login items via Keychain Access or security CLI
11 manual false Browser profiles - Export browser state if login sessions or bookmarks matter
12 manual false OrbStack volumes - Backup container volumes or VM state if local runtime data matters
13 manual false Local model/data dirs - Backup Ollama models, downloads, and other large local state only if worth the size
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
manifest="${repo_root}/config/recovery/private-assets.tsv"
status=0
expand_path() {
local raw="$1"
if [[ "${raw}" == "~"* ]]; then
printf '%s\n' "${raw/#\~/${HOME}}"
else
printf '%s\n' "${raw}"
fi
}
while IFS=$'\t' read -r kind required source_path archive_path note; do
[[ -z "${kind}" || "${kind}" == \#* ]] && continue
case "${kind}" in
manual)
printf '[manual] %s - %s\n' "${source_path}" "${note}"
;;
file|dir)
resolved="$(expand_path "${source_path}")"
if [[ -e "${resolved}" ]]; then
printf '[ok] %s\n' "${resolved}"
else
printf '[missing] %s - %s\n' "${resolved}" "${note}"
[[ "${required}" == "true" ]] && status=1
fi
;;
*)
printf '[warn] Unknown manifest kind: %s\n' "${kind}"
status=1
;;
esac
done <"${manifest}"
exit "${status}"
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
manifest="${repo_root}/config/recovery/private-assets.tsv"
timestamp="$(date +%Y%m%d-%H%M%S)"
output_dir="${1:-${HOME}/Backups/dotfiles-private}"
archive_path="${output_dir}/private-assets-${timestamp}.tgz"
staging_dir="$(mktemp -d)"
status=0
cleanup() {
rm -rf "${staging_dir}"
}
trap cleanup EXIT
expand_path() {
local raw="$1"
if [[ "${raw}" == "~"* ]]; then
printf '%s\n' "${raw/#\~/${HOME}}"
else
printf '%s\n' "${raw}"
fi
}
mkdir -p "${output_dir}" "${staging_dir}/metadata"
cp "${manifest}" "${staging_dir}/metadata/private-assets.tsv"
manual_file="${staging_dir}/metadata/manual-steps.txt"
missing_file="${staging_dir}/metadata/missing.txt"
info_file="${staging_dir}/metadata/backup-info.txt"
{
echo "Created: $(date -u +%FT%TZ)"
echo "Host: $(hostname)"
echo "Archive: ${archive_path}"
} >"${info_file}"
while IFS=$'\t' read -r kind required source_path archive_rel note; do
[[ -z "${kind}" || "${kind}" == \#* ]] && continue
case "${kind}" in
manual)
printf '%s - %s\n' "${source_path}" "${note}" >>"${manual_file}"
;;
file|dir)
resolved="$(expand_path "${source_path}")"
target="${staging_dir}/${archive_rel}"
if [[ -e "${resolved}" ]]; then
mkdir -p "$(dirname "${target}")"
ditto "${resolved}" "${target}"
else
printf '%s\t%s\n' "${resolved}" "${note}" >>"${missing_file}"
[[ "${required}" == "true" ]] && status=1
fi
;;
*)
printf 'Unknown kind: %s\n' "${kind}" >>"${missing_file}"
status=1
;;
esac
done <"${manifest}"
tar -C "${staging_dir}" -czf "${archive_path}" .
chmod 600 "${archive_path}"
shasum -a 256 "${archive_path}" >"${archive_path}.sha256"
echo "Wrote ${archive_path}"
echo "Wrote ${archive_path}.sha256"
echo "Manual follow-up list is embedded at metadata/manual-steps.txt"
if [[ -f "${missing_file}" ]]; then
echo "Warning: some required assets were missing. See metadata/missing.txt in the archive."
fi
exit "${status}"