Compare commits

...

No commits in common. "master" and "old" have entirely different histories.
master ... old

17 changed files with 159 additions and 67 deletions

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# mikroskeem's AUR build bot
NOTE: This is actually not ready, so it is not recommended to run it in production (don't be like me!)
## Installing
* Set up new Arch Linux nspawn container (I recommend using this [script](https://gist.github.com/artizirk/fab2ce13277a190ee6063b03b8e0a6e9) made by @arti)
* Install [aurutils](https://aur.archlinux.org/packages/aurutils) and set it up
* Copy `buildpkg` to `/usr/bin` in builder container
* Set up [OpenSMTPD](https://wiki.archlinux.org/index.php/OpenSMTPD) server on container and host (to send emails to builder in case of failure)
- Note: Don't forget to firewall!
* Copy `aur` script to `/usr/bin` in host machine
* Set up nginx to serve packages to host (and maybe for public)
* Take look at `scripts/` directory, you might find useful scripts there
## Known issues
* You can't edit PKGBUILD-s
* You can't accept GPG keys automatically (insecure to do so, but you can do `gpg --recv-key <key>` in container shell)
* Not documentated enough!
* Probably something more I'm not currently aware of
* Storing GPG password is insecure, if your builder gets hacked, then revoke your key
## TODO
* Pacman cache automatic cleanup timer
* AUR build data automatic cleanup
## More ideas
* Telegram Bot to build packages?

12
aur Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
aur(){
if [ -z "$1" ]; then
echo "aur: <package name to build and install>"
return 1
fi
sudo machinectl shell --setenv=INVOKER="${USER}@$(hostname)" builduser@builder /usr/bin/buildpkg $1
}
aur $*
# vim: set ft=sh

45
buildpkg Executable file
View File

@ -0,0 +1,45 @@
#!/bin/bash
# Get package name
PACKAGE=${1}
shift
# Defaults
XDG_CACHE_HOME=${XDG_CACHE_HOME:="${HOME}/.cache"}
PKG_SOURCE_DIR="$XDG_CACHE_HOME/aursync/$PACKAGE"
MAIL_RECIPIENT=${INVOKER:="mark@Willywonka"}
if [ ! "$(whoami)" == "builduser" ]; then
su builduser -c "${0}" "${PACKAGE}"
exit
fi
# Update packages
echo "#### Updating packages"
sudo pacman --noconfirm -Syu
# aursync starts 'less' to show files, no thanks
export PAGER=cat
# Check for previous failed build and clean up
if [ -f "$PKG_SOURCE_DIR/FAILED" ]; then
echo "#### Cleaning up previous failed build"
rm -rf "$PKG_SOURCE_DIR"
fi
# Start aursync
LOGF=$(mktemp)
(
set -o pipefail
aursync -n ${PACKAGE} | tee ${LOGF}
)
# Mark package source dir failed
if [ ! $? -eq 0 ]; then
touch "$PKG_SOURCE_DIR/FAILED"
echo "#### Build failed"
cat ${LOGF} | mail -s "Build for AUR package '$PACKAGE' failed" ${MAIL_RECIPIENT}
fi
rm ${LOGF}
# vim:ft=sh

View File

@ -1,3 +0,0 @@
#!/bin/bash
tmate -S /run/user/1000/aur-buildbot/tmate-sockets/tmate-0.sock attach-session

View File

@ -1,25 +0,0 @@
#!/bin/bash
source vars.sh
mkdir -p "${XDG_BUILDBOT_TMATE}"
CONFIG_FILE_LOC="$(mktemp --suffix="-aur-buildbot.conf")"
# Check if tmate sessions are empty
# TODO: implement concurrent builds
if [ -z "$(find "${XDG_BUILDBOT_TMATE}" -maxdepth 0 -empty -exec echo "1" ';')" ]; then
echo "Concurrent builds are not supported yet!"
exit 0
fi
# Write configuration file
cat > "${CONFIG_FILE_LOC}" <<EOF
set-option -g tmate-webhook-url "https://warp.mikroskeem.eu/aur_buildbot"
set-option -g tmate-webhook-userdata "some private data"
EOF
# Start up tmate
tmate -S "${XDG_BUILDBOT_TMATE}/tmate-0.sock" -f "${CONFIG_FILE_LOC}" new-session -d '/usr/bin/python3 webhook-handler.py /bin/bash -i'
# Remove configuration file
rm "${CONFIG_FILE_LOC}"

38
scripts/init-gpg.sh Executable file
View File

@ -0,0 +1,38 @@
#!/bin/bash
# Go to home directory for sure
pushd $HOME >/dev/null
# Kill gpg-agent
pkill gpg-agent
# Rewrite gpg-agent configuration
cat > ~/.gnupg/gpg-agent.conf <<EOF
keyserver-options auto-key-retrieve
default-cache-ttl 4320000
max-cache-ttl 8640000
allow-loopback-pinentry
EOF
# Start gpg-agent
gpg-agent
# Create dummy file
_dummyfile=`mktemp`
echo "foobar" > "${_dummyfile}"
# Cache password in gpg-agent by signing dummy file
cat ~/passphrase.txt | env -i gpg \
--pinentry-mode loopback --passphrase-fd 0 \
--no-tty --batch --yes \
--detach-sig --output "${_dummyfile}.sig" "${_dummyfile}"
# Verify given signature
env -i gpg --verify \
"${_dummyfile}.sig" "${_dummyfile}"
echo $?
rm "${_dummyfile}" "${_dummyfile}.sig"
popd >/dev/null

1
scripts/passphrase.txt Normal file
View File

@ -0,0 +1 @@
# put pw here

4
scripts/remove-package.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
pushd /srv/http/built-packages >/dev/null
repose aurpackages -zdvs ${1}
popd

6
scripts/resign-all.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
pushd /srv/http/built-packages >/dev/null
rm *.sig
~/resign-repo.sh
~/resign-missing.sh
popd >/dev/null

9
scripts/resign-missing.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
pushd /srv/http/built-packages >/dev/null
find -name "*.pkg.tar.xz" | while read _p; do
if [ ! -f "${_p}.sig" ]; then
echo "Signing ${_p}"
gpg --output ${_p}.sig --detach-sig ${_p}
fi
done
popd >/dev/null

5
scripts/resign-repo.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
pushd /srv/http/built-packages >/dev/null
gpg --yes --output aurpackages.db.sig --detach-sig aurpackages.db
gpg --yes --output aurpackages.files.sig --detach-sig aurpackages.files
popd >/dev/null

2
scripts/update-packages.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
PAGER=cat aursync -s -n -u -f

8
smtpd/smtpd.conf Normal file
View File

@ -0,0 +1,8 @@
listen on host0
table aliases file:/etc/smtpd/aliases
table vdoms "/etc/smtpd/vdoms"
accept for local alias <aliases> deliver to mbox
accept from any for domain <vdoms> deliver to mbox
accept for any relay

1
smtpd/vdoms Normal file
View File

@ -0,0 +1 @@
builder

View File

@ -1,14 +0,0 @@
#!/usr/bin/env python
import tornado.ioloop
import tornado.web
import pprint
class DumpingHandler(tornado.web.RequestHandler):
def post(self):
pprint.pprint(self.request)
pprint.pprint(self.request.body.decode())
if __name__ == "__main__":
tornado.web.Application([("/.*", DumpingHandler)]).listen(8080)
tornado.ioloop.IOLoop.instance().start()

View File

@ -1,4 +0,0 @@
#!/bin/bash
export XDG_BUILDBOT="${XDG_RUNTIME_DIR}/aur-buildbot"
export XDG_BUILDBOT_TMATE="${XDG_RUNTIME_DIR}/aur-buildbot/tmate-sockets"

View File

@ -1,21 +0,0 @@
#!/usr/bin/env python
import json
import os
import sys
import time
import tornado.ioloop
import tornado.web
class WebHookHandler(tornado.web.RequestHandler):
def post(self):
data = json.loads(self.request.body.decode())
if data["type"] == "session_register":
print(data["params"]["stoken_ro"])
target = sys.argv[1:]
os.spawnlp(os.P_NOWAIT, target[0], target)
if __name__ == "__main__":
tornado.web.Application([("/aur_buildbot", WebHookHandler)]).listen(8080)
tornado.ioloop.IOLoop.instance().start()
time.sleep(5)