Для решения задачи полной переустановки Linux-дистрибутива на удалённом сервере, к которому имеется только доступ по SSH, подготовлен скрипт
[[https://github.com/marcan/takeover.sh takeover.sh]]. Скрипт создаёт минималистичное рабочее окружение в памяти, состоящее из инструментария busybox и простейшего init-процесса. Подключившись по SSH к данному окружению можно провести переустановку с отмонтированием корневого раздела. В том числе можно выполнить операции полной очистки всех данных или переразбить дисковые разделы.Скрипт обеспечивает только создание окружения, непосредственно операции по переустановке выполняются вручную, после соединения к созданному окружению по SSH. Скрипт перемонтирует корневой раздел, но не трогает данные, поэтому в случае если что-то пошло не так и вручную не были произведены необратимые изменения для возврата к исходному состоянию достаточно перезагрузить сервер. После завершения установки новой ОС для выхода из созданного окружения и загрузки новой системы достаточно инициировать перезагрузку. Перед выполнением операции на реальном внешнем сервере рекомендуется провести тестовую переустановку с использованием виртуальной машины.
++ Порядок операций:
Создадим директорию с окружением для запуска скрипта (/takeover) и примонтируем к ней раздел tmpfs для хранения нового раздела в оперативной памяти:
mount -t tmpfs none /takeover
Скопируем в директорию рабочее окружение одного из минималистичных дистрибутивов для восстановления после сбоев, например, [[https://www.system-rescue-cd.org/ SystemRescueCD]]. После копирования убедимся, что окружение работоспособно при помощи команды:
chroot /takeover /bin/sh
Скопируем в корень созданного окружения статически собранный вариант пакета
[[https://www.busybox.net/downloads/binaries/1.26.2-defconfig-.../ busybox]] (/takeover/busybox) и проверим его работоспособность:
/takeover/busybox sh
Скопируем в окружение скрипт [[https://github.com/marcan/takeover.sh/blob/master/takeover.sh takeover.sh]] и простейший init-процесс fakeinit, предварительно скомпилировав его из файла [[https://github.com/marcan/takeover.sh/blob/master/fakeinit.c fakeinit.c]]:
gcc -static ./fakeinit.c -o ./fakeinit
Отключаем по возможности все сервисы на переустанавливаемом сервере, убиваем процесс cron и завершаем работу http-сервера (скрипт по умолчанию открывает новый SSH-вход на 80 порту (на 22 порту пока висит старый SSH), поэтому важно, чтобы на этом порту не было обработчиков).
Запускаем /takeover/takeover.sh и выполняем предложенные действия (задаём пароль входа и соглашаемся с продолжением выполнения операции). Далее заходим в новое окружение по SSH:
ssh -p 80 root@my_host
После входа удаляем все оставшиеся фоновые процессы старой системы и отмонтируем все разделы старой системы из директории /old_root, после чего отмонтируем корень старой системы (/old_root). Предварительно копируем в текущее окружение набор модулей ядра от старой системы /old_root/lib/modules, на случае если они понадобятся в процессе замены старой системы.
Выполняем операции по замене системы, не забываем отмонтировать дисковые разделы. После завершения работы перезагужаем систему
reboot -f
или
echo b > /proc/sysrq-trigger
Скрипт takeover.sh:
#!/bin/sh
set -e
TO=/takeover
OLD_TELINIT=/sbin/telinit
PORT=80
cd "$TO"
if [ ! -e fakeinit ]; then
./busybox echo "Please compile fakeinit.c first"
exit 1
fi
./busybox echo "Please set a root password for sshd"
./busybox chroot . /bin/passwd
./busybox echo "Setting up target filesystem..."
./busybox rm -f etc/mtab
./busybox ln -s /proc/mounts etc/mtab
./busybox mkdir -p old_root
./busybox echo "Mounting pseudo-filesystems..."
./busybox mount -t tmpfs tmp tmp
./busybox mount -t proc proc proc
./busybox mount -t sysfs sys sys
if ! ./busybox mount -t devtmpfs dev dev; then
./busybox mount -t tmpfs dev dev
./busybox cp -a /dev/* dev/
./busybox rm -rf dev/pts
./busybox mkdir dev/pts
fi
./busybox mount -t devpts devpts dev/pts
TTY="$(./busybox tty)"
./busybox echo "Checking and switching TTY..."
exec <"$TO/$TTY" >"$TO/$TTY" 2>"$TO/$TTY"
./busybox echo "Type 'OK' to continue"
./busybox echo -n "> "
read a
if [ "$a" != "OK" ] ; then
exit 1
fi
./busybox echo "Preparing init..."
./busybox cp $OLD_TELINIT tmp/telinit
./busybox cat >tmp/init <<EOF
#!${TO}/busybox sh
exec <"${TO}/${TTY}" >"${TO}/${TTY}" 2>"${TO}/${TTY}"
cd "${TO}"
./busybox echo "Init takeover successful"
./busybox echo "Pivoting root..."
./busybox pivot_root . old_root
./busybox echo "Chrooting and running init..."
exec ./busybox chroot . /fakeinit
EOF
./busybox chmod +x tmp/init
./busybox echo "Starting secondary sshd"
./busybox chroot . /usr/bin/ssh-keygen -A
./busybox chroot . /usr/sbin/sshd -p $PORT
./busybox echo "You should SSH into the secondary sshd now."
./busybox echo "Type OK to continue"
./busybox echo -n "> "
read a
if [ "$a" != "OK" ] ; then
exit 1
fi
./busybox echo "About to take over init. This script will now pause for a few seconds."
./busybox echo "If the takeover was successful, you will see output from the new init."
./busybox echo "You may then kill the remnants of this session and any remaining"
./busybox echo "processes from your new SSH session, and umount the old root filesystem."
./busybox mount --bind tmp /sbin
./tmp/telinit u
./busybox sleep 10
init-процесс fakeinit.c
#define _XOPEN_SOURCE 700
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
sigset_t set;
int status, i;
for (i = 0; i < 64; i++)
close(i);
if (getpid() != 1) return 1;
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, 0);
for (;;) wait(&status);
}
URL: https://github.com/marcan/takeover.sh http://unix.stackexchange.com/questions/226872/how-to-shrink...
Обсуждается: http://www.opennet.dev/tips/info/3007.shtml