Rescue/Recovery
Recovery
Полное руководство по резервному копированию, восстановлению и переносу операционных систем Linux и Windows, созданию автономных Recovery-систем для конечных пользователей, а также массовому развёртыванию с использованием "спасательной" системы ALT Rescue.
Типовые сценарии
В настоящем руководстве предлагаются решения для следующих типовых задач:
- Создание резервной копии (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 можно командами 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-разделов.
Обратите внимание: в данном руководстве в качестве исходного и целевого диска в примерах и коде указывается устройство /dev/sda, в качестве разделов также указываются произвольные номера. Однако в вашем случае диски могут иметь совершенно другие названия нодов, например, /dev/c0d0p3 или /dev/nvme1p5, поэтому никогда не копируйте ничего из этого руководства, предварительно не проверив свои названия утилитами lsblk/blkid/cfdisk.
Для форматирования разделов предлагается использовать утилиты 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) по причине того, что старое не видит сетевого интерфейса и полноценно обновиться из репозитория нет возможности, то при запуске старых версий make-initrd (< 0.8.15-alt1.M80P.7), в которых не учитываются т.н. "неявные зависимости" (soft dependencies) внутри ядра, также можно получить незагружаемую систему. Поэтому в системах с корнем на разделе 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-массив. Перед запуском make-initrd на системах, установленных на RAID-массив, сначала убедитесь, что в userspace имеется пакет make-initrd-mdadm -- он не был включен в ранние версии инсталляторов на основе бранчей P8 и C8.
В арсенале 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. Не используйте partclone и e2image для по-блочного копирования Linux-разделов, для их сохранения и восстановления предпочтительно использовать утилиту tar и по-файловый метод (см. пояснения далее).
Наиболее простой и переносимый компрессор -- gzip. Его аналог, который умеет задействовать все ядра и распараллеливать сжатие -- pigz, наиболее рекомендуемый компрессор. Современная замена gzip -- zstd, он тоже имеется в наличии. Вообще, на диск ALT Rescue включены почти все известные компрессоры. Для расчёта контрольных сумм образов можно использовать такие утилиты, как md5sum, sha1sum, sha256sum -- на диске они тоже имеются.
Для работы по сети с диском ALT Rescue, для выполнения обновления или установки пакетов из чрута, есть два варианта. Первый -- в режиме Legacy/CSM загрузиться, выбрав 4-й пунтк меню "Remote SSH access, DHCP auto-detect". Тогда сеть поднимается автоматически по протоколу 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Гб для записи на ISO9660, можно использовать утилиту 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 -qnc >DiskC.ntfs.gz partclone.ntfs -c -s /dev/sda2 | pigz -qnc >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! ;-)