From 8ea4ef181e92bfe5f410e365b8ed614f939c8da1 Mon Sep 17 00:00:00 2001 From: Joel Grunbaum <joelgrun@gmail.com> Date: Sun, 29 Mar 2020 06:40:55 +0000 Subject: [PATCH] Large change to overall structure, moved to one file --- README.org | 30 ++++--- /dev/null | 7 - main.sh | 163 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+), 20 deletions(-) diff --git a/README.org b/README.org index 1d4450d..d51eb89 100755 --- a/README.org +++ b/README.org @@ -1,28 +1,32 @@ #+TITLE: Auto-build package repository for Arch Linux * What is this? -This is a set of files to auto-build a personal repository for Arch. -It uses a chroot environment to build the packages, so that a build environment can be made on a server running a non-arch operating system. +This is a package autobuild solution for Arch Linux. +It supports the automated building of packages from the AUR. + +Currently it supports package signing and building clean from source. +It can help to set itself up and generate GPG keys if need be. + +The chroot files are here from an older version of this project and are here as I think they're interesting. * Set-up -Edit ~create_chroot.sh~ variables at the top to your details. -Run ~sudo create_chroot.sh~, and create the git repository in ~/build/repo~ when prompted, with a remote repository. +Edit the variables at the top of ~main.sh~ to suit your repository details. +Have a look at the init function near the bottom of the file to decide if you want to run it. +If you decide to generate a GPG key, edit the name, comment and email so that it fits you. You may also want to set ~MAKEFLAGS="-j$(nproc)"~ within the chroot to enable parallel compilation. For xz compression, add the ~--threads=0~ option to COMPRESSXZ such that it reads ~COMPRESSXZ=(xz -c -z - --threads=0)~. ccache may be useful to decrease the times of git packages, due to the little changes. * Usage -All scripts must be run as root. -To enter the chroot, use the ~enter_chroot.sh~ script. -To add a package from the AUR, use the ~add_package.sh~ script, with the git URL as the argument. -To build the packages use the ~build_packages.sh~ script, which will enter the chroot, and build the packages from the PKGBUILDs stored in ~/build/repo~. - -The packages are built and put into the directory ~/build/repo/x86_64~, then pushed with git. -Only the latest packages are stored in ~/build/repo/x86_64~ to avoid multiple older versions building up. - -To enable automatic building, create a cronjob for root, something of the sort of ~0 12 * * * /path/to/dir/build_packages.sh~ to build ever day at noon. +To add a package ~main.sh add [package]~ should be run. Currently I only support adding one package at a time. +To update all packages, use ~main.sh build-all~. A ~-f~ flag can be used to force a rebuild of all the packages. +To allow automatic building, use a cronjob or write a systemd unit, there are many guides out there, although I may add examples if I feel like it. * To Dos +- Multiple packages from a single PKGBUILD + Some PKGBUILDs can create many packages at once, currently I am unable to handle this. - Error catching for builds which fail. + Have emailing, but nothing more advanced. Would be nice to have some basic error handling in the script - Create a universal variables file + Not sure how useful this would be, but could be nice diff --git a/add_dependency.sh b/add_dependency.sh deleted file mode 100755 index ad37d51..0000000 --- a/add_dependency.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -CHDIR=$(dirname "$(realpath $0)")/chroot -RUSER=joelgrun -RLOC=35.225.177.191 -RPATH=/var/www/joelg.cf/html/ - -mount --bind $CHDIR $CHDIR -$CHDIR/bin/arch-chroot $CHDIR su joel -c "cd /build/repo/dependencies; - git clone https://aur.archlinux.org/$1.git - cd $1; - makepkg -si --noconfirm; - ln $1-*.pkg.tar.xz ../../x86_64/; - cd ../../x86_64; - #rm Chizi123.db Chizi123.files; - repo-add ../Chizi123.db.tar.xz $1-*.pkg.tar.xz; - #ln ../Chizi123.db.tar.xz Chizi123.db; - #ln ../Chizi123.files.tar.xz Chizi123.files; - cd ../; - rsync -aL --delete x86_64 $RUSER@$RLOC:$RPATH - git add x86_64/; - git commit -m \"added $1\"; - git push" -umount $CHDIR diff --git a/add_package.sh b/add_package.sh deleted file mode 100755 index 16e46ca..0000000 --- a/add_package.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -CHDIR=$(dirname "$(realpath $0)")/chroot -RUSER=joelgrun -RLOC=35.225.177.191 -RPATH=/var/www/joelg.cf/html/ - -mount --bind $CHDIR $CHDIR -$CHDIR/bin/arch-chroot $CHDIR su joel -c "cd /build/repo; - git clone https://aur.archlinux.org/$1.git - cd $1; - makepkg -s --noconfirm; - ln $1-*.pkg.tar.xz ../x86_64/; - cd ../x86_64; - #rm Chizi123.db Chizi123.files; - repo-add ../Chizi123.db.tar.xz $1-*.pkg.tar.xz; - #ln ../Chizi123.db.tar.xz Chizi123.db; - #ln ../Chizi123.files.tar.xz Chizi123.files; - cd ../; - rsync -aL --delete x86_64 $RUSER@$RLOC:$RPATH;" - #git add x86_64/; - #git commit -m \"added $1\"; - #git push" -umount $CHDIR diff --git a/autobuild.service b/autobuild.service deleted file mode 100644 index e62d848..0000000 --- a/autobuild.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Autobuild repo service - -[Service] -ExecStart=/data/repo/build_packages.sh -Type=oneshot - -[Install] -WantedBy=multi-user.target diff --git a/autobuild.timer b/autobuild.timer deleted file mode 100644 index 67a4471..0000000 --- a/autobuild.timer +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Build repo on timer - -[Timer] -OnCalendar=daily -Persistent=true - -[Install] -WantedBy=timers.target diff --git a/build.sh b/build.sh deleted file mode 100755 index 02e42f0..0000000 --- a/build.sh +++ /dev/null @@ -1,150 +0,0 @@ -#!/bin/bash - -#Number of old packages to store, should be at least 1 -NUM_BACK=5 -#remote details -RUSER=joelgrun -RLOC=35.225.177.191 -RPATH=/var/www/joelg.cf/html/ - -function newest_matching_file -{ - # Use ${1-} instead of $1 in case 'nounset' is set - local -r glob_pattern=${1-} - - if (( $# != 1 )) ; then - echo 'usage: newest_matching_file GLOB_PATTERN' >&2 - return 1 - fi - - # To avoid printing garbage if no files match the pattern, set - # 'nullglob' if necessary - local -i need_to_unset_nullglob=0 - if [[ ":$BASHOPTS:" != *:nullglob:* ]] ; then - shopt -s nullglob - need_to_unset_nullglob=1 - fi - - newest_file= - for file in $glob_pattern ; do - [[ -z $newest_file || $file -nt $newest_file ]] \ - && newest_file=$file - done - - # To avoid unexpected behaviour elsewhere, unset nullglob if it was - # set by this function - (( need_to_unset_nullglob )) && shopt -u nullglob - - # Use printf instead of echo in case the file name begins with '-' - [[ -n $newest_file ]] && printf '%s\n' "$newest_file" - - return 0 -} - -function oldest_matching_file -{ - # Use ${1-} instead of $1 in case 'nounset' is set - local -r glob_pattern=${1-} - - if (( $# != 1 )) ; then - echo 'usage: oldest_matching_file GLOB_PATTERN' >&2 - return 1 - fi - - # To avoid printing garbage if no files match the pattern, set - # 'nullglob' if necessary - local -i need_to_unset_nullglob=0 - if [[ ":$BASHOPTS:" != *:nullglob:* ]] ; then - shopt -s nullglob - need_to_unset_nullglob=1 - fi - - oldest_file= - for file in $glob_pattern ; do - [[ -z $oldest_file || $file -ot $oldest_file ]] \ - && oldest_file=$file - done - - # To avoid unexpected behaviour elsewhere, unset nullglob if it was - # set by this function - (( need_to_unset_nullglob )) && shopt -u nullglob - - # Use printf instead of echo in case the file name begins with '-' - [[ -n $oldest_file ]] && printf '%s\n' "$oldest_file" - - return 0 -} - -#update system -sudo pacman -Syu --noconfirm - -#go to build directory -cd $(dirname "$(realpath $0)") - -#Remove old packages -#git rm -r x86_64/* -#rm -r x86_64 -#mkdir x86_64 - -#dependencies -cd dependencies -for d in `find . -maxdepth 1 -not -path '*/\.*' -type d` -do - #Only do package directories - if [ "$d" = "./x86_64" ] || [ "$d" = "." ]; then - continue - fi - cd $d - #update package to latest from AUR - git pull -f - makepkg -si --noconfirm - if [ $? = 0 ]; then - latest=$(newest_matching_file '*.pkg.tar.xz') - while [ $NUM_BACK \< $(find . -name "*.pkg.tar.xz" | wc -l) ] - do - oldest=$(oldest_matching_file '*.pkg.tar.xz') - rm $oldest - done - cd .. - rm ../x86_64/"$d"*".pkg.tar.xz" - ln $d/$latest ../x86_64/$latest - else - cd .. - fi - repo-add ../Chizi123.db.tar.xz ../x86_64/$latest -done -cd .. - -#main packages -for d in `find . -maxdepth 1 -not -path '*/\.*' -type d` -do - #Only do package directories - if [ "$d" = "./x86_64" ] || [ "$d" = "." ] || [ "$d" = "./dependencies" ]; then - continue - fi - cd $d - #update package to latest from AUR - git pull -f - makepkg -s --noconfirm - if [ $? = 0 ]; then - latest=$(newest_matching_file '*.pkg.tar.xz') - while [ $NUM_BACK \< $(find . -name "*.pkg.tar.xz" | wc -l) ] - do - oldest=$(oldest_matching_file '*.pkg.tar.xz') - rm $oldest - done - cd .. - rm x86_64/"$d"*".pkg.tar.xz" - ln $d/$latest x86_64/$latest - else - cd .. - fi - repo-add ./Chizi123.db.tar.xz x86_64/$latest -done - -#ln Chizi123.db.tar.xz x86_64/Chizi123.db -#ln Chizi123.files.tar.xz x86_64/Chizi123.files -#git add x86_64 -#git commit -m "'$(date +%d/%m/%y-%H:%M)'" -#git push -rsync -aL --delete x86_64 $RUSER@$RLOC:$RPATH diff --git a/build_packages.sh b/build_packages.sh deleted file mode 100755 index bb61675..0000000 --- a/build_packages.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -CHDIR=$(dirname "$(realpath $0)")/chroot -mount --bind $CHDIR $CHDIR -$CHDIR/bin/arch-chroot $CHDIR su joel -c "/build/repo/build.sh" -umount $CHDIR diff --git a/enter_chroot.sh b/enter_chroot.sh deleted file mode 100755 index a4f6270..0000000 --- a/enter_chroot.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -CHDIR=$(dirname "$(realpath $0)")/chroot -mount --bind $CHDIR $CHDIR -$CHDIR/bin/arch-chroot $CHDIR su joel -umount $CHDIR diff --git a/fix_AUR.sh b/fix_AUR.sh deleted file mode 100755 index 3b57c2a..0000000 --- a/fix_AUR.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -CHDIR=$(dirname "$(realpath $0)")/chroot -mount --bind $CHDIR $CHDIR -$CHDIR/bin/arch-chroot $CHDIR su joel -c "find /build/repo/dependencies -maxdepth 1 -not -path '*\/.*' -type d -exec git -C {} fetch \; -exec git -C {} reset --hard origin/master \; - find /build/repo -maxdepth 1 -not -path '*\/.*' -type d -exec git -C {} fetch \; -exec git -C {} reset --hard origin/master \;" -umount $CHDIR diff --git a/main.sh b/main.sh new file mode 100644 index 0000000..53a4e0b --- /dev/null +++ b/main.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +REPODIR=/repo/x86_64 +BUILDDIR=/repo/build +REPONAME= +UPDATE=N +CLEAN=N +SIGN=N +KEY="" +NUM_OLD=5 +export PACKAGER="John Doe <jd@change.me>" +EMAIL="" + +ERRORS="" + +#Helper for finding newest and oldest files +#Sourced from stack overflow +function newold_matching_file +{ + # Use ${1-} instead of $1 in case 'nounset' is set + local -r glob_pattern=${2-} + + # To avoid printing garbage if no files match the pattern, set + # 'nullglob' if necessary + local -i need_to_unset_nullglob=0 + if [[ ":$BASHOPTS:" != *:nullglob:* ]] ; then + shopt -s nullglob + need_to_unset_nullglob=1 + fi + + file= + for f in $glob_pattern ; do + if [ $1 == "n" ]; then + [[ -z $f || $f -nt $_file ]] && file=$f + elif [ $1 == "o" ]; then + [[ -z $f || $f -ot $_file ]] && file=$f + fi + done + + # To avoid unexpected behaviour elsewhere, unset nullglob if it was + # set by this function + (( need_to_unset_nullglob )) && shopt -u nullglob + + # Use printf instead of echo in case the file name begins with '-' + [[ -n $file ]] && printf '%s\n' "$file" + + return 0 +} + +#Build latest version of a package +function build_pkg { + #check if PKGBUILD has updated, don't rebuild if hasn't changed + #rebuild if git is in filename (git tree may change without PKGBUILD) + #rebuild if forced + if [[ ! -z $(git pull | grep "Already up to date.") && -z $(echo $1 | grep git) && -z $2 ]]; then + return 2 + fi + makepkg -s --noconfirm $([ $CLEAN == "Y" ] && echo "-c") $([ $SIGN == "Y" ] && echo "--sign --key $KEY") $([ "$2" == "-f" ] && echo -f) + if [ $? != 0 ]; then + #Register error + ERRORS=$(printf '%s %s' "$ERRORS" "$1") + return 1 + fi + + #copy package to repo directory + latest="$(newold_matching_file n '*.pkg.tar.xz')" + cp $latest $REPODIR/$latest + repo-add $([ "$SIGN" == "Y" ] && echo "--sign --key $KEY") $REPODIR/$REPONAME.db.tar.xz $REPODIR/$latest + + #Remove old versions of packages + while [ $NUM_OLD \< $(find . -name '*.pkg.tar.xz' | wc -l) ] + do + old=$(newold_matching_file o '*.pkg.tar.xz') + rm $REPODIR/$old $old + done + return 0 +} + +#Update packages in BUILDDIR +function build_all { + #system update + if [ $UPDATE == "Y" ]; then + sudo pacman -Syu --noconfirm + fi + #update every package currently stored + for d in $(find $BUILDDIR -maxdepth 1 -mindepth 1 -not -path '*/\.*' -type d) + do + cd $d + build_pkg $(echo $d | rev | cut -d'/' -f1 | rev) $1 + done + + return 0 +} + +#Add a new package to be built +function add { + cd $BUILDDIR + git clone https://aur.archlinux.org/$1.git + cd $1 + build_pkg $1 new + return 0 +} + +#Check config and create build folders +function init { + #check for configuration here + [ -z $REPODIR ] && echo "Enter REPODIR" && return 1 + [ -z $BUILDDIR ] && echo "Enter BUILDDIR" && return 2 + [ -z $REPONAME ] && echo "Enter REPONAME" && return 3 + + #make build directories + [ ! -d $REPODIR ] && mkdir -p $REPODIR + [ ! -d $BUILDDIR ] && mkdir -p $BUILDDIR + + #packages required to build others + sudo pacman -S --noconfirm base-devel git + + #add repo to pacman.conf so can install own packages + if [ -z $(grep "$REPONAME" /etc/pacman.conf) ]; then + printf "[$REPONAME]\nSigLevel = Optional TrustAll\nServer = file://$REPODIR\n" >> /etc/pacman.conf + fi + + #create GPG key for package signing + if [ "$SIGN" == "Y" && "$KEY" == "" ]; then + ( + echo "Key-Type: RSA" + echo "Key-Length: 2048" + echo "Subkey-Type: RSA" + echo "Subkey-Length: 2048" + echo "Passphrase: \"\"" + echo "Expire-Date: 0" + echo "Name-Real: John Doe" + echo "Name-Comment: Arch buildbot" + echo "Name-Email: $(whoami)@localhost" + echo "%commit" + ) | gpg --batch --generate-key + gpg --export --output $REPONAME.key --armor "John Doe" + gpg --export-secret-keys --output $REPONAME.secret.key --armor "John Doe" + echo "Please change the key information in this file" + fi + + return 0 +} + +case $1 in + "init") + init;; + "add") + add $2;; + "build-all") + build_all $([ "$2" == "-f" ] && echo "-f") + if [ "$ERRORS" != "" ]; then + echo "Errors in packages $ERRORS" + if [ "$EMAIL" != "" ]; then + printf "Build for $(date)\nErrors found in $ERRORS\nPlease address these soon" | sendmail $EMAIL + fi + else + echo "All packages built successfully" + fi + ;; + *) + printf "Invalid usage\nUsage: $0 init|add|build_all\n";; +esac -- Gitblit v1.9.3