Drop the backup and restore scripts: setup.sh only
Files and app logins move across by hand, so archiving and unpacking a home directory isn't this repo's job any more. setup.sh installs the machine and stops there. Two things restore.sh used to cover, kept where they still matter: the post-reboot `sudo flatpak update` that fetches the NVIDIA GL runtime (Flatpak can only match it to a loaded driver, so it can't happen during setup), and the notes on which dotfiles not to copy over from Fedora. The server-marvin mount is now optional — press Enter at the prompt to skip it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,111 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run on the Bazzite box BEFORE wiping it. Archives your home folder to server-marvin as
|
||||
# tar.zst files, then reads every archive back to prove it's intact.
|
||||
#
|
||||
# scripts/backup.sh # -> /var/mnt/server-marvin-personal/desktop-backup-<date>
|
||||
# scripts/backup.sh /some/other/dir # any directory NOT on the disk you're about to wipe
|
||||
#
|
||||
# Re-running skips archives that already finished (FORCE=1 redoes them).
|
||||
# Close Steam, Firefox, Discord and Claude first — files that change mid-read get a warning.
|
||||
set -euo pipefail
|
||||
|
||||
SHARE=/var/mnt/server-marvin-personal
|
||||
DEST="${1:-$SHARE/desktop-backup-$(date +%F)}"
|
||||
|
||||
step() { printf '\n\033[1;34m== %s ==\033[0m\n' "$*"; }
|
||||
warn() { printf '\033[1;33mwarning:\033[0m %s\n' "$*" >&2; }
|
||||
die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
# -- Make sure the backup lands somewhere that survives the reinstall ------------------
|
||||
if [[ $DEST == "$SHARE"/* ]]; then
|
||||
ls "$SHARE" >/dev/null 2>&1 || true # poke the automount
|
||||
mountpoint -q "$SHARE" || die "$SHARE isn't mounted — is server-marvin up?"
|
||||
fi
|
||||
mkdir -p "$DEST"
|
||||
disk_of() { findmnt -n -o SOURCE -T "$1" | sed 's/\[.*//'; }
|
||||
[[ $(disk_of "$DEST") != "$(disk_of "$HOME")" ]] \
|
||||
|| die "$DEST is on the same disk as your home — that's the disk Ubuntu will wipe"
|
||||
echo "Backing up $HOME -> $DEST"
|
||||
df -h "$DEST" | tail -1
|
||||
|
||||
# -- Archive helper ---------------------------------------------------------------------
|
||||
archive() { # archive <name> <tar args + members...>
|
||||
local name=$1 out="$DEST/$1.tar.zst"; shift
|
||||
step "$name"
|
||||
if [[ -s $out && -z ${FORCE:-} ]]; then echo "already done, skipping"; return; fi
|
||||
local rc=0
|
||||
tar --create --file="$out.partial" --use-compress-program='zstd -T0 -3' \
|
||||
--directory="$HOME" \
|
||||
--checkpoint=100000 --checkpoint-action='ttyout= %{%H:%M:%S}t %T%*\r' \
|
||||
"$@" || rc=$?
|
||||
echo
|
||||
# GNU tar exits 1 when a file changed while it was being read (an app was still open).
|
||||
# Everything else still made it in, so keep the archive; anything above 1 is fatal.
|
||||
(( rc <= 1 )) || die "tar failed on $name (exit $rc)"
|
||||
(( rc == 0 )) || warn "$name: some files changed while being read — close apps and FORCE=1 to redo if it matters"
|
||||
mv "$out.partial" "$out"
|
||||
ls -lh "$out" | awk '{print " " $5}'
|
||||
}
|
||||
|
||||
# Big, self-contained folders get their own archive so they can be restored (or skipped)
|
||||
# separately. Everything else goes in home.tar.zst.
|
||||
archive home \
|
||||
--anchored \
|
||||
--exclude=./.cache \
|
||||
--exclude=./.local/share/Trash \
|
||||
--exclude=./.local/share/Steam \
|
||||
--exclude=./.steam \
|
||||
--exclude=./.local/share/containers \
|
||||
--exclude=./.local/share/flatpak \
|
||||
--exclude=./.local/share/baloo \
|
||||
--exclude='./.var/app/*/cache' \
|
||||
--exclude='./.claude.json.tmp.*' \
|
||||
--exclude=./.xlcore \
|
||||
--exclude=./ComfyUI \
|
||||
--no-anchored \
|
||||
--exclude=node_modules \
|
||||
--exclude=__pycache__ \
|
||||
.
|
||||
|
||||
# FFXIV game install (~124 GB) — Square's patch servers make a redownload take hours.
|
||||
[[ -d $HOME/.xlcore ]] && archive xlcore ./.xlcore
|
||||
|
||||
# ComfyUI minus its venv (rebuilt on Ubuntu); this is ~110 GB of models.
|
||||
[[ -d $HOME/ComfyUI ]] && archive comfyui \
|
||||
--anchored --exclude=./ComfyUI/venv --exclude=./ComfyUI/.venv \
|
||||
--no-anchored --exclude=__pycache__ \
|
||||
./ComfyUI
|
||||
|
||||
# Steam: only saves and settings. Games get redownloaded; the ones on the Data drive stay put.
|
||||
archive steam-saves \
|
||||
./.local/share/Steam/userdata \
|
||||
./.local/share/Steam/steamapps/compatdata
|
||||
|
||||
# -- Reference info for the rebuild -------------------------------------------------------
|
||||
step "manifest"
|
||||
m="$DEST/manifest"; mkdir -p "$m"
|
||||
flatpak list --app --columns=application,origin,installation > "$m/flatpaks.txt" 2>/dev/null || true
|
||||
code --list-extensions > "$m/vscode-extensions.txt" 2>/dev/null || true
|
||||
brew leaves > "$m/brew-leaves.txt" 2>/dev/null || true
|
||||
rpm-ostree status > "$m/rpm-ostree-status.txt" 2>/dev/null || true
|
||||
cp /etc/fstab "$m/fstab"
|
||||
cp -r "$HOME/.local/share/flatpak/overrides" "$m/flatpak-overrides-user" 2>/dev/null || true
|
||||
cp -r /var/lib/flatpak/overrides "$m/flatpak-overrides-system" 2>/dev/null || true
|
||||
lsblk -f > "$m/disks.txt"
|
||||
ls "$HOME/.local/share/Steam/steamapps/common" > "$m/steam-games-home.txt" 2>/dev/null || true
|
||||
ls /run/media/"$USER"/Data/SteamLibrary/steamapps/common > "$m/steam-games-data-drive.txt" 2>/dev/null || true
|
||||
ls "$m"
|
||||
|
||||
# -- Prove every archive reads back cleanly ----------------------------------------------
|
||||
if [[ -z ${SKIP_VERIFY:-} ]]; then
|
||||
for f in "$DEST"/*.tar.zst; do
|
||||
step "verify $(basename "$f")"
|
||||
tar --use-compress-program=zstd --list --file="$f" > /dev/null || die "$f is corrupt — rerun with FORCE=1"
|
||||
echo "ok"
|
||||
done
|
||||
fi
|
||||
|
||||
step "done"
|
||||
du -sh "$DEST"/*.tar.zst
|
||||
echo "Backup is in: $DEST"
|
||||
echo "Safe to wipe the 990 PRO once you've eyeballed that list."
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run on Ubuntu AFTER setup.sh and a reboot. Unpacks the Bazzite backup into your home,
|
||||
# minus the Fedora/KDE-specific bits that would fight a fresh Ubuntu desktop.
|
||||
#
|
||||
# scripts/restore.sh # newest desktop-backup-* on server-marvin
|
||||
# scripts/restore.sh /path/to/backup # a specific backup folder
|
||||
# ONLY="home steam-saves" scripts/restore.sh # just some archives
|
||||
#
|
||||
# Everything is still in the archives, so anything skipped here can be pulled out later:
|
||||
# tar -I zstd -xf home.tar.zst -C ~ ./.config/some-app
|
||||
set -euo pipefail
|
||||
|
||||
SHARE=/mnt/server-marvin-personal
|
||||
|
||||
step() { printf '\n\033[1;34m== %s ==\033[0m\n' "$*"; }
|
||||
die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
[[ $EUID -ne 0 ]] || die "run as your user, not with sudo"
|
||||
ls "$SHARE" >/dev/null 2>&1 || true # poke the automount
|
||||
SRC="${1:-$(ls -d "$SHARE"/desktop-backup-* 2>/dev/null | sort | tail -1)}"
|
||||
[[ -n $SRC && -d $SRC ]] || die "no backup found — pass the folder, or check $SHARE is mounted"
|
||||
ONLY=${ONLY:-home steam-saves xlcore comfyui}
|
||||
echo "Restoring from $SRC: $ONLY"
|
||||
|
||||
pgrep -x steam >/dev/null && die "quit Steam first"
|
||||
|
||||
# Flatpak apps need a GL extension matching the NVIDIA driver, and flatpak can only see the
|
||||
# driver version once it's loaded — i.e. now, after the reboot. Without this they render in software.
|
||||
step "Flatpak NVIDIA runtime"
|
||||
sudo flatpak update -y --noninteractive
|
||||
|
||||
# Old configs (Heroic, Lutris, XIVLauncher, Proton prefixes, ...) hold absolute
|
||||
# /var/home/ckoch/... paths. One symlink makes all of them resolve on Ubuntu.
|
||||
[[ -e /var/home ]] || sudo ln -s /home /var/home
|
||||
|
||||
# Left out of home.tar.zst on purpose:
|
||||
skip=(
|
||||
--anchored
|
||||
# Fedora's shell dotfiles; Ubuntu's are better and setup.sh already added what's needed
|
||||
--exclude=./.bashrc --exclude=./.bash_profile --exclude=./.bash_logout --exclude=./.profile
|
||||
--exclude=./.bashrc.d --exclude=./.zshrc --exclude=./.zprofile
|
||||
# .NET tool shims built against Homebrew's SDK (setup.sh reinstalled dotnet-ef)
|
||||
--exclude=./.dotnet
|
||||
# pip --user installs for Fedora's Python, and launchers for the old distroboxes
|
||||
--exclude=./.local/bin --exclude='./.local/lib/python*'
|
||||
--exclude='./.local/share/applications/claude*'
|
||||
--exclude='./.local/share/applications/war1gus*'
|
||||
--exclude=./.local/share/applications/code.desktop
|
||||
# desktop state that would clobber Ubuntu's: GNOME's settings db, keyring, default apps,
|
||||
# and KDE-generated GTK themes that would recolor GNOME apps
|
||||
--exclude=./.config/dconf --exclude=./.local/share/keyrings --exclude=./.config/mimeapps.list
|
||||
--exclude=./.config/gtk-3.0 --exclude=./.config/gtk-4.0
|
||||
--exclude=./.config/gtkrc --exclude=./.config/gtkrc-2.0 --exclude=./.gtkrc-2.0
|
||||
# Bazzite leftovers
|
||||
--exclude=./.config/bazzite --exclude=./.config/autostart/sb-key-notify.desktop
|
||||
# old SMB password file (setup.sh stored the credentials in /etc/samba)
|
||||
--exclude=./.smbcredentials
|
||||
)
|
||||
|
||||
for name in $ONLY; do
|
||||
f="$SRC/$name.tar.zst"
|
||||
step "$name"
|
||||
[[ -f $f ]] || { echo "not in backup, skipping"; continue; }
|
||||
args=()
|
||||
[[ $name == home ]] && args=("${skip[@]}")
|
||||
tar --extract --file="$f" --use-compress-program=zstd --directory="$HOME" \
|
||||
--checkpoint=100000 --checkpoint-action='ttyout= %{%H:%M:%S}t %T%*\r' \
|
||||
"${args[@]}"
|
||||
echo "ok"
|
||||
done
|
||||
|
||||
# Claude Code keys memory/history by folder path; /var/home/ckoch is now /home/ckoch.
|
||||
if [[ -d ~/.claude/projects ]]; then
|
||||
for d in ~/.claude/projects/-var-home-*; do
|
||||
[[ -d $d ]] || continue
|
||||
new=~/.claude/projects/${d##*/-var}
|
||||
[[ -e $new ]] || mv "$d" "$new"
|
||||
done
|
||||
[[ -f ~/.claude.json ]] && sed -i 's#"/var/home/#"/home/#g' ~/.claude.json
|
||||
fi
|
||||
|
||||
step "Done — a few things to finish by hand"
|
||||
cat <<EOF
|
||||
- Steam: open it, sign in, then Settings > Storage > Add drive > /mnt/data/SteamLibrary
|
||||
(games on the Data drive come back without downloading; home-drive games redownload).
|
||||
- ComfyUI: rebuild its venv —
|
||||
cd ~/ComfyUI && python3 -m venv venv && venv/bin/pip install -r requirements.txt
|
||||
- Old pip --user tools (rembg etc.) weren't restored: pipx install "rembg[cli]" if you want it.
|
||||
- Log out and back in so every app picks up the restored settings.
|
||||
EOF
|
||||
+21
-12
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fresh Ubuntu 26.04 LTS -> my desktop, in one pass. Run as your user; it sudos as needed.
|
||||
# Safe to re-run: each step checks before it changes anything. Reboot when it finishes,
|
||||
# then run scripts/restore.sh.
|
||||
# then run `sudo flatpak update` once so the Flatpak apps get the NVIDIA GL runtime.
|
||||
set -euo pipefail
|
||||
|
||||
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
@@ -9,7 +9,7 @@ REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
# Second NVMe (970 EVO Plus, label "Data"): SteamLibrary + emulator files. Never formatted.
|
||||
DATA_UUID=29db4bd3-b743-417d-aa39-4da4acc9df3f
|
||||
DATA_MNT=/mnt/data
|
||||
# server-marvin SMB share — the backup lives here. \040 is fstab's escaped space.
|
||||
# server-marvin SMB share, mounted if you give it credentials. \040 is fstab's escaped space.
|
||||
MARVIN_SHARE='//192.168.1.193/Personal\040Files\040-\040ckoch'
|
||||
MARVIN_MNT=/mnt/server-marvin-personal
|
||||
MARVIN_CREDS=/etc/samba/credentials-marvin
|
||||
@@ -229,14 +229,17 @@ fi
|
||||
sudo blkid -U "$DATA_UUID" >/dev/null || warn "Data drive ($DATA_UUID) not found — fstab entry is nofail, so boot is fine"
|
||||
|
||||
if [[ ! -f $MARVIN_CREDS ]]; then
|
||||
read -rp "server-marvin SMB username: " smb_user
|
||||
read -rsp "server-marvin SMB password: " smb_pass; echo
|
||||
sudo install -d -m 0755 /etc/samba
|
||||
printf 'username=%s\npassword=%s\n' "$smb_user" "$smb_pass" \
|
||||
| sudo install -m 600 /dev/stdin "$MARVIN_CREDS"
|
||||
unset smb_pass
|
||||
echo "server-marvin SMB share — press Enter to skip mounting it."
|
||||
read -rp " username: " smb_user
|
||||
if [[ -n $smb_user ]]; then
|
||||
read -rsp " password: " smb_pass; echo
|
||||
sudo install -d -m 0755 /etc/samba
|
||||
printf 'username=%s\npassword=%s\n' "$smb_user" "$smb_pass" \
|
||||
| sudo install -m 600 /dev/stdin "$MARVIN_CREDS"
|
||||
unset smb_pass
|
||||
fi
|
||||
fi
|
||||
if ! grep -q "$MARVIN_MNT" /etc/fstab; then
|
||||
if [[ -f $MARVIN_CREDS ]] && ! grep -q "$MARVIN_MNT" /etc/fstab; then
|
||||
echo "$MARVIN_SHARE $MARVIN_MNT cifs credentials=$MARVIN_CREDS,uid=$(id -u),gid=$(id -g),iocharset=utf8,vers=3.0,x-systemd.automount,_netdev,nofail 0 0" \
|
||||
| sudo tee -a /etc/fstab >/dev/null
|
||||
fi
|
||||
@@ -249,7 +252,13 @@ step "Small carry-overs from Bazzite"
|
||||
echo 'options bluetooth disable_ertm=1' | sudo tee /etc/modprobe.d/bluetooth-xbox.conf >/dev/null
|
||||
|
||||
step "Done"
|
||||
cat <<EOF
|
||||
Reboot now (NVIDIA driver + docker/kvm groups take effect), then:
|
||||
scripts/restore.sh
|
||||
cat <<'EOF'
|
||||
Reboot now — the NVIDIA driver and your docker/kvm groups only take effect after that.
|
||||
|
||||
Then, once:
|
||||
sudo flatpak update # pulls the NVIDIA GL runtime the Flatpak apps need.
|
||||
# Skip it and apps render in software until the daily
|
||||
# timer catches up ~10 minutes after boot.
|
||||
|
||||
Then sign in to things, and add /mnt/data/SteamLibrary in Steam > Settings > Storage.
|
||||
EOF
|
||||
|
||||
Reference in New Issue
Block a user