First commit

This commit is contained in:
2023-01-13 23:04:14 +01:00
parent 72a691dce0
commit 1050702522
31 changed files with 1324 additions and 4 deletions

199
bin/buildpkg Executable file
View File

@@ -0,0 +1,199 @@
#!/bin/bash
help() {
echo "buildpkg [options] pkgdir"
echo "-w | --workdir dir"
echo "-b | --basedirname dirname"
echo "-u | --builduser username"
echo "-m | --mirror url"
echo "-d | --mount dir"
echo "-r | --repo name"
echo "-r | --repo name|url"
echo "-p | --pkgs pkglist"
echo "-o | --outputdir dir"
echo "-n | --nodeps"
echo "--dbg"
echo "--help"
}
build() {
BASEDIR=${WORKDIR}/${BASEDIRNAME}
BUILDDIR=${WORKDIR}/${BUILDDIRNAME}
if ! checkbuildbase; then
return 1
fi
if ! createbuildroot; then
cleanbuildroot
return 1
fi
if ! configurebuildroot; then
cleanbuildroot
return 1
fi
if ! buildpkg; then
cleanbuildroot
return 1
fi
cleanbuildroot
}
checkbuildbase() {
if [ ! -d "${WORKDIR}" ]; then
if ! mkdir -p "${WORKDIR}"; then
return 1
fi
fi
if [ -d "${BASEDIR}" ]; then
cp /etc/resolv.conf "${BASEDIR}"/etc/
cp /etc/pacman.d/mirrorlist "${BASEDIR}"/etc/pacman.d/
if ! systemd-nspawn -a -D "${BASEDIR}" pacman -Syu --noconfirm; then
return 1
fi
else
if [[ $(stat -f -c %T "${WORKDIR}") == "btrfs" ]]; then
if ! btrfs subvolume create "${BASEDIR}"; then
return 1
fi
else
if ! mkdir -p "${BASEDIR}"; then
return 1
fi
fi
mkdir -p "${BASEDIR}"/var/lib/pacman
if ! pacman -Sy -r "${BASEDIR}" --noconfirm base-devel; then
return 1
fi
cp /etc/resolv.conf "${BASEDIR}"/etc/
cp /etc/pacman.d/mirrorlist "${BASEDIR}"/etc/pacman.d/
if ! systemd-nspawn -a -D "${BASEDIR}" pacman-key --init; then
return 1
fi
if ! systemd-nspawn -a -D "${BASEDIR}" pacman-key --populate; then
return 1
fi
fi
}
createbuildroot() {
if [ -d "${BUILDDIR}" ]; then
if ! rm -r "${BUILDDIR}"; then
return 1
fi
fi
if [[ $(stat -f -c %T "${WORKDIR}") == "btrfs" ]]; then
if ! btrfs subvolume snapshot "${BASEDIR}" "${BUILDDIR}"; then
return 1
fi
else
# CAUTION: /tmp is mounted with nosuid and is not useable as is
if ! cp -r "${BASEDIR}" "${BUILDDIR}"; then
return 1
fi
fi
if [[ "${MOUNTDIR}" != "" ]]; then
mkdir -p "${BUILDDIR}${MOUNTDIR}"
mount -o bind -o ro "${MOUNTDIR}" "${BUILDDIR}${MOUNTDIR}"
fi
sed -i -e '/ParallelDownloads/ s/^#*/#/' "${BUILDDIR}"/etc/pacman.conf
sed -i -e '/MAKEFLAGS=/ s/^#*/#/' "${BUILDDIR}"/etc/makepkg.conf
local -r CPUCORES=$(grep -c ^processor /proc/cpuinfo)
sed -i "s/^MAKEFLAGS=.*/MAKEFLAGS=\"-j${CPUCORES}\"/" "${BUILDDIR}"/etc/makepkg.conf
}
configurebuildroot() {
if ! systemd-nspawn -a -D "${BUILDDIR}" useradd -r -m "${BUILDUSER}"; then
return 1
fi
echo "${BUILDUSER} ALL=(root) NOPASSWD: /usr/bin/pacman" > "${BUILDDIR}"/etc/sudoers.d/"${BUILDUSER}"
if ! cp -r "${PKGDIR}" "${BUILDDIR}"/home/"${BUILDUSER}"/pkg; then
return 1
fi
if ! systemd-nspawn -a -D "${BUILDDIR}" chown -R "${BUILDUSER}":"${BUILDUSER}" /home/"${BUILDUSER}"/pkg; then
return 1
fi
if [ "${MIRROR}" != "" ]; then
echo "Server = ${MIRROR}" > "${BUILDDIR}"/etc/pacman.d/mirrorlist
fi
if [ "${REPOS}" != "" ]; then
for REPODATA in "${REPOS[@]}"; do
readarray -d "|" -t REPOITEMS<<<"${REPODATA}"
if [ "${REPOITEMS[1]}" == "" ]; then
if grep "\[${REPODATA}\]" /etc/pacman.conf; then
sed -i -e "/\[${REPODATA}\]/ {s/#//;}" "${BUILDDIR}"/etc/pacman.conf
sed -i -e "/\[${REPODATA}\]/ {n;s/#//;}" "${BUILDDIR}"/etc/pacman.conf
else
echo -e "\n[${REPODATA}]\nInclude = /etc/pacman.d/mirrorlist" >> "${BUILDDIR}"/etc/pacman.conf
fi
else
echo -e "\n[${REPOITEMS[0]}]\nSigLevel = Optional TrustAll\nServer = ${REPOITEMS[1]}" >> "${BUILDDIR}"/etc/pacman.conf
fi
done
if ! systemd-nspawn -a -D "${BUILDDIR}" pacman -Sy; then
return 1
fi
fi
if [ "${PKGS}" != "" ]; then
if ! systemd-nspawn -a -D "${BUILDDIR}" pacman -S --needed --noconfirm "${PKGS[@]}"; then
return 1
fi
fi
}
buildpkg() {
if [ ${NODEPS} == 0 ]; then
if ! systemd-nspawn -a -D "${BUILDDIR}" --chdir=/home/"${BUILDUSER}"/pkg --user="${BUILDUSER}" makepkg -s --needed --noconfirm; then
return 1
fi
else
if ! systemd-nspawn -a -D "${BUILDDIR}" --chdir=/home/"${BUILDUSER}"/pkg --user="${BUILDUSER}" makepkg -s -d --needed --noconfirm; then
return 1
fi
fi
if ! cp "${BUILDDIR}"/home/"${BUILDUSER}"/pkg/*.pkg.tar.zst "${OUTPUTDIR}"; then
return 1
fi
}
cleanbuildroot() {
if [[ "${MOUNTDIR}" != "" ]]; then
umount "${BUILDDIR}${MOUNTDIR}"
fi
if [ ${DBGMODE} == 0 ]; then
rm -r "${BUILDDIR}"
fi
}
if [ ${#} == 0 ]; then
help
exit 1
fi
PKGDIR=${*: -1}
WORKDIR=/var/cache/pkgbuilder/
BASEDIRNAME=arch-base
BASEDIR=""
BUILDDIRNAME=$(date "+%Y-%m-%d_%H-%M-%S")
BUILDDIR=""
BUILDUSER=pkgbuilder
MOUNTDIR=""
MIRROR=""
REPOS=()
PKGS=()
OUTPUTDIR=$(pwd)
NODEPS=0
DBGMODE=0
while [[ ${#} -gt 0 ]]; do
case ${1} in
--help) help; exit 0;;
-w | --workdir) WORKDIR="${2}"; shift; shift;;
-b | --basedirname) BASEDIRNAME="${2}"; shift; shift;;
-u | --builduser) BUILDUSER="${2}"; shift; shift;;
-d | --mount) MOUNTDIR=${2}; shift; shift;;
-m | --mirror) MIRROR="${2}"; shift; shift;;
-r | --repo) REPOS+=("${2}"); shift; shift;;
-p | --pkgs) PKGS+=("${2}"); shift; shift;;
-o | --outputdir) OUTPUTDIR="${2}"; shift; shift;;
-n | --nodeps) NODEPS=1; shift;;
--dbg) DBGMODE=1; shift;;
*) shift;;
esac
done
build

388
bin/pkgbuilder Executable file
View File

@@ -0,0 +1,388 @@
#!/bin/bash
showHelp() {
echo "arch-pkg-builder"
echo "----------------"
echo "arch-pkg-builder [args] command [args]"
echo ""
echo "command :"
echo " list List packages infos"
echo " infos pkgname Display package infos"
echo " build pkgname Build and publish package"
echo " bump pkgname Bump release and publish package"
echo " checkupdate pkgname Check package update"
echo " checkupdateall Check all packages update"
echo " update pkgname Update package"
echo " updateall Update all packages"
echo ""
echo "args :"
echo " --cnf configfile"
echo " --notify"
echo " --nopush"
echo " --dry-run"
echo " --dbg"
}
readSetting() { # $1=filename $2=name $3=defaultvalue
local -r LINE=$(grep "^${2}=" "${1}")
local -r VALUE=${LINE/${2}=/}
if [ "${VALUE}" != "" ]; then
echo "${VALUE}"
else
echo "${3}"
fi
}
writeSetting() { #$1=filename $2=valuename $3=value
local -r LINE=$(grep "^${2}=" "${1}")
if [ "${LINE}" != "" ]; then
sed -i "s/^${2}=.*/${2}=${3}/" "${1}"
else
echo "${2}=${3}" >> "${1}"
fi
}
tblCell() { #$1=Text $2=Size
local CELL=""
CELL=$(printf "%-${2}s")
CELL="${1}${CELL}"
CELL=${CELL:0:${2}}
echo "${CELL}"
}
getPluginFile() { # $1=PKGDIR $2=PKGNAME $3=PLUGINDIR
local -r PKGDIR=${1}
local -r PKGNAME=${2}
local -r PLUGINDIR=${3}
local -r PLUGIN=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "plugin" "manual")
if [ "${PLUGIN}" == "custom" ]; then
if [ ! -f "${PKGDIR}"/"${PKGNAME}"/plugin ]; then
return 1
fi
echo "${PKGDIR}"/"${PKGNAME}"/plugin
else
if [ ! -f "${PLUGINDIR}"/"${PLUGIN}" ]; then
return 1
fi
echo "${PLUGINDIR}"/"${PLUGIN}"
fi
}
notify() {
if [ ${NOTIFY} == 0 ]; then
return 0
fi
if [ "${NOTIFYMSG}" == "" ]; then
return 0
fi
if [ ! -f /usr/bin/sendmail ]; then
return 0
fi
local EMAIL=""
EMAIL=$(readSetting "${CNFFILE}" "EMAIL" "")
if [ "${EMAIL}" == "" ]; then
return 0
fi
echo -e "subject:PKGBuilder - Notifications\n${NOTIFYMSG}" | sendmail "${EMAIL}"
}
pkgList() {
if [ ! -d "${PKGDIR}" ]; then
return 1
fi
for PKGDIRNAME in "${PKGDIR}"/*; do
[[ -e "${PKGDIRNAME}" ]] || break
local PKGNAME=""
PKGNAME=$(basename "${PKGDIRNAME}")
local VALUES=()
VALUES+=("$(tblCell "${PKGNAME}" 30)")
VALUE=$(tblCell "$(readSetting "${PKGDIRNAME}"/settings version)" 24)
VALUES+=("${VALUE}")
VALUES+=("$(tblCell "$(readSetting "${PKGDIRNAME}"/settings plugin)" 20)")
VALUES+=("$(tblCell "$(readSetting "${PKGDIRNAME}"/settings target)" 20)")
VALUE=$(tblCell "$(readSetting "${PKGDIRNAME}"/settings lastbuilddate)" 20)
VALUES+=("${VALUE}")
VALUES+=("$(readSetting "${PKGDIRNAME}"/settings lastbuildstatus)")
echo "${VALUES[@]}"
done
}
pkgInfos() { # $1=PKGNAME
local -r PKGNAME=${1}
if [ ! -f "${PKGDIR}"/"${PKGNAME}"/settings ]; then
return 1
fi
cat "${PKGDIR}"/"${PKGNAME}"/settings
}
pkgCreate() { # $1=PKGNAME $2=MODELNAME
local -r PKGNAME=${1}
local -r MODELNAME=${2}
if [ ! -d "${MODELDIR}"/"${MODELNAME}" ]; then
return 1
fi
cp -r "${MODELDIR}"/"${MODELNAME}" "${PKGDIR}"/"${PKGNAME}"
}
pkgBuild() { # $1=PKGNAME
local -r PKGNAME=${1}
local -r BUILDDATE=$(date "+%Y.%m.%d %H:%M:%S")
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuilddate" "${BUILDDATE}"
fi
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
. "${PLUGINFILE}"
local PKGFILES=""
if ! PKGFILES=$(plugin_getpkgfiles "${PKGDIR}" "${PKGNAME}"); then
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuildstatus" "Error - No PKG files provided"
fi
return 1
fi
if [ ! -d "${PKGFILES}" ]; then
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuildstatus" "Error - PKG files not found"
fi
return 1
fi
mkdir "${WORKDIR}"/.output
local BUILDARGS=()
BUILDARGS+=(-w "${WORKDIR}")
BUILDARGS+=(-d /var/lib/pkgbuilder)
BUILDARGS+=(-o "${WORKDIR}"/.output)
local -r PKGMIRROR=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "mirror" "")
if [[ "${PKGMIRROR}" != "" ]]; then
BUILDARGS+=(-m "${PKGMIRROR}")
fi
# shellcheck disable=SC2207
local -r PKGPKGS=($(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "pkgs" ""))
if [[ "${PKGPKGS[*]}" != "" ]]; then
for PKGPKG in "${PKGPKGS[@]}"; do
BUILDARGS+=(-p "${PKGPKG}")
done
fi
local -r PKGNODEPS=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "nodeps" "")
if [[ "${PKGNODEPS}" == "1" ]]; then
BUILDARGS+=(-n)
fi
# shellcheck disable=SC2207
local -r PKGREPOS=($(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "repos" ""))
if [[ "${PKGREPOS[*]}" != "" ]]; then
for PKGREPO in "${PKGREPOS[@]}"; do
BUILDARGS+=(-r "${PKGREPO}")
done
fi
if [[ "${DBGMODE}" == "1" ]]; then
BUILDARGS+=(--dbg)
fi
BUILDARGS+=("${PKGFILES}")
# shellcheck disable=SC2068
if ! buildpkg ${BUILDARGS[@]}; then
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuildstatus" "Error - Build"
fi
return 1
fi
local PKGFILENAME=""
PKGFILENAME=$(ls "${WORKDIR}"/.output/"${PKGNAME}"*.pkg.tar.zst)
local VERSION=""
VERSION=$(pacman -Qp "${PKGFILENAME}" | awk -F ' ' '{print $2}')
if [[ "${DRYRUN}" == "0" ]]; then
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "version" "${VERSION}"
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "builddate" "${BUILDDATE}"
writeSetting "${PKGDIR}"/"${PKGNAME}"/settings "lastbuildstatus" "Ok"
fi
local -r PKGTARGET=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "target" "")
if [[ "${DRYRUN}" == "0" ]]; then
if [[ "${NOPUSH}" == "0" ]]; then
if [ ! -d "${VARDIR}"/packages/"${PKGTARGET}" ]; then
mkdir -p "${VARDIR}"/packages/"${PKGTARGET}"
fi
cp "${PKGFILENAME}" "${VARDIR}"/packages/"${PKGTARGET}"
fi
fi
pkgPush "${PKGNAME}" "${PKGFILENAME}"
rm -r "${WORKDIR}"/.output
}
pkgPush() { # $1=PKGNAME $2=PKGFILE
local -r PKGNAME=${1}
local -r PKGFILE=${2}
if [[ ${NOPUSH} == 0 ]]; then
local -r PKGTARGET=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "target" "")
if [ -f "${TRGDIR}"/"${PKGTARGET}" ]; then
local -r PKGTARGETTYPE=$(readSetting "${TRGDIR}"/"${PKGTARGET}" "type" "")
local -r TARGETDEST=$(readSetting "${TRGDIR}"/"${PKGTARGET}" "dest" "")
if [[ "${DRYRUN}" == "0" ]]; then
case ${PKGTARGETTYPE} in
dir)
if [ -d "${TARGETDEST}" ]; then
local -r TARGETFILENAME=${TARGETDEST}/$(basename "${PKGFILE}")
cp "${PKGFILE}" "${TARGETFILENAME}"
repo-add -n -R "${TARGETDEST}/${PKGTARGET}.db.tar.zst" "${TARGETFILENAME}"
fi
;;
ssh)
local -r TARGETPUBKEY=$(readSetting "${TRGDIR}"/"${PKGTARGET}" "pubkey" "")
local -r TARGETSRV=$(awk -F':/' '{print $1}' <<< "${TARGETDEST}")
local -r TARGETDIR=/$(awk -F':/' '{print $2}' <<< "${TARGETDEST}")
local -r TARGETFILENAME=${TARGETDEST}/$(basename "${PKGFILE}")
if [ "${TARGETPUBKEY}" == "" ]; then
scp "${PKGFILE}" "${TARGETDEST}"
ssh "${TARGETSRV}" repo-add -n -R "${TARGETDIR}"/"${PKGTARGET}".db.tar.zst "${TARGETDIR}"/"$(basename "${TARGETFILENAME}")"
else
scp -i "${TARGETPUBKEY}" "${PKGFILE}" "${TARGETDEST}"
ssh -i "${TARGETPUBKEY}" "${TARGETSRV}" repo-add -n -R "${TARGETDIR}"/"${PKGTARGET}".db.tar.zst "${TARGETDIR}"/"$(basename "${TARGETFILENAME}")"
fi
;;
esac
fi
fi
fi
}
pkgBump() { # $1=PKGNAME
local -r PKGNAME=${1}
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
. "${PLUGINFILE}"
if ! plugin_isbumpable; then
return 1
fi
if [[ "${DRYRUN}" == "0" ]]; then
if ! plugin_bump "${PKGDIR}" "${PKGNAME}"; then
return 1
fi
pkgBuild "${PKGNAME}"
fi
}
pkgCheckUpdate() { # $1=PKGNAME
local -r PKGNAME=${1}
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
. "${PLUGINFILE}"
local -r PKGVERSION=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "version" "0")
local -r PKGPLUGIN=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "plugin" "")
local VALUES=()
VALUES+=("$(tblCell "${PKGNAME}" 30)")
VALUE=$(tblCell "$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings version)" 24)
VALUES+=("${VALUE}")
if ! plugin_isupdatable; then
VALUES+=(" ")
VALUES+=("$(tblCell 'Skipping' 25)")
VALUES+=("$(tblCell "${PKGPLUGIN}" 25)")
echo "${VALUES[@]}"
return 0
fi
local -r ONLINEVERSION=$(plugin_getlatestversion)
if [ "${ONLINEVERSION}" == "" ]; then
return 1
fi
if [[ "${ONLINEVERSION}" != "${PKGVERSION}" ]]; then
VALUES+=(" -> ")
VALUES+=("$(tblCell "${ONLINEVERSION}" 25)")
NOTIFYMSG+="${PKGNAME} ${PKGVERSION} -> ${ONLINEVERSION}\n"
else
VALUES+=(" ")
VALUES+=("$(tblCell 'Up to date' 25)")
fi
VALUES+=("$(tblCell "${PKGPLUGIN}" 25)")
echo "${VALUES[@]}"
}
pkgCheckUpdateAll() {
if [ ! -d "${PKGDIR}" ]; then
return 1
fi
for PKGDIRNAME in "${PKGDIR}"/*; do
[[ -e "${PKGDIRNAME}" ]] || break
local PKGNAME=""
PKGNAME=$(basename "${PKGDIRNAME}")
pkgCheckUpdate "${PKGNAME}"
done
notify
}
pkgUpdate() { # $1=PKGNAME
local -r PKGNAME=${1}
local PLUGINFILE=""
if ! PLUGINFILE=$(getPluginFile "${PKGDIR}" "${PKGNAME}" "${PLUGINDIR}"); then
return 1
fi
. "${PLUGINFILE}"
if ! plugin_isupdatable; then
return 1
fi
local -r ONLINEVERSION=$(plugin_getlatestversion)
if [ "${ONLINEVERSION}" == "" ]; then
return 1
fi
local -r PKGVERSION=$(readSetting "${PKGDIR}"/"${PKGNAME}"/settings "version" "0")
if [[ "${ONLINEVERSION}" == "${PKGVERSION}" ]]; then
return 0
fi
if ! plugin_update; then
return 1
fi
pkgBuild "${PKGNAME}"
}
pkgUpdateAll() {
if [ ! -d "${PKGDIR}" ]; then
return 1
fi
for PKGDIRNAME in "${PKGDIR}"/*; do
[[ -e "${PKGDIRNAME}" ]] || break
local PKGNAME=""
PKGNAME=$(basename "${PKGDIRNAME}")
pkgUpdate "${PKGNAME}"
done
}
CNFFILE="/etc/pkgbuilder/config"
ARGCMD=""
ARGPKG=""
ARGMDL=""
NOTIFYMSG=""
NOTIFY=0
NOPUSH=0
DRYRUN=0
DBGMODE=0
while [[ ${#} -gt 0 ]]; do
case ${1} in
--help) showHelp; exit 0;;
list | checkupdateall | updateall) ARGCMD="${1}"; shift;;
infos | build | bump | checkupdate | update) ARGCMD="${1}"; ARGPKG="${2}"; shift; shift;;
create) ARGCMD="${1}"; ARGMDL="${2}"; ARGPKG="${3}"; shift; shift;;
--cnf) CNFFILE="${2}"; shift; shift;;
--notify) NOTIFY=1; shift;;
--nopush) NOPUSH=1; shift;;
--dry-run) DRYRUN=1; shift;;
--dbg) DBGMODE=1; shift;;
*) shift;;
esac
done
PKGDIR=$(readSetting "${CNFFILE}" "PKGDIR" "/etc/pkgbuilder/packages")
TRGDIR=$(readSetting "${CNFFILE}" "TRGDIR" "/etc/pkgbuilder/targets")
PLUGINDIR=$(readSetting "${CNFFILE}" "PLUGINDIR" "/usr/share/pkgbuilder/plugins")
MODELDIR=$(readSetting "${CNFFILE}" "MODELDIR" "/usr/share/pkgbuilder/models")
WORKDIR=$(readSetting "${CNFFILE}" "WORKDIR" "/var/cache/pkgbuilder")
VARDIR=$(readSetting "${CNFFILE}" "VARDIR" "/var/lib/pkgbuilder")
case ${ARGCMD} in
list) pkgList;;
infos) pkgInfos "${ARGPKG}";;
create) pkgCreate "${ARGPKG}" "${ARGMDL}";;
build) pkgBuild "${ARGPKG}";;
bump) pkgBump "${ARGPKG}";;
checkupdate) pkgCheckUpdate "${ARGPKG}";;
checkupdateall) pkgCheckUpdateAll;;
update) pkgUpdate "${ARGPKG}";;
updateall) pkgUpdateall;;
*) showHelp; exit 1;;
esac