Difference between revisions of "Archbootstrap"

From ArchWiki
Jump to: navigation, search
(added download script)
(9 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{out of date}}
+
[[Category:Boot process]]
You can simply install this script using this command:
+
[http://tokland.googlecode.com/svn/trunk/archlinux/arch-bootstrap.sh arch-bootstrap.sh] creates a base Arch Linux system where you can chroot to. Report bugs [http://code.google.com/p/tokland/issues/list here]. Some examples:
<nowiki>target='/usr/bin/archbootstrap';
+
curl http://wiki.archlinux.org/index.php/Archbootstrap |
+
grep -A 99999 '<pre>' | grep -B 99999 '</pre>' |
+
sed -e 's/\(<pre>\|<\/pre>\)//g' > "$target"; chmod +x "$target";
+
</nowiki>
+
  
Or you can copypasta it from here:
+
* Using default architecture (i686) and repository (http://mirrors.kernel.org/archlinux):
<pre>#!/bin/bash
+
#########################################################################
+
# archbootstrap                                                        #
+
#                                                                      #
+
# archbootstrap is to archlinux what debootstrap is to Debian.         #
+
#                                                                      #
+
#                                                                      #
+
# archbootstrap is public domain though i wouldn't mind getting credit. #
+
#                                                                      #
+
# by David Leinhäuser (archlinux@calavera.de)                           #
+
# (minor tweak by lucke)                                                #
+
#########################################################################
+
  
 +
{{bc|
 +
$ bash arch-bootstrap.sh myarch
 +
}}
  
####################
+
* Bootstrap a ''x86_64'' system using a specific repository:
# Default Settings #
+
####################
+
MYVERSION="0.3"                              # Version number of this script.
+
GETCMD="${GETCMD:-wget --passive-ftp -c -q}" # What we use to download files.
+
PREINSTALL="${PREINSTALL:-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.
+
{{bc|
PKG_PACMAN="setup/pacman.pkg.tar.gz"        # Where to find pacman.
+
$ bash arch-bootstrap.sh -a x86_64 -r "ftp://ftp.archlinux.org" myarch
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}/os/i686"
+
 
+
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 I in "${PACKAGES[@]}"; do
+
PKGPREFIX="${I%%/*}"
+
PKGFILE="${I##*/}"
+
PKGNAME="${PKGFILE%-*-*.pkg.tar.gz}"
+
if match "${PKGNAME}" ${PREINSTALL}; then
+
fetch "${FURL}/${PKGFILE}"
+
add_pkgs "${PKG_CACHE}/${PKGFILE}"
+
fi
+
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</pre>
+

Revision as of 13:02, 13 June 2012

arch-bootstrap.sh creates a base Arch Linux system where you can chroot to. Report bugs here. Some examples:

$ bash arch-bootstrap.sh myarch
  • Bootstrap a x86_64 system using a specific repository:
$ bash arch-bootstrap.sh -a x86_64 -r "ftp://ftp.archlinux.org" myarch