Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
file 125 lines (101 sloc) 3.056 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
#!/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(common)

newroot=/mnt
hostcache=0
copykeyring=1
copymirrorlist=1

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 Allow installation to a non-mountpoint directory
    -G Avoid copying the host's pacman keyring to the target
    -i Avoid auto-confirmation of package selections
    -M Avoid copying the host's mirrorlist to the target

    -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
}

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 ':C:cdGiM' flag; do
  case $flag in
    C)
      pacman_config=$OPTARG
      ;;
    d)
      directory=1
      ;;
    c)
      hostcache=1
      ;;
    i)
      interactive=1
      ;;
    G)
      copykeyring=0
      ;;
    M)
      copymirrorlist=0
      ;;
    :)
      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=("${@:-base}")

if (( ! hostcache )); then
  pacman_args+=(--cachedir="$newroot/var/cache/pacman/pkg")
fi

if (( ! interactive )); then
  pacman_args+=(--noconfirm)
fi

if [[ $pacman_config ]]; then
  pacman_args+=(--config="$pacman_config")
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 -m 0755 -p "$newroot"/var/{cache/pacman/pkg,lib/pacman,log} "$newroot"/{dev,run,etc}
mkdir -m 1777 -p "$newroot"/tmp
mkdir -m 0555 -p "$newroot"/{sys,proc}

# 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 "${pacman_args[@]}"; then
  die 'Failed to install packages to new root'
fi

if (( copykeyring )); then
  # 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
fi

if (( copymirrorlist )); then
  # install the host's mirrorlist onto the new root
  cp -a /etc/pacman.d/mirrorlist "$newroot/etc/pacman.d/"
fi

# vim: et ts=2 sw=2 ft=sh:
Something went wrong with that request. Please try again.