Руководство по упаковке Go для Arch Linux
В этом уроке я покажу, как упаковать приложение Go для пользовательского репозитория Arch Linux (AUR). Мы откроем учетную запись AUR, пройдемся по шаблону PKGBUILD и будем следовать рекомендациям Arch Wiki для Go. К концу руководства вы сможете загрузить свой собственный пакет Arch, использующий Go в AUR.
Требования
- Git
- Go
- Arch Linux x86_64
- AUR aкаунт
Настройка учетной записи AUR и ключа SSH
Мы заполним имя пользователя и адрес электронной почты в этой форме, а также самый важный открытый ssh-ключ. Остальное опционально.
Сгенерируйте и заполните открытый ключ SSH.
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
$ cat ~/.ssh/aur_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDiniLTrxNbDH/R66BYUHieRT9sTqkn2678picCjF8MoTxsZume105hsDFSfg79pzfedY3iJQXMsCzk11pcnUNsGHxT/wh9s8aFrlI+n9JVMpEe7VOZqTLYyNBXtpAJUaY2Ptp4/l2p81dhpeCGTMhYNu2eDxaCaI5QvDOkyEmAZYAmuLT19OwJv8YW/1+1tg+Piaxyg/b+Dic7EeQQT10AI9drfRQG5pazREYkLGjClJP6pw/OnNcScMWR/Sd4phiz84DKnBLWXIIdbK+CDKDyFPt1FMIXkY1YSY+RAyXgJ3m1z6byCRs5BrN4RZArPcIEmVRRffkhq7tVBK0mwygTl8Hku60MqvdENLrylPcH3Ua2iqYLhftuMNfsZffUb9d5MI0BCaoQuzMfEMG0ZZZuDoZ38HZDjZbFFG0Fg+rt6IRTdRogZ0bzWacM0ig8J+HDnJnNIhXut5RC/f4W1RIXITujNp0blQRISrh9lGXcH/qz002ovcAoAd2yRkRdhh3NlP9mAZ/Rns47FwKP94ooG2/Zb2JRNJLJgdgaEWT+u1v5G4tPAoySxwZ0HBZSxSEmZC34piiPxdaHd6NAy3drt3Nt7QWVdBU9pD17lj8PsBuzXVReBkM+/0MFMLYDThunwVVhpZSHtmDTzWoGijIJnzaZrJMPcZZab/vF1WJ/yQ== talhaaltinel@hotmail.com
После того, как вы скопируете свой открытый ключ SSH в поле открытого ключа SSH, измените файл ~/.gitconfig
.
[url "ssh://aur@aur.archlinux.org/"]
insteadOf = https://aur.archlinux.org/
insteadOf = http://aur.archlinux.org/
Наконец, запустите последнюю команду и введите ответ в форме для подтверждения.
Понимание PKGBUILD
Если вы проверите /usr/share/pacman/PKGBUILD.proto
, вы увидите поля, которые можно заполнить.
# This is an example PKGBUILD file. Use this as a start to creating your own,
# and remove these comments. For more information, see 'man PKGBUILD'.
# NOTE: Please fill out the license field for your package! If it is unknown,
# then please put 'unknown'.
# Maintainer: Your Name <youremail@domain.com>
pkgname=NAME
pkgver=VERSION
pkgrel=1
epoch=
pkgdesc=""
arch=()
url=""
license=('GPL')
groups=()
depends=()
makedepends=()
checkdepends=()
optdepends=()
provides=()
conflicts=()
replaces=()
backup=()
options=()
install=
changelog=
source=("$pkgname-$pkgver.tar.gz"
"$pkgname-$pkgver.patch")
noextract=()
md5sums=()
validpgpkeys=()
prepare() {
cd "$pkgname-$pkgver"
patch -p1 -i "$srcdir/$pkgname-$pkgver.patch"
}
build() {
cd "$pkgname-$pkgver"
./configure --prefix=/usr
make
}
check() {
cd "$pkgname-$pkgver"
make -k check
}
package() {
cd "$pkgname-$pkgver"
make DESTDIR="$pkgdir/" install
}
Таким образом, вам не обязательно заполнять все эти поля, но полезно запомнить, что они собой представляют:
pkgname
иpkgversion
— это имя пакета программного обеспечения и версия программного обеспечения, которое вы предоставляете.pkgrel
иepoch
— это дополнительные способы подменить версиюpkgversion
, в большинстве случаев вы не будете их использовать.pkgdesc
— это описание вашего программного обеспечения,Arch
— это архитектура, и в большинстве случаев это просто x86_64.- URL-адрес и лицензия — это URL-адрес репозитория программного обеспечения и фактическое имя лицензии, они очень важны.
- группы предоставляют нам возможность установить несколько пакетов программного обеспечения, думайте об этом как о гноме (очень большая группа программного обеспечения)
depends
— это зависимости времени выполненияmakedependents
— это зависимости времени компиляцииcheckdependents
— это проверка/проверка зависимостейoptdependents
— необязательные зависимости времени выполнения.Provides
используется в качестве альтернативной замены другого пакета.Conflicts
используются, чтобы не устанавливать конфликтующий пакет.replaces
используется как то, что может заменить этот встроенный пакет.- резервная копия перечисляет файлы, которые следует скопировать при обновлении пакета.
- параметры могут включать в себя такие вещи, как флаги компилятора, настройки сжатия и т. д.
install
можно использовать для указания пользовательских сценариев установки или команд, которые будут запускаться в процессе установки.- журнал изменений указывает местоположение файла журнала изменений или примечаний к выпуску
source
перечисляет исходные файлы, необходимые для сборки пакета. Он включает URL-адреса или пути к исходному коду или другим необходимым файлам.noextract
позволяет указать файлы, которые не следует извлекать в процессе сборки.md5sums
,b2sums
,sha512sums
,sha256sums
— это контрольные суммы, их также можно пропустить, если они не нужныvalidpgpkeys
также аналогичен приведенным выше контрольным суммам.
Есть также 4 наиболее распространенные стандартные функции оболочки PKGBUILD
, такие как;
Prepare()
используется для внесения изменений или применения исправлений к исходному коду до начала процесса сборки.build()
— это место, где происходит фактическая компиляция или сборка программного пакета.check()
запускает тесты, чтобы убедиться, что программное обеспечение работает должным образом. Используется для проверки правильности пакета перед установкой.package()
помещает собранные файлы в упакованный формат, подходящий для установки. Он копирует файлы во временную структуру каталогов, которая отражает конечный каталог установки.
Создайте .gitignore
Поскольку мы будем собирать несколько раз для подтверждения нашего пакета, я настоятельно рекомендую хороший .gitignore
, чтобы случайно не отправить ваши артефакты. Ниже мой файл .gitignore
.
*
!/.gitignore
!/.SRCINFO
!/PKGBUILD
Базовый PKGBUILD для Go
По своей мысли я создал очень простой файл PKGBUILD для k3sup, который является прекрасным инструментом для начальной загрузки кластеров k3s. Пожалуйста, проверьте k3sup и поддержите, если хотите.
Дружеское напоминание для имени пакета; xyzpackage
означает сборку из стабильной версии исходного кода, xyzpackage-git
означает сборку из последней фиксации исходного кода, xyzpackage-bin
означает получение предварительно собранного двоичного файла без фазы сборки.
# Maintainer: Talha Altinel <talhaaltinel@hotmail.com>
pkgname=k3sup
pkgver=0.13.0
pkgrel=1
pkgdesc='A tool to bootstrap K3s over SSH in < 60s'
arch=('x86_64')
url='https://github.com/alexellis/k3sup'
license=('MIT')
depends=('openssh')
makedepends=('git' 'go>=1.20')
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/alexellis/k3sup/archive/${pkgver}.tar.gz")
sha256sums=('24939844ac6de581eb05ef6425c89c32b2d0e22800f1344c19b2164eec846c92')
_commit=('1d2e443ea56a355cc6bd0a14a8f8a2661a72f2e8')
build() {
cd "$pkgname-$pkgver"
CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build \
-ldflags "-s -w -X github.com/alexellis/k3sup/cmd.Version=$pkgver -X github.com/alexellis/k3sup/cmd.GitCommit=$_commit" \
-o k3sup \
.
for shell in bash fish zsh; do
./k3sup completion "$shell" > "$shell-completion"
done
}
package() {
cd "$pkgname-$pkgver"
install -vDm755 -t "$pkgdir/usr/bin" k3sup
mkdir -p "${pkgdir}/usr/share/bash-completion/completions/"
mkdir -p "${pkgdir}/usr/share/zsh/site-functions/"
mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/"
install -vDm644 bash-completion "$pkgdir/usr/share/bash-completion/completions/k3sup"
install -vDm644 fish-completion "$pkgdir/usr/share/fish/vendor_completions.d/k3sup.fish"
install -vDm644 zsh-completion "$pkgdir/usr/share/zsh/site-functions/_k3sup"
install -vDm644 -t "$pkgdir/usr/share/licenses/$pkgname" LICENSE
}
На этапе сборки я компилирую исходный код для создания двоичного файла k3sup, а также запускаю его для генерации завершения сценария оболочки. Отдайте должное этой функциональности, которая реализована в библиотеке Go spf13/cobra для CLI.
На этапе упаковки я перемещаю двоичный файл, завершения сценария оболочки и лицензию на правильные места.
Все это звучит круто и приятно, но нам не хватает нескольких вещей, поэтому в Arch Wiki есть подробное руководство по этому поводу, но, короче говоря, мне нужна программа под названием namcap
, и когда я делаю sudo pacman -S namcap
, затем запускаю namcap на PKGBUILD и создаю .zst
архив.
$ namcap ./PKGBUILD
$ makepkg -s && namcap k3sup-0.13.0-1-x86_64.pkg.tar.zst
k3sup W: ELF file ('usr/bin/k3sup') lacks FULL RELRO, check LDFLAGS.
k3sup W: ELF file ('usr/bin/k3sup') lacks PIE.
k3sup W: Dependency included, but may not be needed ('openssh')
Самым большим сюрпризом было то, что все направляющие арки на самом деле допускали только специально созданные двоичные файлы Go с CGO :( приведенный выше PKGBUILD был полностью действительным, но если вы хотите, чтобы ваш пакет находился в официальных репозиториях Arch за пределами AUR, вам необходимо обеспечить FULL RELRO и PIE Я не буду слишком подробно объяснять эти термины, по сути, это бинарное усиление для обеспечения максимальной безопасности.
Усиленная безопасность PKGBUILD для Go
# Maintainer: Talha Altinel <talhaaltinel@hotmail.com>
pkgname=k3sup
pkgver=0.13.0
pkgrel=1
pkgdesc='A tool to bootstrap K3s over SSH in < 60s'
arch=('x86_64')
url='https://github.com/alexellis/k3sup'
license=('MIT')
depends=('glibc' 'openssh')
makedepends=('git' 'go>=1.20')
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/alexellis/k3sup/archive/${pkgver}.tar.gz")
sha256sums=('24939844ac6de581eb05ef6425c89c32b2d0e22800f1344c19b2164eec846c92')
_commit=('1d2e443ea56a355cc6bd0a14a8f8a2661a72f2e8')
build() {
cd "$pkgname-$pkgver"
export CGO_CPPFLAGS="${CPPFLAGS}"
export CGO_CFLAGS="${CFLAGS}"
export CGO_CXXFLAGS="${CXXFLAGS}"
export CGO_LDFLAGS="${LDFLAGS}"
export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw"
go build \
-ldflags "-s -w -X github.com/alexellis/k3sup/cmd.Version=$pkgver -X github.com/alexellis/k3sup/cmd.GitCommit=$_commit" \
-o k3sup \
.
for shell in bash fish zsh; do
./k3sup completion "$shell" > "$shell-completion"
done
}
package() {
cd "$pkgname-$pkgver"
install -Dm755 -t "$pkgdir/usr/bin" k3sup
mkdir -p "${pkgdir}/usr/share/bash-completion/completions/"
mkdir -p "${pkgdir}/usr/share/zsh/site-functions/"
mkdir -p "${pkgdir}/usr/share/fish/vendor_completions.d/"
install -Dm644 bash-completion "$pkgdir/usr/share/bash-completion/completions/k3sup"
install -Dm644 fish-completion "$pkgdir/usr/share/fish/vendor_completions.d/k3sup.fish"
install -Dm644 zsh-completion "$pkgdir/usr/share/zsh/site-functions/_k3sup"
install -Dm644 -t "$pkgdir/usr/share/licenses/$pkgname" LICENSE
}
Теперь мы снова запускаем namcap
для проверки после запуска makepkg
.
$ namcap ./PKGBUILD
$ makepkg -s && namcap k3sup-0.13.0-1-x86_64.pkg.tar.zst ✔ 03:18:13
k3sup W: Dependency included, but may not be needed ('openssh')
Теперь все это выглядит удивительно безопасным на двоичном уровне, если ваша версия glibc
не имеет уязвимостей безопасности;)
Давайте сейчас отправим это в AUR. Не забывайте обновлять .SRCINFO
перед каждой отправкой. Также обратите внимание на уже занятые имена пакетов в AUR.
$ updpkgsums && makepkg --printsrcinfo > .SRCINFO
$ git init
$ git remote add origin https://aur.archlinux.org/k3sup.git
$ git add . && git commit -m "initial release"
$ git push -u origin master
Конечный результат
https://aur.archlinux.org/packages/k3sup
$ git clone https://aur.archlinux.org/packages/k3sup
$ cd ./k3sup && less ./PKGBUILD
$ makepkg -si