initial: migrace.sh + struktura repa

This commit is contained in:
2026-04-24 14:28:22 +02:00
commit 23b6e58e57
2 changed files with 483 additions and 0 deletions
+137
View File
@@ -0,0 +1,137 @@
# Migrace Arch Linuxu z nvme1n1 na nvme0n1
Skript migruje tvůj běžící Arch (na `nvme1n1`) na druhý NVMe disk (`nvme0n1`) s většími oddíly:
- `/boot` = 1 GB (EFI, FAT32)
- `/` = 150 GB (ext4)
- `/home` = zbytek ~780 GB (ext4)
Systémový obsah se kopíruje 1:1 (balíčky, služby, configy, Docker, GPG, atd.), jen na větší disk.
---
## Před migrací (z běžícího systému)
```bash
# 1. Záloha klíčů ze starého opuštěného disku
sudo mount /dev/nvme0n1p3 /mnt
mkdir -p ~/zaloha_stary_disk_2026
sudo cp -a /mnt/archos/gpg ~/zaloha_stary_disk_2026/ 2>/dev/null
sudo cp -a /mnt/archos/luks_keyfile ~/zaloha_stary_disk_2026/ 2>/dev/null
sudo cp -a /mnt/archos/kody_yubikey ~/zaloha_stary_disk_2026/ 2>/dev/null
sudo cp -a /mnt/archos/zalohy_cloudron_kliče ~/zaloha_stary_disk_2026/ 2>/dev/null
sudo chown -R $USER:$USER ~/zaloha_stary_disk_2026
sudo umount /mnt
# 2. Nech borgmatic doběhnout (pro jistotu čerstvá záloha)
borgmatic --stats
borgmatic list --last 3
# 3. Push skriptu na git.arch-linux.cz
# (udělej repo migrace/ a pushni migrace.sh + README.md)
# 4. Arch ISO na USB flash
# stáhni z https://archlinux.org/download/
sudo dd if=archlinux-*-x86_64.iso of=/dev/sdX bs=4M status=progress oflag=sync
sync
```
---
## Postup v live USB
```bash
# 1. Boot z USB flash (v BIOSu, nebo F8/F11/F12 boot menu)
# 2. V live prostředí:
# - připoj internet (ethernet automaticky; wifi přes iwctl)
iwctl
# device list
# station wlan0 scan
# station wlan0 get-networks
# station wlan0 connect <SSID>
# exit
ping -c 2 archlinux.org
# 3. Stáhni skript
curl -O https://git.arch-linux.cz/Archos/migrace/raw/branch/main/migrace.sh
# nebo kompletní repo:
# pacman -Sy git
# git clone https://git.arch-linux.cz/Archos/migrace.git
# cd migrace
# 4. Spusť
chmod +x migrace.sh
sudo bash ./migrace.sh
# 5. Skript se tě postupně ptá před každým destruktivním krokem.
# Odpovídej "ano" (vše jiné = zrušit).
# 6. Po dokončení:
reboot
# 7. V BIOSu nastav boot priority: nvme0n1 PŘED nvme1n1
```
---
## Po rebootu (nový systém)
```bash
# Ověř, že běžíš z nového disku
df -hT /
# /dev/nvme0n1p2 ext4 147G XG YG X% /
lsblk
# nvme0n1 → mountnutý (/, /boot, /home)
# nvme1n1 → volný (starý systém jen leží)
bootctl status
# YubiKey test
gpg --card-status
# Docker
systemctl status docker
# Síť
nmcli
```
---
## Kdyby cokoliv padlo
**Nenabootuje nový systém:**
1. V BIOSu přepni zpět na `nvme1n1` → starý systém stále funguje (nic jsme na něm neměnili)
2. Boot z live USB, mount `/dev/nvme0n1p2` na `/mnt`, arch-chroot a zkontroluj:
```bash
mount /dev/nvme0n1p2 /mnt
mount /dev/nvme0n1p1 /mnt/boot
arch-chroot /mnt
cat /etc/fstab
cat /boot/loader/entries/*.conf
blkid | grep nvme0n1
bootctl --path=/boot install
mkinitcpio -P
exit
reboot
```
**Starý systém je pořád celý na nvme1n1** dokud ho ručně nepřerozdělíš, je to tvoje záchranná síť.
---
## Až vše funguje (týden+)
```bash
# Smaž staré oddíly a použij nvme1n1 na co chceš
sudo cfdisk /dev/nvme1n1
# Návrhy využití:
# - Docker volumes na oddělený disk (rychlejší than sdílet NVMe)
# - Lokální borg mirror (druhá záloha vedle Hetzner Storage Box)
# - /home/archos/scratch pro build cache a VM disky
# - RAID1 mirror nvme0n1 (paranoia mode)
```
+346
View File
@@ -0,0 +1,346 @@
#!/bin/bash
# migrace.sh - Přesun Arch Linuxu z nvme1n1 na nvme0n1
# Autor: pro Archose, v1.0 (2026-04)
#
# Spouštěj z live USB prostředí (Arch ISO).
# NIKDY ne z běžícího systému, který chceš migrovat.
set -e # padni při první chybě
set -u # padni při nedefinované proměnné
# ======== BAREVNÉ VÝSTUPY ========
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log() { echo -e "${BLUE}[INFO]${NC} $*"; }
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
err() { echo -e "${RED}[ERR]${NC} $*" >&2; }
# ======== KONFIGURACE ========
SRC_DISK="/dev/nvme1n1" # stávající systém
SRC_BOOT="${SRC_DISK}p1"
SRC_ROOT="${SRC_DISK}p2"
SRC_HOME="${SRC_DISK}p3"
DST_DISK="/dev/nvme0n1" # cíl
DST_BOOT="${DST_DISK}p1"
DST_ROOT="${DST_DISK}p2"
DST_HOME="${DST_DISK}p3"
ROOT_SIZE_GB=150
BOOT_SIZE_MB=1024
MNT_OLD="/mnt/old"
MNT_NEW="/mnt/new"
LOG_FILE="/tmp/migrace-$(date +%Y%m%d-%H%M%S).log"
# ======== POMOCNÉ FUNKCE ========
confirm() {
local msg="$1"
echo
echo -e "${YELLOW}>>> $msg${NC}"
read -rp "Pokračovat? (ano/NE): " odp
if [[ "$odp" != "ano" ]]; then
err "Zrušeno uživatelem."
exit 1
fi
}
check_root() {
if [[ $EUID -ne 0 ]]; then
err "Spusť jako root (sudo bash migrace.sh)"
exit 1
fi
}
check_live_env() {
# Pokud je /dev/nvme1n1p2 mountnutý jako /, tak jsme v běžícím systému
if findmnt -n -o SOURCE / | grep -q "nvme1n1p2"; then
err "Běžíš z nvme1n1p2, kterou chceš migrovat!"
err "Tohle MUSÍ běžet z live USB prostředí."
exit 1
fi
}
check_disks() {
for d in "$SRC_DISK" "$DST_DISK"; do
if [[ ! -b "$d" ]]; then
err "Disk $d neexistuje!"
exit 1
fi
done
log "Zdroj: $SRC_DISK ($(lsblk -dno SIZE $SRC_DISK))"
log "Cíl: $DST_DISK ($(lsblk -dno SIZE $DST_DISK))"
}
# ======== KROKY ========
step_01_info() {
clear
cat <<EOF
╔═══════════════════════════════════════════════════════════════╗
║ MIGRACE ARCH LINUXU: nvme1n1 → nvme0n1 ║
╚═══════════════════════════════════════════════════════════════╝
Plán:
1. Přerozdělit $DST_DISK (${ROOT_SIZE_GB} GB root + zbytek home + 1 GB EFI)
2. Mkfs nových oddílů (ext4 + fat32)
3. Rsync /, /boot, /home ze $SRC_DISK na $DST_DISK
4. Upravit fstab a systemd-boot entry na novém systému
5. Chroot a bootctl install
6. Umount a reboot
Log: $LOG_FILE
Stávající stav:
EOF
lsblk -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINTS "$SRC_DISK" "$DST_DISK"
echo
confirm "Potvrzuješ výše uvedený plán?"
}
step_02_partition() {
log "Krok 2: Přerozdělení $DST_DISK"
echo
warn "VŠECHNA DATA NA $DST_DISK BUDOU SMAZÁNA!"
echo "Aktuálně na $DST_DISK:"
lsblk -o NAME,SIZE,FSTYPE,LABEL "$DST_DISK"
confirm "Smazat $DST_DISK a udělat nové oddíly?"
log "Mažu staré oddíly..."
wipefs -a "$DST_DISK"
sgdisk --zap-all "$DST_DISK"
log "Vytvářím nové oddíly..."
sgdisk -n 1:0:+${BOOT_SIZE_MB}M -t 1:ef00 -c 1:"EFI" "$DST_DISK"
sgdisk -n 2:0:+${ROOT_SIZE_GB}G -t 2:8300 -c 2:"arch_root" "$DST_DISK"
sgdisk -n 3:0:0 -t 3:8300 -c 3:"arch_home" "$DST_DISK"
partprobe "$DST_DISK"
sleep 2
ok "Nové rozdělení:"
lsblk -o NAME,SIZE,FSTYPE,LABEL "$DST_DISK"
}
step_03_mkfs() {
log "Krok 3: Formátování"
confirm "Formátovat $DST_BOOT (FAT32), $DST_ROOT (ext4), $DST_HOME (ext4)?"
mkfs.fat -F32 -n EFI "$DST_BOOT"
mkfs.ext4 -F -L arch_root "$DST_ROOT"
mkfs.ext4 -F -L arch_home "$DST_HOME"
ok "Formátováno."
}
step_04_mount() {
log "Krok 4: Mount"
mkdir -p "$MNT_NEW" "$MNT_OLD"
# Cíl
mount "$DST_ROOT" "$MNT_NEW"
mkdir -p "$MNT_NEW/boot" "$MNT_NEW/home"
mount "$DST_BOOT" "$MNT_NEW/boot"
mount "$DST_HOME" "$MNT_NEW/home"
# Zdroj (read-only!)
mount -o ro "$SRC_ROOT" "$MNT_OLD"
mkdir -p "$MNT_OLD/boot" "$MNT_OLD/home"
mount -o ro "$SRC_BOOT" "$MNT_OLD/boot"
mount -o ro "$SRC_HOME" "$MNT_OLD/home"
ok "Namountováno:"
mount | grep -E "$MNT_NEW|$MNT_OLD"
}
step_05_rsync_root() {
log "Krok 5a: Rsync / (bez /boot, /home, virtuálních FS)"
confirm "Spustit rsync root (rychlé, cca 5 min)?"
rsync -aAXHv --info=progress2 \
--exclude='/boot/*' \
--exclude='/home/*' \
--exclude='/dev/*' \
--exclude='/proc/*' \
--exclude='/sys/*' \
--exclude='/tmp/*' \
--exclude='/run/*' \
--exclude='/mnt/*' \
--exclude='/media/*' \
--exclude='/lost+found' \
"$MNT_OLD/" "$MNT_NEW/"
ok "Rsync root hotov."
}
step_06_rsync_boot() {
log "Krok 5b: Rsync /boot"
rsync -aAXHv --info=progress2 "$MNT_OLD/boot/" "$MNT_NEW/boot/"
ok "Rsync boot hotov."
}
step_07_rsync_home() {
log "Krok 5c: Rsync /home (cca 600 GB, 20-40 minut)"
confirm "Spustit rsync home?"
rsync -aAXHv --info=progress2 "$MNT_OLD/home/" "$MNT_NEW/home/"
ok "Rsync home hotov."
}
step_08_update_fstab() {
log "Krok 6: Úprava fstab"
local new_root_uuid new_boot_uuid new_home_uuid
new_root_uuid=$(blkid -s UUID -o value "$DST_ROOT")
new_boot_uuid=$(blkid -s UUID -o value "$DST_BOOT")
new_home_uuid=$(blkid -s UUID -o value "$DST_HOME")
log "Nové UUID:"
log " root ($DST_ROOT): $new_root_uuid"
log " boot ($DST_BOOT): $new_boot_uuid"
log " home ($DST_HOME): $new_home_uuid"
# Záloha starého fstab
cp "$MNT_NEW/etc/fstab" "$MNT_NEW/etc/fstab.pred-migraci"
cat > "$MNT_NEW/etc/fstab" <<EOF
# Migrace na nvme0n1 - $(date)
# Záloha původního: /etc/fstab.pred-migraci
# /dev/nvme0n1p2 - root
UUID=$new_root_uuid / ext4 rw,relatime 0 1
# /dev/nvme0n1p1 - boot (EFI)
UUID=$new_boot_uuid /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2
# /dev/nvme0n1p3 - home
UUID=$new_home_uuid /home ext4 rw,relatime 0 2
# Datový šifrovaný disk (beze změny)
/dev/mapper/data_crypt /mnt/data ext4 defaults 0 2
EOF
ok "Nový fstab:"
cat "$MNT_NEW/etc/fstab"
}
step_09_update_boot_entry() {
log "Krok 7: Úprava systemd-boot entry"
local new_root_partuuid
new_root_partuuid=$(blkid -s PARTUUID -o value "$DST_ROOT")
log "Nový PARTUUID root: $new_root_partuuid"
local entry_file
entry_file=$(ls "$MNT_NEW/boot/loader/entries/"*.conf | head -1)
if [[ -z "$entry_file" ]]; then
err "Nenašel jsem boot entry v $MNT_NEW/boot/loader/entries/"
exit 1
fi
# Záloha
cp "$entry_file" "${entry_file}.pred-migraci"
# Nahrazení PARTUUID
sed -i -E "s|PARTUUID=[a-f0-9-]+|PARTUUID=$new_root_partuuid|" "$entry_file"
ok "Nová boot entry ($entry_file):"
cat "$entry_file"
}
step_10_chroot_bootctl() {
log "Krok 8: Chroot + bootctl install + mkinitcpio"
confirm "Spustit bootctl install a mkinitcpio v chroot?"
# Příprava chrootu
for fs in dev proc sys run; do
mount --rbind /$fs "$MNT_NEW/$fs"
mount --make-rslave "$MNT_NEW/$fs"
done
mount --bind /sys/firmware/efi/efivars "$MNT_NEW/sys/firmware/efi/efivars" || true
chroot "$MNT_NEW" /bin/bash <<'CHROOT_EOF'
set -e
echo ">>> bootctl install..."
bootctl --path=/boot install
echo ">>> mkinitcpio -P..."
mkinitcpio -P
echo ">>> bootctl status:"
bootctl status || true
echo ">>> Hotovo v chroot."
CHROOT_EOF
ok "Chroot dokončen."
}
step_11_umount() {
log "Krok 9: Umount"
umount -R "$MNT_NEW" || true
umount -R "$MNT_OLD" || true
ok "Odpojeno."
}
step_12_final() {
cat <<EOF
╔═══════════════════════════════════════════════════════════════╗
║ HOTOVO ║
╚═══════════════════════════════════════════════════════════════╝
Co dál:
1. reboot
2. V BIOSu nastav boot priority: $DST_DISK PŘED $SRC_DISK
(nebo stiskni boot menu klávesu při startu - F8/F11/F12)
3. Až nabootuje nový systém, ověř:
df -hT / # mělo by být $DST_ROOT
lsblk
bootctl status
4. NECHEJ STARÝ $SRC_DISK NA POKOJI minimálně týden!
Kdyby cokoliv, boothneš do něj a můžeš opravit.
5. Až budeš jistý, můžeš $SRC_DISK použít na cokoliv:
sudo cfdisk $SRC_DISK
Log uložen v: $LOG_FILE
EOF
}
# ======== MAIN ========
main() {
check_root
check_live_env
check_disks
exec > >(tee -a "$LOG_FILE") 2>&1
step_01_info
step_02_partition
step_03_mkfs
step_04_mount
step_05_rsync_root
step_06_rsync_boot
step_07_rsync_home
step_08_update_fstab
step_09_update_boot_entry
step_10_chroot_bootctl
step_11_umount
step_12_final
}
main "$@"