Многие разработчики и любопытные пользователи нередко сталкиваются с необходимостью откатить недавно установленные пакеты, которые привнесли в их систему не совсем ожидаемые обновления. Это обычно случается при установке пакетов из неофициальных источников, из testing-репозиториев или просто из частных репозиториев разработчиков и контейнеров, содержащих пакеты исключительно для тестирования. Последнее особенно актуально для нашей команды QA — откатывать установленные для тестирования пакеты им приходится очень часто.

Откатывать пакеты вручную не очень удобно, особенно если их много и вы не вполне уверены, что именно надо откатить для возврата системы в нормальное состояние. На помощь может прийти urpm-reposync, но этот инструмент может оказаться слишком мощным — он осуществит полную синхронизацию вашей системы с подключенными репозиториями, и откатить только часть пакетов с его помощью затруднительно.

Хорошая новость — теперь ниша между ручным откатом пакетов и использованием reposync заполнена утилитой urpmi.recover, способной откатывать установленные вами пакеты. Urpmi.recover может вернуть пакетную базу в состояние на определенную дату в прошлом, либо откатить заданное количество транзакций по установке пакетов.

Urpmi.recover является частью пакета urpmi и автоматически попадет в вашу систему с обновлениями.

Для осуществления такого отката пакетов, urpmi.recover сохраняет старые версии обновляемых пакетов в директории /var/spool/repackage. И для того, чтобы начать пользоваться утилитой, необходимо сначала инициализировать сохранение старых версий пакетов, выполнив команду

# urpmi.recover --checkpoint

Этой командой вы как-бы говорите: «Сейчас у меня система в стабильном состоянии, но я собираюсь установить потенциально опасные пакеты. Пожалуйста, начиная с этого момента, отслеживай все устанавливаемые пакеты и сохраняй их старые версии в случае обновления».

Вы можете выполнять эту команду и в будущем для переопределения стабильного состояния системы. При этом при каждом вызове urpmi.recover --checkpoint директория /var/spool/repackage будет очищаться, так что откатиться на более раннюю дату вы уже не сможете.

Пока отслеживание установки и обновления пакетов включено, старые версии пакетов сохраняются в поддиректориях /var/spool/repackage, соответствующих дате обновления, так что вы всегда можете изучить эти пакеты самостоятельно.

Если в некоторый момент времени вы решаете, что настало время откатить систему в прошлое, то просто выполните команду

# urpmi.recover --rollback <timestamp>

Время отката можно указать как число секунд с начала Эпохи, но для людей предусмотрены и более удобные варианты, например:

# urpmi.recover --rollback "2014-03-07 13:20:47"

или даже так:

# urpmi.recover --rollback "1 hour ago"

Можно откатить и заданное количество транзакций, указав опцию --transactions и передав количество транзакций для отката опции --rollback:

# urpmi.recover --transactions --rollback <число_транзакций>

В частности, если вы только что установили пакет (который притянул кучу зависимостей), то вы можете просто откатить это обновление, выполнив

# urpmi.recover --transactions --rollback 1

Наконец, отключить отслеживание установки пакетов вы можете командой

# urpmi.recover --disable

Эта команда также очистит /var/spool/repackage.

Вот так с помощью urpmi.recover можно откатывать состояние пакетной базы. Утилита находится в экспериментальном состоянии и отсутствие ошибок не гарантируется, тестируйте на свой страх и риск:). Впрочем, перед осуществлением отката urpmi.recover сообщит вам, что именно он собирается сделать (какие пакеты удалить, какие откатить), и у вас будет возможность отказаться, если вам что-то не понравится. Наконец, в случае чего, urpm-reposync готов прийти на помощь.

Также стоит помнить, что мэйнтейнеры не всегда заботятся об обеспечении корректного отката пакетов на предыдущие версии — так что если новая версия пакета вам что-то сломала в системе, то откат на старую может и не помочь.