2013-05-02 05:24:28 +02:00
|
|
|
#!/bin/bash
|
2017-03-28 22:13:18 +02:00
|
|
|
# License: GNU GPLv2
|
|
|
|
#
|
2013-05-02 05:24:28 +02:00
|
|
|
# This program 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; version 2 of the License.
|
|
|
|
#
|
|
|
|
# This program 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.
|
|
|
|
|
|
|
|
m4_include(lib/common.sh)
|
2017-03-07 19:19:29 +01:00
|
|
|
m4_include(lib/archroot.sh)
|
2013-05-02 05:24:28 +02:00
|
|
|
|
2019-03-28 22:40:47 +01:00
|
|
|
# umask might have been changed in /etc/profile
|
|
|
|
# ensure that sane default is set again
|
|
|
|
umask 0022
|
|
|
|
|
2013-05-02 05:24:28 +02:00
|
|
|
working_dir=''
|
|
|
|
|
2017-04-05 21:36:00 +02:00
|
|
|
files=()
|
|
|
|
|
2013-05-02 05:24:28 +02:00
|
|
|
usage() {
|
|
|
|
echo "Usage: ${0##*/} [options] working-dir [systemd-nspawn arguments]"
|
|
|
|
echo "A wrapper around systemd-nspawn. Provides support for pacman."
|
|
|
|
echo
|
|
|
|
echo ' options:'
|
|
|
|
echo ' -C <file> Location of a pacman config file'
|
|
|
|
echo ' -M <file> Location of a makepkg config file'
|
|
|
|
echo ' -c <dir> Set pacman cache'
|
2017-04-05 21:36:00 +02:00
|
|
|
echo ' -f <file> Copy file from the host to the chroot'
|
2017-04-05 21:36:01 +02:00
|
|
|
echo ' -s Do not run setarch'
|
2013-05-02 05:24:28 +02:00
|
|
|
echo ' -h This message'
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2017-04-05 21:36:01 +02:00
|
|
|
while getopts 'hC:M:c:f:s' arg; do
|
2013-05-02 05:24:28 +02:00
|
|
|
case "$arg" in
|
|
|
|
C) pac_conf="$OPTARG" ;;
|
|
|
|
M) makepkg_conf="$OPTARG" ;;
|
2018-06-10 23:20:48 +02:00
|
|
|
c) cache_dirs+=("$OPTARG") ;;
|
2017-04-05 21:36:00 +02:00
|
|
|
f) files+=("$OPTARG") ;;
|
2017-04-05 21:36:01 +02:00
|
|
|
s) nosetarch=1 ;;
|
2013-05-02 05:24:28 +02:00
|
|
|
h|?) usage ;;
|
2017-04-02 10:09:55 +02:00
|
|
|
*) error "invalid argument '%s'" "$arg"; usage ;;
|
2013-05-02 05:24:28 +02:00
|
|
|
esac
|
|
|
|
done
|
2017-05-06 00:41:07 +02:00
|
|
|
shift $((OPTIND - 1))
|
2013-05-02 05:24:28 +02:00
|
|
|
|
|
|
|
(( $# < 1 )) && die 'You must specify a directory.'
|
2017-03-07 19:27:36 +01:00
|
|
|
check_root
|
2013-05-02 05:24:28 +02:00
|
|
|
|
2013-08-10 03:33:59 +02:00
|
|
|
working_dir=$(readlink -f "$1")
|
2013-05-02 05:24:28 +02:00
|
|
|
shift 1
|
|
|
|
|
|
|
|
[[ -z $working_dir ]] && die 'Please specify a working directory.'
|
|
|
|
|
2018-06-10 23:20:48 +02:00
|
|
|
pacconf_cmd=$(command -v pacman-conf || command -v pacconf)
|
|
|
|
|
|
|
|
if (( ${#cache_dirs[@]} == 0 )); then
|
arch-nspawn should not take pacman cache from host
Previously, arch-nspawn was using the hosts' pacman cache in
the chroot even when the chroot was set up with a different
cache by mkarchroot, unless specified with the -c flag.
Problem is that makechrootpkg passes no -C, -M nor -c flags
to arch-nspawn, so all values must be obtained from the
working directory.
This change take the cache directories from the pacman.conf
specified with the -C option unless the -c option was given
(as is the case when the chroot is set up with mkarchroot),
and, when neither -C nor -c is given (as is the case when
invoked by makechrootpkg), the cache directory is taken
from the pacman.conf in the working directory.
This wasn't such an issue when i686 was mainline, however,
which building packages in a chroot against archlinux32 on
an x86_64 platform, the cache of the host should _never_ be
used.
Rebased by eschwartz on top of cachedir reworking.
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2017-11-19 06:53:37 +01:00
|
|
|
mapfile -t cache_dirs < <($pacconf_cmd --config "${pac_conf:-$working_dir/etc/pacman.conf}" CacheDir)
|
2013-05-02 05:24:28 +02:00
|
|
|
fi
|
|
|
|
|
2017-05-06 00:41:10 +02:00
|
|
|
# shellcheck disable=2016
|
2019-03-22 12:21:08 +01:00
|
|
|
host_mirrors=($($pacconf_cmd --repo extra Server 2> /dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#'))
|
2013-05-02 05:24:28 +02:00
|
|
|
|
2019-03-28 21:38:50 +01:00
|
|
|
while read -r line; do
|
|
|
|
mapfile -t lines < <($pacconf_cmd --config "${pac_conf:-$working_dir/etc/pacman.conf}" \
|
|
|
|
--repo $line Server | sed -r 's#(.*/)[^/]+/os/.+#\1$repo/os/$arch#')
|
|
|
|
if [[ ${lines[0]} != ${host_mirrors[0]} ]]; then
|
|
|
|
for line in "${lines[@]}"; do
|
|
|
|
if [[ $line = file://* ]]; then
|
|
|
|
line=${line#file://}
|
|
|
|
in_array "$line" "${cache_dirs[@]}" || cache_dirs+=("$line")
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
done < <($pacconf_cmd --config "${pac_conf:-$working_dir/etc/pacman.conf}" --repo-list)
|
|
|
|
|
2013-05-02 05:24:28 +02:00
|
|
|
# {{{ functions
|
|
|
|
build_mount_args() {
|
|
|
|
declare -g mount_args=()
|
|
|
|
|
2019-03-22 12:21:08 +01:00
|
|
|
for host_mirror in "${host_mirrors[@]}"; do
|
|
|
|
if [[ $host_mirror == *file://* ]]; then
|
|
|
|
host_mirror_path=$(echo "$host_mirror" | sed -r 's#file://(/.*)/\$repo/os/\$arch#\1#g')
|
2019-03-28 21:54:09 +01:00
|
|
|
mount_args+=("--bind-ro=${host_mirror_path//:/\\:}")
|
2019-03-22 12:21:08 +01:00
|
|
|
fi
|
|
|
|
done
|
2013-05-02 05:24:28 +02:00
|
|
|
|
2019-03-28 21:54:09 +01:00
|
|
|
mount_args+=("--bind=${cache_dirs[0]//:/\\:}")
|
2013-05-02 05:24:28 +02:00
|
|
|
|
2017-05-06 00:41:08 +02:00
|
|
|
for cache_dir in "${cache_dirs[@]:1}"; do
|
2019-03-28 21:54:09 +01:00
|
|
|
mount_args+=("--bind-ro=${cache_dir//:/\\:}")
|
2013-05-02 05:24:28 +02:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
copy_hostconf () {
|
2019-05-06 20:51:28 +02:00
|
|
|
unshare --fork --pid gpg --homedir "$working_dir"/etc/pacman.d/gnupg/ --no-permission-warning --quiet --batch --import --import-options import-local-sigs "$(pacman-conf GpgDir)"/pubring.gpg >/dev/null 2>&1
|
arch-nspawn: don't delete the guest gpg configuration
It's important to ensure the guest has up to date data because updating
a chroot after quite some time can potentially rely on updated
archlinux-keyring, something which the host machine either kept up to
date on or manually fixed, but it kills automation to mess around with
chroot configs like that. Alternatively, signed packages added with -I
need to work, and we assume the host is configured to accept these.
That is *not* a good reason to completely nuke whatever is in the guest,
though. A guest might have been manually configured to accept keys which
aren't accepted by the host; one example of this happening in practice,
is archlinux32 when building 32-bit packages from an archlinux host.
The right solution is to append to, rather thna overwrite, the chrooted
guest's pacman keyring.
To do this, we will use gpg's native facility to dump the keyring from
one GNUPGHOME and import it into another. We'd use pacman-key's --import
option directly, but this doesn't support passing custom options like
--import-options import-local-sigs
Finally use pacman-key's native facility to import the trust status from
the host.
While we are at it, fix a bug where we didn't respect the host's
pacman.conf settings for the GpgDir. While it isn't wildly likely a user
will choose to customize this, it is a valid and supported use case and
we must think about this ourselves.
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
2018-12-02 01:36:23 +01:00
|
|
|
pacman-key --gpgdir "$working_dir"/etc/pacman.d/gnupg/ --import-trustdb "$(pacman-conf GpgDir)" >/dev/null 2>&1
|
2014-12-29 06:27:34 +01:00
|
|
|
#printf 'Server = %s\n' "${host_mirrors[@]}" >"$working_dir/etc/pacman.d/mirrorlist"
|
2013-05-02 05:24:28 +02:00
|
|
|
|
2017-05-06 00:41:08 +02:00
|
|
|
[[ -n $pac_conf ]] && cp "$pac_conf" "$working_dir/etc/pacman.conf"
|
|
|
|
[[ -n $makepkg_conf ]] && cp "$makepkg_conf" "$working_dir/etc/makepkg.conf"
|
2013-05-02 05:24:28 +02:00
|
|
|
|
2017-04-05 21:36:00 +02:00
|
|
|
local file
|
|
|
|
for file in "${files[@]}"; do
|
|
|
|
mkdir -p "$(dirname "$working_dir$file")"
|
|
|
|
cp -T "$file" "$working_dir$file"
|
|
|
|
done
|
|
|
|
|
2018-01-15 17:57:00 +01:00
|
|
|
sed -r "s|^#?\\s*CacheDir.+|CacheDir = ${cache_dirs[*]}|g" -i "$working_dir/etc/pacman.conf"
|
2013-05-02 05:24:28 +02:00
|
|
|
}
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
umask 0022
|
|
|
|
|
|
|
|
# Sanity check
|
|
|
|
if [[ ! -f "$working_dir/.arch-chroot" ]]; then
|
2014-05-11 04:22:03 +02:00
|
|
|
die "'%s' does not appear to be an Arch chroot." "$working_dir"
|
2017-05-06 00:41:08 +02:00
|
|
|
elif [[ $(cat "$working_dir/.arch-chroot") != "$CHROOT_VERSION" ]]; then
|
2013-07-30 21:24:48 +02:00
|
|
|
die "chroot '%s' is not at version %s. Please rebuild." "$working_dir" "$CHROOT_VERSION"
|
2013-05-02 05:24:28 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
build_mount_args
|
|
|
|
copy_hostconf
|
|
|
|
|
2018-01-15 17:57:00 +01:00
|
|
|
eval "$(grep -a '^CARCH=' "$working_dir/etc/makepkg.conf")"
|
2013-05-03 04:52:32 +02:00
|
|
|
|
2017-04-05 21:36:01 +02:00
|
|
|
[[ -z $nosetarch ]] || unset CARCH
|
|
|
|
|
2014-12-29 06:33:00 +01:00
|
|
|
exec systemd-nspawn -q \
|
2013-05-03 04:52:32 +02:00
|
|
|
-D "$working_dir" \
|
2017-09-06 23:27:50 +02:00
|
|
|
-E "PATH=/usr/local/sbin:/usr/local/bin:/usr/bin" \
|
2019-04-16 17:15:34 +02:00
|
|
|
--register=no \
|
|
|
|
--as-pid2 \
|
|
|
|
--rlimit=NOFILE=10000 \
|
|
|
|
--resolv-conf=copy-host \
|
2013-05-03 04:52:32 +02:00
|
|
|
"${mount_args[@]}" \
|
2017-09-13 00:25:06 +02:00
|
|
|
"$@"
|