aboutsummaryrefslogblamecommitdiff
path: root/pistrap-debian
blob: eefaa9a1045965fd3faab3e2862cd62765eba12a (plain) (tree)











































































































































































































































                                                                                                                                                                      
#!/bin/bash
set -e

# Variables set through command-line arguments
# the assigned values are used as defaults if no matching argument is provided
FORCE=0
MIRROR=""
HOSTNAME="pi"
TIMEZONE="UTC"
WPA_ESSID=""
WPA_PSK=""
ROOT_PASSWORD="toor"
SSH_KEY="$HOME/.ssh/id_rsa.pub"

# Paths for installation
DEVICE=/dev/nonexisting
PARTITION1="$DEVICE"p1
PARTITION2="$DEVICE"p2
ROOTFS=/mnt/pi

print_usage() {
    cat 1>&2 <<EOF
Usage: $0 [OPTION]... DEVICE
Create a bootable image for a RaspberryPi 2 on DEVICE.

Options:
  --force				Don't ask for any confirmations.
  --mirror=<$MIRROR>				Use a debian mirror, such as "fr" or "ch"
  --hostname=<$HOSTNAME>			Use a given hostname for the device.
  --timezone=<$TIMEZONE>			Set timezone data as listed in /usr/share/zoneinfo
  --wpa-essid=<$WPA_ESSID>			Use a given wireless ESSID. Sets up wireless networking.
  --wpa-psk=<$WPA_PSK>				Use a given WPA pre-shared key.
  --password=<$ROOT_PASWORD>				Set the given root password.
  --ssh-key=<$SSH_KEY>	Add the given SSH key to root's authorized_keys file. If invalid, password login will be enabled.
  --root-fs=<$ROOTFS>			Use given directory as mount point during installation.
EOF

}


# Process options
while [ $# -gt 1 ]
do
    case "$1" in
	-f|--force)
	    FORCE=1
	    ;;
	--mirror=*)
	    MIRROR=."${1#*=}"
	    ;;
	--hostname=*)
	    HOSTNAME="${1#*=}"
	    ;;
	--timezone=*)
	    TIMEZONE="${1#*=}"
	    ;;
	--wpa-essid=*)
	    WPA_ESSID="${1#*=}"
	    ;;
	--wpa-psk=*)
	    WPA_PSK="${1#*=}"
	    ;;
	--password=*)
	    ROOT_PASSWORD="${1#*=}"
	    ;;
	--ssh-key=*)
	    SSH_KEY="${1#*=}"
	    ;;
	--root-fs=*)
	    ROOTFS="${1#*=}"
	    ;;
	*)
	    echo "Unknown argument: $1" 1>&2
	    exit 1
    esac
    shift
done

# Process last argument, the device to use
if [ -z "$1" ] || [ "$1" = -h ] || [ "$1" = --help ]; then
    print_usage
    exit 1
fi
if [ ! -e "$1" ]; then
    echo "Device not found: $1" 1>&2
    exit 1
fi
if [ ! -b "$1" ]; then
    echo "Specified device is not a block device: $1" 1>&2
    exit 1
fi
DEVICE="$1"
PARTITION1="$DEVICE"p1
PARTITION2="$DEVICE"p2

# Check environment
if [ "$EUID" != 0 ]; then
    echo "This script must be run as root." 1>&2
    exit 1
fi

# Argument processing and enivronment check are done at this point
# Start with actual script

# Setup partitions on SD card
partition() {
    parted "$DEVICE" --script mklabel msdos &&
    parted "$DEVICE" --script mkpart primary fat32 1M 200M &&
    parted "$DEVICE" --script mkpart primary ext4 200M 100% &&
    mkfs.vfat -F 32 "$PARTITION1" &&
    mkfs.ext4 "$PARTITION2"
}

mountrootfs() {
    mkdir "$ROOTFS" &&
    mount "$PARTITION2" "$ROOTFS" &&
    
    mkdir "$ROOTFS"/boot &&
    mount "$PARTITION1" "$ROOTFS"/boot
}

mkrootfs() {
    # Create initial debian filesystem
    qemu-debootstrap --arch=armhf \
		     --include=ssh,sudo,ntpdate,fake-hwclock,openssl,ca-certificates,vim,nano,cryptsetup,lvm2,locales,less,cpufrequtils,wireless-tools,wpasupplicant \
		     jessie \
		     "$ROOTFS" \
		     "http://ftp${MIRROR}.debian.org/debian/"

    # Set package configuration to use raspberrypi.org archive for kernel package
    cat > "$ROOTFS"/etc/apt/sources.list <<EOF
deb http://ftp${MIRROR}.debian.org/debian jessie main contrib non-free
deb http://ftp${MIRROR}.debian.org/debian jessie-updates main contrib non-free
deb http://security.debian.org jessie/updates main contrib non-free
deb http://archive.raspberrypi.org/debian wheezy main
EOF

    cat > "$ROOTFS"/etc/apt/preferences.d/raspberrypi <<EOF
Package: *
Pin: origin archive.raspberrypi.org
Pin-Priority: 1

Package: raspberrypi-bootloader
Pin: origin archive.raspberrypi.org
Pin-Priority: 1000

Package: libraspberrypi0
Pin: origin archive.raspberrypi.org
Pin-Priority: 1000

Package: libraspberrypi-bin
Pin: origin archive.raspberrypi.org
Pin-Priority: 1000
EOF

    chroot "$ROOTFS" /bin/sh -c "wget https://archive.raspberrypi.org/debian/raspberrypi.gpg.key -O - | apt-key add -"
    
    chroot "$ROOTFS" apt-get update

    # libraspberrypi-bin contains kernel, firmware and some binary tools
    chroot "$ROOTFS" apt-get install locales dbus openssh-server dosfstools libraspberrypi-bin

    cat > "$ROOTFS"/boot/config.txt <<EOF
gpu_mem=128
start_file=start_x.elf
fixup_file=fixup_x.dat
EOF

    # Set up network
    if [ -n "$WPA_ESSID" ]; then
	cat > "$ROOTFS"/etc/network/interfaces.d/wlan0 <<EOF
auto wlan0
iface wlan0 inet dhcp
        wpa-essid "$WPA_ESSID"
        wpa-psk "$WPA_PSK"
EOF
	chmod 660 "$ROOTFS"/etc/network/interfaces.d/wlan0
	chroot "$ROOTFS" apt-get install firmware-realtek
    else
	cat > "$ROOTFS"/etc/network/interfaces.d/eth0 <<EOF
auto eth0
iface eth0 inet dhcp
EOF
    fi

    # Set up file mounts
    cat > "$ROOTFS"/etc/fstab <<EOF
UUID=$(blkid -s UUID -o value "$PARTITION1") /boot vfat noatime   0 2
UUID=$(blkid -s UUID -o value "$PARTITION2") /     ext4 noatime   0 1
tmpfs                                        /tmp  tmpfs defaults 0 0
EOF

    # Set timezone
    echo "$TIMEZONE" > "$ROOTFS"/etc/timezone
    ln -sf /usr/share/zoneinfo/"$TIMEZONE" "$ROOTFS"/etc/localtime

    # Set host configuration
    echo "$HOSTNAME" > "$ROOTFS"/etc/hostname
    sed -i "/^127.0.0.1/ s/\$/ $HOSTNAME/" "$ROOTFS"/etc/hosts
    sed -i "/^::1/ s/\$/ $HOSTNAME/" > "$ROOTFS"/etc/hosts

    # Login options
    chroot "$ROOTFS" /bin/sh -c "echo root:$ROOT_PASSWORD | chpasswd"

    if [ -e "$SSH_KEY" ]; then
	mkdir "$ROOTFS"/root/.ssh
	chmod 600 "$ROOTFS"/root/.ssh
	cat "$SSH_KEY" >> "$ROOTFS"/root/.ssh/authorized_keys
	chmod 600 "$ROOTFS"/root/.ssh/authorized_keys
	sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/g' "$ROOTFS"/etc/ssh/sshd_config
	echo "Success: SSH password login was disabled! Use the key in $SSH_KEY to login." 1>&2
    else
	sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/g' "$ROOTFS"/etc/ssh/sshd_config
	echo "Warning: no SSH key found, SSH password login has been enabled for root! Please enable key-login only as soon as possible." 1>&2
    fi
}

umountrootfs() {
    rm -f "$ROOTFS"/usr/bin/qemu-arm-static
    umount "$ROOTFS"/boot
    umount "$ROOTFS"
    rm -r "$ROOTFS"
}


if [ "$FORCE" != 1 ]; then
    echo "WARNING: The following operations may have destructive consequences." 1>&2
    echo "Partition device $DEVICE and create bootable root file system on $ROOTFS" 1>&2
    read -p "Continue? [Y,n] " yn
    if [ "$yn" != "Y" ] && [ "$yn" != "y" ]; then
	echo "Aborting." 1>&2
	exit 1
    fi
fi

partition && mountrootfs && mkrootfs && umountrootfs