Additions:
PKGPREFIX="${I\%\%/*}"
PKGPREFIX="${I\%\%/*}"
Deletions:
Additions:
# archbootstrap is public domain though i wouldnt mind getting credit. #
Deletions:
# archbootstrap is public domain though i wouldn't mind getting credit. #
Script Information
This is useful for use with UML or chroot jails, or just making images. This will bootstrap an install of
ArchLinux from repositories into a given directory.
I didn't write this, but there were some changes to the repo structure that broke the original so I've made several modifications to make it work again because it's really quite useful. The original author's and those who've modified it before me still have their credits in the script if you'd like to get in touch with them. It's been working for me since I've fixed it, but I haven't used it in the last couple months so I don't know if it still works. Feel free to leave a comment if it isn't, and I'll see if I can take a quick poke and a jiggle and make it work again.
Source Code
#!/bin/bash
#########################################################################
# archbootstrap #
# #
# archbootstrap ist to archlinux what debootstrap ist to Debian. #
# #
# archbootstrap is public domain though i wouldn't mind getting credit. #
# #
# by David Leinhäuser (archlinux@calavera.de) #
# modified 07/22/2005 by Alexander Mieland <dma147@linux-stats.org #
# modified 19 Dec 2006 by Kevin Leacock [http://kevinsnet.com] #
#########################################################################
####################
# Default Settings #
####################
MYVERSION="0.4-KCL" # Version number of this script.
GETCMD="${GETCMD:-wget --passive-ftp -c -q}" # What we use to download files.
PREINSTALL="${PREINSTALL:-kernel-headers glibc iputils}" # Packages to install before using
# pacman to fetch the rest.
IGNORE="${IGNORE:-}" # Packages not to be installed.
TARGET="${1:---help}" # Where to bootstrap to
SERVER="${2:-ftp://ftp.archlinux.org}" # Where to fetch all the files.
INTERACTIVE="${INTERACTIVE:-1}" # Interactive mode or batch mode
# REPOS="current" # Which repository to use.
REPOS="current"
EXTRADIR="os/i686" # Which repository to use.
PKG_PACMAN="setup/pacman.pkg.tar.gz" # Where to find pacman.
PKGLIST="setup/packages.txt" # Where to find the packages list.
PKG_PREFIX="base" # Install pkgs with this prefix.
####################
# Helper Functions #
####################
PREV_DIR="$(pwd)" # remember current directory so we can chdir back later.
# Print an error message to stderr and quit.
function error() {
echo "Error: $*" >&2
cd "${PREV_DIR}"
exit 1;
}
# Simply exit the script.
function quit() {
cd "${PREV_DIR}"
exit 0;
}
# Wrapper around cd for lazy people like me.
function chngdir() {
cd "$@" || error "chdir failed."
}
#Wrapper around mkdir for lazy people like me.
function makedir() {
mkdir -p "$@" || error "mkdir failed."
}
#Fetch given URLs into current dir.
function fetch() {
while [ -n "${1}" ]; do
if [ -z "${1##file://*}" ]; then
F="${1#file://}"
echo "Copying ${F}."
cp "${1#file://}" . || error "Error copying ${F}."
else
echo "Fetching ${1}."
${GETCMD} "${1}" || error "Error fetching ${1}."
fi
shift
done
}
#Read the package list
PACKAGES=()
function read_pkglist() {
while read -s; do
PACKAGES=("${PACKAGES[@]}" "${REPLY}")
done <"${BOOTSTRAP}/${PKGLIST##*/}"
}
#Return 1 if the first argument does not equal any of the other arguments.
function match() {
PATTERN="${1}"
shift
while [ -n "${1}" ]; do
[ "${PATTERN}" == "${1}" ] && return 0
shift
done
return 1
}
######################
# Sanity checks etc. #
######################
case "${TARGET}" in
--help|-h)
cat <<-EOT
Usage: $0 DIR [SERVER]
Bootstrap Archlinux into DIR (from SERVER).
EOT
quit;
;;
--version)
echo "archbootstrap ${MYVERSION}";
quit;
;;
esac
[ "$UID" == "0" ] || error "You need to be root."
# This is an easy way to get an useful absolute path.
chngdir "${TARGET}"
TARGET="$(pwd)"
#[ -n "$(ls)" ] && error "${1} is not empty."
# Create working directory.
TEMP="${TARGET}/tmp"
makedir -m 1777 -p "${TEMP}"
BOOTSTRAP="${TEMP}/bootstrap"
PKG_CACHE="${TARGET}/var/cache/pacman/pkg"
makedir -m 0755 -p "${BOOTSTRAP}" "${PKG_CACHE}"
chngdir "${BOOTSTRAP}"
########################################
# Stuff we need for our staged install #
########################################
STAGEFILE="${BOOTSTRAP}/stage"
function set_stage() {
echo "${1}" >"${STAGEFILE}"
STAGE="${1}"
}
if [ -e "${STAGEFILE}" ]; then
STAGE="$(< "${STAGEFILE}")"
else
STAGE="start"
fi
##################
# pacman wrapper #
##################
PACMAN=("$(which chroot)" "${TARGET}" "${BOOTSTRAP#${TARGET}}/usr/bin/pacman.static")
function add_pkgs() {
PKGS=()
while [ -n "${1}" ]; do
PKGS=("${PKGS[@]}" "${1#${TARGET}}")
shift
done
"${PACMAN[@]}" -A "${PKGS[@]}" || error "Could not add a package."
}
function sync_pkgs() {
if [ "${INTERACTIVE}" == "1" ]; then
"${PACMAN[@]}" -Syf "${@}" || error "Could not sync a package."
else
echo y | "${PACMAN[@]}" -Syf "${@}" || \
error "Could not sync a package."
fi
}
#############
# Main loop #
#############
PREV_STAGE=""
FURL="${SERVER}/${REPOS}/${EXTRADIR}"
echo "archbootstrap $MYVERSION"
until [ "${PREV_STAGE}" == "${STAGE}" ]; do
PREV_STAGE="${STAGE}"
case "${STAGE}" in
start)
chngdir "${BOOTSTRAP}"
fetch "${FURL}/${PKG_PACMAN}" "${FURL}/${PKGLIST}"
tar xfz ${PKG_PACMAN##*/} || \
error "Could not untar ${BOOTSTRAP}${PKG_PACMAN##*/}."
makedir "${TARGET}/etc"
{ echo "[${REPOS}]";
echo "Server = ${FURL}"; } >"${TARGET}/etc/pacman.conf" || \
error "Could not create ${TARGET}/etc/pacman.conf."
cp -f "/etc/resolv.conf" "${TARGET}/etc/resolv.conf" || \
error "Could not copy /etc/resolv.conf."
set_stage "pre_packages"
;;
pre_packages)
chngdir "${PKG_CACHE}"
[ "${#PACKAGES[@]}" == "0" ] && read_pkglist;
for QQ in $PREINSTALL; do
for I in "${PACKAGES[@]}"; do
PKGPREFIX="${I
/*}"
PKGFILE="${I*/}"
PKGNAME="${PKGFILE%-*-*.pkg.tar.gz}"
if match "${PKGNAME}" "${QQ}"; then
fetch "${FURL}/${PKGFILE}"
add_pkgs "${PKG_CACHE}/${PKGFILE}"
fi
done
done
set_stage "packages"
;;
packages)
chngdir "${BOOTSTRAP}"
PKGS=()
[ "${#PACKAGES[@]}"
"0" ] && read_pkglist;
for I in "${PACKAGES[@]}"; do
PKGPREFIX="${I
/*}"
PKGFILE="${I##*/}"
PKGNAME="${PKGFILE%-*-*.pkg.tar.gz}"
[ "${PKGPREFIX}" == "${PKG_PREFIX}" ] || continue
match "${PKGNAME}" ${IGNORE} ${PREINSTALL} && continue
PKGS=("${PKGS[@]}" "${PKGNAME}")
done
sync_pkgs "${PKGS[@]}"
set_stage "cleanup"
;;
cleanup)
echo "Cleaning up..."
chngdir "${TARGET}"
rm -Rf "${BOOTSTRAP}" || error "Could not remove ${BOOTSTRAP}."
quit
;;
esac
done
Categories:
CategoryStable,
CategoryDiscontinued