arcanis.me/ru/_posts/2014-03-23-creating-custom-repo.html
2014-08-25 21:31:50 +04:00

253 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
category: ru
type: paper
hastr: true
layout: paper
tags: archlinux, настройка, linux
title: Создание собственного репозитория
short: creating-custom-repo
description: Небольшая статья, посвященная созданию собственного репозитория для Archlinux.
---
<h2><a href="#prepare" class="anchor" id="prepare"><span class="octicon octicon-link"></span></a>Подготовка</h2>
<p>Для начала находим сервер и желание с ним заниматься сексом. Для простоты, лучше, чтобы там стоял Archlinux, хотя, это и не совсем обязательно (можно создать отдельный корень под Arch). Из пакетов, пожалуй, нам понадобится только два, <code>devtools</code> и сам <code>pacman</code>:</p>
{% highlight bash %}
pacman -Sy devtools
{% endhighlight %}
<p><a href="https://www.archlinux.org/packages/devtools/" title="Пакет Archlinux">devtools</a> - набор скриптов, предназначенный для автоматизации сборки пакетов в чистом чруте. Думаю, большинство мейнтейнеров Arch'а пользуются им.</p>
<p>Создадим рабочие директории и установим цвета:</p>
{% highlight bash %}
# цвета
if [ ${USECOLOR} == "yes" ]; then
bblue='\e[1;34m'
bwhite='\e[1;37m'
cclose='\e[0m'
fi
export USECOLOR
# директории
if [ ! -d "${PREPAREDIR}" ]; then
[ -e "${PREPAREDIR}" ] && error_mes "file" "${PREPAREDIR}"
echo -e "${bwhite}[II] ${bblue}Creating directory ${bwhite}'${PREPAREDIR}'${cclose}"
mkdir -p "${PREPAREDIR}" || error_mes "unknown"
fi
if [ ! -d "${REPODIR}" ]; then
[ -e "${REPODIR}" ] && error_mes "file" "${REPODIR}"
echo -e "${bwhite}[II] ${bblue}Creating directory ${bwhite}'${REPODIR}'${cclose}"
mkdir -p "${REPODIR}/"{i686,x86_64} || error_mes "unknown"
fi
if [ ! -d "${REPODIR}/i686" ]; then
[ -e "${REPODIR}/i686" ] && error_mes "file" "${REPODIR}/i686"
echo -e "${bwhite}[II] ${bblue}Creating directory ${bwhite}'${REPODIR}/i686'${cclose}"
mkdir -p "${REPODIR}/i686" || error_mes "unknown"
fi
if [ ! -d "${REPODIR}/x86_64" ]; then
[ -e "${REPODIR}/x86_64" ] && error_mes "file" "${REPODIR}/x86_64"
echo -e "${bwhite}[II] ${bblue}Creating directory ${bwhite}'${REPODIR}/x86_64'${cclose}"
mkdir -p "${REPODIR}/x86_64" || error_mes "unknown"
fi
if [ ! -d "${STAGINGDIR}" ]; then
[ -e "${STAGINGDIR}" ] && error_mes "file" "${STAGINGDIR}"
echo -e "${bwhite}[II] ${bblue}Creating directory ${bwhite}'${STAGINGDIR}'${cclose}"
mkdir -p "${STAGINGDIR}" || error_mes "unknown"
fi
{% endhighlight %}
<p>Директории <code>${REPODIR}/{i686,x86_64}</code> для самого репозитория, <code>${PREPAREDIR}</code> - директория, где будут лежать собранные пакеты, <code>${STAGINGDIR}</code> - директория, откуда будут собираться пакеты.</p>
<h2><a href="#theory" class="anchor" id="theory"><span class="octicon octicon-link"></span></a>Немного теории</h2>
<p>Создаем директорию, расшариваем ее (например, по <a href="/ru/2014/03/06/site-changes/" title="Статья про изменения сайта">ftp</a>). В ней две субдиректории - <code>i686</code> и <code>x86_64</code>, для каждого типа архитектур соответственно. И наполняем их набором пакетов по Вашему усмотрению.</p>
<p>Процесс обновления репозитория можно разбить на следующие части:</p>
<ol>
<li>Создание PKGBUILD'ов (обновление их из AUR'а).</li>
<li>Сборка пакетов для различных архитектур в чистом чруте.</li>
<li>Подписывание пакетов.</li>
<li>Создание списка пакетов.</li>
<li>Обновление репозиториев:
<ol><li>Удаление старых пакетов из репозитория.</li>
<li>Копирование новых пакетов.</li>
<li>Обновление базы.</li></ol>
</li>
<li>Очистка.</li>
</ol>
<p>Теперь по шагам.</p>
<h3><a href="#pkgbuild" class="anchor" id="pkgbuild"><span class="octicon octicon-link"></span></a>Создание PKGBUILD'ов</h3>
<p>Скачаем исходники для всех нужных пакетов из AUR'а:</p>
{% highlight bash %}
cd "${STAGINGDIR}"
yaourt -G package-name
{% endhighlight %}
<h3><a href="#building" class="anchor" id="building"><span class="octicon octicon-link"></span></a>Сборка пакетов</h3>
<p>Автоматически соберем каждый пакет:</p>
{% highlight bash %}
func_build() {
if [ ${USECOLOR} == "yes" ]; then
_bblue='\e[1;34m'
_bwhite='\e[1;37m'
_cclose='\e[0m'
fi
_PREPAREDIR="$1"
_ROOTDIR="$2"
eval $(/usr/bin/grep 'arch=' PKGBUILD)
eval $(/usr/bin/grep 'pkgname=' PKGBUILD)
echo -e "${_bwhite}[II] ${_bblue}=>${_cclose} Building ${_bwhite}${pkgname}${_cclose}"
if echo ${arch} | /usr/bin/grep 'any' -q; then
LC_MESSAGES=C /usr/bin/sudo /usr/bin/staging-i686-build -r "${_ROOTDIR}" -c
else
eval $(/usr/bin/grep 'pkgname=' PKGBUILD)
if echo ${pkgname} | /usr/bin/grep lib32 -q; then
LC_MESSAGES=C /usr/bin/sudo /usr/bin/multilib-staging-build -r "${_ROOTDIR}" -c
else
if /usr/bin/grep 'lib32' PKGBUILD -q; then
LC_MESSAGES=C /usr/bin/sudo /usr/bin/staging-i686-build -r "${_ROOTDIR}" -c
LC_MESSAGES=C /usr/bin/sudo /usr/bin/multilib-staging-build -r "${_ROOTDIR}" -c
else
LC_MESSAGES=C /usr/bin/sudo /usr/bin/staging-i686-build -r "${_ROOTDIR}" -c
LC_MESSAGES=C /usr/bin/sudo /usr/bin/staging-x86_64-build -r "${_ROOTDIR}" -c
fi
fi
fi
/usr/bin/cp *.pkg.tar.xz "${_PREPAREDIR}"
}
export -f func_build
# сборка
echo -e "${bwhite}[II]${cclose} Building packages"
cd "${STAGINGDIR}"
/usr/bin/find -name 'PKGBUILD' -type f -execdir /usr/bin/bash -c "func_build "${PREPAREDIR}" "${ROOTDIR}"" \;
{% endhighlight %}
<p>Для удобства рекомендую добавить в файл <code>/etc/sudoers</code> следующие строки:</p>
{% highlight bash %}
username ALL=NOPASSWD: /usr/bin/staging-i686-build
username ALL=NOPASSWD: /usr/bin/staging-x86_64-build
username ALL=NOPASSWD: /usr/bin/multilib-staging-build
{% endhighlight %}
<h3><a href="#signing" class="anchor" id="signing"><span class="octicon octicon-link"></span></a>Подпись пакетов</h3>
{% highlight bash %}
# подпись
if [ ${USEGPG} == "yes" ]; then
echo -e "${bwhite}[II]${cclose} Signing"
cd "${PREPAREDIR}"
for PACKAGE in $(/usr/bin/find . -name '*.pkg.tar.xz'); do
/usr/bin/gpg -b ${PACKAGE}
done
fi
{% endhighlight %}
<p>Для удобства рекомендую настроить <a href="https://wiki.archlinux.org/index.php/GPG#gpg-agent" title="ArchWiki">gpg-agent</a>.</p>
<h3><a href="#list" class="anchor" id="list"><span class="octicon octicon-link"></span></a>Создание списка пакетов</h3>
{% highlight bash %}
# создание списка пакетов
cd "${PREPAREDIR}"
i686_PACKAGES=$(/usr/bin/find * -name '*-i686.pkg.tar.xz' -o -name '*-any.pkg.tar.xz')
x86_64_PACKAGES=$(/usr/bin/find * -name '*-x86_64.pkg.tar.xz' -o -name '*-any.pkg.tar.xz')
echo -e "${bwhite}[II] ${bblue}=>${cclose} i686 packages: \n${bwhite}${i686_PACKAGES}${cclose}"
echo -e "${bwhite}[II] ${bblue}=>${cclose} x86_64 packages: \n${bwhite}${x86_64_PACKAGES}${cclose}"
{% endhighlight %}
<h3><a href="#updating" class="anchor" id="updating"><span class="octicon octicon-link"></span></a>Обновление репозиториев</h3>
<p>Функция для удаления пакетов из базы данных и из репозитория:</p>
{% highlight bash %}
func_remove() {
_PACKAGE="$1"
/usr/bin/rm -f "${_PACKAGE}"{,.sig}
}
{% endhighlight %}
<p>Обновление репозитория <code>i686</code>:</p>
{% highlight bash %}
# обновление репозитория i686
echo -e "${bwhite}[II]${cclose} Updating ${bwhite}i686${cclose} repo"
cd "${REPODIR}/i686"
for PACKAGE in ${i686_PACKAGES}; do
PKGNAME=$(/usr/bin/package-query -p -f %n "${PREPAREDIR}/${PACKAGE}")
for PKG in $(/usr/bin/find "${REPODIR}/i686" -name "${PKGNAME}"'*.pkg.tar.xz'); do
_PKGNAME=$(/usr/bin/package-query -p -f %n "${PKG}")
[ "${PKGNAME}" == "${_PKGNAME}" ] && func_remove "${PKG}"
done
/usr/bin/cp "${PREPAREDIR}/${PACKAGE}" .
[ ${USEGPG} == "yes" ] && /usr/bin/cp "${PREPAREDIR}/${PACKAGE}.sig" .
/usr/bin/repo-add ${DBNAME}.db.tar.gz "${PACKAGE}"
/usr/bin/repo-add --files ${DBNAME}.files.tar.gz "${PACKAGE}"
done
{% endhighlight %}
<p>Обновление репозитория <code>x86_64</code>:</p>
{% highlight bash %}
# обновление репозитория x86_64
echo -e "${bwhite}[II]${cclose} Updating ${bwhite}x86_64${cclose} repo"
cd "${REPODIR}/x86_64"
for PACKAGE in ${x86_64_PACKAGES}; do
PKGNAME=$(/usr/bin/package-query -p -f %n "${PREPAREDIR}/${PACKAGE}")
for PKG in $(/usr/bin/find "${REPODIR}/x86_64" -name "${PKGNAME}"'*.pkg.tar.xz'); do
_PKGNAME=$(/usr/bin/package-query -p -f %n "${PKG}")
[ "${PKGNAME}" == "${_PKGNAME}" ] && func_remove "${PKG}"
done
/usr/bin/cp "${PREPAREDIR}/${PACKAGE}" .
[ ${USEGPG} == "yes" ] && /usr/bin/cp "${PREPAREDIR}/${PACKAGE}.sig" .
/usr/bin/repo-add ${DBNAME}.db.tar.gz "${PACKAGE}"
/usr/bin/repo-add --files ${DBNAME}.files.tar.gz "${PACKAGE}"
done
{% endhighlight %}
<h3><a href="#clear" class="anchor" id="clear"><span class="octicon octicon-link"></span></a>Очистка</h3>
{% highlight bash %}
# очистка
cd "${PREPAREDIR}"
/usr/bin/rm -rf *
cd "${STAGINGDIR}"
/usr/bin/rm -rf *
{% endhighlight %}
<h3><a href="#symlinks" class="anchor" id="symlinks"><span class="octicon octicon-link"></span></a>Создание симлинков</h3>
<p>Вы можете захотеть создать директорию, которая будет содержать симлинки на актуальные версии пакетов с именами, не содержащими версии:</p>
{% highlight bash %}
# создание симлинков
if [ ${SYMLINK} == "yes" ]; then
echo -e "${bwhite}[II]${cclose} Creating symlinks"
if [ ! -d "${REPODIR}/non-versioned" ]; then
[ -e "${REPODIR}/non-versioned" ] && error_mes "file" "${REPODIR}/non-versioned"
echo -e "${bwhite}[II] ${bblue}Creating directory ${bwhite}'${REPODIR}/non-versioned'${cclose}"
mkdir -p "${REPODIR}/non-versioned" || error_mes "unknown"
fi
cd "${REPODIR}/non-versioned"
for PACKAGE in ${i686_PACKAGES}; do
PKGNAME=$(/usr/bin/package-query -p -f %n "${REPODIR}/i686/${PACKAGE}")
/usr/bin/ln -sf "../i686/${PACKAGE}" "${PKGNAME}-i686.pkg.tar.xz"
done
for PACKAGE in ${x86_64_PACKAGES}; do
PKGNAME=$(/usr/bin/package-query -p -f %n "${REPODIR}/x86_64/${PACKAGE}")
/usr/bin/ln -sf "../x86_64/${PACKAGE}" "${PKGNAME}-x86_64.pkg.tar.xz"
done
fi
{% endhighlight %}
<h3><a href="#file" class="anchor" id="file"><span class="octicon octicon-link"></span></a>Файл</h3>
<p><a href="https://github.com/arcan1s/repo-scripts" title="GitHub">Скрипты</a> целиком. Скачиваем исходники для пакетов, запускаем скрипт (при необходимости, редактируем переменные) и радуемся жизни.</p>
<h2><a href="#using" class="anchor" id="using"><span class="octicon octicon-link"></span></a>Использование репозитория</h2>
<p>Просто добавляем в файл <code>/etc/pacman.conf</code> следующие строки:</p>
{% highlight bash %}
[$REPONAME]
Server = ftp://$REPOADDRESS/repo/$arch
{% endhighlight %}