Рассмотрю вариант тиражирование настроеной ОС Linux через локальную сеть.
Схема такого тиражирования довольно проста:
- Создаем образ который мы собирается тиражировать
- Собираем минимальный образ линукс для загрузки через сеть, он будет распаковывать сжатый образ тиражируемой системы
- Настраиваем сервер для раздачи загрузчика
Следуя этому плану устанавливаем ОС Linux на какой нибудь ПК, также можно использовать виртуальный ПК, мне удобнее было использовать отдельный ноутбук.
Затем нам необходимо снять с него образ.
Снятие образа с отдельного жесткого диска
Для снятия образа я буду использовать утилиту mksquashfs, она позволяет в дальнейшем распаковывать в несколько потоков, что в несколько раз быстрее работы архиватора tar.
Создаем рабочий каталог
1 | mkdir root |
Монтируем в него корень и все остальные разделы в соответствии с их точками монтирования. У меня система имеет два раздела с точками монтирования / и /home:
1 2 | sudo mount /dev/sdc1 ./root sudo mount /dev/sda6 ./root/home |
Затем планируем снимок образа, мне удобнее всего было разбить образ на части:
- /home
- /var
- /usr
- /etc
В случае каких либо изменений можно будет переписывать не все разделы целиком а только отдельные.
Для такого снятия я написал небольшой срипт:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #Создаем каталог image, куда мы сложим сжатые образы mkdir -p image #Зачищаем предыдущие образы, если таковые имеются if [ -f image/root.squashfs ]; then rm image/root.squashfs -f fi if [ -f image/home.squashfs ]; then rm image/home.squashfs -f fi if [ -f image/etc.squashfs ]; then rm image/etc.squashfs -f fi if [ -f image/etc.squashfs ]; then rm image/etc.squashfs -f fi #Создаем точку монтирования root mkdir root #Монтируем все необходимые разделы. mount /dev/sdc1 root mount /dev/sdc6 root/home #Снимаем образы с каталогов с системой sudo mksquashfs root image/root.squashfs -e root/tmp root/usr root/etc root/var root/home -comp xz -mem 8G sudo mksquashfs root/etc image/etc.squashfs -comp xz -mem 8G sudo mksquashfs root/var image/var.squashfs -comp xz -mem 8G sudo mksquashfs root/usr image/usr.squashfs -comp xz -mem 8G sudo mksquashfs root/home image/home.squashfs -comp xz -mem 8G |
Образы готовы, теперь перейдем в загрузке по сети.
Для загрузки можно использовать gentoo-minimal — это образ gentoo предназначеный для установки gentoo на ПК, он отлично подходит чтобы его можно было загрузить через сеть.
Настройка DHCP и TFTP описана в статье PXE-загрузка-загружаем LiveCD Ubuntu
Подготовка загрузчика Gentoo
Скачиваем с сайта Gentoo x64 уcтановочный образ Gentoo Minimal, так как с 32-х разрядным у меня не заработало, опеределялось только около 800 Мб оперативной памяти и unsquashfs падал из-за нехватки памяти, в последней версии не у меня не заработала локальная сеть, не загружался модуль tg3, пока не нашел как это исправить, поэтому залил старый образ gentoo-minimal в файлообменник.
Для распаковки созданых образов нам необходима утилита unsquashfs, но ее нет в gentoo, возьмем ее из репозитория Slackware Linux , нас интересует архив squashfs-tools-4.3-x86_64-1.txz, поместим его вместе с iso образом.
Скрипт generate.sh
Сайте gentoo есть статья по альтернативной установке, она не подходит для нового образа gentoo-minimal, поэтому внесем в нее некоторые изменения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #!/bin/bash -xe sudo ./clean.sh source ./config.cfg test -z "$tftproot" -o -z "$image" && echo "Usage: $0 " >&2 && exit 1 test -e "$tmp" && echo "Temporary path '$tmp' already exists." >&2 && exit 1 # prepare directories mkdir -p "$tmp" "$iso" "$initrd/mnt/cdrom" # extract files from ISO image sudo mount -o ro,loop "$image" "$iso" cp "$iso"/{image.squashfs,isolinux/gentoo,isolinux/gentoo.igz} "$tmp" sudo umount "$iso" # patch initramfs and add squashfs to it xz -dc "$tmp/gentoo.igz" | ( cd "$initrd" && sudo cpio -idv ) sudo patch -d "$initrd" -p0 <<'EOF' --- init.orig 2018-07-21 18:33:34.528587830 +0300 +++ init 2018-07-21 21:08:15.106424520 +0300 @@ -491,9 +491,9 @@ CHROOT=${NEW_ROOT} fi - if [ /dev/nfs != "$REAL_ROOT" ] && [ sgimips != "$LOOPTYPE" ] && [ 1 != "$aufs" ] && [ 1 != "$overlayfs" ]; then - bootstrapCD - fi +# if [ /dev/nfs != "$REAL_ROOT" ] && [ sgimips != "$LOOPTYPE" ] && [ 1 != "$aufs" ] && [ 1 != "$overlayfs" ]; then +# bootstrapCD +# fi if [ "${REAL_ROOT}" = '' ] then @@ -558,7 +558,7 @@ REAL_ROOT="${ROOT_DEV}" else prompt_user "REAL_ROOT" "root block device" - got_good_root=0 + got_good_root=1 continue fi ;; @@ -636,7 +636,7 @@ else bad_msg "Block device ${REAL_ROOT} is not a valid root device..." REAL_ROOT="" - got_good_root=0 + got_good_root=1 fi done @@ -718,7 +718,7 @@ [ -z "${LOOP}" ] && find_loop [ -z "${LOOPTYPE}" ] && find_looptype - cache_cd_contents + #cache_cd_contents # If encrypted, find key and mount, otherwise mount as usual if [ -n "${CRYPT_ROOT}" ] EOF echo "Unpack image squashfs" sudo ./unsqfs.sh $tmp $tmp/image.squashfs if [ $auto -eq 1 ]; then echo "Add Squashfs tool in image" sudo ./prepare.sh sudo ./mkautostart.sh sudo ./pack_image.sh sudo ./mkpxeboot.sh fi |
Скрипт config.sh
Для работы этого скрипта создадим файл конфигурации config.cfg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/usr/bin/env bash #Дериктория куда будут сложены загрузочные файлы tftproot="tftp" #Путь к образу gentoo-minimal image="source/install-amd64-minimal-20180719T214502Z.iso" archivesqfs="source/squashfs-tools-4.3-x86_64-1.txz" #расположение временного каталога tmp="./tmp" #Расположение каталога для распаковки gentoo minimal iso="$tmp/iso" #Расположение каталога где будет раполагаться распакованый initrd initrd="$tmp/initrd.dir" #Автоматический режим auto=1 |
Скрипт prepare.sh
Таже нам нужен файл prepare.sh, который установит squashfs-tool в наш образ
1 2 3 | #!/bin/bash -xe source ./config.cfg tar -xvf $archivesqfs -C "tmp/root" --exclude install |
После запуска скрипта будет создана дериктория tmp, в которой располагается распакованые образы initrd и image.squashfs
Запускаем скрипт prepare.sh,который установит squashfs-tools в загрузчик
Скрипт mkautostart.sh
Нам необходимо добавить скрипт автозапуска, который запустит скрипт разметки и установки, он должен располагаться в /root/.bashrc
Для этого выполним файл mkautostart.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #!/bin/bash -xe source ./config.cfg sudo patch -d "$tmp/root/root/" -p0 <<'EOF' --- .bashrc.orig 2018-07-19 03:56:34.000000000 +0300 +++ .bashrc 2018-07-22 17:12:50.973585791 +0300 @@ -12,3 +12,25 @@ fi fi fi + +setterm -blank 0 +server='192.168.0.1' +share="pxeboot" +if [ $(tty) = "/dev/tty1" ];then +rmmod tg3 +sleep 1s +modprobe tg3 +while : + do + sleep 1; + if [ $(ping $server -c 10 -w 30 -q &> /dev/null && echo $?) ] + then + break + fi + done +ntpdate $server +ip address +mkdir -p /mnt/net +mount -t nfs 192.168.0.1:/srv/template /mnt/net +/mnt/net/script.sh +fi |
Скрипт pack_image.sh
После запуска скрипта в автозагрузку root/.bashrc добавятся строчки ожидания сервера, затем монтирование общего каталога на сервере и запуска с него установочного скрипта
Теперь нам необходимо упаковать образ, для этого выполним pack_image.sh :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/bin/bash -xe source ./config.cfg sudo mksquashfs $tmp/root $tmp/image.squashfs cp "$tmp/image.squashfs" "$initrd/mnt/cdrom" ( cd "$initrd" && find . -print | cpio -o -H newc | gzip -9 -c - ) > "$tmp/initramfs.gz" # prepare boot data if [ ! -d $tftproot/pxelinux.cfg ]; then mkdir -p "$tftproot/pxelinux.cfg" fi cat > "$tftproot/pxelinux.cfg/default" <<'EOF' default Gentoo label Gentoo kernel gentoo append initrd=initramfs.gz root=/dev/ram0 init=/linuxrc loop=image.squashfs looptype=squashfs cdroot=1 real_root=/ EOF cp "$tmp"/{gentoo,initramfs.gz} "$tftproot/" # ## cleanup sudo rm -rf "$tmp" |
Теперь необходимо добавить подключение по nfs, на сервере в файле /etc/exports
1 | /srv/template 192.168.1.1/255.255.255.0(rw,insecure,nohide,all_squash,anonuid=1000,anongid=1000,no_subtree_check) |
Перезапускаем nfs-kernel-server
1 | systemctl restart nfs-kernel-server |
Скрипт авторазметки script.sh
Остался скрипт авторазметки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #!/bin/bash SETCOLOR_SUCCESS="echo -en \\033[1;32m" SETCOLOR_FAILURE="echo -en \\033[1;31m" SETCOLOR_NORMAL="echo -en \\033[0;39m" function failedExit { if [ $? -eq 0 ]; then $SETCOLOR_SUCCESS echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" $SETCOLOR_NORMAL echo else $SETCOLOR_FAILURE echo -n "$(tput hpa $(tput cols))$(tput cub 6)[fail]" $SETCOLOR_NORMAL echo exit 1 fi } function failedOk { if [ $? -eq 0 ]; then $SETCOLOR_SUCCESS echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" $SETCOLOR_NORMAL echo else $SETCOLOR_FAILURE echo -n "$(tput hpa $(tput cols))$(tput cub 6)[fail]" $SETCOLOR_NORMAL echo fi } ip address net='net' mkdir /mnt/root echo "Create table" (parted /dev/sda mktable msdos -s &>/dev/null parted /dev/sda mkpart primary 1 20G print free -s &>/dev/null parted /dev/sda mkpart primary 20G 24G print free -s &>/dev/null parted /dev/sda mkpart primary 24G 28G print free -s &>/dev/null) failedExit parted /dev/sda print -s echo "MkFS..." (echo "y" | mkfs.ext4 -U '52324238-502c-4a6c-a8a4-e63480b7d9ea' /dev/sda1 &>/dev/null echo "y" | mkfs.ext4 -U '18719e4d-7318-4077-876a-2ae6392465d9' /dev/sda3 &>/dev/null mkswap -U '9ce9eb70-1ec1-46c7-9691-c83e5720ab1e' /dev/sda2 &>/dev/null) failedExit ### Mount /dev/sda echo "Mount disk..." mount /dev/sda1 /mnt/root &>/dev/null failedExit ### Unpack Squashfs to /mnt/root echo "Unpack FS "$i unsquashfs -d /mnt/root -f /mnt/$net/root.squashfs failedOk for i in 'usr' 'var' 'etc'; do echo "Unpack FS "$i unsquashfs -d /mnt/root/$i -f /mnt/$net/$i.squashfs failedOk done ### Mount /dev/sda3 echo "Unpack FS home" mount /dev/sda3 /mnt/root/home &>/dev/null failedExit unsquashfs -d /mnt/root/home -f /mnt/$net/home.squashfs failedOk echo "Mount Directory" (mount -o bind /dev /mnt/root/dev &>/dev/null mount -o bind /proc /mnt/root/proc &>/dev/null mount -o bind /sys /mnt/root/sys &>/dev/null chroot /mnt/root grub-install /dev/sda &>/dev/null) failedExit echo "Poweroff" poweroff |
Скрипт clean.sh
Добавим скрипт очистки от файлов сборки
1 2 | sudo rm -rf tmp sudo rm -rf tftp |
Кладем его вместе с образами в каталог /srv/template
Готово, мы получили сервер для тиражирования по сети.
Можем попробовать загрузиться.
Все скрипты можно найти в GitHub