Непростое обновление, превратившееся в бессонную ночь

Вчера договорились с corsico заняться обновлением его сервера. Планировали поставить версию PHP 7.x. Заранее протестировали код на временном сервере, и я думал, что всё пройдёт достаточно легко и просто, за час-полтора справлюсь. Но не тут то было! Типичное обновление превратилось в весьма непростой IT-квест.
Первая неприятность вылезла уже в пакетном менеджере: он не хотел ставить никакой новый софт и выдавал кучу непонятных предупреждений на все пакеты. После более тщательного изучения вопроса оказалось, что предупреждения безвредны (просто слишком старая версия apt), а работать он отказывается из-за неудачных предыдущих попыток поставить PHP 7.3. Применив force-директивы dpkg, я удалил остатки этого пакета, после чего заработал apt update и появилась возможность поставить более новый софт, включая PHP 7.4.
Казалось бы, всё хорошо, ещё немного и всё заработает. Но увы: PHP 7 потребовал обновления Apache до 2.x. Поставил, попытался запустить, и тут ошибка: не удаётся инициализировать генератор случайных чисел. Первая реакция — «чё?». После непродолжительного поиска выясняется, что это из-за старой версии ядра. Делаю apt update && apt upgrade. Вижу, что обновляется почти вся система (причём часть пакетов появляется в предлагаемых к обновлению не сразу, а после повторного выполнения команды), в том числе и ядро. Становится ясно, что нужно перезагрузиться, но и у меня, и у corsico по этому поводу были самые нехорошие предчувствия.
corsico связался с датацентром, на всякий случай запросил доступ по KVM. Те предоставили, и мы отправили сервер на перезагрузку. Как выяснилось, это было очень правильное решение: после перезагрузки сервер перестал пинговаться. Зайдя по KVM, я увидел, что загрузка оборвалась на этапе запуска GRUB, который ушёл в rescue mode. Причём GRUB все диски видел, но при попытке подцепить модули normal и linux выдавал ошибку missing symbol или что-то подобное. По всей видимости, он обновился но криво.
Стало ясно, что дело попахивает крупными неприятностями: чтобы восстановить сервер, нужно загружаться со стороннего носителя. Но сервер стоит далеко, ночью к нему не факт что пустят, а время идёт, сайт недоступен, пользователи паникуют. Тут я обратил внимание, что в меню KVM-приложения есть пункт для монтирования ISO-образов CD-ROM. Сначала даже не поверил, что это сработает: слишком уж фантастичным это казалось: грузить физический сервер с виртуального диска. Срочно скачала Puppy Linux и отправил сервер в перезагрузку. Следующая пара минут прошла в напряжённом ожидании. Время тянулось очень медленно… И всё же экране возникло изображение загрузочного экрана Puppy. Вот оно, спасение!
Загрузка длилась очень долго. Видимо, виртуальный CD-ROM работает медленно. Но вот появилась GUI (выбрать текстовый вариант загрузки я на эмоциях не сообразил), я запустил терминал и напечатал долгожданное grub-install /dev/sdb. И вроде даже сработало, но вывод сильно отличался от обычного и выдалось сообщение, что какого-то пакета не хватает. Было опасение, что что-то опять пошло не так.
Снова перезагрузка. На этот раз grub запускается в нормальном режиме, но вместо меню показывает свою командную строку. Пытаюсь ещё раз загрузиться в Puppy в надежде, что получится доустановить недостающие пакеты и сгенерировать нормальный конфиг, но упираюсь в то, что IP-адрес и прочие параметры нужно настраивать статически. IP-адрес я знаю, а вот шлюз, DNS и прочее — нет. В итоге отказался от этой затеи, вместо Puppy решил загрузиться с образа Ubuntu mini. Увы, тот просто не увидел /dev/sdb, возможно, из-за того, что там используется RAID-контроллер.
Делать нечего, пришлось снова перезагрузиться и в командной строке GRUB вводить вручную команды root, initrd, kernel. Точных имён файлов я, естественно, не помнил (иначе бы не стал заниматься всеми этими сложностями с повторной загрузкой Puppy и Ubuntu Mini). Но оказалось, что GRUB умеет делать автодополнение имён по Tab. Это меня и спасло!
Вроде бы процесс загрузки начался, но длился он недолго. Дальше я попал в оболочку busybox, запущенную с initrd. Пытаюсь монтировать диск, но безрезультатно: пишет path not found (точное сообщение уже не помню). Минут 20, наверное, ломал мозг, как такое может быть: вот он, файл /dev/sdb2, на него можно cat даже сделать (заглючив в процессе терминал), но вот mount его не видит. Потом оказалось, что дело было не в этом. Нужно было явно указать тип файловой системы. После этого наконец-то всё смонтировалось и загрузилось.
Первым делом побежал проверять Apache. Ура, запускается! Но сайт всё равно недоступен. Оказалось, не подцепились настройки Интернета, да и сам интерфейс отключен. Перезапускаю networking, вроде заработало. Делаю снова grub-install и grub-mkconfig и облегчённо вздыхаю: вот оно, спасение!
Дальше было более прозаично: обновлял конфиги Apache, перенастраивал модули, так как у 2.4 хватает отличий в настройках, но вскоре сайт запустился. Оставалось только проверить, что теперь сервер корректно переживёт перезагрузку.
Но не тут то было: на следующей перезагрузке сеть снова не подключилась. Почему — так и не понял, по всей видимости, из-за того, что раньше её инициализировала служба System V, которая из-за обновления перестала запускаться. В итоге нашёл конфиг с сетевыми настройками и переписал его под systemd. Но проверка работоспособности всего этого потребовала ещё нескольких перезагрузок, а сервер там запускается ну очень не быстро…
Потом ещё очень долго возился к кодировкой главной страницы сайта. Я думал, она на статике, пытался прописать charset везде, где только можно, но без толку. Был момент, когда хотелось биться головой о клавиатуру от непонимания. Потом оказалось, что corsico когда-то сделал index.php, где проверял, с какого устройства заходит пользователь, и который потом включал в себя эту статическую страницу. Только после этого вопрос решился!
В итоге всё закончилось около 5 утра. И ещё раз убедился, что я — человек, который всё делает со второго раза (и хорошо если со второго), предварительно «собрав» все неподходящие варианты действий. Например, если бы я перед запуском выполнил grub-update, этап с плясками с виртуальным CD-ROM и Puppy Linux бы не потребовался. (Но с другой стороны, не узнал бы про возможность загрузки с виртуального образа.)