#!/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