summaryrefslogtreecommitdiff
path: root/src/chroot-tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/chroot-tools')
-rw-r--r--src/chroot-tools/Makefile3
-rwxr-xr-xsrc/chroot-tools/chcleanup57
-rw-r--r--src/chroot-tools/chroot.conf13
-rwxr-xr-xsrc/chroot-tools/librechroot164
-rwxr-xr-xsrc/chroot-tools/libremakepkg187
-rwxr-xr-xsrc/chroot-tools/libremkchroot68
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 "$@"