|
|||||||
Пакетная система Debian: низкоуровневая работа с deb-пакетами
Время создания: 24.10.2010 22:15
Текстовые метки: linux, deb, пакет
Раздел: Компьютер - Linux - Инсталляция программ
Запись: xintrea/mytetra_syncro/master/base/0000001758/text.html на raw.github.com
|
|||||||
|
|||||||
Пакетная система Debian: низкоуровневая работа с deb-пакетами Формат deb-пакета Краеугольный камень пакетной системы Debian — это deb-пакет (см. deb(5)), представляющий из себя архив формата ar, внутри которого содержится три файла: 1. debian-binary — текстовый файл, содержащий версию формата deb-пакета, в данный момент это 2.0. Программы, работающие с deb-пакетами, должны читать только первую строку этого файла и не падать, если минорная версия вдруг поменяется (например, станет 2.1). 2. control.tar.gz — служебная информация о пакете, скрипты, вспомогательные файлы (см deb-control(5)). Должен содержать только файлы, единственная папка, которая может присутствовать — «.» (текущая директория). В этот архив обязательно должен входить файл control, его минимальное содержимое рассмотрим чуть ниже. 3. data.tar — собственно файлы, устанавливаемые в систему. Чаще всего этот файл сжат каким-нибудь архиватором (поддерживаются расширения .gz, .xz, .bz2, .lzma), чаще всего в архивах встречается data.tar.gz. Указанный порядок следования файлов в архиве обязателен. Если в этом архиве требуется разместить еще какие-нибудь файлы (не представляю, зачем это может кому-нибудь понадобиться), они должны находиться перед data.tar.gz, т.е. последний файл в архиве всегда data.tar. Но если сообщество когда-нибудь решит добавить в формат deb еще файлы, они будут помещены после data.tar. Файл control в архиве control.tar.gz описывает назначение, версию и зависимости пакета, его формат более-менее подробно описан в deb-control(5). Пересказывать всю справку сейчас не буду, опишу лишь минимальное содержимое, необходимое для взаимодействия с инфраструктурой dpkg: Package: имя пакета Version: строка версии (при выборе политики назначения версий следует придерживаться deb-version(5)) Maintainer: John Doe <johndoe@foo.com> (человек, поддерживающий пакет, а не автор программы) Description: короткое описание пакета Длинное описание, на несколько строк. Каждая строка, входящая в длинное описание, должна начинаться с пробела Работа с пакетами средствами ar Теоретически данной информации должно быть достаточно, чтобы собрать простейший пакет «на коленке» и установить его в систему. Пусть наш пакет (назовем его test) просто добавляет в систему файл /usr/share/example-content/test со строчкой «test». Сделаем архив data.tar.gz со структурой папок и единственным файлом, а также файлик debian-binary: $ mkdir -p usr/share/example-content/ $ echo test > usr/share/example-content/test $ tar czf data.tar.gz usr $ echo 2.0 > debian-binary Создадим файл control со следующим содержанием: $ cat control Package: test Version: 1.0 Maintainer: Dummy Maint <dummy@example.org> Description: test package Test package created on my own knees. $ tar czf control.tar.gz control Теперь соберем все воедино: $ ar -qS test-1.0.deb debian-binary control.tar.gz data.tar.gz В текущем каталоге должен появиться файл test-1.0.deb. Его «физическое» содержимое можно просмотреть с помощью следующей команды: $ ar t test-1.0.deb debian-binary control.tar.gz data.tar.gz Посмотреть файл debian-binary: $ ar p test-1.0.deb debian-binary 2.0 Посмотреть список файлов в пакете: $ ar p test-1.0.deb data.tar.gz|tar -tzf - usr/ usr/share/ usr/share/example-content/ usr/share/example-content/test Посмотреть содержимое файла control: $ ar p test-1.0.deb control.tar.gz |tar -O -xzf - control Package: test Version: 1.0 Maintainer: Dummy Maint <dummy@example.org> Description: test package Test package created on my own knees. Можно установить этот пакет и убедиться, что файл /usr/share/example-content/test успешно создан, но лучше этого не делать, поскольку из-за недостатка информации в control в пакетной системе может появиться мусор: $ sudo dpkg -i test-1.0.deb Selecting previously deselected package test. (Reading database ... 97631 files and directories currently installed.) Unpacking test (from test-1.0.deb) ... Setting up test (1.0) ... Работа с пакетами средствами dpkg-deb Все вышеописанное позволяет управляться с deb-пакетами на самом низком уровне, не имея под рукой ничего, кроме стандартных средств Unix (доподлинно известно, что программа ar входила в состав первых Unix 1970х годов). Однако, как несложно догадаться, есть и более высокоуровневые способы создания пакетов и изучения их содержимого. В частности, если уж так необходимо поковыряться с пакетом на низком уровне, все вышеописанные действия настоятельно рекомендуется выполнять с помощью утилиты dpkg-deb(1). Создание пакета средствами dpkg-deb Минимальный формат вызова команды dpkg-deb для построения пакета следующий: dpkg-deb -b исходная_папка Все, что находится в исходной папке, кроме директории DEBIAN, помещается в data.tar.gz. Содержимое DEBIAN будет использовано для создания control.tar.gz, в частности, будет прочитан и проанализирован файл control и в случае каких-либо ошибок (отсутствует одно из необходимых полей или эти поля имеют неправильные значения) пакет просто не будет создан. Процесс создания нашего тестового пакета с нуля теперь выглядит так (в последней команде предполагается, что в текущей папке остался файл control от сборки пакета средствами ar): Подготовка структуры: $ mkdir -p test-1.1/usr/share/example-content/ test-1.1/DEBIAN $ echo test 1.1 > test-1.1/usr/share/example-content/test $ sed 's/Version: 1.0/Version: 1.1/g' control > test-1.1/DEBIAN/control Попытаемся собрать пакет: $ dpkg-deb -b test-1.1 warning, in file 'test-1.1/DEBIAN/control' near line 5 package 'test': missing architecture dpkg-deb: building package `test' in `test-1.1.deb'. dpkg-deb: warning: ignoring 1 warnings about the control file(s) Несмотря на отсутствие важного, но не необходимого поля Architecture, был создан пакет test-1.1.deb. Добавим поле и пересоздадим пакет: $ sed -i "1a \ Architecture: all" test-1.1/DEBIAN/control $ dpkg-deb -b test-1.1 dpkg-deb: building package `test' in `test-1.1.deb' Еще одна немаловажная деталь. Как правило, в названии файла пакета указывается его архитектура, а команда dpkg-deb -b назвала файл по имени папки, из которой он был создан. Если бы папка называлась ololo, то мы получили бы ololo.deb. Чтобы файл пакета автоматически именовался в формате имя-версия-архитектура, при вызове dpkg -b необходимо указывать папку, куда будет положен итоговый архив, например, текущую. Тогда все компоненты имени файла будут извлечены из control: $ cp -R test-1.1 ololo $ dpkg -b ololo dpkg-deb: building package `test' in `ololo.deb'. $ dpkg -b ololo . dpkg-deb: building package `test' in `./test_1.1_all.deb'. Теперь всё относительно нормально, продолжаем изучение возможностей dpkg-deb на примере нового пакета. Получение информации о пакете Узнать версию формата deb, размер пакета и содержимое файла control: $ dpkg -I test_1.1_all.deb new debian package, version 2.0. size 644 bytes: control archive= 259 bytes. 160 bytes, 6 lines control Package: test Architecture: all Version: 1.1 Maintainer: Dummy Maint <dummy@example.org> Description: test package Test package created on my own knees. Список файлов, устанавливаемых в систему (кроме служебных): $ dpkg -c test_1.1_all.deb drwxr-xr-x bvk/bvk 0 2010-10-22 13:21 ./ drwxr-xr-x bvk/bvk 0 2010-10-22 13:21 ./usr/ drwxr-xr-x bvk/bvk 0 2010-10-22 13:21 ./usr/share/ drwxr-xr-x bvk/bvk 0 2010-10-22 13:21 ./usr/share/example-content/ -rw-r--r-- bvk/bvk 9 2010-10-22 13:21 ./usr/share/example-content/test Обратите внимание на владельца устанавливаемых файлов и каталогов: это не root, а некий пользователь. Чтобы исправить эту проблему, можно собирать пакеты из-под root’а, либо воспользоваться специальной утилитой fakeroot из одноименного пакета. Она перехватывает системные вызовы chmod(2) и stat(2) для файлов, и возвращает значения, как если бы файл принадлежал пользователю root. Небольшой пример: $ id uid=1000(bvk) gid=1000(bvk) ... $ touch trololo $ ls -l trololo -rw-r--r-- 1 bvk bvk 0 2010-10-22 13:23 trololo $ fakeroot ls -l trololo -rw-r--r-- 1 root root 0 2010-10-22 13:23 trololo Думаю, принцип понятен. Пересоберем пакет еще более правильно: $ fakeroot dpkg -b test-1.1 . dpkg-deb: building package `test' in `test_1.1_all.deb'. $ dpkg -c test_1.1_all.deb drwxr-xr-x root/root 0 2010-10-22 13:25 ./ drwxr-xr-x root/root 0 2010-10-22 13:25 ./usr/ drwxr-xr-x root/root 0 2010-10-22 13:25 ./usr/share/ drwxr-xr-x root/root 0 2010-10-22 13:25 ./usr/share/example-content/ -rw-r--r-- root/root 9 2010-10-22 13:25 ./usr/share/example-content/test Теперь наконец ок. Можно получаить информацию о пакете в заданном формате: $ dpkg-deb -W --showformat='${Package}-${Version}-${Architecture} (${Maintainer})\n' test_1.1_all.deb test-1.1-all (Dummy Maint <dummy@example.org>) Список полей, которые можно указать в –showformat, можно узнать из вывода команды: $ dpkg-deb -I Подать на STDOUT архив data.tar.gz из пакета (уже «разжатый»), может быть полезно для извлечения только некоторых файлов: $ dpkg-deb --fsys-tarfile test-1.0.deb |tar -Ox usr/share/example-content/test test Перепаковка пакета Пожалуй, теперь наступил момент применить свежеполученные знания на практике :) Часто возникает следующая проблема: из некоего источника поступил пакет с некорректными зависимостями, например, требуется устаревший пакет, отсутствующий в системе и всех репозиториях, но доподлинно известно, что другой, уже установленный пакет предоставляет нужную функциональность. В скачанном пакете требуется изменить файл control, убрав или исправив зависимость. Правильно было бы скачать и распаковать исходник пакета (apt-get source), произвести необходимые изменения в скриптах сборки, установить все необходимые для пересборки библиотеки и окружение и т.д. и т.п., но для частного использования (т.е. без распространения по репозиториям) достаточно просто распаковать пакет, изменить необходимые файлы и запаковать обратно. Проиллюстрирую последовательность действий на примере невинного пакета hello: $ aptitude download hello Get:1 http://yum.fireground.ru/ubuntu/mirror/ maverick/main hello i386 2.5-1 [34.4kB] Fetched 34.4kB in 0s (824kB/s) # да-да, я сижу под убунтой и описываю debian # распаковать содержимое пакета в папку hello (если не существует, будет создана): $ dpkg-deb -x hello_2.5-1_i386.deb hello # распаковать содержимое control.tar.gz в hello/DEBIAN $ dpkg-deb -e hello_2.5-1_i386.deb hello/DEBIAN # что-нибудь поменять в control, например, версию пакета: $ sed -i 's/Version: .*$/Version: 2.5-1test/' hello/DEBIAN/control # собрать новый пакет: $ fakeroot dpkg -b hello/ . dpkg-deb: warning: 'hello//DEBIAN/control' contains user-defined field 'Original-Maintainer' dpkg-deb: building package `hello' in `./hello_2.5-1test_i386.deb'. dpkg-deb: warning: ignoring 1 warnings about the control file(s) Пакет собран. Убедиться, в том, что в нем нет ошибок из-за немного нетрадиционного способа сборки, можно с помощью программы lintian: $ sudo aptitude install lintian ... $ lintian hello_2.5-1test_i386.deb $ echo $? 0 Всё в порядке! Об установке пакетов в систему, механизме зависимостей, структуре репозиториев и еще более правильных способах сборки пакетов читайте в следующих статьях :) |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|