#!/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 hostcache=0 copykeyring=1 initkeyring=0 copymirrorlist=1 pacman_args=() pacmode=-Sy unshare=0 copyconf=0 pacman_config=/etc/pacman.conf m4_include(common) usage() { cat < 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" group. EOF } pacstrap() { (( EUID == 0 )) || die 'This script must be run with root privileges' # create obligatory directories msg 'Creating install root at %s' "$newroot" mkdir -m 0755 -p "$newroot"/var/{cache/pacman/pkg,lib/pacman,log} "$newroot"/{dev,run,etc/pacman.d} mkdir -m 1777 -p "$newroot"/tmp mkdir -m 0555 -p "$newroot"/{sys,proc} # mount API filesystems $setup "$newroot" || die "failed to setup chroot %s" "$newroot" if [[ ! -d $newroot/etc/pacman.d/gnupg ]]; then if (( initkeyring )); then pacman-key --gpgdir "$newroot"/etc/pacman.d/gnupg --init elif (( copykeyring )) && [[ -d /etc/pacman.d/gnupg ]]; then # if there's a keyring on the host, copy it into the new root cp -a --no-preserve=ownership /etc/pacman.d/gnupg "$newroot/etc/pacman.d/" fi fi msg 'Installing packages to %s' "$newroot" if ! $pid_unshare pacman -r "$newroot" "${pacman_args[@]}"; then die 'Failed to install packages to new root' fi if (( copymirrorlist )); then # install the host's mirrorlist onto the new root cp -a /etc/pacman.d/mirrorlist "$newroot/etc/pacman.d/" fi if (( copyconf )); then cp -a "$pacman_config" "$newroot/etc/pacman.conf" fi } 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 ;; D) pacman_args+=(-dd) ;; c) hostcache=1 ;; i) interactive=1 ;; G) copykeyring=0 ;; K) initkeyring=1 ;; M) copymirrorlist=0 ;; N) unshare=1 ;; P) copyconf=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 pacman_args+=("$pacmode" "${@:-base}" --config="$pacman_config") if (( ! hostcache )); then pacman_args+=(--cachedir="$newroot/var/cache/pacman/pkg") fi if (( ! interactive )); then pacman_args+=(--noconfirm) fi [[ -d $newroot ]] || die "%s is not a directory" "$newroot" if (( unshare )); then setup=unshare_setup $mount_unshare bash -c "$(declare_all); pacstrap" else setup=chroot_setup pacstrap fi # vim: et ts=2 sw=2 ft=sh: