| 1 | #!/bin/bash |
|---|
| 2 | # Arch Linux bootstrap script. Released under the terms of the GPL. |
|---|
| 3 | # henning mueller <henning@orgizm.net> |
|---|
| 4 | |
|---|
| 5 | usage() { |
|---|
| 6 | cat >&2 <<EOF |
|---|
| 7 | usage: $(basename $0) [options] <ftp|cd> <target> [source] |
|---|
| 8 | |
|---|
| 9 | This script is for installing Arch Linux after manual partitioning and |
|---|
| 10 | network configuration. |
|---|
| 11 | |
|---|
| 12 | For the FTP installation, the original throttled Arch mirror is selected by |
|---|
| 13 | default, so run with another mirror as [source], please. The full URL is |
|---|
| 14 | expected in this case. Example: |
|---|
| 15 | ftp://ftp5.gwdg.de/pub/linux/archlinux/current/os/x86_64 |
|---|
| 16 | |
|---|
| 17 | If you want to bootstrap another architecture than the script is currently |
|---|
| 18 | running on, you have to specify a custom source. |
|---|
| 19 | |
|---|
| 20 | Options: |
|---|
| 21 | -c Force chroot on Arch Linux. Local pacman cache will not be used. |
|---|
| 22 | -f Generate fstab with UUIDs. Don't rely on that. |
|---|
| 23 | -i <file> Include packages from <file> in the installation. <file> should |
|---|
| 24 | contain one package name per line. |
|---|
| 25 | -x Xen mode. Activate serial console and deactivate virtual |
|---|
| 26 | terminals. |
|---|
| 27 | |
|---|
| 28 | EOF |
|---|
| 29 | exit 1 |
|---|
| 30 | } |
|---|
| 31 | |
|---|
| 32 | wget="wget -q -t0" |
|---|
| 33 | arch=$(uname -m) |
|---|
| 34 | |
|---|
| 35 | while [ $# -gt 1 ]; do |
|---|
| 36 | case $1 in |
|---|
| 37 | -c) chroot=true; shift;; |
|---|
| 38 | -f) fstab=true; shift;; |
|---|
| 39 | -i) |
|---|
| 40 | [ ! -f $2 ] && |
|---|
| 41 | echo "Package file '$2' does not exist." && |
|---|
| 42 | exit 1 |
|---|
| 43 | addpkgs=$(cat $2 | tr "\n" " ") |
|---|
| 44 | shift; shift |
|---|
| 45 | ;; |
|---|
| 46 | -v) wget="wget -t0"; shift;; |
|---|
| 47 | -x) xen=true; shift;; |
|---|
| 48 | -h) usage;; |
|---|
| 49 | *) break |
|---|
| 50 | esac |
|---|
| 51 | done |
|---|
| 52 | |
|---|
| 53 | mode=$1 |
|---|
| 54 | target=$2 |
|---|
| 55 | source=$3 |
|---|
| 56 | |
|---|
| 57 | [ "$mode" == "" ] || [ "$target" == "" ] && usage |
|---|
| 58 | [ "$mode" == "ftp" ] || [ "$mode" == "cd" ] || usage |
|---|
| 59 | |
|---|
| 60 | [ "$UID" != "0" ] && |
|---|
| 61 | echo "run as root, please." >&2 && |
|---|
| 62 | exit 1 |
|---|
| 63 | |
|---|
| 64 | [ $(echo $target | egrep ^/) ] || |
|---|
| 65 | target=$(pwd)/$target |
|---|
| 66 | |
|---|
| 67 | [ -d "$target" ] || |
|---|
| 68 | mkdir -p $target |
|---|
| 69 | |
|---|
| 70 | [ "$source" == "" ] && |
|---|
| 71 | source=ftp://ftp5.gwdg.de/pub/linux/archlinux/current/os/$arch || |
|---|
| 72 | arch=$(basename $source) |
|---|
| 73 | |
|---|
| 74 | [ -f /etc/arch-release ] && [ ! $chroot ] && |
|---|
| 75 | on_arch=true |
|---|
| 76 | |
|---|
| 77 | cache=$target/var/cache/pacman/pkg |
|---|
| 78 | [ $on_arch ] && { |
|---|
| 79 | mkdir -p $(dirname $cache) |
|---|
| 80 | mkdir -p $target/var/lib/pacman |
|---|
| 81 | [ ! -d $cache ] && |
|---|
| 82 | ln -s /var/cache/pacman/pkg $cache |
|---|
| 83 | } || { |
|---|
| 84 | mkdir -p $cache |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | [ "$mode" == "ftp" ] && { |
|---|
| 88 | install() { |
|---|
| 89 | cd $cache |
|---|
| 90 | echo " · $1" |
|---|
| 91 | |
|---|
| 92 | package=$(ls $1*.pkg.tar.gz 2>/dev/null | tail -1) |
|---|
| 93 | |
|---|
| 94 | [ ! -f "$package" ] && |
|---|
| 95 | $wget $source/$1*.pkg.tar.gz || |
|---|
| 96 | exit 1 |
|---|
| 97 | |
|---|
| 98 | package=$(ls $1*.pkg.tar.gz | tail -1) |
|---|
| 99 | tar xzf $package -C $target || |
|---|
| 100 | exit 1 |
|---|
| 101 | } |
|---|
| 102 | } |
|---|
| 103 | [ "$mode" == "cd" ] && { |
|---|
| 104 | install() { |
|---|
| 105 | exit 1 |
|---|
| 106 | } |
|---|
| 107 | } |
|---|
| 108 | |
|---|
| 109 | [ $on_arch ] || { |
|---|
| 110 | echo · downloading and installing bash. |
|---|
| 111 | for package in glibc ncurses readline bash; do |
|---|
| 112 | install $package |
|---|
| 113 | done |
|---|
| 114 | } |
|---|
| 115 | |
|---|
| 116 | echo · downloading and installing pacman. |
|---|
| 117 | for package in libdownload libarchive acl attr zlib bzip2; do |
|---|
| 118 | install $package |
|---|
| 119 | done |
|---|
| 120 | for package in openssl xz-utils pacman-?. pacman-mirrorlist; do |
|---|
| 121 | install $package |
|---|
| 122 | done |
|---|
| 123 | |
|---|
| 124 | echo · installing base. |
|---|
| 125 | cd $target |
|---|
| 126 | cp /etc/resolv.conf etc/resolv.conf |
|---|
| 127 | |
|---|
| 128 | mkdir sys proc dev tmp 2> /dev/null |
|---|
| 129 | |
|---|
| 130 | [ -z "$addpkgs" ] && { # TODO source for extra and community |
|---|
| 131 | echo -e "[core]\nServer = $source" >> tmp/pacman.conf |
|---|
| 132 | config="--config tmp/pacman.conf" |
|---|
| 133 | } |
|---|
| 134 | |
|---|
| 135 | # sed -ie "s/#S/S/g" etc/pacman.d/mirrorlist |
|---|
| 136 | |
|---|
| 137 | cp etc/pacman.d/mirrorlist etc/pacman.d/mirrorlist.original |
|---|
| 138 | tmp=$(echo $source | sed -e "s/current/\$repo/") |
|---|
| 139 | echo "Server = $tmp" > etc/pacman.d/mirrorlist |
|---|
| 140 | |
|---|
| 141 | [ $on_arch ] && { |
|---|
| 142 | pacman --noconfirm $config -r $target \ |
|---|
| 143 | -Sfy base $addpkgs || exit 1 |
|---|
| 144 | } || { |
|---|
| 145 | mount -o bind /dev dev |
|---|
| 146 | mount -t proc none proc |
|---|
| 147 | mount -t sysfs none sys |
|---|
| 148 | |
|---|
| 149 | chroot $target /bin/bash <<EOF |
|---|
| 150 | pacman --noconfirm $config \ |
|---|
| 151 | -Sfy base $addpkgs || exit 1 |
|---|
| 152 | EOF |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | [ $xen ] && { |
|---|
| 156 | echo · preparing for use in xen. |
|---|
| 157 | |
|---|
| 158 | vc=xvc0 |
|---|
| 159 | |
|---|
| 160 | [ -f /etc/debian_version ] && vc=hvc0 |
|---|
| 161 | |
|---|
| 162 | cat <<EOF > etc/inittab |
|---|
| 163 | rc::sysinit:/etc/rc.sysinit |
|---|
| 164 | rs:S1:wait:/etc/rc.single |
|---|
| 165 | rm:2345:wait:/etc/rc.multi |
|---|
| 166 | rh:06:wait:/etc/rc.shutdown |
|---|
| 167 | su:S:wait:/sbin/sulogin -p |
|---|
| 168 | c:2345:respawn:/sbin/agetty -8 38400 $vc linux |
|---|
| 169 | EOF |
|---|
| 170 | |
|---|
| 171 | echo $vc > etc/securetty |
|---|
| 172 | } |
|---|
| 173 | |
|---|
| 174 | [ $fstab ] && { |
|---|
| 175 | grep $target /proc/mounts | while read line; do |
|---|
| 176 | device=$(echo $line | cut -d ' ' -f 1) |
|---|
| 177 | uuid=$(/lib/udev/vol_id --uuid $device) |
|---|
| 178 | |
|---|
| 179 | [ "$(echo $line | sed -e "s:$target::" | cut -d ' ' -f 2)" == "" ] && |
|---|
| 180 | repl='/' || repl='' |
|---|
| 181 | |
|---|
| 182 | [ "$uuid" != "" ] && |
|---|
| 183 | echo $line | sed -e "s:$target:$repl:" -e "s:$device:UUID=$uuid:" \ |
|---|
| 184 | >> etc/fstab |
|---|
| 185 | done |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | echo · cleaning up. |
|---|
| 189 | [ -h $cache ] && rm $cache && mkdir $cache |
|---|
| 190 | [ $on_arch ] || umount sys proc dev |
|---|
| 191 | mv etc/resolv.conf.pacorig etc/resolv.conf |
|---|
| 192 | rm -f etc/*.pac* tmp/pac* .FILELIST .INSTALL .PKGINFO |
|---|
| 193 | ln -s . boot/boot |
|---|
| 194 | |
|---|
| 195 | echo -e "\nPackage installation complete.\n" |
|---|
| 196 | |
|---|
| 197 | [ ! $xen ] && cat <<EOF |
|---|
| 198 | Probably you have to install a boot loader. |
|---|
| 199 | Therefor chroot into your system (you have to be root): |
|---|
| 200 | mount -o bind /dev $target/dev |
|---|
| 201 | mount -t proc none $target/proc |
|---|
| 202 | mount -t sysfs none $target/sys |
|---|
| 203 | chroot $target /bin/bash |
|---|
| 204 | |
|---|
| 205 | For grub: |
|---|
| 206 | install-grub <hdd> <boot-partition> (example: /dev/sda /dev/sda1) |
|---|
| 207 | |
|---|
| 208 | For lilo: |
|---|
| 209 | lilo |
|---|
| 210 | |
|---|
| 211 | A default initramfs setup was created during the package installation process. |
|---|
| 212 | If you have special demands, generate a new one after editing |
|---|
| 213 | /etc/mkinitcpio.conf and /etc/mkinitcpio.d/kernel26-fallback.conf: |
|---|
| 214 | mkinitcpio -p kernel26 -k <kernel-version> (example: 2.6.26-ARCH) |
|---|
| 215 | |
|---|
| 216 | Don't forget to set a root password. |
|---|
| 217 | |
|---|
| 218 | For completing the installation, edit /etc/rc.conf and /etc/fstab before |
|---|
| 219 | unmounting the devices and rebooting. |
|---|
| 220 | |
|---|
| 221 | EOF |
|---|
| 222 | |
|---|
| 223 | [ $xen ] && cat <<EOF |
|---|
| 224 | Don't forget to set a root password: |
|---|
| 225 | chroot $target /bin/bash |
|---|
| 226 | passwd |
|---|
| 227 | |
|---|
| 228 | For completing the installation, edit /etc/rc.conf and /etc/fstab before |
|---|
| 229 | creating the xen guest. |
|---|
| 230 | |
|---|
| 231 | Your xen config could look like this: |
|---|
| 232 | kernel = '/boot/vmlinuz26-xen' |
|---|
| 233 | memory = 256 |
|---|
| 234 | name = 'guest' |
|---|
| 235 | disk = [ 'phy:/dev/mapper/lvm-guest,sda1,w' ] |
|---|
| 236 | vif = [ 'bridge=br0' ] |
|---|
| 237 | ramdisk = '/boot/kernel26-xen.img' |
|---|
| 238 | root = '/dev/sda1 ro' |
|---|
| 239 | vcpus = 1 |
|---|
| 240 | extra = '3 console=xvc0' |
|---|
| 241 | restart = 'onreboot' |
|---|
| 242 | |
|---|
| 243 | EOF |
|---|