Руководство по упаковке 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