Могу ли я откатить apt-get upgrade, если что-то пойдёт не так?

Вопрос или проблема

Существует ли способ, перед началом aptitude upgrade или apt-get upgrade, подготовить что-то, чтобы вы могли “легко” откатить свою систему к состоянию “apt”, в котором она была до фактического обновления, если что-то пойдет не так?

То есть, например, переустановить старую версию пакетов, которые были обновлены в процессе.

(РЕДАКТИРОВАНИЕ) Несколько подсказок: Я знаю, что etckeeper, например, использует какой-то хук на apt, чтобы его уведомляли каждый раз, когда apt устанавливает или удаляет пакет. Я предполагаю, что может быть какой-то скрипт, который может сохранить список вновь установленных пакетов и их предыдущий номер версии, чтобы можно было переустановить их из кэша apt (/var/cache/apt/archives). Также есть checkinstall, который может отслеживать изменения файлов…

Есть ли какие-либо подробности о том, как это правильно реализовать?

Я только что должен был найти ответ на этот вопрос, потому что последние apt-get upgrade на сервере Debian сделали невозможным загрузку самой последней версии ядра, за пределами busybox, с неудачной попыткой смонтировать корневую ZFS-раздел. По крайней мере, старое ядро все еще могло загружаться, но оно было несовместимо с другим программным обеспечением. Таким образом, появилась необходимость отката.

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

$ apt-get -s install $(apt-history rollback | tr '\n' ' ')

Если это делает то, что вы хотите, удалите -s (также известный как --dry-run) и запустите снова. Вот шаги, которые я предпринял, чтобы это правильно сработало:

  1. Я временно сократил свой /var/log/dpkg.log, чтобы оставить только сегодняшнее обновление

  2. Я установил крошечный скрипт apt-history с здесь в ~/.bashrc и запустил

    $ apt-history rollback > rollback.txt
    ...
    libzfs2:amd64=0.6.4-4~wheezy 
    zfsutils:amd64=0.6.4-4~wheezy 
    zfs-initramfs:amd64=0.6.4-4~wheezy
    ...
    
  3. Это предоставляет хорошо отформатированный список версионных пакетов для отката, который можно подать в apt-get install. Обрежьте этот список по мере необходимости в текстовом редакторе и затем выполните (с -s для тестового запуска сначала):

    $ apt-get -s install $(cat rollback.txt | tr '\n' ' ')
    $ apt-get install $(cat rollback.txt | tr '\n' ' ')
    

Apt будет предупреждать об откате, что ожидаемо. Чтобы предотвратить то, чтобы этот откат был перезаписан следующим обновлением, пакеты нужно будет закрепить, пока оригинальная проблема не будет решена. Например, с помощью: apt-mark hold zfsutils libzfs2 ...


function apt-history(){
    case "$1" in
      install)
            cat /var/log/dpkg.log | grep 'install '
            ;;
      upgrade|remove)
            cat /var/log/dpkg.log | grep $1
            ;;
      rollback)
            cat /var/log/dpkg.log | grep upgrade | \
                grep "$2" -A10000000 | \
                grep "$3" -B10000000 | \
                awk '{print $4"="$5}'
            ;;
      *)
            cat /var/log/dpkg.log
            ;;
    esac
}

Лог-файлы /var/log/apt/history.log и /var/log/apt/term.log являются ближайшими к вашему описанию:

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

history.log предоставляет сводный список каждого действия, которое apt выполняет в следующем формате:

Start-Date: 2013-06-21  16:05:05
Commandline: apt-get install rdiff-backup
Install: python-pyxattr:i386 (0.5.0-3, automatic), rdiff-backup:i386 (1.2.8-6), python-pylibacl:i386 (0.5.0-3, automatic
), librsync1:i386 (0.9.7-7, automatic)
End-Date: 2013-06-21  16:05:42

В частности, он дает список вновь установленных пакетов или удаленных пакетов. Кроме того, term.log показывает, что фактически появилось на терминале во время действия, так что это покажет старые и новые версии пакетов. Случайный образец из моего history.log:

Preparing to replace gnupg 1.4.10-4 (using .../gnupg_1.4.10-4+squeeze1_i386.deb) ...
Unpacking replacement gnupg ...
Processing triggers for install-info ...
Processing triggers for man-db ...
Processing triggers for doc-base ...
Processing 1 changed doc-base file(s)...
Registering documents with scrollkeeper...
Setting up gnupg (1.4.10-4+squeeze1) 

Автоматический откат apt не рекомендуется, но если вы используете логи, то это должно быть возможно сделать вручную, если только не произошло сбоя, который нарушил действия apt, например, из-за несовместимой базы данных dpkg. В этом случае вам нужно будет исправить проблему, прежде чем продолжать.

Нет, apt не облегчает это.

Лучший вариант – это какой-то тип снимка. Либо файловые системные снимки через lvm/zfs/btrfs, либо снимки экземпляров, если вы используете виртуальную машину любого рода.

Единственный другой вариант – составить инвентаризацию установленных пакетов (dpkg -l) до и после. Если вы хотите “откатиться”, вам нужно будет явно установить предыдущую версию.

Ответ или решение

Да, откатить обновление, выполненное с помощью apt-get upgrade, можно, но это не так просто, как хотелось бы. Важно понимать, что программа apt сама по себе не предоставляет встроенной функциональности для легкого отката обновлений. Тем не менее, есть несколько шагов, которые вы можете предпринять, чтобы упростить данный процесс.

Подготовка к откату

  1. Создание резервной копии: Рекомендуется создавать резервные копии системных данных перед обновлениями. Это можно сделать с помощью таких инструментов, как rsync, tar или с использованием системы резервирования на уровне файловой системы, как LVM, ZFS или Btrfs, которые поддерживают моментальные снимки.

  2. Сохранение списка установленных пакетов: Перед обновлением стоит сохранить текущий список установленных пакетов и их версий. Это можно сделать с помощью команды:

    dpkg --get-selections > installed-packages.txt

Откат обновления

Если обновление уже выполнено и что-то пошло не так, вы можете использовать следующие методы:

  1. Используйте логи apt: Логи apt, находящиеся в /var/log/apt/history.log и /var/log/apt/term.log, содержат информацию о всех установках и обновлениях. Однако, если они не были изменены с момента обновления, их можно просмотреть, чтобы определить, какие пакеты были обновлены. Вы можете использовать для этого команду:

    less /var/log/apt/history.log
  2. Скрипты и утилиты: Вы можете использовать дополнительные скрипты, такие как apt-history, чтобы упрощать процесс получения списка пакетов для отката. Для этого вам необходимо будет самостоятельно установить такой скрипт, который будет извлекать информацию о версиях пакетов из логов. Пример скрипта:

    function apt-history() {
       case "$1" in
         rollback)
             cat /var/log/dpkg.log | grep upgrade | awk '{print $4"="$5}'
             ;;
         *)
             cat /var/log/dpkg.log
             ;;
       esac
    }
  3. Переустановка предыдущих версий пакетов: После получения списка пакетов, их можно переустановить на предыдущие версии. Например:

    apt-get install package_name=previous_version
  4. Использование утилиты apt-mark для удержания пакетов: Чтобы предотвратить дальнейшее обновление пакетов после отката, можно использовать:

    apt-mark hold package_name
  5. Системные снимки: Если ваш сервер использует файловую систему, поддерживающую снимки (например, LVM или ZFS), вы можете просто вернуть систему к состоянию до обновления, восстанавливая снимок.

Заключение

Хотя автоматического и простого способа отката обновлений в apt нет, с правильной подготовкой и использованием логов, утилит и, возможно, скриптов, вы можете значительно упростить процесс. Наилучшим способом обеспечения стабильной работы системы является регулярное создание резервных копий и использование снимков файловой системы, что заметно снизит риски, связанные с обновлениями.

Оцените материал
Добавить комментарий

Капча загружается...