Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/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
- out() { printf "$1 $2\n" "${@:3}"; }
- error() { out "==> ERROR:" "$@"; } >&2
- msg() { out "==>" "$@"; }
- msg2() { out " ->" "$@";}
- die() { error "$@"; exit 1; }
- in_array() {
- local i
- for i in "${@:2}"; do
- [[ $1 = "$i" ]] && return
- done
- }
- api_fs_mount() {
- if ! mountpoint -q "$1"; then
- mount -B "$1" "$1" && ROOT_IS_BIND=1
- fi &&
- mount -t proc proc "$1/proc" -o nosuid,noexec,nodev &&
- mount -t sysfs sys "$1/sys" -o nosuid,noexec,nodev &&
- mount -t devtmpfs udev "$1/dev" -o mode=0755,nosuid &&
- mount -t devpts devpts "$1/dev/pts" -o mode=0620,gid=5,nosuid,noexec &&
- mount -t tmpfs shm "$1/dev/shm" -o mode=1777,nosuid,nodev &&
- mount -t tmpfs run "$1/run" -o nosuid,nodev,mode=0755 &&
- mount -t tmpfs tmp "$1/tmp" -o mode=1777,strictatime,nodev,nosuid,size=50M
- }
- api_fs_umount() {
- umount \
- "$1/tmp" \
- "$1/run" \
- "$1/dev/shm" \
- "$1/dev/pts" \
- "$1/dev" \
- "$1/sys" \
- "$1/proc"
- (( ROOT_IS_BIND )) && umount "$1"
- }
- valid_number_of_base() {
- local base=$1 len=${#2} i=
- for (( i = 0; i < len; i++ )); do
- (( (${2:i:1} & ~(base - 1)) == 0 )) || return
- done
- }
- mangle() {
- local i= chr= out=
- unset {a..f} {A..F}
- for (( i = 0; i < ${#1}; i++ )); do
- chr=${1:i:1}
- case $chr in
- [[:space:]\\])
- printf -v chr '%03o' "'$chr"
- out+=\\
- ;;&
- # fallthrough
- *)
- out+=$chr
- ;;
- esac
- done
- printf '%s' "$out"
- }
- unmangle() {
- local i= chr= out= len=$(( ${#1} - 4 ))
- unset {a..f} {A..F}
- for (( i = 0; i < len; i++ )); do
- chr=${1:i:1}
- case $chr in
- \\)
- if valid_number_of_base 8 "${1:i+1:3}" ||
- valid_number_of_base 16 "${1:i+1:3}"; then
- printf -v chr '%b' "${1:i:4}"
- (( i += 3 ))
- fi
- ;;&
- # fallthrough
- *)
- out+=$chr
- esac
- done
- printf '%s' "$out${1:i}"
- }
- fstype_is_pseudofs() {
- # list taken from util-linux source: libmount/src/utils.c
- local pseudofs_types=('anon_inodefs'
- 'autofs'
- 'bdev'
- 'binfmt_misc'
- 'cgroup'
- 'configfs'
- 'cpuset'
- 'debugfs'
- 'devfs'
- 'devpts'
- 'devtmpfs'
- 'dlmfs'
- 'fuse.gvfs-fuse-daemon'
- 'fusectl'
- 'hugetlbfs'
- 'mqueue'
- 'nfsd'
- 'none'
- 'pipefs'
- 'proc'
- 'pstore'
- 'ramfs'
- 'rootfs'
- 'rpc_pipefs'
- 'securityfs'
- 'sockfs'
- 'spufs'
- 'sysfs'
- 'tmpfs')
- in_array "$1" "${pseudofs_types[@]}"
- }
- newroot=/mnt
- hostcache=1
- usage() {
- cat <<EOF
- usage: ${0##*/} [options]
- Options:
- -r root Install to 'root' (default: /mnt)
- -d Allow installation to a non-mountpoint directory
- -c Use the package cache on the host, rather than the target
- EOF
- }
- if [[ -z $1 || $1 = @(-h|--help) ]]; then
- usage
- exit $(( $# ? 0 : 1 ))
- fi
- (( EUID == 0 )) || die 'This script must be run with root privileges'
- while getopts ':cdr:' flag; do
- case $flag in
- d)
- directory=1
- ;;
- r)
- newroot=$OPTARG
- ;;
- c)
- hostcache=0
- ;;
- :)
- die '%s: option requires an argument -- '\''%s'\' "${0##*/}" "$OPTARG"
- ;;
- ?)
- die '%s: invalid option -- '\''%s'\' "${0##*/}" "$OPTARG"
- ;;
- esac
- done
- shift $(( OPTIND - 1 ))
- if (( $# )); then
- pacman_args=("$@")
- else
- pacman_args=('base' 'base-devel')
- fi
- if (( ! hostcache )); then
- pacman_args+=(--cachedir="$newroot/var/cache/pacman/pkg")
- fi
- [[ -d $newroot ]] || die "%s is not a directory" "$newroot"
- if ! mountpoint -q "$newroot" && (( ! directory )); then
- die '%s is not a mountpoint!' "$newroot"
- fi
- # create obligatory directories
- msg 'Creating install root at %s' "$newroot"
- mkdir -p "$newroot/var/lib/pacman" "$newroot"/{dev,proc,sys,run,tmp,etc}
- # always call umount on quit after this point
- trap 'api_fs_umount "$newroot" 2>/dev/null' EXIT
- # mount API filesystems
- api_fs_mount "$newroot" || die "failed to setup API filesystems in new root"
- msg 'Installing packages to %s' "$newroot"
- if ! pacman -r "$newroot" -Sy --noconfirm "${pacman_args[@]}"; then
- die 'Failed to install packages to new root'
- fi
- # if there's a keyring on the host, copy it into the new root, unless it exists already
- if [[ -d /etc/pacman.d/gnupg && ! -d $newroot/etc/pacman.d/gnupg ]]; then
- cp -a /etc/pacman.d/gnupg "$newroot/etc/pacman.d/"
- fi
- # install the host's mirrorlist onto the new root
- cp -a /etc/pacman.d/mirrorlist "$newroot/etc/pacman.d/"
- # vim: et ts=2 sw=2 ft=sh:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement