Add private asset backup inventory
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
Executable
+40
@@ -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}"
|
||||
Executable
+76
@@ -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}"
|
||||
Reference in New Issue
Block a user