diff options
Diffstat (limited to 'src/chroot-tools')
-rw-r--r-- | src/chroot-tools/Makefile | 3 | ||||
-rwxr-xr-x | src/chroot-tools/chcleanup | 57 | ||||
-rw-r--r-- | src/chroot-tools/chroot.conf | 13 | ||||
-rwxr-xr-x | src/chroot-tools/librechroot | 164 | ||||
-rwxr-xr-x | src/chroot-tools/libremakepkg | 187 | ||||
-rwxr-xr-x | src/chroot-tools/libremkchroot | 68 |
6 files changed, 492 insertions, 0 deletions
diff --git a/src/chroot-tools/Makefile b/src/chroot-tools/Makefile new file mode 100644 index 0000000..3ae95ea --- /dev/null +++ b/src/chroot-tools/Makefile @@ -0,0 +1,3 @@ +libre_execdir=$(sbindir) +libre_datadir=$(sysconfdir)/libretools.d +include ../../common.mk diff --git a/src/chroot-tools/chcleanup b/src/chroot-tools/chcleanup new file mode 100755 index 0000000..821c572 --- /dev/null +++ b/src/chroot-tools/chcleanup @@ -0,0 +1,57 @@ +#!/bin/bash -eE +# (c) Nicolás Reynolds <fauno@parabola.nu> +# Released under GPLv3 +# +# Performs chroot cleanup smartly, it only removes the unneeded packages or +# leaves you with a cleansystem +# +# See: HOOKPREBUILD + +DRYRUN=${DRYRUN:-false} +source "$(which libremessages)" + +if [[ ! -f /.arch-chroot ]] && ! ${DRYRUN}; then + error "(chcleanup): Must be run inside of a chroot" + exit 1 +fi + +source /etc/libretools.d/chroot.conf +# If we're running makepkg +if [ -f PKGBUILD ]; then + source PKGBUILD + CHROOTEXTRAPKG+=("${depends[@]}" + "${makedepends[@]}" + "${checkdepends[@]}") +fi + +msg "Cleaning chroot..." + +TEMPDIR="$(mktemp --tmpdir -d $(basename $0).XXXXX)" +cp -a /var/lib/pacman/sync "${TEMPDIR}/" +cleanup_log="${TEMPDIR}"/libretools-cleanup.log + +# Get the full list of packages needed by dependencies, including the base system +pacman -b "${TEMPDIR}" \ + -Sp --print-format "%n" \ + base base-devel sudo "${CHROOTEXTRAPKG[@]}" \ + >"${cleanup_log}" + +# Diff installed packages against a clean chroot then remove leftovers +packages=($(comm -23 <(pacman -Qq | sort -u) \ + <(sort -u "${cleanup_log}"))) + +RET=0 +if [[ ${#packages[@]} != 0 ]]; then + msg2 "Removing %d packages" ${#packages[@]} + + if ${DRYRUN}; then + echo "${packages[@]}" + else + # Only remove leftovers, -Rcs removes too much + pacman --noconfirm -Rn "${packages[@]}" || RET=$? + fi +fi +# Cleanup +rm -rf "${TEMPDIR}" + +exit $RET diff --git a/src/chroot-tools/chroot.conf b/src/chroot-tools/chroot.conf new file mode 100644 index 0000000..d84e8b4 --- /dev/null +++ b/src/chroot-tools/chroot.conf @@ -0,0 +1,13 @@ +# The full path to the chroot is +# $CHROOTDIR/$CHROOT/$CHROOTCOPY +# where $CHROOTCOPY is set at runtime, either +# - based on the username +# - set with the `-l COPY` flag +# The purpose of having a $CHROOT setting is that multiple clones of the same +# base $CHROOT can quickly and easily be created. +CHROOTDIR=/var/lib/archbuild +CHROOT=default + +# Extra packages to have installed on the chroot. +# This is in addition to CHROOTPKG=(base base-devel sudo) +CHROOTEXTRAPKG=(distcc ccache tsocks libretools) diff --git a/src/chroot-tools/librechroot b/src/chroot-tools/librechroot new file mode 100755 index 0000000..7f113f5 --- /dev/null +++ b/src/chroot-tools/librechroot @@ -0,0 +1,164 @@ +#!/bin/bash -euE +# librechroot + +# Copyright 2010 Nicolás Reynolds +# Copyright 2011 Joshua Haase +# Copyright 2012 Luke Shumaker +# +# This file is part of Parabola. +# +# Parabola is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Parabola is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Parabola. If not, see <http://www.gnu.org/licenses/>. + +. /usr/share/libretools/conf.sh +load_conf_libretools_chroot + +. "$(which libremessages)" +. /usr/share/devtools/makechrootpkg.sh + +cleanup=(':'); +cleanup() { + for cmd in "${cleanup[@]}"; do + $cmd + done +} + +cmd=${0##*/} +usage() { + echo "Usage: $cmd [OPTIONS] " + echo 'Interacts with a chroot.' + echo '' + echo 'This command will make the following configuration changes in' + echo 'the chroot:' + echo " - overwrite \`/etc/libretools.d/chroot.conf'" + echo " - overwrite \`/etc/pacman.d/mirrorlist'" + echo " - set \`CacheDir' in \`/etc/pacman.conf'" + echo '' + echo 'Options:' + echo ' Settings:' + echo " -n <CHROOT> Use this chroot instead of \`$CHROOT'" + echo " -l <COPY> Use this chroot copy instead \`$CHROOTCOPY'" + echo ' -N Disable networking in the chroot' + echo '' + echo ' Modes: (the last mode given will be used)' + echo ' -C Clean /repo in the chroot' + echo ' -c Clean the packages installed in the chroot' + echo ' -I <FILE> Install the package FILE into the chroot' + echo ' -i <PKG> Install the package PKG from repos into the chroot' + echo ' -m Make sure the chroot exists; do nothing else' + echo ' -r <CMD> Run CMD in the chroot' + echo " -s Sync the copy with the \`root' copy" + echo ' -u Update the chroot' + echo ' -h Show this message' +} + +main() { + CHROOTCOPY=$LIBREUSER + [[ $CHROOTCOPY != root ]] || CHROOTCOPY=copy + + local mode=enter + local archroot_args=(-f) + local ARG='' + while getopts 'n:l:NCcI:i:mr:suh' arg; do + case $arg in + n) CHROOT=$OPTARG;; + l) CHROOTCOPY=$OPTARG;; + N) archroot_args+=(-N);; + + C) mode=clean_repo;; + c) mode=clean_pacman;; + I) mode=install_file; ARG=$OPTARG;; + i) mode=install_pkg; ARG=$OPTARG;; + m) mode=noop;; + r) mode=run; ARG=$OPTARG;; + s) mode=sync;; + u) mode=update;; + + h) usage; exit 0;; + *) usage; exit 1;; + esac + done + shift $(($OPTIND - 1)) + if [[ $# > 0 ]]; then + usage + exit 1 + fi + + # not local + rootdir="${CHROOTDIR}/${CHROOT}/root" + copydir="${CHROOTDIR}/${CHROOT}/${CHROOTCOPY}" + + ######################################################################## + + if (( EUID )); then + error "This script must be run as root." + exit 1 + fi + + # Keep this lock as long as we are running + # Note that '9' is the same FD number as in (mk)archroot + lock_open_write 9 "$copydir" \ + "Waiting for existing lock on \`$copydir' to be released" + + if [[ ! -d $rootdir ]]; then + libremkchroot "$CHROOT" + fi + + if [[ ! -d $copydir ]] && [[ $mode != sync ]]; then + chroot_sync + fi + + mkdir -p $copydir/etc/libretools.d + { + if [[ -n ${CHROOTEXTRAPKG[@]:-} ]]; then + printf 'CHROOTEXTRAPKG=(' + printf "'%s' " "${CHROOTEXTRAPKG[@]}" + printf ')\n' + else + printf 'CHROOTEXTRAPKG=()\n' + fi + } > $copydir/etc/libretools.d/chroot.conf + + ######################################################################## + + trap cleanup EXIT + case "$mode" in + clean_repo) + rm -rf "${copydir}/repo/*" + bsdtar -czf "${copydir}/repo/repo.db.tar.gz" -T /dev/null + ln -s "repo.db.tar.gz" "${copydir}/repo/repo.db" + ;; + clean_pacman) + cleanup+=("rm -f $copydir/clean $copydir/chrootexec") + cp -a "$(which chcleanup)" "${copydir}/clean" + echo '#!/bin/bash' > "${copydir}/chrootexec" + echo 'mkdir /build' >> "${copydir}/chrootexec" + echo 'cd /build; /clean' >> "${copydir}/chrootexec" + chmod 755 "${copydir}/chrootexec" + archroot "${archroot_args[@]}" "${copydir}" -r /chrootexec + ;; + install_file) + cleanup+=("rm $copydir/${ARG##*/}") + cp "$ARG" "$copydir/${ARG##*/}" + archroot "${archroot_args[@]}" "${copydir}" -r "pacman -U /${ARG##*/} --noconfirm" + ;; + install_pkg) archroot "${archroot_args[@]}" "${copydir}" -i $ARG ;; + noop) :;; + run) archroot "${archroot_args[@]}" "${copydir}" -r "$ARG" ;; + sync) chroot_sync;; + update) archroot "${archroot_args[@]}" "${copydir}" -u ;; + enter) archroot "${archroot_args[@]}" "${copydir}" -r bash ;; + esac +} + +main "$@" diff --git a/src/chroot-tools/libremakepkg b/src/chroot-tools/libremakepkg new file mode 100755 index 0000000..a9e1fb7 --- /dev/null +++ b/src/chroot-tools/libremakepkg @@ -0,0 +1,187 @@ +#!/bin/bash -euE +# libremakepkg + +# Copyright 2010 - 2011 Nicolás Reynolds +# Copyright 2011 Joshua Ismael Haase Hernández +# Copyright 2012 Luke Shumaker +# +# This file is part of Parabola. +# +# Parabola is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Parabola is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Parabola. If not, see <http://www.gnu.org/licenses/>. + +. /usr/share/libretools/conf.sh +load_conf_libretools_chroot + +. "$(which libremessages)" +. /usr/share/devtools/makechrootpkg.sh + +shopt -s nullglob + +# Boring functions ############################################################# + +## +# End inmediately but print a useful message +## +trap_exit() { + copy_logs + error "$*" + exit 1 +} + +extract() { + local user=$LIBREUSER + $INCHROOT || user=nobody + + local clean + if $INCHROOT; then + clean=chcleanup + else + cp -a "$(which chcleanup)" "${copydir}/clean" + clean=/clean + fi + + chroot_exec "${clean} && sudo -u ${user} ${MAKEPKG} ${makepkg_args} -o" +} + +build() { + local user=$LIBREUSER + $INCHROOT || user=nobody + + chroot_exec -N "sudo -u ${user} ${MAKEPKG} ${makepkg_args} -e" +} + +# Functions that check for issues with the build ############################### + +check_pkgbuild() { + msg "Checking PKGBUILD for issues" + # TODO + if ! pkgbuild-check-nonfree -f; then + if [[ $? -eq 15 ]]; then + # other errors mean fail, not nonfree + error "PKGBUILD contains non-free issues" + exit 15 + else + warning "PKGBUILD couldn't be check aganist non-free issues" + fi + fi +} + +check_src() { + msg "Checking src directory for issues" + # TODO +} + +check_pkg() { + msg "Checking final package for issues" + # TODO +} + + +# The main program ############################################################# + +cmd=${0##*/} +usage() { + echo "Usage: $cmd [options] [-- makepkg args]" + echo 'This program will build your package.' + echo '' + echo 'If run from outside of a chroot, this will set PKGDEST and' + echo "SRCDEST in the chroot's \`/etc/makepkg.conf', as well as making" + echo "whataver alterations to the chroot \`librechroot' makes." + echo '' + echo 'Options:' + echo " -n <CHROOT> Use this chroot instead of \`$CHROOT'" + echo " -l <COPY> Use this chroot copy instead \`$CHROOTCOPY'" + echo " -m <MAKEPKG> Use the command MAKEPKG instead of \'makepkg'" + echo ' -h Show this message' +} + +main() { + # Parse command line ################################################### + + CHROOTCOPY=$LIBREUSER + [[ $CHROOTCOPY != root ]] || CHROOTCOPY=copy + + makepkg_args='-s --noconfirm -L ' + MAKEPKG=makepkg + + INCHROOT=false + if [[ -f /.arch-chroot ]]; then + INCHROOT=true + fi + + while getopts 'n:l:m:Rh' arg ; do + case "${arg}" in + n) CHROOT=$OPTARG;; + l) CHROOTCOPY=$OPTARG;; + m) MAKEPKG=$OPTARG;; + h) usage; exit 0;; + *) usage; exit 1;; + esac + done + shift $(($OPTIND - 1)) + # Pass all arguments after -- right to makepkg + makepkg_args+=" $*" + + if $INCHROOT; then + copydir='' + else + copydir="${CHROOTDIR}/${CHROOT}/${CHROOTCOPY}" + fi + + # Init ################################################################# + + if (( EUID )); then + error "This script must be run as root" + exit 1 + fi + + if [[ ! -f PKGBUILD ]]; then + # This is the message used by makepkg + error "PKGBUILD does not exist" + exit 1 + fi + + # Trap signals from makepkg + trap 'trap_exit "(libremakepkg): TERM signal caught. Exiting..."' TERM HUP QUIT + trap 'trap_exit "(libremakepkg): Aborted by user! Exiting..."' INT + trap 'trap_exit "(libremakepkg): An unknown error has occurred. Exiting..."' ERR + + SRCDEST="$(get_conf_makepkg SRCDEST .)" + PKGDEST="$(get_conf_makepkg PKGDEST .)" + + # OK, we're starting now ############################################### + + lock_open_write 9 "$copydir" \ + "Waiting for existing lock on \`$copydir' to be released" + + # Set target CARCH as it might be used within the PKGBUILD to select + # correct sources + MAKEPKG_CONF=$copydir/etc/makepkg.conf + export CARCH="$(get_conf_makepkg CARCH)" + unset MAKEPKG_CONF + + $INCHROOT || chroot_init + + check_pkgbuild + $INCHROOT || chroot_copy_in + extract + check_src + build + check_pkg + + add_to_local_repo + $INCHROOT || chroot_copy_out +} + +main "$@" diff --git a/src/chroot-tools/libremkchroot b/src/chroot-tools/libremkchroot new file mode 100755 index 0000000..6a13792 --- /dev/null +++ b/src/chroot-tools/libremkchroot @@ -0,0 +1,68 @@ +#!/bin/bash -euE +# libremkchroot + +# Copyright 2011, 2012 Luke Shumaker +# +# This file is part of Parabola. +# +# Parabola is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Parabola is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Parabola. If not, see <http://www.gnu.org/licenses/>. + +. /usr/share/libretools/conf.sh +load_conf_libretools_chroot + +. "$(which libremessages)" + +cmd=${0##*/} + +usage() { + echo "Usage: $cmd [OPTIONS] [CHROOT]" + echo 'This script will create a chroot to build packages in.' + echo "Use \`librechroot' to interact with the chroot after it is created." + echo '' + echo "The default CHROOT is \`${CHROOT}'." + echo '' + echo 'Options:' + echo ' -h Show this message' + echo '' + echo ' -C <file> Location of pacman config file.' + echo ' -M <file> Location of makepkg config file.' +} + +main() { + archroot_args=(-f); + while getopts 'hC:M:' arg; do + case "$arg" in + C|M) archroot_args+=("-$arg" "$OPTARG");; + + h) usage; exit 0;; + *) usage; exit 1;; + esac + done + shift $(($OPTIND - 1)) + case $# in + 0) :;; + 1) CHROOT="$1";; + *) usage; exit 1;; + esac + + if (( EUID )); then + error "This script must be run as root" + exit 1 + fi + + mkdir -p "${CHROOTDIR}/${CHROOT}" + archroot "${archroot_args[@]}" "${CHROOTDIR}/${CHROOT}/root" -i base base-devel sudo "${CHROOTEXTRAPKG[@]}" +} + +main "$@" |