Загрузка пакетов для последующей установки

В связи с существованием выделенной линии и безлимитным тарифом у меня не было проблем с синхронизацией локального зеркала. Для этого был создан небольшой скрипт, который производил синхронизацию со внешним источником по rsync (последняя версия скрипта размещена на странице mandriva.ru).
Но однажды ко мне на e-mail пришло письмо с описанием ошибки в скрипте (после выхода Mandriva 2010 скрипт сопротивлялся и пытался скачать 2009), а так же с просьбой доработать скрипт до возможности скачивания отдельных пакетов, которые в последствии можно было бы устанавливать на целевые машины.
Идея мне показалась хорошей и к тому же, судя по неоднократно выплывающим на форумах вопросам, актуальной. Дело было к ночи спать не хотелось, по сему, решил посмотреть, что можно было придумать ориентируясь на доступный функционал уже установленного ПО на Mandriva 2010.0.
Первым делом нужно было посмотреть на те возможности, которые предлагает нам консольный установщик urpmi. Посмотрев справку к программе было обнаружено, что urpmi в Mandriva 2010.0 был доработан разработчиками и добавлен параметр: --download-all, который позволяет указать директорию, в которую будет производится загрузка требуемых пакетов. Стоит заметить что в предыдущих версиях urpmi данный параметр отсутствовал, и для изъятия скаченных пакетов приходилось вытаскивать их из кеша.
По мимо этого, также был весьма полезный параметр --urpmi-root, который в свою очередь позволяет производить манипуляции с пакетами в изолированном окружении, не внося изменений в локальную систему.
Исходя из этого, можно сказать, что у нас имеются все необходимые инструменты, для того чтобы скачать все нужные пакеты.

Проведем эксперимент:
1. Создадим директорию в которой urpmi будет проводить свои манипуляции:
mkdir -p ~/test

2. Добавим в эту директорию необходимые источники пакетов, к примеру:
sudo urpmi.addmedia --urpmi-root ~/test --distrib 'http://mirror.yandex.ru/mandriva/official/2010.0/i586'

3. создадим директорию test2 в которую будем загружать требуемые пакеты и сменим владельца на root:
mkdir ~/test2; chmod a=rwx ~/test2; sudo chown root.username ~/test2

4. Загрузим, например, пакет mc, выполнив следующую команду:
sudo urpmi --noclean --no-install --urpmi-root ~/test --download-all ~/test2 --auto  mc

5. Проверяем наместе ли файлы:
ls -l ~/test2/rpms


Для частоты эксперимента требуется выполнить шаг 4 повторно, чтобы убедиться, что загруженные пакеты повторно не загружаются. И что же мы видим при этом? Не то что мы ожидаем. Мы знаем что требуемые пакеты уже загружены, но по какой-то не ведомой причине пакеты вновь загружаются, быть может это баг или может так и должно (нужно как-нибудь собраться и отписать отчет об ошибке в bugzilla).
Но не будем отчаиваться сразу, стоит проверить, загрузятся ли пакеты в кеш, чтобы их потом оттуда взять, для этого выполним следующее:

6. sudo urpmi --noclean --no-install --urpmi-root ~/test --download-all  --auto  mc
7. ls -l  test/var/cache/urpmi/rpms #проверяем содержимое кеша

Пакеты лежат на месте. И опять для чистоты эксперимента повторяем шаги 6 и 7.
В этот раз пакеты повторно не загружались и они лежат там где и прежде. Это не может не радовать.
Значит основной цели мы добились, скачали требуемый пакет со всеми зависимостями, которые потребуются для установки на любой компьютер, где нет пакета mc. Если вы заходите скачать мета-пакет, к примеру, task-kde4, помните, что будет загружены все пакеты, необходимые для существования данного мета-пакета, иными словами, данный способ загружает не единичный пакет, а все необходимые для установки пакеты.

Но не будем останавливаться на достигнутом, нужно всегда думать о будущих проблемах. А проблема состоит в том, что если вы подключите локальный источник пакетов, команда --download-all в любом случае инициирует загрузку пакета в кеш, при этом игнорируя существующий пакет из локального источника (быть может это тоже баг и о нем нужно сообщить в bugzilla). У нас остается вопрос, как сделать так, чтобы загрузка происходила только тех пакетов, которых действительно не хватает в системе с учетом локального источника.
Проведем еще один эксперимент:

8. Удалим пакет из кеша, к примеру xz-4.999.9beta-1mdv2010.0.i586.rpm
9. создадим символическую ссылку на этот пакет из локального источника : 
sudo ln -s /mnt/hd/Distrib/mandriva/official/2010.0/i586/media/main/release/xz-4.999.9beta-1mdv2010.0.i586.rpm ~/test/var/cache/urpmi/rpms/xz-4.999.9beta-1mdv2010.0.i586.rpm
10. повторим шаги 6 и 7.

Как мы можем видеть, пакет повторно не загружался, т.е. существование символической ссылки в кеше на пакет из локального источника является достаточным условием, чтобы не производилось повторная загрузка пакета. Из этого следует, что необходимо произвести создание символических ссылок из локального источника в кеш, для исключения загрузки существующих пакетов в локальном источнике.
Создадим символические ссылки из локального источника:

11. for i in `find /mnt/hd/Distrib/mandriva/official/2010.0/i586/media/ -iname "*.rpm" -print`; do sudo ln -s "$i" ~/test/var/cache/urpmi/rpms/`basename "$i"`; done
12. удалим пакеты файлы из кеша начинающиеся на mc-*
13. повторим шаг 6 и 7.

Как мы можем видеть, в этот раз загрузился только пакет mc.
Нам остается только скопировать данный пакет на новое место и удалить уже не нужную временную директорию

14. mkdir ~/rpms; find ~/test/var/cache/urpmi/rpms/ -type f -exec cp -f {} ~/rpms \;
15. sudo rm -rf ~/test

Подготовим новый локальный источник для последующего применения:

16. genhdlist2 --allow-empty-media --clean --xml-info --quiet ~rpms/


Теперь мы можем добавить новый локальный источник, находящийся в директории rpms, который содержит требуемые пакеты.

Пример конечного вида скрипта для загрузки пакетов со всеми зависимостями в Mandriva 2010

#!/bin/bash
[[ "$#" == "0" ]] && echo $0 список пакетов && exit

TEMPRPMSROOT="$TMP/TEMPRPMSROOT"
RPMS="$HOME/RPMS"
[[ -d $TEMPRPMSROOT ]] ||  mkdir -p "$TEMPRPMSROOT"
[[ -d $RPMS ]] ||  mkdir -p "$RPMS"

URL='http://mirror.yandex.ru/mandriva/official/2010.0/i586'
localURL='/mnt/hd/Distrib/mandriva/official/2010.0/i586'
sudo urpmi.addmedia --urpmi-root "$TEMPRPMSROOT" --distrib "$URL"
sudo mount --bind $RPMS $TEMPRPMSROOT/var/cache/urpmi/rpms
for i in `find $localURL/media -iname "*.rpm" -print`; do sudo ln -s "$i" $TEMPRPMSROOT/var/cache/urpmi/rpms/`basename "$i"`; done
sudo urpmi --noclean --no-install  --urpmi-root "$TEMPRPMSROOT" --download-all --auto $*
sudo find $TEMPRPMSROOT/var/cache/urpmi/rpms -type l -exec rm -f {} \;
sudo umount $TEMPRPMSROOT/var/cache/urpmi/rpms
sudo rm -rf $TEMPRPMSROOT
genhdlist2 --allow-empty-media --clean --xml-info --quiet $RPMS

Опубликовать в своем блоге livejournal.com

Комментарии Вконтакте facebook

Комментарии (0)

rss свернуть / развернуть
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.
Блоги, Полезные советы и секреты, Загрузка пакетов для последующей установки