По какой-то причине репозитории большинства дистрибутивов и базы пакетов в них устроены таким образом, чтобы усложнить обновление системы изолированной от сети. В большинстве случаев база представляет собой набор файлов, не все из которых ещё и нужны для получения информации об обновлениях, и часто для оффлайн обновления предлагают создать локальный репозиторий/зеркало и обновляться из него, предварительно скачав десяток-другой гигабайтов никому не нужных пакетов. Это, например, меня не устраивает, особенно после использования Gentoo, где процедура оффлайн обновления очень простая.
Порывшись в <любимый_поисковик> я так и не нашёл устраивающих меня руководств по оффлайн-обновлению CentOS (плохо искал? возможно, что где-то это уже есть). Неужели ни для кого не актуально? В итоге опытным путём, посредством ковыряния live образа CentOS 7, выяснил, что для обновления локальной базы достаточно скачать всего несколько файлов, создать ещё пару: cachecookie, mirrorlist.txt - без них Yum будет ругаться, что база повреждена. Итак, предположим, что имеем свежеустановленную систему со стандартным набором ftp репозиториев base, extras, updates. При желании можно расширить bash-скрипт на epel или другие репозитории.
#!/bin/bash
MIRROR=ftp://mirror.yandex.ru/centos/7.2.1511
mkdir -p ./local_repo/x86_64/7
cd ./local_repo/x86_64/7
wget -nc -P "./base" $MIRROR/os/x86_64/repodata/repomd.xml
wget -nc -P "./base" $MIRROR/os/x86_64/repodata/*-x86_64-comps.xml.gz
wget -nc -P "./base" $MIRROR/os/x86_64/repodata/*-primary.sqlite.bz2
wget -nc -P "./extras" $MIRROR/extras/x86_64/repodata/repomd.xml
wget -nc -P "./extras" $MIRROR/extras/x86_64/repodata/*-primary.sqlite.bz2
wget -nc -P "./updates" $MIRROR/updates/x86_64/repodata/repomd.xml
wget -nc -P "./updates" $MIRROR/updates/x86_64/repodata/*-primary.sqlite.bz2
for item in base extras updates; do mkdir ./$item/gen && \
bunzip2 -k ./$item/*.bz2 && \
mv ./$item/*.sqlite ./$item/gen/primary_db.sqlite; done
for item in base extras updates; do touch ./$item/cachecookie; done
echo $MIRROR/os/x86_64/ > ./base/mirrorlist.txt
echo $MIRROR/extras/x86_64/ > ./extras/mirrorlist.txt
echo $MIRROR/updates/x86_64/ > ./updates/mirrorlist.txt
Скрипт создаст стуктуру каталогов со всеми необходимыми файлами для дальнейшего получения информации о пакетах, которые предстоит обновить или установить. Притащив полученную директорию на обновляемую машину и закинув её содержимое в «/var/cache/yum/x86_64/7/» (сразу после установки у CentOS база вообще отсутствует) можно спокойно получать список ссылок на пакеты, которые нужно обновить или установить, включая их зависимости. Циклов можно было сделать чуть меньше, а что-то в цикл запихнуть, но во время отладки так было проще.
Затем получаем список ссылок на скачивание пакетов:
# yum list updates | tail -n +3 | cut -d" " -f1 | xargs yumdownloader --urls --resolve | tail -n +4
# yum list updates | tail -n +3 | cut -d" " -f1 | xargs yumdownloader --urls --resolve | tail -n +4 > pkgs_urls_list.txt
Но так скачаются все пакеты в один каталог, а нужно распихивать их потом в /var/cache/yum/.../<имя репозитория>/packages поэтому лучше создать отдельные файлы со ссылками для каждого репозитория. Получить список пакетов для обновления из каждого репозитория в отдельности можно командой, например для extras
# yum repository-packages extras list updates
или только названия пакетов
# yum repo-pkgs extras list updates | tail -n +4 | cut -d" " -f1
или получить список ссылок:
# yum repo-pkgs extras list updates | tail -n +4 | cut -d" " -f1 | xargs yumdownloader --urls --resolve | grep tp://
Получить список ссылок для скачивания отдельного пакета с его зависимостями можно командой
yumdownloader --urls --resolve имя_пакета | grep tp://
Остаётся только принести пакеты на обновляемый компьютер, разложить их по соответсвующим «/var/cache/yum/x86_64/7/имя_репозитория/packages» и обновить систему.