If some core settings are changed in custom pacman.conf, they won't be prepended with new rootdir automatically.
174 lines
4.3 KiB
Bash
174 lines
4.3 KiB
Bash
#!/bin/bash
|
|
|
|
#
|
|
# Assumptions:
|
|
# 1) User has partitioned, formatted, and mounted partitions on /mnt
|
|
# 2) Network is functional
|
|
# 3) Arguments passed to the script are valid pacman targets
|
|
# 4) A valid mirror appears in /etc/pacman.d/mirrorlist
|
|
#
|
|
|
|
shopt -s extglob
|
|
|
|
# m4_include() is recognized as a function definition
|
|
# shellcheck source=common disable=SC1073,SC1065,SC1064,SC1072
|
|
m4_include(common)
|
|
|
|
hostcache=0
|
|
copykeyring=1
|
|
initkeyring=0
|
|
copymirrorlist=1
|
|
copyconfig=0
|
|
pacman_config=/etc/pacman.conf
|
|
pacman_args=()
|
|
pacmode='-Sy'
|
|
setup=chroot_setup
|
|
unshare=0
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
usage: ${0##*/} [options] root [packages...]
|
|
|
|
Options:
|
|
-C <config> Use an alternate config file for pacman
|
|
-c Use the package cache on the host, rather than the target
|
|
-D Skip pacman dependency checks
|
|
-G Avoid copying the host's pacman keyring to the target
|
|
-i Prompt for package confirmation when needed (run interactively)
|
|
-K Initialize an empty pacman keyring in the target (implies '-G')
|
|
-M Avoid copying the host's mirrorlist to the target
|
|
-N Run in unshare mode as a regular user
|
|
-P Copy the host's pacman config to the target
|
|
-U Use 'pacman -U' to install packages
|
|
|
|
-h Print this help message
|
|
|
|
pacstrap installs packages to the specified new root directory.
|
|
If no packages are given, pacstrap defaults to the 'base' metapackage.
|
|
|
|
EOF
|
|
}
|
|
|
|
if [[ -z $1 || $1 = @(-h|--help) ]]; then
|
|
usage
|
|
exit $(( $# ? 0 : 1 ))
|
|
fi
|
|
|
|
while getopts ':C:cDGiKMNPU' flag; do
|
|
case $flag in
|
|
C)
|
|
pacman_config="$OPTARG"
|
|
;;
|
|
c)
|
|
hostcache=1
|
|
;;
|
|
D)
|
|
pacman_args+=(-dd)
|
|
;;
|
|
G)
|
|
copykeyring=0
|
|
;;
|
|
i)
|
|
interactive=1
|
|
;;
|
|
K)
|
|
initkeyring=1
|
|
;;
|
|
M)
|
|
copymirrorlist=0
|
|
;;
|
|
N)
|
|
setup=unshare_setup
|
|
unshare=1
|
|
;;
|
|
P)
|
|
copyconfig=1
|
|
;;
|
|
U)
|
|
pacmode='-U'
|
|
;;
|
|
:)
|
|
die "%s: option requires an argument -- '%s'" "${0##*/}" "$OPTARG"
|
|
;;
|
|
?)
|
|
die "%s: invalid option -- '%s'" "${0##*/}" "$OPTARG"
|
|
;;
|
|
esac
|
|
done
|
|
shift $(( OPTIND - 1 ))
|
|
|
|
(( $# )) || die 'No root directory specified'
|
|
newroot="$1"; shift
|
|
[[ -d "$newroot" ]] || die '%s: not a directory' "$newroot"
|
|
|
|
pacman_args+=("$pacmode" "${@:-base}" --config="$pacman_config")
|
|
|
|
if (( ! interactive )); then
|
|
pacman_args+=(--noconfirm)
|
|
fi
|
|
|
|
set -e
|
|
gpgdir="$(pacman-conf --config="$pacman_config" GPGDir)"
|
|
cachedir="$(pacman-conf --config="$pacman_config" CacheDir)"
|
|
if (( copyconfig )); then
|
|
dbpath="$newroot$(pacman-conf --config="$pacman_config" DBPath)"
|
|
logfile="$newroot$(pacman-conf --config="$pacman_config" LogFile)"
|
|
cachedir_target="$newroot$cachedir"
|
|
gpgdir_target="$newroot$gpgdir"
|
|
|
|
pacman_args+=(--dbpath="$dbpath" --logfile="$logfile")
|
|
else
|
|
dbpath="$newroot"/var/lib/pacman
|
|
logfile="$newroot"/var/log/pacman.log
|
|
cachedir_target="$newroot"/var/cache/pacman/pkg
|
|
gpgdir_target="$newroot"/etc/pacman.d/gnupg
|
|
fi
|
|
|
|
if (( ! hostcache )); then
|
|
cachedir="$cachedir_target"
|
|
fi
|
|
pacman_args+=(--cachedir="$cachedir")
|
|
set +e
|
|
|
|
pacstrap() {
|
|
check_root
|
|
|
|
# create obligatory directories
|
|
msg 'Creating install root at %s' "$newroot"
|
|
mkdir -m 0755 -p "$dbpath" "$cachedir_target" "$(dirname "$logfile")" "$newroot"/{dev,run,etc/pacman.d}
|
|
mkdir -m 1777 -p "$newroot"/tmp
|
|
mkdir -m 0555 -p "$newroot"/{sys,proc}
|
|
|
|
# mount API filesystems
|
|
$setup "$newroot"
|
|
|
|
if [[ ! -d "$gpgdir_target" ]]; then
|
|
if (( initkeyring )); then
|
|
pacman-key --gpgdir "$gpgdir_target" --init
|
|
elif (( copykeyring )) && [[ -d "$gpgdir" ]]; then
|
|
# if there's a keyring on the host, copy it into the new root
|
|
cp -aT --no-preserve=ownership "$gpgdir" "$gpgdir_target"
|
|
fi
|
|
fi
|
|
|
|
msg 'Installing packages to %s' "$newroot"
|
|
$pid_unshare pacman --root "$newroot" "${pacman_args[@]}" || die 'Failed to install packages to new root'
|
|
|
|
if (( copymirrorlist )); then
|
|
# install the host's mirrorlist onto the new root
|
|
cp -a /etc/pacman.d/mirrorlist "$newroot"/etc/pacman.d/ || warning "Failed to copy the host's mirrorlist to new root"
|
|
fi
|
|
|
|
if (( copyconfig )); then
|
|
cp -a "$pacman_config" "$newroot"/etc/pacman.conf
|
|
fi
|
|
}
|
|
|
|
if (( unshare )); then
|
|
$mount_unshare bash -c "$(declare_all); pacstrap"
|
|
else
|
|
pacstrap
|
|
fi
|
|
|
|
# vim: et ts=2 sw=2 ft=sh:
|