future-install-scripts/pacstrap.in
Mike Yuan 05d231aff9
pacstrap: respect custom pacman.conf configs
If some core settings are changed in custom pacman.conf,
they won't be prepended with new rootdir automatically.
2023-03-03 19:27:04 +08:00

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: