Skip to content

Instantly share code, notes, and snippets.

@RobertCNelson
Last active August 29, 2015 14:27
Show Gist options
  • Select an option

  • Save RobertCNelson/b54ddad33e839f292eba to your computer and use it in GitHub Desktop.

Select an option

Save RobertCNelson/b54ddad33e839f292eba to your computer and use it in GitHub Desktop.
#!/bin/bash -e
#
# Copyright (c) 2015 Robert Nelson <[email protected]>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
DIR="$PWD"
TEMPDIR=$(mktemp -d)
###
imagename="example-image"
###
check_root () {
if ! [ $(id -u) = 0 ] ; then
echo "$0 must be run as sudo user or root"
exit 1
fi
}
check_for_command () {
if ! which "$1" > /dev/null ; then
echo -n "You're missing command $1"
NEEDS_COMMAND=1
if [ -n "$2" ] ; then
echo -n " (consider installing package $2)"
fi
echo
fi
}
detect_software () {
unset NEEDS_COMMAND
check_for_command mkfs.vfat dosfstools
check_for_command partprobe parted
check_for_command kpartx kpartx
check_for_command bmaptool bmap-tools
if [ "${NEEDS_COMMAND}" ] ; then
echo ""
echo "Your system is missing some dependencies"
echo ""
exit
fi
unset test_sfdisk
test_sfdisk=$(LC_ALL=C sfdisk -v 2>/dev/null | grep 2.17.2 | awk '{print $1}')
if [ "x${test_sdfdisk}" = "xsfdisk" ] ; then
echo ""
echo "Detected known broken sfdisk:"
echo "See: https://github.com/RobertCNelson/netinstall/issues/20"
echo ""
exit
fi
}
drive_error_ro () {
echo "-----------------------------"
echo "Error: for some reason your SD card is not writable..."
echo "Check: is the write protect lever set the locked position?"
echo "Check: do you have another SD card reader?"
echo "-----------------------------"
echo "Script gave up..."
exit
}
sfdisk_partition_layout () {
sfdisk_options="--force --in-order --Linux --unit M"
sfdisk_boot_startmb="1"
sfdisk_boot_fstype="83"
sfdisk_var_startmb="${conf_var_startmb}"
test_sfdisk=$(LC_ALL=C sfdisk --help | grep -m 1 -e "--in-order" || true)
if [ "x${test_sfdisk}" = "x" ] ; then
echo "log: sfdisk: 2.26.x or greater detected"
sfdisk_options="--force"
sfdisk_boot_startmb="${sfdisk_boot_startmb}M"
fi
LC_ALL=C sfdisk ${sfdisk_options} "${media}" <<-__EOF__
${sfdisk_boot_startmb},,${sfdisk_boot_fstype},*
__EOF__
sync
}
format_partition_error () {
echo "LC_ALL=C ${mkfs} ${mkfs_partition} ${mkfs_label}"
echo "Failure: formating partition"
exit
}
format_partition_try2 () {
echo "-----------------------------"
echo "BUG: [${mkfs_partition}] was not available so trying [${mkfs}] again in 5 seconds..."
partprobe ${media}
sync
sleep 5
echo "-----------------------------"
echo "Formating with: [${mkfs} ${mkfs_partition} ${mkfs_label}]"
echo "-----------------------------"
LC_ALL=C ${mkfs} ${mkfs_partition} ${mkfs_label} || format_partition_error
sync
}
format_partition () {
echo "Formating with: [${mkfs} ${mkfs_partition} ${mkfs_label}]"
echo "-----------------------------"
LC_ALL=C ${mkfs} ${mkfs_partition} ${mkfs_label} || format_partition_try2
sync
}
format_rootfs_partition () {
mkfs_partition="${media_prefix}${media_rootfs_partition}"
mkfs="mkfs.ext4"
mkfs_label="-L rootfs"
format_partition
}
create_partitions () {
media_rootfs_partition=1
echo "Using sfdisk to create partition layout"
echo "Version: `LC_ALL=C sfdisk --version`"
echo "-----------------------------"
sfdisk_partition_layout
echo "Partition Setup:"
echo "-----------------------------"
LC_ALL=C fdisk -l "${media}"
echo "-----------------------------"
media_loop=$(losetup -f || true)
if [ ! "${media_loop}" ] ; then
echo "losetup -f failed"
echo "Unmount some via: [sudo losetup -a]"
echo "-----------------------------"
losetup -a
echo "sudo kpartx -d /dev/loopX ; sudo losetup -d /dev/loopX"
echo "-----------------------------"
exit
fi
losetup ${media_loop} "${media}"
kpartx -av ${media_loop}
sleep 1
sync
test_loop=$(echo ${media_loop} | awk -F'/' '{print $3}')
if [ -e /dev/mapper/${test_loop}p${media_rootfs_partition} ] ; then
media_prefix="/dev/mapper/${test_loop}p"
else
ls -lh /dev/mapper/
echo "Error: not sure what to do (new feature)."
exit
fi
format_rootfs_partition
}
populate_rootfs () {
echo "Populating rootfs Partition"
echo "Please be patient, this may take a few minutes, as its transfering a lot of data.."
echo "-----------------------------"
if [ ! -d ${TEMPDIR}/disk ] ; then
mkdir -p ${TEMPDIR}/disk
fi
ROOTFS_TYPE=ext4
partprobe ${media}
if ! mount -t ${ROOTFS_TYPE} ${media_prefix}${media_rootfs_partition} ${TEMPDIR}/disk; then
echo "-----------------------------"
echo "BUG: [${media_prefix}${media_rootfs_partition}] was not available so trying to mount again in 5 seconds..."
partprobe ${media}
sync
sleep 5
echo "-----------------------------"
if ! mount -t ${ROOTFS_TYPE} ${media_prefix}${media_rootfs_partition} ${TEMPDIR}/disk; then
echo "-----------------------------"
echo "Unable to mount ${media_prefix}${media_rootfs_partition} at ${TEMPDIR}/disk to complete populating rootfs Partition"
echo "Please retry running the script, sometimes rebooting your system helps."
echo "-----------------------------"
exit
fi
fi
lsblk | grep -v sr0
echo "-----------------------------"
#sudo mkdir /tmp/rootfs
#sudo mount /dev/sdd1 /tmp/rootfs
if [ -d /tmp/rootfs ] ; then
echo "rsync: /tmp/rootfs/ -> ${TEMPDIR}/disk/"
rsync -aAx --delete /tmp/rootfs/ ${TEMPDIR}/disk/ --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}
echo "# /etc/fstab: static file system information." > ${TEMPDIR}/disk/etc/fstab
echo "#" >> ${TEMPDIR}/disk/etc/fstab
echo "/dev/mmcblk0p1 / ext4 noatime,errors=remount-ro 0 1" >> ${TEMPDIR}/disk/etc/fstab
echo "debugfs /sys/kernel/debug debugfs defaults 0 0" >> ${TEMPDIR}/disk/etc/fstab
if [ -f ${TEMPDIR}/disk/boot/uEnv.txt ] ; then
#make sure we dont use an uuid, as the it will no longer be accurate...
sed -i -e 's:uuid:#uuid:g' ${TEMPDIR}/disk/boot/uEnv.txt
fi
else
echo "mount microsd to /tmp/rootfs"
exit
fi
sync
sync
echo "-----------------------------"
cd ${TEMPDIR}/disk
sync
cd "${DIR}"/
umount ${TEMPDIR}/disk || umount -l ${TEMPDIR}/disk || true
echo "Finished populating rootfs Partition"
echo "-----------------------------"
}
media="${DIR}/${imagename}.img"
check_root
if [ -f "${media}" ] ; then
rm -rf "${media}" || true
fi
#2GB
dd if=/dev/zero of="${media}" bs=1024 count=0 seek=$((1024 * 1700))
#4GB
#dd if=/dev/zero of="${media}" bs=1024 count=0 seek=$((1024 * 3600))
check_root
detect_software
create_partitions
populate_rootfs
if [ -f ${imagename}.img ] ; then
echo "-----------------------------"
chown -R 1000:1000 ${imagename}.img
echo "img: ${imagename}.img"
if [ -f /usr/bin/bmaptool ] ; then
bmaptool create -o ${imagename}.bmap ${imagename}.img
chown -R 1000:1000 ${imagename}.bmap
echo "bmap: ${imagename}.bmap"
fi
echo "-----------------------------"
# xz -z -v ${imagename}.img
# if [ -f ${imagename}.img.xz ] ; then
# chown -R 1000:1000 ${imagename}.img.xz
# fi
fi
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment