Rescue/Recovery

Материал из ALT Linux Wiki

Recovery

Полное руководство по резервному копированию, восстановлению и переносу операционных систем Linux и Windows, созданию автономных Recovery-систем для конечных пользователей, а также массовому развёртыванию с использованием "спасательной" системы ALT Rescue.

Stub.png
Данная страница находится в разработке.
Эта страница ещё не закончена. Информация, представленная здесь, может оказаться неполной или неверной.


Типовые сценарии

В настоящем руководстве предлагаются решения для следующих типовых задач:

  • Создание резервной копии (backup) системы для последующего восстановления на том же компьютере.
  • Восстановление (restore) системы из ранее созданной резервной копии.
  • Подготовка системы к переносу на другой компьютер или к массовому развёртыванию.
  • Перенос настроенной системы из виртуальной среды (Qemu/KVM, VirtualBox) на "голое железо" или в другую виртуальную среду.
  • Единовременный перенос настроенной системы с одного компьютера на другой, в том числе, по сети, без создания промежуточных образов.
  • Привязка к новому диску и к новому "железу" системы, перенесённой с другого диска или компьютера.
  • Перенос системы с изменением существующей схемы разметки, например, без использования RAID/LVM на разметку с использованием RAID/LVM, с EFI/GPT-разметки на Legacy/MBR-разметку, либо наоборот.
  • Автоматизация процесса восстановления из резервной копии -- создание полноценной Recovery-системы для конечного пользователя.
  • Автоматизация массового развёртывания.

Обзор инструментов и методов

Во всех сценариях предлагается использовать "спасательный" загрузочный диск ALT Rescue, собранный на пакетной базе Сизифа. Из всех известных мне "спасательных" систем, ALT Rescue обеспечивает наиболее подходящий функционал, доступность всех перечисленных далее инструментов, обладает хорошей совместимостью с серверными и десктопными ОС Альт, с ОС Microsoft Windows, с другими ОС на основе Linux, поддерживает загрузку в режимах Legacy/CSM и UEFI, а также сетевую загрузку. С 2019 года сборки образов ALT Rescue имеют встроенную поддержку для автоматизации перечисленных здесь сценариев, правда, пока ещё не всех операций, но мы над этим работаем.

Если отдельного ISO-образа ALT Rescue под рукой нет, на некоторых установочных ISO-образах (например, Альт Рабочая станция 7 СПТ, 8 и 8СП) в режиме Legacy/CSM доступен пункт "Восстановление системы" с аналогичным функционалом. Поскольку эти диски собраны в 2017 году и раньше, проблем загрузки на новом железе в них может быть больше, да и встроенной поддержки автоматизации перечисленных здесь сценариев на них, скорее всего, тоже не будет.

Все описываемые далее операции подразумевают загрузку с носителя ALT Rescue и дальнейшую работу с привилегиями суперпользователя root.

Для определения действующей разметки, названий устройств ваших разделов, их LABEL и UUID, предлагается использовать такие утилиты, как lsblk, blkid, blockdev, fdisk, cfdisk, cgdisk и sfdisk. Основная утилита для работы с программными RAID-массивами Linux -- mdadm. На диске ALT Rescue есть всё необходимое для работы с томами LVM2. Для работы с записями NVRAM можно использовать утилиту efibootmgr, только сначала поинтересуйтесь, не портит ли она ваше "железо". В ряде случаев придётся чрутиться в целевую систему, откуда будет устанавливаться загрузчик grub2 и запускаться make-initrd для создания образа начальной загрузки (для окончательной привязки целевой системы к "реальному железу").

Примечание: Обратите внимание: в данном руководстве в качестве исходного и целевого диска в примерах и коде указывается устройство /dev/sda, в качестве разделов также указываются произвольные номера. Однако в вашем случае диски могут иметь совершенно другие названия нодов, например, /dev/c0d0p3 или /dev/nvme1p5, поэтому никогда не копируйте ничего из этого руководства, предварительно не проверив свои названия утилитами lsblk/blkid/cfdisk.

Посмотреть существующую схему разметки диска /dev/sda можно командами fdisk /dev/sda (консольный интерфейс) ЛИБО cfdisk /dev/sda (NCURCES интерфейс) -- что вам удобнее. Редактировать разметку диска Legacy/MBR вручную удобнее всего также этими двумя утилитами, однако для редактирования вручную разметки GUID/GPT следует использовать команду cgdisk /dev/sda. Для работы с разметкой в скриптах рекомендуется использовать утилиту sfdisk -- она понимает и Legacy/MBR, и GUID/GPT, имеет удобный синтаксис, умеет целиком сохранять и восстанавливать всю схему разметки диска, с её помощью можно добавлять или удалять отдельные разделы, не трогая остального, назначать PART-LABEL и PART-UUID для GUID/GPT-разделов.

Для форматирования разделов предлагается использовать утилиты mkfs.ext4, mkfs.fat, итп. Здесь стоит иметь ввиду, что если целевая система имеет очень старый userspace, а диск форматируется новым Сизифным mkfs.ext4, то без дополнительных опций такая система загружаться не сможет: старые версии grub2 могут ничего не знать о новых фичах ext4. Если внутри целевой системы версия пакета e2fsprogs < 1.43, то диски следует форматировать из Сизифной сборки ALT Rescue с добавлением опции -O ^64bit, например:

# смотрим в чруте:
rpm -q e2fsprogs
e2fsprogs-1.42.13-alt2

# форматируем раздел (снаружи чрута):
mkfs.ext4 -q -j -O ^64bit -L SYSTEM /dev/sda2

# посмотреть, с какими фичами создана файловая система ext4/3/2 можно командой:
dumpe2fs /dev/sda2 2>&1 | grep -E ' (features|flags):'

С файловой системой ext4 нужно учитывать ещё одну тонкость. Если вы перенесли на машину RPM с более новым ядром (kernel-image-*.rpm >= 4.14) по причине того, что старое не видит сетевого интерфейса и полноценно обновиться из репозитория нет возможности, то при запуске старых версий make-initrd (< 0.8.15-alt1.M80P.7), в которых ещё не учитывались т.н. "неявные зависимости" (soft dependencies) внутри ядра, также можно получить не загружаемую систему -- см. altbug #34854, altbug #34865 и altbug #34860. Поэтому в системах с корнем на разделе ext4 в выводе make-initrd всегда следите за тем, чтобы в генерируемый образ попали модули libcrc32c и crc32c-intel (для x86-систем). С более старыми версиями make-initrd данную проблему можно обойти, вручную добавив в /etc/initrd.mk внутри целевой системы перед запуском одноимённой команды такую строчку:

MODULES_PRELOAD += libcrc32c crc32c
Примечание: Если корень и/или SWAP находятся на программном RAID-массиве, версия make-initrd в целевой системе должна быть не менее, чем 0.8.15-alt1.M80P.8 (в P8, для других бранчей требуется уточнение). Иначе система не сможет загрузиться в случае выхода из строя хотя бы одного диска в RAID-массиве или после перезагрузки компьютера, при которой ядро не смогло корректно остановить соответствующий RAID-массив. См. altbug #34963. Перед запуском make-initrd на системах, установленных на RAID-массив, сначала убедитесь, что в userspace имеется пакет make-initrd-mdadm -- он не был включен в ранние версии инсталляторов на основе бранчей P8 и C8 -- см. altbug #29831.

В арсенале ALT Rescue имеются утилиты для по-блочного копирования: partimage, partclone, e2image. Утилиту partimage можно использовать для восстановления разделов NTFS, созданных той же утилитой (вплоть до NTFS v3.0 -- Windows XP и более ранних ОС Microsoft Windows). Не используйте её для бэкапов, особенно NTFS v3.1 (Windows Vista) и более поздних. Вообще, для по-блочного копирования NTFS-разделов рекомендуется использовать partclone.ntfs, для растягивания томов на весь раздел, при необходимости -- ntfsresize, для по-файловых бэкапов NTFS-разделов на диске ALT Rescue имеется утилита wimlib-imagex из пакета wimtools. Не используйте partclone и e2image для по-блочного копирования Linux-разделов, для их сохранения и восстановления предпочтительно использовать утилиту tar и по-файловый метод (см. пояснения далее).

Наиболее простой и переносимый компрессор -- gzip. Его аналог, который умеет задействовать все ядра и распараллеливать сжатие -- pigz, наиболее рекомендуемый компрессор. Современная замена gzip -- zstd, он тоже имеется в наличии. Вообще, на диск ALT Rescue включены почти все известные компрессоры. Для расчёта контрольных сумм образов можно использовать такие утилиты, как md5sum, sha1sum, sha256sum -- на диске они тоже имеются.

Для работы по сети с диском ALT Rescue, для выполнения обновления или установки пакетов из чрута, есть два варианта. Первый -- в режиме Legacy/CSM загрузиться, выбрав пунтк меню "Rescue with remote SSH access (DHCP)". Тогда сеть поднимается автоматически по протоколу DHCP, на сетевой интерфейс назначается IP-адрес, устанавливается пароль пользователя root, запускается служба sshd с разрешением входа root'у по паролю и вся эта информация при загрузке выводится на первый виртуальный терминал. Второй вариант -- поднять сеть вручную, например, так:

# смотрим, какие вообще есть интерфейсы:
ip l

# включаем авто-определение настроек для проводного интерфейса:
dhcpcd -i eth0

# секунд через 20-40 смотрим, какой IP-адрес назначен интерфейсу:
ip a

# если нужен удалённый доступ к этому хосту, включаем SSH и задаём root'овый пароль:
echo "PermitRootLogin yes" >> /etc/openssh/sshd_config
service sshd start
passwd

Для очистки диска и копирования отдельных блоков на диск или с него используется команда dd. Для очистки сигнатур файловых систем и других блочных устройств используется команда wipefs -a /имя/устройства. Чтобы ядро перечитало новую разметку диска, можно использовать команду partprobe /имя/диска, команду blockdev --rereadpt /имя/диска, ЛИБО извлечь диск и вставить его по-новой (верно только для съёмных накопителей), ЛИБО перезагрузить компьютер полностью, что надёжнее всего. Для разделения больших файлов на куски, например, по 1Гб для записи на ISO-9660 DVD, можно использовать утилиту split. Обратная склейка кусков выполняется командой cat. Для записи различных Legacy-загрузчиков в MBR, в том числе, Microsoft, можно использовать утилиту ms-sys.

Подготовка системы ALT к бэкапу или переносу

Перед выполнением ниже перечисленных действий, загружаемся с носителя ALT Rescue и монтируем разделы с исходной системой на чтение и запись, например, корень -- в /mnt/target, домашний каталог -- в /mnt/target/home:

test -d /mnt/target || mkdir -m755 /mnt/target
mount -t ext4 -o noatime,nodiratime /dev/sda2 /mnt/target
mount -t ext4 -o noatime,nodiratime,nosuid /dev/sda3 /mnt/target/home

Теперь удалите файл /mnt/target/etc/udev/rules.d/70-persistent-net.rules, если таковой имеется в наличии -- он будет создан при первом же запуске автоматически.

Далее: пропустите этот раздел:

  • если бэкап системы предназначен для последующего восстановления на тот же самый компьютер в неизменном виде;
  • если хотите сохранить всю систему ALT "как есть" (единственное, когда действительно надо делать именно так, это полный бэкап для восстановления потом на тот же самый компьютер, так что, скорее всего, это не ваш вариант);
  • если планируется единовременный перенос системы ALT с одного компьютера на другой с очень схожей или такой же конфигурацией, и работа этих двух компьютеров в одной сети исключена.

Если же планируется создать несколько клонов одного компьютера и/или если конфигурации исходного и целевого компьютеров различаются (как вариант, выполняется перенос системы из виртуальной среды на "голое железо"), данный раздел -- для вас.

Переименовываем проводной физический интерфейс в eth0 для однообразия (пример):

mv -f /mnt/target/etc/net/ifaces/enp0s4 /mnt/target/etc/net/ifaces/eth0

Это может оказаться полезным, если заранее не знаем, как он будет называться в целевой системе, если целевые системы будут иметь разные интерфейсы. В данном примере интерфейс в исходной системе назывался "enp0s4", у вас он может называться как-то иначе. Если же заведомо достоверно известно, что интерфейсы исходной и целевой системы не отличаются, пропустите этот шаг.

Примечание: Обратите внимание: в системах, настраиваемых для последующего клонирования, имя компьютера желательно изначально давать также однообразно, чтобы при создании уникального клона его было легко переименовать. В настоящем руководстве предлагается использовать такое имя исходного компьютера: "computername". Приватные и публичные ключи SSH, SSL-сертификаты, итп при клонировании необходимо генерировать новые, а во-избежании недоразумений, лучше всего их ещё и вычищать из исходного образа до создания бэкапа.


Очистка среды обычного пользователя /home/$username (пример):

userdir="/mnt/target$(grep ':500:500:' /mnt/target/etc/passwd | cut -f6 -d:)"
if [ -d "$userdir" ]; then
        rm -rf "$userdir/.cache"
        rm -rf "$userdir/.dbus"
        rm -rf "$userdir/.linuxmint"
        rm -rf "$userdir/.local"
        rm -rf "$userdir/.config/caja"
        rm -rf "$userdir/.config/gconf"
        rm -rf "$userdir/.config/goa-1.0"
        rm -rf "$userdir/.config/menus"
        rm -rf "$userdir/.config/mintmenu"
        rm -rf "$userdir/.config/pulse"
        rm -rf "$userdir/.xsession.d"
        rm -f "$userdir/.config/Trolltech.conf"
        rm -f "$userdir/.config/monitors.xml"
        rm -f "$userdir/.ICEauthority"
        rm -f "$userdir/.bash_history"
        rm -f "$userdir/".xsession-errors*
        rm -f "$userdir/.ssh/agent"
fi
unset userdir

Очистка среды пользователя root (пример):

rm -rf /mnt/target/root/.cache
rm -rf /mnt/target/root/.local
rm -rf /mnt/target/root/.install-log
rm -f /mnt/target/root/.bash_history

Очистка системной конфигурации (пример):

rm -f /mnt/target/etc/resolv.conf.dnsmasq
rm -f /mnt/target/etc/openssh/ssh_host_*key*
rm -f /mnt/target/etc/*.bak
rm -f /mnt/target/etc/*.old

Очистка системных журналов (пример):

cd /mnt/target/var/log
rm -f Xorg.0.log* alterator-net-iptables
find . -type f -name '*.old' -delete
rm -rf "$(ls -d journal/???* || echo NotExistingsDir)"
find . -type f -and ! -empty | cut -c3- | grep -v README |
while read filename; do
        test ! -r "$filename" || :> "$filename"
done
unset filename
cd "$OLDPWD"

Очистка корневой системы от прочего "мусора" (пример):

rm -rf /mnt/target/tmp/alterator
rm -rf /mnt/target/tmp/.private/*
rm -rf /mnt/target/tmp/hsperfdata_root
rm -rf /mnt/target/var/lib/ldm/.dbus/session-bus
rm -f /mnt/target/var/cache/fontconfig/*.cache-?
rm -f /mnt/target/var/lib/NetworkManager/dhclient-*.lease
rm -f /mnt/target/var/lib/NetworkManager/dhclient-*.conf
rm -f /mnt/target/var/lib/NetworkManager/timestamps
rm -f /mnt/target/var/run/alteratord/alteratord.log
rm -f /mnt/target/var/run/alteratord.pid
rm -f /mnt/target/var/lib/systemd/random-seed
rm -f /mnt/target/var/lib/dbus/machine-id
rm -f /mnt/target/etc/machine-id
rm -f /mnt/target/run/blkid/blkid*
rm -f /mnt/target/run/messagebus.pid

Лучше один раз сохранить нужные команды в скрипт, чтобы не пришлось потом вводить всё заново. Если делаете чистку диска не скриптом, используйте, например, mc (Midnight Commander), чтобы пройтись по всем каталогам и удалить всё явно лишнее. В любом случае необходимо понимать, что и зачем удаляется.

Куда сохранять образы системы и другие файлы?

Если надо сохранить файлы на хост-систему из виртуальной машины QEMU, запущенной с опциями:

-fsdev local,security_model=none,id=fsdev1,path=/path/to/backupdir
-device virtio-9p-pci,id=fs1,fsdev=fsdev1,mount_tag=backup

то даём такие команды в виртуалке:

grep -qws 9p /proc/modules || modprobe 9p
test -d /mnt/backup || mkdir -m755 /mnt/backup
mount -t 9p -o rw,nosuid,trans=virtio,version=9p2000.L,access=any backup /mnt/backup

Если надо сохранить файлы на хост-систему из виртуальной машины VirtualBox, даём такие команды в виртуалке:

grep -qws vboxsf /proc/modules || modprobe vboxsf
test -d /mnt/backup || mkdir -m755 /mnt/backup
mount -t vboxsf -o rw,nosuid backup /mnt/backup

В обоих примерах backup -- название общего ресурса между хостовой и гостевой системами.

Один из самых удобных способов в большой сети -- сохранять бэкапы на уже имеющийся сервер:

test -d /mnt/backup || mkdir -m755 /mnt/backup
mount -t cifs -o noatime,nodev,nosuid,ip=192.168.1.10,dir_mode=0750,file_mode=0640,\
        iocharset=utf8,domain=DOMAINNAME,username=USERNAME,password=PASSWORD \
        //SAMBASERVER/sharename /mnt/backup

Можно сохранять бэкапы на выделенный для этих целей внешний USB HDD с меткой тома OSBACKUPS и файловой системой NTFS:

test -d /mnt/backup || mkdir -m755 /mnt/backup
mount -t ntfs-3g -o noatime,nodiratime,nodev,nosuid,\
        fmask=0133,dmask=0022,efs_raw,big_writes,recover \
        -L OSBACKUPS /mnt/backup

Хотя более предпочтительны для хранения бэкапов файловые системы xfs или ext3:

test -d /mnt/backup || mkdir -m755 /mnt/backup
mount -t xfs -o noatime,nodiratime,nodev,nosuid -L OSBACKUPS /mnt/backup
mount -t ext3 -o noatime,nodiratime,nodev,nosuid -L OSBACKUPS /mnt/backup

Если метка тома при форматировании диска не была указана, монтируемый раздел можно определить по последним сообщениям в dmesg сразу после подключения внешнего HDD:

# dmesg | tail
[ 3163.416320] sd 0:0:0:0: [sda] 3907029167 512-byte logical blocks: (2.00 TB/1.82 TiB)
...
[ 3163.504836]  sda: sda1

# lsblk /dev/sda
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0  1,8T  0 disk
└─sda1   8:1    0  1,8T  0 part

# blkid -c /dev/null -o value -s TYPE /dev/sda1
ext3

# test -d /mnt/backup || mkdir -m755 /mnt/backup
# mount -t ext3 -o noatime,nodiratime,nodev,nosuid /dev/sda1 /mnt/backup

А самый напрашивающийся способ очень часто -- сохранить бэкапы локально, если используется по-файловый метод и позволяет место на диске, а после создания бэкапов перенести их куда надо. Для этого в ранее смонтированном разделе /mnt/target/home создадим директорию Recovery, а когда будем создавать образы tar'ом, просто включим её в список исключаемых из архива.

test -d /mnt/target/home/Recovery ||
        mkdir /mnt/target/home/Recovery
rmdir /mnt/backup || rm -f /mnt/backup
ln -snf /mnt/target/home/Recovery /mnt/backup

Сохранение разделов с ОС Linux

Рекомендуемый метод сохранения -- по-файловый, с использованием утилиты tar. Альтернатива -- сохранить все занятые блоки раздела при помощи partclone или другой подобной утилиты сильно уступает по-файловому методу: дольше, объём больше, может быть привязка к определённой версии утилиты, а главный недостаток -- привязка к размеру блочного устройства, невозможность восстановить данные на устройство меньшего размера, необходимость увеличивать размер тома после восстановления на раздел большего размера. Никаких преимуществ у по-блочного метода в сравнении с по-файловым методом НЕТ. По крайней мере, если говорить о файловых системах Linux. С разделами Windows NTFS ситуация несколько иная.

Сохраняем домашние каталоги пользователей (пример):

cd /mnt/target/home
tar -cpSf - --numeric-owner --one-file-system \
        --exclude='lost+found' --exclude='Recovery' * |
        pigz -9qnc > /mnt/backup/home.tgz
cd "$OLDPWD"

Сохраняем корневой каталог (пример):

cd /mnt/target
tar -cpSf - --numeric-owner --one-file-system \
        --exclude='lost+found' --exclude='home/*' * |
        pigz -9qnc > /mnt/backup/root.tgz
cd "$OLDPWD"

Другие полезные опции tar для сохранения дополнительной информации, исключения лишнего и уменьшения флуда:

--acls                      если надо сохранить атрибуты POSIX ACL
--xattrs                    если надо сохранить расширенные атрибуты
--selinux                   если надо сохранить мандатные метки SELinux
--exclude='boot/efi/*'      если не надо сохранять содержимое отдельного раздела ESP
--exclude-caches            если не надо сохранять содержимое кэш-директорий
--warning=no-cachedir       чтобы не было предупреждений о пропускаемых кэш-директориях
--warning=no-file-ignored   чтобы не было предупреждений о невозможности забэкапить
                            сокеты итп, что и так создаётся при первом же запуске

Если в вашем образе ALT Rescue нет компрессора pigz (например, пункт "Восстановление системы" в установочных образах СПТ7 и Альт Рабочая станция 8СП), можно использовать вместо него gzip, либо запускать tar с опцией -z:

tar -cpzSf - ... > /mnt/backup/filename.tgz

Сохранение раздела EFI

В подавляющем большинстве случаев сохранять раздел EFI (ESP) не следует. При создании бэкапа системы с EFI-загрузкой используйте дополнительный ключ команды tar: --one-file-system ЛИБО --exclude='boot/efi/*' чтобы исключить из образа файлы, которые всё равно будут созданы заново в целевой системе описываемым далее способом. На системах с Legacy/CSM-загрузкой такого раздела и вовсе нет. Единственное, когда может потребоваться сохранять и восстанавливать раздел EFI (ESP), -- мульти-загрузка UEFI с несколькими ОС, например, ALT, Ubunu и Windows. В этом случае используйте по-файловый метод и команду tar для сохранения раздела:

# монтируем раздел EFI (после того, как смонитруем корень)
mount -o ro,umask=0,quiet,showexec,iocharset=utf8,codepage=866 \
        -t vfat /dev/sda1 /mnt/target/boot/efi

# создаём отдельный образ EFI-раздела
cd /mnt/target/boot/efi
tar -cpzSf /mnt/backup/efi.tgz --numeric-owner --one-file-system EFI
cd "$OLDPWD"

# размонтируем раздел EFI
umount /mnt/target/boot/efi || umount -l /mnt/target/boot/efi
Примечание: Здесь монтируется стандартный EFI-раздел. Спецификация UEFI предписывает на встроенных накопителях использовать файловую систему FAT32, а на съёмных накопителях EFI-раздел может быть FAT32, FAT16 и FAT12. Тем не менее, встречаются "кривые прошивки" (например, в моноблоках HP), где данная спецификация нарушается и первый EFI-раздел с предустановленной Windows 10 отформатирован в файловой системе NTFS! Поэтому будьте внимательны при монтировании EFI-раздела. Подобные "косяки" лучше сразу выправлять описанным здесь и далее способом.


Сохранение раздела BBP

В подавляющем большинстве случаев сохранять раздел BIOS Boot Partition (BIOS Grub) не следует. На системах с Legacy/CSM-загрузкой такого раздела и вовсе нет. Единственное, когда может потребоваться сохранять и восстанавливать раздел BBP -- при массовом развёртывании на одинаковые компьютеры в режиме загрузки UEFI с одинаковыми дисками ускоренным методом, то есть, без входа в чрут, что в ряде случаев экономит до 40% времени на разливку одной машины. Единственный способ сохранения такого раздела -- все блоки командой dd:

dd if=/dev/sda2 bs=512 | pigz -9qnc > /mnt/backup/bbp.gz

Для ускорения и уменьшения образа рекомендуется разбивать диск исходной системы вручную и перед установкой системы затереть этот раздел нулями, опять же командой dd. В этом случае после установки загрузчика можно будет точно узнать, где заканчиваются данные grub2 stage1.5 и начинаются нули.

Сохранение области VBR

В подавляющем большинстве случаев сохранять область VBR не следует. На системах с UEFI-загрузкой такой области и вовсе нет. Единственное, когда может потребоваться сохранять и восстанавливать область VBR -- при массовом развёртывании на одинаковые компьютеры в режиме загрузки Legacy/CSM с одинаковыми дисками ускоренным методом, то есть, без входа в чрут, что в ряде случаев экономит до 40% времени на разливку одной машины. Единственный способ сохранения области VBR -- несколько первых блоков диска командой dd:

dd if=/dev/sda bs=512 count=80 | pigz -9qnc > /mnt/backup/vbr.gz

Для ускорения и уменьшения образа рекомендуется разбивать диск исходной системы вручную и перед установкой системы затереть начальную часть диска нулями, опять же командой dd. В этом случае после установки загрузчика можно будет точно узнать, где заканчиваются данные grub2 stage1.5 и начинаются нули.

dd if=/dev/zero bs=1M count=4 of=/dev/sda

Сохранение разделов с ОС Windows

Если MS Windows 7/8/10 подготовлена к массовому развёртыванию в соответствии с документацией Microsoft (режим 4-specialize, экран приветствия OOBE), то лучше использовать по-файловый метод и утилиту wimlib-imagex, которая умеет создавать WIM- и ESD-образы NTFS-разделов. В противном случае остаётся использовать только по-блочный метод и утилиту partclone.ntfs, причём таким бэкапом можно будет воспользоваться для восстановления только на том же самом компьютере, для клонирования на другие машины данный образ, скорее всего, непригоден.

Перед сохранением разделов, удалите с них явно лишнее:

mount -o noatime,nodiratime,nodev,nosuid,fmask=0133,\
        dmask=0022,efs_raw,big_writes,recover \
        -t ntfs-3g /dev/sda1 /mnt/target
rm -f /mnt/target/hiberfil.sys
rm -f /mnt/target/pagefile.sys
umount /mnt/target || umount -l /mnt/target

По-блочный метод (partclone.ntfs):

partclone.ntfs -c -s /dev/sda1 | pigz -9qnc >DiskC.ntfs.gz
partclone.ntfs -c -s /dev/sda2 | pigz -9qnc >DiskD.ntfs.gz

По-файловый метод (wimlib-imagex):

wimlib-imagex capture /dev/sda1 w764base.esd \
        --boot --solid --solid-compress=LZMS:100 \
        --solid-chunk-size=16M "Windows 7 x64 Pro" \
        "Windows 7 x64 Professional Russian"

Сохранение других разделов

ToDo: ...

Сохранение схемы разметки диска

Для сохранения существующей схемы разметки можно использовать несколько простых команд:

# сохраняем информацию о разделах указанного диска:
sfdisk -d /dev/sda > /mnt/backup/sda.sfdisk

# Смотрим, какие RAID-массивы имеются, какие разделы используюся
cat /proc/mdstat

# сохраняем дампы суперблоков устройств программных RAID-массивов:
mkdir -p /mnt/backup/raid/md{0,1}
mdadm --dump=/mnt/backup/raid/md0 /dev/sda2 /dev/sdb2
mdadm --dump=/mnt/backup/raid/md1 /dev/sda3 /dev/sdb3

# сохраняем всю конфигурацию LVM2:
vgcfgbackup -vf /mnt/backup/lvm2.cfg

# сохраняем теги файловых систем:
blkid -c /dev/null > /mnt/backup/blkid.tab

Сохранение контрольных сумм образов и других больших файлов

Прежде чем переносить куда-либо созданные образы, хорошо бы сразу посчитать их контрольные суммы. Для надёжности желательно выполнять проверку хотя бы двумя разными алгоритмами:

cd /mnt/backup
md5sum *.tgz *.gz > checksum.MD5
sha256sum *.tgz *.gz > checksum.256
cd "$OLDPWD"

Восстановление схемы разметки диска

Для восстановления ранее сохранённой схемы разметки "один в один" можно использовать несколько простых команд:

# обнуляем начало диска:
dd if=/dev/zero bs=1M count=4 of=/dev/sda oflag=direct

# восстанавливаем информацию о разделах указанного диска:
sfdisk /dev/sda < /mnt/backup/sda.sfdisk

# заставляем ядро перечитать новую таблицу разметки
sync; sleep 5; partprobe /dev/sda

# удаляем сигнатуры на всех созданных разделах диска
wipefs -a /dev/sda?*

# предварительно чистим устройства программных RAID-массивов:
dd if=/dev/zero bs=1M of=/dev/sda2 oflag=direct status=progress
dd if=/dev/zero bs=1M of=/dev/sda3 oflag=direct status=progress
dd if=/dev/zero bs=1M of=/dev/sdb2 oflag=direct status=progress
dd if=/dev/zero bs=1M of=/dev/sdb3 oflag=direct status=progress

# восстанавливаем суперблоки устройств программного RAID:
mdadm --restore=/mnt/backup/raid/md0 /dev/sda2 /dev/sdb2
mdadm --restore=/mnt/backup/raid/md1 /dev/sda3 /dev/sdb3

# собираем и запускаем программные RAID-массивы:
mdadm -As && cat /proc/mdstat

# восстанавливаем всю конфигурацию LVM2:
vgcfgrestore -vf /mnt/backup/lvm2.cfg

Обратите внимание: указанный здесь способ восстановления конфигурации RAID-массивов простой, универсальный, но совершенно неэффективный. Кроме того, если на исходной системе определялся homehost, а на целевой системе подразумевается смена имени хоста, homehost RAID-массивов в таком случае лучше тоже сразу поменять. Именно поэтому вместо указанного здесь способа предпочтительно создавать RAID-массивы вручную, целиком и полностью заново.

Ручная разметка диска: схема Legacy/MBR

  • Поддерживаются диски размером до 2Тб.
  • Допускается загрузка в режиме Legacy/CSM (BIOS).
  • Допускается загрузка в режиме UEFI, но с оговорками, на практике применяется крайне редко.

Рекомендуемая разметка, режим загрузки BIOS:

  • Первый раздел: SWAP (Type Linux swap, 0x82), размером от RAM до RAM*2.
  • Второй раздел: корневой (ext4, Type Linux 0x83) размером 20-40Гб, активный.
  • Третий раздел: /home либо /var (ext4, Type Linux 0x83), вся оставшаяся часть диска.

Рекомендуемая разметка, режим загрузки UEFI:

  • Первый раздел: ESP (FAT32, Type EFI, 0xEF), размером 100Мб, активный.
  • Второй раздел: SWAP (Type Linux swap, 0x82), размером от RAM до RAM*2.
  • Третий раздел: корневой (ext4, Type Linux, 0x83), размером 20-40Гб.
  • Четвёртый раздел: /home либо /var (ext4, Type Linux, 0x83), вся оставшаяся часть диска.

Авто-разметка диска: схема Legacy/MBR

#!/bin/sh

# Целевой диск
target="/dev/sda"

# Размер раздела подкачки (#1)
swapsize="8G"

# Размер корневого раздела (#2)
rootsize="30G"

# Размер раздела данных (#3, если не указать,
# распределяется всё оставшееся место на диске)
#
homesize=

# Предварительная очистка диска
echo "Please wait, initializing HDD..."
(       if [ -b ${target}1 ]; then
                wipefs -a $(ls -r ${target}?*)
        fi
        wipefs -a $target
        dd if=/dev/zero bs=1M count=4 of=$target
) >/dev/null 2>&1

# Создание разделов
LC_ALL=C sfdisk -X dos -W always -q $target <<-EOF
,$swapsize,S
,$rootsize,L,*
,$homesize,L
EOF
sync; sleep 5
partprobe $target

# Форматирование разделов
wipefs -a $(ls -r ${target}?*)
mkswap -L SWAP ${target}1
mkfs.ext4 -j -q -L SYSTEM ${target}2
mkfs.ext4 -j -q -L USERDATA ${target}3

Ручная разметка диска: схема GUID/GPT

  • Поддерживаются диски любого размера, в том числе, более 2Тб.
  • Загрузка в режиме Legacy/CSM (BIOS), хотя и допускается, поддерживается весьма условно, не всеми прошивками BIOS, только с "гибридной" MBR и кучей других оговорок, поэтому здесь не обсуждается.
  • Допускается загрузка в режиме UEFI, при этом должен быть создан раздел ESP с файловой системой FAT32 и для загрузки grub2 stage1.5 на том же диске должен быть создан ещё один раздел -- BIOS Boot Partition (BPP).

Рекомендуемая разметка, режим загрузки UEFI:

  • Первый раздел: ESP (FAT32, Type EFI, 0xEF00), размером 100Мб.
  • Второй раздел: BPP (без файловой системы, GUID 21686148-6449-6E6F-744E-656564454649), размером 8Мб.
  • Третий раздел: SWAP (Type Linux swap, 0x8200), размером от RAM до RAM*2.
  • Четвёртый раздел: корневой (ext4, Type Linux, 0x8300), размером 20-40Гб.
  • Пятый раздел: /home либо /var (ext4, Type Linux, 0x8300), вся оставшаяся часть диска.

Обратите внимание: разделы ESP и BPP обязательны для загрузки Linux в режиме UEFI, они не могут располагаться внутри томов LVM2, на шифрованных дисках и быть созданы поверх программных RAID-массивов. Современные версии grub2 понимают RAID и LVM2, поэтому создавать отдельный раздел /boot сейчас нет никакой необходимости. При использовании мульти-загрузки большого числа операционных систем, размер EFI-раздела можно увеличить.

Авто-разметка диска: схема GUID/GPT

#!/bin/sh

# Целевой диск
target="/dev/sda"

# Размер раздела ESP (#1)
efisize="100M"

# Размер раздела подкачки (#3)
swapsize="8G"

# Размер корневого раздела (#4)
rootsize="30G"

# Размер раздела данных (#5, если не указать,
# распределяется всё оставшееся место на диске)
#
homesize=

# Предварительная очистка диска
echo "Please wait, initializing HDD..."
(	if [ -b ${target}1 ]; then
		wipefs -a $(ls -r ${target}?*)
	fi
	wipefs -a $target
	dd if=/dev/zero bs=1M count=4 of=$target
) >/dev/null 2>&1

# Создание разделов
LC_ALL=C sfdisk -X gpt -W always -q $target <<-EOF
,$efisize,U
,8M,21686148-6449-6E6F-744E-656564454649
,$swapsize,S
,$rootsize
,$homesize
EOF
sync; sleep 5
partprobe $target
LC_ALL=C sfdisk -q --part-label $target 1 ESP
LC_ALL=C sfdisk -q --part-label $target 2 GRUB
LC_ALL=C sfdisk -q --part-label $target 3 SWAP
LC_ALL=C sfdisk -q --part-label $target 4 ROOT
LC_ALL=C sfdisk -q --part-label $target 5 HOME

# Форматирование разделов
wipefs -a $(ls -r ${target}?*)
mkfs.fat -f2 -F32 -n ESP ${target}1
mkswap -L SWAP ${target}3
mkfs.ext4 -j -q -L SYSTEM ${target}4
mkfs.ext4 -j -q -L USERDATA ${target}5

Обратите внимание: на различие PART-LABEL и LABEL по выводу blkid -- такое допускается, это ни одно и то же.

Разметка диска: создание RAID-массивов

При создании RAID-массивов необходимо учитывать следующее:

  • Тип раздела Linux RAID autodetect (0xFD) подразумевает возможность загрузки с такого массива средствами ядра, если версия суперблока 0.9, однако и для других версий суперблока такой тип раздела поддерживается, просто собирает такие массивы уже не ядро, а mdamd путём сканирования на стадии загрузки initrd.
  • В зависимости от версии суперблока 1.0, 1.1 или 1.2, данные массива могут или не могут располагаться в самом начале, что важно для процесса загрузки. Загрузиться можно с массива, у которого версия суперблока 0.9 или 1.0, по умолчанию же выбирается версия 1.2.
  • У массивов с суперблоком версии 0.9 есть значительные ограничения на размер устройств и на общее число устройств в массиве.
  • Если grub2 устанавливается на RAID-массив, на некоторых платформах могут быть проблемы с gfxboot, поэтому в такой конфигурации предпочтительно запускать grub2 в режиме текстового меню, без графики.
# создаём массив RAID1 "/dev/md/ROOT" с суперблоком v1.0:
mdadm --create --verbose --metadata=1.0 --name=ROOT --homehost=$(hostname)
        --level=1 --raid-devices=2 /dev/md/ROOT /dev/sd[ab]2

# после восстановления разделов добавляем данные обо всех массивах в конфиг:
mdadm --detail --scan --verbose | awk '/ARRAY/ {print}' >> /mnt/target/etc/mdadm.conf

Разметка диска: конфигурирование LVM2

Тут всё довольно стандартно:

# определяем физические тома
pvcreate /dev/md/R[12]

# определяем группу логических томов
vgcreate vg0 /dev/md/R[12]

# создаём логические тома
lvcreate -L8G -i2 -n swap vg0         # /dev/vg0/swap
lvcreate -L30G -i2 -n root vg0        # /dev/vg0/root
lvcreate -l100%FREE -i2 -n home vg0   # /dev/vg0/home

Форматирование разделов, восстанавливаемых по-файловым методом

В простейшем случае определяем только метки томов, хотя это необязательно:

target="/dev/sda"
mkfs.fat -f2 -F32 -n ESP ${target}1
mkswap -L SWAP ${target}3
mkfs.ext4 -j -q -L SYSTEM ${target}4
mkfs.jfs -q -L USERDATA ${target}5
mkfs.xfs -q -f -L BIGDATA /dev/sdb1

Также не забывайте про особенности ext4, старый userspace и новый e2fsprogs. При необходимости, замените одну строку в предыдущем примере на:

# чтобы старый grub2 мог загрузиться с раздела, отформатированного Сизифным mkfs.ext4:
mkfs.ext4 -j -q -O ^64bit -L SYSTEM ${target}4

Если диск в целевой системе предполагается всего один, то для простоты переноса лучше сразу поменять все значения UUID=... в файлах /etc/fstab и /etc/sysconfig/grub2 на соответствующие значения /dev/sdaN либо LABEL=... В строке GRUB_AUTOUPDATE_DEVICE=... файла /etc/sysconfig/grub2 также следует сразу изменить значение вида '/dev/disk/by-uuid/... ' на '/dev/sda '. Если же дисков будет более одного, либо есть желание оставить старые варианты UUID'ов как есть, в том числе, для ускорения массового развёртывания, придётся добавить UUID'ы из исходной системы при форматировании дисков в целевой системе:

target="/dev/sda"
mkfs.fat -f2 -F32 -U D8D3-34C6 -n ESP ${target}1
mkswap -U 9648717b-80c5-4497-9564-bbfb7b52b42f -L SWAP ${target}3
mkfs.ext4 -j -q -U 961341fe-545d-4fc9-84a6-15d5e534b305 -L SYSTEM ${target}4
mkfs.jfs -q -U cdd59135-4689-4f5f-a7a8-93a4e199000f -L USERDATA ${target}5
mkfs.xfs -q -f -U fa49e240-f86a-4d50-8b0e-c074a0cfd601 -L BIGDATA /dev/sdb1

Восстановление разделов с ОС Linux

target="/dev/sda"
cd /mnt/backup

#...

# Восстановление корневого раздела
echo; echo "Restoring system partition..."
test -d /mnt/target || mkdir -pm755 /mnt/target
mount -t ext4 -o noatime ${target}2 /mnt/target
unpigz -qnc root.tgz | tar -xpSf - --overwrite -C /mnt/target

# Восстановление раздела данных
echo; echo "Restoring data partition..."
test -d /mnt/target/home || mkdir -m755 /mnt/target/home
mount -t ext4 -o noatime,nosuid ${target}3 /mnt/target/home
unpigz -qnc home.tgz | tar -xpSf - --overwrite -C /mnt/target/home

Другие полезные опции tar при восстановлении:

--acls     если надо восстановить атрибуты POSIX ACL
--xattrs   если надо восстановить расширенные атрибуты
--selinux  если надо восстановить мандатные метки SELinux

Восстановление раздела EFI

Как правило, не требуется, только в случае EFI мульти-загрузки с несколькми ОС:

target="/dev/sda"
cd /mnt/backup

#...

# Восстановление раздела ESP
echo; echo "Restoring ESP partition..."
rm -rf /mnt/target/boot/efi/* 2>/dev/null
mount -o umask=0,quiet,showexec,iocharset=utf8,codepage=866 \
        -t vfat ${target}1 /mnt/target/boot/efi
unpigz -qnc efi.tgz | tar -xpSf - --overwrite -C /mnt/target/boot/efi

Восстановление раздела BBP

Как правило, не требуется, только в случае отказа от входа в чрут для ускорения массового развёртывания:

unpigz -qnc bbp.gz | dd of=/dev/sda2 bs=512 oflag=direct status=none

Восстановление разделов с ОС Windows

По-блочный метод (partclone.ntfs):

unpigz -qnc DiskC.ntfs.gz | partclone.ntfs -r -s - -o /dev/sda1
partclone.ntfsfixboot -w /dev/sda1
unpigz -qnc DiskD.ntfs.gz | partclone.ntfs -r -s - -o /dev/sda2

По-файловый метод (wimlib-imagex):

mkfs.ntfs -q -f -U -I -L Data /dev/sda2
mkfs.ntfs -q -f -U -I -L System /dev/sda1
wimlib-imagex apply w764base.esd /dev/sda1
ms-sys -7 -w /dev/sda

Восстановление других разделов

ToDo: ...

Перенос системы по локальной сети

ToDo: ...

Изменение размеров томов

ToDo: ...

Создание уникального клона

Независимо от того, будет делаться чрут в целевую систему или нет, при создании нескольких клонов необходимо обеспечить их уникальность:

computer="notebook"

#...

# Обеспечиваем уникальность
echo; echo "Personification..."
iface="$(ip route 2>/dev/null | grep -E '^default via ' | awk '{print $5;}')"
test -n "$iface" || iface="$(ls -1 /sys/class/net/ | grep -v lo | head -n1)"
hw="$(ip link show dev ${iface:-eth0} 2>/dev/null | tail -n1 |
        awk '{print $2;}' | sed 's,:,,g' | cut -c7-)"
test -z "$hw" || computer="$computer-$hw"
dbus-uuidgen > /mnt/target/etc/machine-id
cp -Lf /mnt/target/etc/machine-id /mnt/target/var/lib/dbus/machine-id
sed -i "s,computername,$computer," /mnt/target/etc/sysconfig/network
head -c512 /dev/urandom > /mnt/target/var/lib/systemd/random-seed
chmod 600 /mnt/target/var/lib/systemd/random-seed

Здесь к имени компьютера по умочланию ("notebook") добавляются последние 6 цифр MAC-адреса проводного интерфейса, генерируется уникальный machine-id для dbus, инициализируется пул энтропии systemd. Генерировать хостовые ключи SSH нужно уже из чрута и желательно это делать в конце процедуры развёртывания. Впрочем, при первом запуске службы SSH эти ключи также будут сгенерированы.

Привязка к новому "железу" и установка загрузчика

Основные команды, выполняемые в чруте целевой системы:

# Установка системного загрузчика
echo "Installing boot loader..."

# BIOS-загрузка
# grub-install --boot-directory=/boot $target

# UEFI-загрузка
grub-install --boot-directory=/boot --efi-directory=/boot/efi $target

# Привязка к "железу", создание initrd
for kver in $(ls /lib/modules/); do
	make-initrd -D -k "$kver" 2>/dev/null
done

# Обновление конфигурации GRUB
LC_ALL=C update-grub

# Создание уникальных ключей SSH
ssh-keygen -A

При выполнении перечисленных операций в каталоге /boot создаются образы initrd для всех установленных в целевой системе ядер, причём, в образы этих initrd помещаются все необходимые для загрузки на данном "железе" модули ядра. Установка загрузчика выполняется путём копирования нужных файлов из /usr в /boot/grub, при этом начальный загрузчик (grub2 stage1, 440 байт) также записывается в MBR, а grub2 stage1.5 записывается либо в VBR, либо в раздел BBP, в зависимости от режима загрузки. Кроме того, данная операция добавляет или обновляет запись "altlinux" в NVRAM при UEFI-загрузке, так что если у вашего оборудования с этим могут возникнуть проблемы, используйте дополнительно опцию --no-nvram и смотрите следующий раздел, где описаны обходные пути. Последняя операция генерирует уникальные хост ключи SSH в каталоге /etc/openssh/. Делать это лучше всего именно на данном этапе, поскольку на ранних стадиях загрузки в компьютере может ещё не быть накопленной в достаточном количестве качественной энтропии.

Обратите внимание: ввиду особенностей реализации make-initrd и высокой вероятностью того, что ядра между загрузочной системой ALT Rescue и целевой системой могут существенно различаться, команду make-initrd без параметров желательно единожды выполнить под root'ом ещё один раз уже после автономной загрузки в целевую систему. Это исправит небольшие артефакты графической заставки. При массовом развёртывании данную операцию можно автоматизировать.

Записи в NVRAM о EFI-загрузчиках

Настоящий раздел актуален только для загрузки в режиме UEFI. Посмотреть текущий набор записей в NVRAM, их порядок, выбор по умолчанию можно командами:

efibootmgr
efibootmgr -v

Штатный установщик системы ALT автоматически добавляет в NVRAM запись "altlinux". Также это выполняется по умолчанию при установке загрузчика grub2-efi, если не указывать дополнительный параметр --no-nvram, что может оказаться полезным в случае проблем с записью в NVRAM на вашем оборудовании. Однако, если вы не использовали чрут и вызов из чрута grub-install, а копировали области начальной загрузки иным способом, cледующая команда добавит запись с загрузчиком системы ALT, который записывается по умолчанию штатным установщиком (пример для Intel x86_64 и диска /dev/sda):

efibootmgr -q -c -t 0 -d /dev/sda -L altlinux -l "\\EFI\\altlinux\\shimx64.efi"

Поскольку место в NVRAM ограничено, следы от предыдущих установок различных операционных систем могут препядствовать добавлению очередной записи. Следующий набор команд удалит все записи о загрузчиках из NVRAM:

efibootmgr | grep -E "^Boot[0-9A-F][0-9A-F][0-9A-F][0-9A-F]" |
while read bootnum junk; do
        efibootmgr -q -B -b "${bootnum:4:4}"
done

После чего можно будет вручную добавить одну или несколько нужных вам записей, что особенно полезно при массовом развёртывании мульти-загрузочных систем.

Если у вашего компьютера проблемы с записью в NVRAM, о чём необходимо поинтересоваться заранее, есть лишь два способа обеспечить автоматическую загрузку в режиме UEFI -- использовать путь по умолчанию (его должны понимать все прошивки, поскольку это часть спецификации UEFI, пример для Intel x86_64):

cd /mnt/target/boot/efi/EFI
cp -rf altlinux BOOT
mv BOOT/grubx64.efi BOOT/bootx64.efi
cd "$OLDPWD"

ЛИБО создать скрипт одной командой, что намного проще (пример для Intel x86_64):

echo "fs0:\\EFI\\altlinux\\grubx64.efi" > /mnt/target/boot/efi/startup.nsh

Для архитектуры i586 следует заменить "x64" на "x32" в двух вышеприведённых примерах.

Автоматизация восстановления и массового развёртывания

С 2019 года сборки образов ALT Rescue имеют встроенную поддержку для автоматизации многих перечисленных здесь сценариев, а то, что ещё не автоматизировано, легко поддаётся автоматизации с использованием нового инструмента -- Rescue Launcher. Вам достаточно в тот же каталог, куда вы сохранили все образы, сложить ещё один скрипт, который будет запущен на первом терминале в интерактивном режиме, после чего скопировать всё содержимое /mnt/backup с вашим скриптом на загрузочную флэшку. При загрузке со стандартной Сизифной флэшки ALT Rescue (не пересобранной из профиля специально для задач Recovery/деплоя), в параметры загрузки ядра нужно будет руками дописать "autorun", всё остальное сделает автоматика. Примеры "боевых" скриптов autorun приведены в конце данного руководства, а здесь -- пошаговая инструкция по созданию загрузочного носителя с образами.

Итак, флэшка ALT Rescue у вас уже есть. Вы с неё загружались и выполняли все операции. Теперь:

  • вставьте её в компьютер с установленной ОС Альт.
  • откройте терминал и получите привелегии root (su-).
  • посмотрите, куда смонтировалась флэшка (mount | tail).
  • размонтируйте её (например, umount /dev/sdс2).
  • создайте на ней ещё один раздел Linux Type 0x83, достаточный для размещения на нём всех файлов бэкапа (fdisk /dev/sdс).
  • очистите этот раздел (wipefs -a /dev/sdc3).
  • отформатируйте его следующим образом (mkfs.ext2 -q -L alt-autorun /dev/sdc3).
  • смонтируйте его куда-нибудь (mkdir /mnt/stick && mount -t ext2 /dev/sdc3 /mnt/stick).
  • запишите на него все файлы вашей системы восстановления/развёртывания:
cd /mnt/backup
chmod 600 *
chmod 755 autorun
cp -Lf * /mnt/stick/; sync
umount /mnt/stick || umount -l /mnt/stick
  • извлеките флэшку и вставьте в целевой компьютер.
  • включите целевой компьютер и выберите загрузку с флэшки.
  • в зависимости от режима загрузки BIOS/UEFI, допишите в параметры загрузки ядра строку "autorun" (без кавычек).
  • дождитесь, когда отработает наша и ваша автоматика и компьютер выключится.

Смотрите детали в разделе Rescue Launcher.

Особенности создания загрузочных Recovery-ситем на DVD-носителях

ToDo: ...

Примеры скриптов

1. Массовое развёртывание Альт 8СП на разные модели ноутбуков из альфа-образа в режиме загрузки BIOS:

#!/bin/sh

# Целевой диск
target="/dev/sda"

# Д.б. true, если требуется проверка контрольных сумм
# файлов образов до начала восстановления -- надёжнее,
# но существенно дольше!
#
validate=true

# Размер раздела подкачки (#1)
swapsize="8G"

# Размер корневого раздела (#2)
rootsize="40G"

# Размер раздела данных (#3, если не указать,
# распределяется всё оставшееся место на диске)
#
homesize=


# Аварийная консоль на случай ошибок в скрипте
rs() {
	echo "Error code: #$1"; echo
	PS1="(DEPLOY) # " exec /bin/bash -i
	sleep 30
	exit 1
}


#######################################
# Точка входа в систему развёртывания #
#######################################

# Для запуска требуется root
test "$(id -u)" = "0" || rs 1

# А также наличие образов развёртывания
test -r root.tgz -a -r home.tgz || rs 2

# Проверяем наличие целевого диска
test -b $target || rs 3

# Проверяем контрольные суммы образов
if $validate; then
	echo "Please wait, validating images..."
	test -r checksum.256 || rs 4
	while read validsum filename; do
		pv "$filename" | sha256sum |
			awk '{print $1;}' >/tmp/testsum.256
		testsum="$(cat /tmp/testsum.256)"
		rm -f /tmp/testsum.256
		echo -n "$filename=$testsum"
		if [ "$testsum" != "$validsum" ]; then
			unset validsum filename testsum
			echo " (FAIL)"
			rs 5
		fi
		unset testsum
		echo " (OK)"
	done < checksum.256
	unset validsum filename
	echo
fi

# Тип, название компьютера и проводного интерфейса
pctype="generic"; computer="notebook"; iface="eth0"
if [ -f /sys/class/dmi/id/chassis_version ]; then
	case "$(cat /sys/class/dmi/id/chassis_version)" in
	"Lenovo V330-15IKB")
		grep -qE ' WIN$' /sys/class/dmi/id/board_version 2>/dev/null &&
			pctype="lenovo-dh" || pctype="lenovo-cl"
		computer="lenovo"
		iface="enp3s0"
		;;
	esac
fi
if [ -f /sys/class/dmi/id/product_name ]; then
	case "$(cat /sys/class/dmi/id/product_name)" in
	"HP 250 G6 Notebook PC")
		pctype="hp-250-g6"
		computer="hp"
		iface="eno1"
		;;
	esac
fi

# Игнорируем прерывания
trap : INT TERM HUP

# Предварительная очистка диска
echo "Please wait, initializing HDD..."
(	if [ -b ${target}1 ]; then
		wipefs -a $(ls -r ${target}?*)
	fi
	wipefs -a $target
	dd if=/dev/zero bs=1M count=4 of=$target
) >/dev/null 2>&1

# Создание и форматирование разделов
LC_ALL=C sfdisk -X dos -W always -q $target <<-EOF
,$swapsize,S
,$rootsize,L,*
,$homesize,L
EOF
sync; sleep 5
blockdev --rereadpt $target
wipefs -a $(ls -r ${target}?*)
mkswap -L SWAP ${target}1 || rs 7
mkfs.ext4 -j -q -O ^64bit -L SYSTEM ${target}2 || rs 8
mkfs.ext4 -j -q -O ^64bit -L USERDATA ${target}3 || rs 9

# Восстановление корневого раздела
echo; echo "Restoring system partition..."
test -d /mnt/target || mkdir -m755 /mnt/target
mount -t ext4 -o noatime ${target}2 /mnt/target || rs 10
pv root.tgz | unpigz -qnc | tar -xpSf - --overwrite -C /mnt/target || rs 11

# Восстановление раздела данных
echo; echo "Restoring data partition..."
test -d /mnt/target/home || mkdir -m755 /mnt/target/home
mount -t ext4 -o noatime,nosuid ${target}3 /mnt/target/home || rs 13
pv home.tgz | unpigz -qnc | tar -xpSf - --overwrite -C /mnt/target/home || rs 14

# Учитываем разницу в железе
case "$pctype" in
lenovo-*)
	k="GRUB_CMDLINE_LINUX_DEFAULT"
	f="/mnt/target/etc/sysconfig/grub2"
	sed -i -E "s,^$k='(.*)',$k='\1 noaer'," $f
	unset k f
esac

# Создаём скрипт в целевом /tmp
cat >/mnt/target/tmp/deploy-slave <<-EOF
#!/bin/sh

mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts

# Установка системного загрузчика
echo "Installing boot loader..."
grub-install $target

# Привязка к железу, создание initrd
for kver in \$(ls /lib/modules/); do
	make-initrd -D -k "\$kver" 2>/dev/null
done
unset kver

# Обновление конфигурации GRUB
update-grub

# Создание уникальных ключей SSH
ssh-keygen -A

umount /dev/pts || umount -l /dev/pts
umount /sys || umount -l /sys
umount /proc || umount -l /proc
exit 0
EOF
chmod 755 /mnt/target/tmp/deploy-slave

# При необходимости, переименовываем проводной интерфейс
if [ "$iface" != "eth0" -a -d /mnt/target/etc/net/ifaces/eth0 ]; then
	/bin/mv -f /mnt/target/etc/net/ifaces/eth0 /mnt/target/etc/net/ifaces/$iface
fi

# Обеспечиваем уникальность
echo; echo "Personification..."
dbus-uuidgen > /mnt/target/etc/machine-id
cp -Lf /mnt/target/etc/machine-id /mnt/target/var/lib/dbus/machine-id
head -c512 /dev/urandom > /mnt/target/var/lib/systemd/random-seed
chmod 600 /mnt/target/var/lib/systemd/random-seed

# Разовый chroot в целевую систему
mount --bind /dev /mnt/target/dev || rs 15
env -i PATH="$PATH" LC_ALL=C LANG=C USER=root TERM=linux \
	chroot /mnt/target /tmp/deploy-slave || rs 16
umount /mnt/target/dev || umount -l /mnt/target/dev
rm -f /mnt/target/tmp/deploy-slave
sync

# Финальная очистка и выключение компьютера
cat >/tmp/finish.sh <<-EOF
#!/bin/sh

cd /
umount /mnt/target/home || umount -l /mnt/target/home
umount /mnt/target || umount -l /mnt/target
umount "\$1" 2>/dev/null || umount -fl "\$1"
echo
echo "Notebook '$computer' successfully restored!"
echo "Enjoy! ;-)"
echo
sleep 5
poweroff
EOF
chmod +x /tmp/finish.sh
exec /tmp/finish.sh "$(pwd)" || poweroff

2. Массовое развёртывание Альт Образование 8 на моноблоки HP из альфа-образа в режиме загрузки UEFI:

#!/bin/sh

# Целевой диск
target="/dev/sda"

# Название компьютера
computer="hp"

# Д.б. true, если требуется проверка контрольных сумм
# файлов образов до начала восстановления -- надёжнее,
# но существенно дольше!
#
validate=false

# Размер раздела ESP (#1)
efisize="100M"

# Размер раздела подкачки (#3)
swapsize="8G"

# Размер корневого раздела (#4)
rootsize="60G"

# Размер раздела данных (#5, если не указать,
# распределяется всё оставшееся место на диске)
#
homesize=


# Аварийная консоль на случай ошибок в скрипте
rs() {
	echo "Error code: #$1"; echo
	PS1="(DEPLOY) # " exec /bin/bash -i
	sleep 30
	exit 1
}


#######################################
# Точка входа в систему развёртывания #
#######################################

# Для запуска требуется root
test "$(id -u)" = "0" || rs 1

# А также наличие образов развёртывания
test -r root.tgz -a -r home.tgz || rs 2

# Проверяем наличие целевого диска
test -b $target || rs 3

# Проверяем контрольные суммы образов
if $validate; then
	echo "Please wait, validating images..."
	test -r checksum.256 || rs 4
	while read validsum filename; do
		pv "$filename" | sha256sum |
			awk '{print $1;}' >/tmp/testsum.256
		testsum="$(cat /tmp/testsum.256)"
		rm -f /tmp/testsum.256
		echo -n "$filename=$testsum"
		if [ "$testsum" != "$validsum" ]; then
			unset validsum filename testsum
			echo " (FAIL)"
			rs 5
		fi
		unset testsum
		echo " (OK)"
	done < checksum.256
	unset validsum filename
	echo
fi

# Игнорируем прерывания
trap : INT TERM HUP

# Предварительная очистка диска
echo "Please wait, initializing HDD..."
(	if [ -b ${target}1 ]; then
		wipefs -a $(ls -r ${target}?*)
	fi
	wipefs -a $target
	dd if=/dev/zero bs=1M count=4 of=$target
) >/dev/null 2>&1

# Создание и форматирование разделов
LC_ALL=C sfdisk -X gpt -W always -q $target <<-EOF
,$efisize,U
,8M,21686148-6449-6E6F-744E-656564454649
,$swapsize,S
,$rootsize
,$homesize
EOF
sync; sleep 5
blockdev --rereadpt $target
LC_ALL=C sfdisk -q --part-label $target 1 ESP
LC_ALL=C sfdisk -q --part-label $target 2 GRUB
LC_ALL=C sfdisk -q --part-label $target 3 SWAP
LC_ALL=C sfdisk -q --part-label $target 4 ROOT
LC_ALL=C sfdisk -q --part-label $target 5 HOME
wipefs -a $(ls -r ${target}?*)
mkfs.fat -f2 -F32 -n ESP ${target}1
mkswap -L SWAP ${target}3 || rs 7
mkfs.ext4 -j -q -O ^64bit -L SYSTEM ${target}4 || rs 8
mkfs.ext4 -j -q -O ^64bit -L USERDATA ${target}5 || rs 9

# Восстановление корневого раздела
echo; echo "Restoring system partition..."
test -d /mnt/target || mkdir -pm755 /mnt/target
mount -t ext4 -o noatime ${target}4 /mnt/target || rs 10
pv root.tgz | unpigz -qnc | tar -xpSf - --overwrite -C /mnt/target || rs 11

# Создание и монтирование раздела ESP
rm -rf /mnt/target/boot/efi/* 2>/dev/null
mount -t vfat -o umask=0,quiet,showexec,iocharset=utf8,codepage=866 ${target}1 /mnt/target/boot/efi || rs 12

# Восстановление раздела данных
echo; echo "Restoring data partition..."
test -d /mnt/target/home || mkdir -m755 /mnt/target/home
mount -t ext4 -o noatime,nosuid ${target}5 /mnt/target/home || rs 13
pv home.tgz | unpigz -qnc | tar -xpSf - --overwrite -C /mnt/target/home || rs 14

# Создаём скрипт в целевом /tmp
cat >/mnt/target/tmp/deploy-slave <<-EOF
#!/bin/sh

mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts

# Установка системного загрузчика
echo "Installing boot loader..."
grub-install --boot-directory=/boot --efi-directory=/boot/efi $target

# Обновление конфигурации GRUB
update-grub

# Создание уникальных ключей SSH
ssh-keygen -A

umount /dev/pts || umount -l /dev/pts
umount /sys || umount -l /sys
umount /proc || umount -l /proc
exit 0
EOF
chmod 755 /mnt/target/tmp/deploy-slave

# Обеспечиваем уникальность
echo; echo "Personification..."
iface="$(ip route 2>/dev/null | grep -E '^default via ' | awk '{print $5;}')"
test -n "$iface" || iface="$(ls -1 /sys/class/net/ | grep -v lo | head -n1)"
hw="$(ip link show dev ${iface:-eth0} 2>/dev/null | tail -n1 |
	awk '{print $2;}' | sed 's,:,,g' | cut -c7-)"
test -z "$hw" || computer="$computer-$hw"
dbus-uuidgen > /mnt/target/etc/machine-id
cp -Lf /mnt/target/etc/machine-id /mnt/target/var/lib/dbus/machine-id
sed -i "s,computername,$computer," /mnt/target/etc/sysconfig/network
head -c512 /dev/urandom > /mnt/target/var/lib/systemd/random-seed
chmod 600 /mnt/target/var/lib/systemd/random-seed
unset hw iface

# Разовый chroot в целевую систему
mount --bind /dev /mnt/target/dev || rs 15
env -i PATH="$PATH" LC_ALL=C LANG=C USER=root TERM=linux \
	chroot /mnt/target /tmp/deploy-slave || rs 16
umount /mnt/target/dev || umount -l /mnt/target/dev
rm -f /mnt/target/tmp/deploy-slave
sync

# Финальная очистка и выключение компьютера
cat >/tmp/finish.sh <<-EOF
#!/bin/sh

cd /
umount /mnt/target/boot/efi || umount -l /mnt/target/boot/efi
umount /mnt/target/home || umount -l /mnt/target/home
umount /mnt/target || umount -l /mnt/target
umount "\$1" 2>/dev/null || umount -fl "\$1"
echo
echo "PC '$computer' successfully restored!"
echo "Enjoy! ;-)"
echo
sleep 5
poweroff
EOF
chmod +x /tmp/finish.sh
exec /tmp/finish.sh "$(pwd)" || poweroff

3. ToDo: ...

Enjoy! ;-)