Created
November 6, 2015 23:13
-
-
Save mikemackintosh/f745c7dd850737167c02 to your computer and use it in GitHub Desktop.
pibuilder.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
IMAGESIZE="990" # in Megabytes | |
USERNAME="bill" | |
PASSWORD="b0ard" | |
PACKAGES="wireless-tools xinit consolekit net-tools fonts-freefont-ttf ifplugd ifupdown hostname fontconfig-config fontconfig iputils-ping wpasupplicant curl binutils locales sudo openssh-server ntp usbmount patch less rsync sudo raspi-config matchbox chromium x11-xserver-utils xwit sqlite3 libnss3 vim" | |
PI_HOSTNAME=${PI_HOSTNAME-"dashboard${RANDOM:0:3}"} | |
# Print some configurations | |
echo "Final Image Size: ${IMAGESIZE}" | |
echo "Device Username: ${USERNAME}" | |
echo "Device Password: ${PASSWORD}" | |
echo "Device Hostname: ${PI_HOSTNAME}" | |
echo "Setting Access Point to: ${WIFI_AP}" | |
echo "Setting Access Point Password to: ${WIFI_PASSWORD}" | |
echo "Installing packages: ${PACKAGES}" | |
echo -e "\n\n\n" | |
# System defaults | |
MIRROR="http://mirror.umd.edu/raspbian/raspbian" | |
#MIRROR="http://archive.raspbian.org/raspbian" | |
CODENAME="wheezy" | |
BOOTSIZE="64M" | |
# Set environment | |
relative_path=`dirname $0` | |
# locate path of this script | |
absolute_path=`cd ${relative_path}; pwd` | |
# Set todays date | |
today=`date +%Y%m%d` | |
# Set variables to help | |
ROOTFS=$absolute_path/rootfs-${today} | |
BOOTFS=$absolute_path/bootfs-${today} | |
OUTIMAGE=$absolute_path/dashboard.img | |
# Build out dirs | |
mkdir -p $ROOTFS $BOOTFS | |
# Check for permissions | |
if [ ${EUID} -ne 0 ]; then | |
echo "this tool must be run as root" | |
exit 1 | |
fi | |
# Catch errors and handle cleaning up the mess | |
trap cleanup 0 1 2 3 9 15 | |
exec 2> ./errors.log | |
# Log helper | |
log() { | |
echo "$@" | |
} | |
# Log errors with this | |
error() { | |
echo "[!!] $@" | |
} | |
# Run commands wihtin the CHROOT | |
chroot_cmd() { | |
PATH=/usr/bin:/usr/sbin:/usr/local/bin:/sbin:$PATH LC_ALL=C LANGUAGE=C LANG=C chroot $ROOTFS "$@" | |
} | |
# Handle cleanup | |
cleanup(){ | |
log "== Cleanup ==" | |
cleanup_bootstrap | |
cat ./errors.log | |
error $@ | |
rm -rf $BOOTFS $ROOTFS $OUTIMAGE | |
} | |
# Bootstrap the OS | |
bootstrap() { | |
# Get the raspbian base | |
log " - Installing base OS " | |
if [ -z $MIRROR ]; then | |
curl -sI http://mirror.umd.edu/raspbian/raspbian/|grep 200 | |
if [ $? -eq 0 ]; then | |
MIRROR="http://archive.raspbian.org/raspbian" | |
else | |
MIRROR="http://mirror.umd.edu/raspbian/raspbian" | |
fi | |
fi | |
# Download and extract the base os | |
qemu-debootstrap --variant=minbase --include wget,curl,binutils --arch armhf wheezy $ROOTFS $MIRROR > /dev/null & | |
while kill -0 ${!} 2>/dev/null; do | |
echo -n "." | |
sleep 1 | |
done | |
echo " Done!" | |
log " - Mounting chroot" | |
#mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc | |
mount -t proc proc $ROOTFS/proc | |
mount -t sysfs sysfs $ROOTFS/sys | |
mount -o bind /dev $ROOTFS/dev | |
cp /usr/bin/qemu-arm-static $ROOTFS/usr/bin/ | |
#chroot_cmd /debootstrap/debootstrap --second-stage | |
manage_firmware | |
} | |
manage_firmware() { | |
# Get pi firmware | |
log " - Downloading Firmware " | |
wget https://github.com/raspberrypi/firmware/archive/master.zip --append-output ./errors.log & | |
while kill -0 ${!} 2>/dev/null; do | |
echo -n "." | |
sleep 1 | |
done | |
echo " Done!" | |
sleep 2 | |
log " - Extracting Firmware " | |
unzip -o master.zip > /dev/null& | |
while kill -0 ${!} 2>/dev/null; do | |
echo -n "." | |
sleep 1 | |
done | |
echo " Done!" | |
log " - Copying Firmware " | |
# Copy over the firmware | |
cp -R firmware-master/boot/* $BOOTFS/ | |
cp -R firmware-master/hardfp/opt/* $ROOTFS/opt/ | |
cp -R firmware-master/modules $ROOTFS/lib/modules | |
} | |
# Unmount and get read to image | |
cleanup_bootstrap(){ | |
rm $ROOTFS/usr/bin/qemu-* | |
umount --force $ROOTFS/proc | |
umount --force $ROOTFS/sys | |
umount --force $ROOTFS/dev | |
} | |
# Create the boot partition | |
create_boot(){ | |
#[[ -d rootfs/ ]] && cp -rv rootfs/* $ROOTFS | |
log " - Copying Local Firmware" | |
cp -rv firmware/* $ROOTFS/boot/ | |
cp -rv firmware/* $BOOTFS | |
# sh -c 'cat >/mnt/bootfs/config.txt<<EOF | |
#dtparam=i2c_arm=on | |
#dtparam=i2c_vc=on | |
#dtparam=act_led_trigger=heartbeat | |
#dtparam=pwr_led_trigger=mmc0 | |
#arm_freq=800 | |
#core_freq=250 | |
#sdram_freq=400 | |
#over_voltage=0 | |
#gpu_mem=16 | |
#disable_overscan=1 | |
#framebuffer_width=1900 | |
#framebuffer_height=1200 | |
#framebuffer_depth=32 | |
#framebuffer_ignore_alpha=1 | |
#hdmi_pixel_encoding=1 | |
#hdmi_group=2 | |
# | |
#EOF | |
#' | |
#dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait | |
#sudo sh -c 'cat >/mnt/bootfs/cmdline.txt<<EOF | |
#dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait | |
#EOF | |
# ' | |
} | |
# Create the user | |
create_user() { | |
log " - Creating User: ${USERNAME}" | |
log " - Creating PASSWORD: ${PASSWORD}" | |
chroot_cmd useradd $USERNAME -m -p `mkpasswd $PASSWORD` -s /bin/bash | |
chroot_cmd usermod -a -G adm,sudo,staff,kmem,plugdev $USERNAME | |
} | |
# Create the image | |
create_img() { | |
log " - Creating Blank Image: ${OUTIMAGE}" | |
dd if=/dev/zero of=$OUTIMAGE bs=1MB count=$IMAGESIZE | |
sudo losetup -f $OUTIMAGE | |
# Partition the device | |
log " - Partitioning" | |
sudo fdisk /dev/loop0 << EOF | |
n | |
p | |
1 | |
+64M | |
t | |
c | |
n | |
p | |
2 | |
w | |
EOF | |
# Remove the loopback device | |
sudo losetup -d /dev/loop0 | |
kpartx -va $OUTIMAGE | sed -E 's/.*(loop[0-9])p.*/1/g' | head -1 | |
# Format the devices | |
log " - Formatting" | |
mkfs.vfat /dev/mapper/loop0p1 | |
mkfs.ext4 /dev/mapper/loop0p2 | |
if [ $? -ne 0 ]; then | |
mkfs.ext4 /dev/mapper/loop0p2 | |
fi | |
log " - Installing RootFS" | |
sudo mkdir -p /mnt/rootfs | |
sudo mount /dev/mapper/loop0p2 /mnt/rootfs | |
sudo rsync -a $ROOTFS/ /mnt/rootfs | |
sudo cp -a firmware-master/hardfp/opt/vc /mnt/rootfs/opt/ | |
sudo umount /mnt/rootfs | |
log " - Installing BootFS" | |
sudo mkdir -p /mnt/bootfs | |
sudo mount /dev/mapper/loop0p1 /mnt/bootfs | |
sudo cp -R $BOOTFS/* /mnt/bootfs | |
sudo umount /mnt/bootfs | |
sudo kpartx -d $OUTIMAGE | |
log " - Copy complete image" | |
cp *.img /build/pkgs/ | |
} | |
configure(){ | |
log " - Update Root .bashrc LANG" | |
echo 'LC_ALL=C | |
LANGUAGE=C | |
LANG=C | |
' > $ROOTFS/root/.bashrc | |
# Set apt sources.list | |
log " - Configuring Kernel Conf" | |
echo "# Kernel image management overrides | |
# See kernel-img.conf(5) for details | |
do_symlinks = yes | |
do_bootloader = no | |
do_initrd = yes | |
link_in_boot = yes | |
" > $ROOTFS/etc/kernel-img.conf | |
# Set apt sources.list | |
log " - Configuring apt packages" | |
# Install wget if it's not installed | |
chroot_cmd apt-get update | |
#echo "deb http://archive.raspbian.org/raspbian wheezy main" >> $ROOTFS/etc/apt/sources.list | |
echo "deb http://www.mirrorservice.org/sites/archive.raspbian.org/raspbian wheezy main" >> $ROOTFS/etc/apt/sources.list | |
echo "deb http://archive.raspberrypi.org/debian/ wheezy main" >> $ROOTFS/etc/apt/sources.list | |
#chroot_cmd wget http://archive.raspbian.org/raspbian.public.key -O - | apt-key add - | |
chroot_cmd wget http://www.mirrorservice.org/sites/archive.raspbian.org/raspbian.public.key -O - | apt-key add - | |
chroot_cmd wget http://archive.raspberrypi.org/debian/raspberrypi.gpg.key -O - | apt-key add - | |
#chroot_cmd add-apt-repository -y universe | |
chroot_cmd apt-get update | |
chroot_cmd apt-get dist-upgrade --force-yes -y | |
chroot_cmd apt-get install -y --force-yes $PACKAGES | |
# Update raspberry pi | |
log " - Configuring raspberry-pi update" | |
chroot_cmd wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update | |
chroot_cmd chmod +x /usr/bin/rpi-update | |
chroot_cmd ldconfig | |
chroot_cmd /usr/bin/rpi-update | |
# Configure cmdline.txt | |
#log " - Configuring cmdline.txt" | |
#echo "dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" > $ROOTFS/boot/cmdline.txt | |
# Set fstab | |
log " - Configuring fstab " | |
echo "proc /proc proc defaults 0 0 | |
/dev/mmcblk0p1 /boot vfat defaults 0 0 | |
" > $ROOTFS/etc/fstab | |
# Set hostname | |
log " - Configuring Hostname" | |
echo $PI_HOSTNAME > $ROOTFS/etc/hostname | |
log " - Configuring Hostname DNS" | |
echo "127.0.0.1 ${PI_HOSTNAME}" >> $ROOTFS/etc/hosts | |
if [ -z $HOSTOVERIDE ]; then | |
log " - Configuring Hostname Override" | |
echo $HOSTOVERIDE >> $ROOTFS/etc/hosts | |
fi | |
# Set interfaces | |
log " - Configuring Interfaces" | |
echo "auto lo | |
iface lo inet loopback | |
auto eth0 | |
allow-hotplug eth0 | |
iface eth0 inet dhcp | |
auto wlan0 | |
allow-hotplug wlan0 | |
iface wlan0 inet dhcp | |
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf | |
iface default inet dhcp | |
# Include files from /etc/network/interfaces.d: | |
source-directory /etc/network/interfaces.d | |
" > $ROOTFS/etc/network/interfaces | |
# Set interfaces | |
log " - Configuring WPA Supplicant" | |
echo " | |
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev | |
update_config=1 | |
network={ | |
ssid=\"${WIFI_AP}\" | |
psk=\"${WIFI_PASSWORD}\" | |
proto=RSN | |
key_mgmt=WPA-PSK | |
pairwise=CCMP | |
auth_alg=OPEN | |
}" > $ROOTFS/etc/wpa_supplicant/wpa_supplicant.conf | |
# Set interfaces | |
log " - Configuring rc.local" | |
cp skel/rc.local $ROOTFS/etc/rc.local | |
sed -i -e "s/USERNAME/$USERNAME/g" $ROOTFS/etc/rc.local | |
log " - Configuring X11" | |
sed -i -e "s/allowed_users=console/allowed_users=anybody/g" $ROOTFS/etc/X11/Xwrapper.config | |
# Set Serial | |
log " - Configuring Serial" | |
echo '# ttyAMA0 - getty | |
# | |
# This service maintains a getty on ttyAMA0 from the point the system is | |
# started until it is shut down again. | |
start on stopped rc RUNLEVEL=[2345] and ( | |
not-container or | |
container CONTAINER=lxc or | |
container CONTAINER=lxc-libvirt) | |
stop on runlevel [!2345] | |
respawn | |
exec /sbin/getty -8 115200 ttyAMA0 | |
' > $ROOTFS/etc/init/ttyAMA0.conf | |
# Set Modules | |
log " - Configuring Modules" | |
echo "vchiq | |
snd_bcm2835 | |
" >> $ROOTFS/etc/modules | |
# Set usbmount | |
log " - Configuring usbmount" | |
sed -i -e 's/""/"-fstype=vfat,flush,gid=plugdev,dmask=0007,fmask=0117"/g' $ROOTFS/etc/usbmount/usbmount.conf | |
# Set cleanup | |
log " - Cleaning Up" | |
echo '#!/bin/bash | |
apt-get clean | |
rm -f /cleanup | |
' > $ROOTFS/cleanup | |
chmod +x $ROOTFS/cleanup | |
chroot_cmd /cleanup | |
} | |
log "## Starting Script ##" | |
log "== Beginning Bootstrap ==" | |
bootstrap | |
log "== Creating Boot Image ==" | |
create_boot | |
log "== Creating User ==" | |
create_user | |
log "== Configuring OS ==" | |
configure | |
log "== Preparing Image ==" | |
cleanup_bootstrap | |
log "== Create the image ==" | |
create_img | |
trap - EXIT |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment