Skip to content

Instantly share code, notes, and snippets.

@crashcoredump
Forked from sathlan/make_usb.sh
Last active August 29, 2015 14:20
Show Gist options
  • Save crashcoredump/667391dcb0d1d0a53522 to your computer and use it in GitHub Desktop.
Save crashcoredump/667391dcb0d1d0a53522 to your computer and use it in GitHub Desktop.
#!/bin/sh -x
START_DIR=$CWD
SHARE_DIR=/backup001/chem/home/chem/src/mfsbsd
KEYBOARD=dvorak
WANT_PHORONIX_TEST_SUITE=4.4.1 # set it to no to disable
# catch error from my own error function even in subshell.
err_handler ()
{
rc=$?
if [ $rc -eq 42 ]; then
{
for i in $MOUNT_POINTS; do
umount $i
done
for i in $MDDEVICES; do
mdconfig -d -u "${i#md}"
done
}
exit $rc
fi
}
trap err_handler CHLD
usage ()
{
echo "USAGE: TODO"
}
PACKAGES_DIR='/backup001/chem/packages'
#PARTITIONS="MFS DIST BOOT_1 LINUX"
PART_COUNT='6'
PART_BOOT_1_SIZE='100'
PART_BOOT_2_SIZE=$PART_BOOT_1_SIZE
PART_DIST_SIZE="3000"
PART_LINUX_SIZE="All"
PART_BOOT_1_IDX=1
PART_BOOT_2_IDX=2
#PART_MFS_IDX=2
PART_DIST_IDX=3
PART_LINUX_IDX=4
PART_MFS_TYPE=freebsd
PART_DIST_TYPE=freebsd
PART_BOOT_1_TYPE=freebsd
PART_BOOT_2_TYPE=freebsd
PART_LINUX_TYPE='!131'
MFS_PATH='http://mfsbsd.vx.sk/files/iso/amd64/9/mfsbsd-9.1-RELEASE-amd64.iso'
ISO_PATH='ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/ISO-IMAGES/9.1/FreeBSD-9.1-RELEASE-amd64-disc1.iso'
MDDEVICES=""
MOUNT_POINTS=""
USB_DEVICE=""
ERASE_DISK=""
while getopts :m:i:l:d:u:e: OPT; do
case $OPT in
m|+m)
MFS_PATH="$OPTARG"
;;
i|+i)
ISO_PATH="$OPTARG"
;;
l|+l)
LINUX_PATH="$OPTARG"
;;
d|+d)
USB_DEVICE="$OPTARG"
;;
u:+u)
UPDATE_WHAT="$OPTARG"
;;
e:+e)
ERASE_DISK="YES"
;;
*)
usage
exit 2
esac
done
shift `expr $OPTIND - 1`
OPTIND=1
error ()
{
echo "$@" >&2
exit 42
}
SECTOR_SIZE=""
DISKINFO=`mktemp -t "make_usb_diskinfo"`
if ! diskinfo -v /dev/$USB_DEVICE 2>/dev/null; then
error "The device is not valid"
fi > "$DISKINFO"
OIFS="$IFS"
IFS="\n"
while read input; do
expr "$input" : '.*sectorsize' >/dev/null && sector_size=${input% *# *}
expr "$input" : '.*size in bytes' >/dev/null && sizeb=${input% *# *}
expr "$input" : '.*size in sectors' >/dev/null && sizes=${input% *# *}
done < "$DISKINFO"
rm "$DISKINFO"
IFS="$OIFS"
if [ -z "$sector_size" ]; then
error "Cannot figure out the sector_size"
fi
TMP_DIR=`mktemp -d -t make_usb`
__fetch ()
{
local file="$1"
if [ -z "$file" ]; then
error "You must provide a non empty name"
fi
if expr "$file" : '[hHFf][tT][tTpP]' >/dev/null 2>&1; then
fetch -o $TMP_DIR $file
file="$TMP_DIR/${file##*/}"
fi
if ! [ -e "$file" ]; then
error "Cannot find the iso $file"
fi
echo $file
}
__get_size ()
{
local file="$1"
local type="$2"
eval eval local size="\$\{PART_${type}_SIZE\}"
if [ "$size" = "All" ]; then
echo 'All'
return 0
fi
if ! [ -e "$file" ]; then
error "The file \"$file\" doesn't exist"
fi
# 20% more for ufs formating
local size_disk=`ls -l "$file" | awk '{print int(($5/1024/1024) * 1.2 )}'`
if [ -n "$size" ]; then
if [ $size -ge $size_disk ]; then
echo $size
return 0
fi
fi
echo $size_disk
}
fetch_dist_iso ()
{
PART_DIST_PATH=`__fetch $ISO_PATH`
}
get_dist_size ()
{
__get_size "$PART_DIST_PATH" DIST
}
fetch_linux_iso ()
{
if [ -z "$LINUX_PATH" ]; then
error "Cannot guess the Linux distribution you want. Use -l to specify the iso path."
fi
PART_LINUX_PATH=`__fetch $LINUX_PATH`
}
get_linux_size ()
{
__get_size "$PART_LINUX_PATH" LINUX
}
fetch_mfs_iso ()
{
PART_MFS_PATH=`__fetch $MFS_PATH`
}
get_mfs_size ()
{
__get_size "$PART_MFS_PATH" MFS
}
delete_partition ()
{
local idx="$1"
if [ -z "$idx" ]; then
error "You must specify the partition index."
fi
if ! gpart delete -i $idx $USB_DEVICE; then
error "Could not delete partion $idx from $USB_DEVICE"
fi
}
cleanup_mbr ()
{
dd if=/dev/zero of=/dev/$USB_DEVICE bs=512 count=1
}
detroy_geom ()
{
if ! gpart destroy $USB_DEVICE; then
error "Could not destroy geom $USB_DEVICE"
fi
cleanup_mbr
}
erase_disk ()
{
if ! gpart show | egrep -q "\\<$USB_DEVICE\\>"; then
return 0
fi
local gpart=`mktemp -t "make_usb_erase_disk"`
if ! gpart show -p $USB_DEVICE; then
error "The device cannot be viewed with gpart."
fi > "$gpart"
(
IFS="\n"
while read input; do
expr "$input" : '.*- free -' && continue
index=$(expr "$input" : '.*'${USB_DEVICE}'s\([0-9]\)')
test -n "$index" && delete_partition $index
done < "$gpart"
rm "$gpart"
)
detroy_geom
}
create_disk_table ()
{
if ! gpart create -s MBR $USB_DEVICE; then
error "Cannot create the partitioning scheme for $USB_DEVICE"
fi
}
create_partitions ()
{
local type="$1"
echo "$IFS"
eval eval local part_type="\$\{PART_${type}_TYPE\}"
eval eval local idx="\$\{PART_${type}_IDX\}"
eval eval size="\$\{PART_${type}_SIZE\}"
case $size in
All)
size_cmd=""
;;
[0-9]*)
if ! printf "%d" $size >/dev/null 2>&1; then
error "Number \"$size\" is not valid for $type"
fi
size_cmd=" -s ${size}M "
;;
*)
error "Number \"$size\" is not valid for $type"
esac
if ! gpart add -t $part_type -i $idx $size_cmd $USB_DEVICE; then
error "Could not create partition $part_type of sector size $sector_size on $USB_DEVICE of size $size M."
fi
}
insert_bootcode ()
{
if ! gpart bootcode -b /boot/boot0 $USB_DEVICE; then
error "Could not insert bootcode stage 0 on $USB_DEVICE"
fi
}
__create_and_copy_dest ()
{
local type="$1"
local source_dir="$2"
local find_user_args="${3:-.}"
eval eval local slice="/dev/${USB_DEVICE}s\$\{PART_${type}_IDX\}"
case $type in
MFS|BOOT*|DIST)
if ! gpart bootcode -p /boot/boot -i "${slice#/dev/${USB_DEVICE}s}" ${USB_DEVICE}; then
error "Could not insert bootcode 1 on $USB_DEVICE"
fi
if ! bsdlabel -w $slice; then
error "Could not write bsd partitions"
fi
if ! newfs -O1 -m0 -L `echo $type | tr -d '_'` -n ${slice}a; then
error "Could not create freebsd filesystem on ${slice}a"
fi
;;
DOS)
;;
LINUX)
if ! mkfs.ext2 -L $type -m0 ${slice}; then
error "Could not create linux filesystem on ${slice}"
fi
;;
*)
error "Cannot find commands for fs creation for type \"$type\""
esac
eval eval PART_${type}_DEST=`mktemp -d -t make_usb_${type}_dest`
eval eval local dest="\$\{PART_${type}_DEST\}"
if [ ! -d "$dest" ]; then
eval eval error "Destination directory doesn't exists (\$\{PART_${type}_DEST\})"
fi
case $type in
MFS|BOOT*|DIST)
if ! mount ${slice}a $dest; then
error "Could not mount freebsd filesystem on ${slice}a"
fi
;;
DOS)
;;
LINUX)
if ! mount -t ext2fs ${slice} ${dest}; then
error "Could not mount linux filesystem on ${slice}"
fi
if ! grub-install --force --no-floppy --root-directory=${dest} ${slice}; then
error "Could not install linux bootstrap code for \"${slice}\" in \"${dest}\""
fi
;;
*)
error "Cannot find commands for mounting for type \"$type\""
esac
MOUNT_POINTS="$MOUNT_POINTS ${dest}"
{
eval cd $source_dir
eval find "$find_user_args" | cpio -dumpv $dest
if [ $? -ne 0 ]; then
error "Problem copying the data from \"$source_dir\" to \"$dest\""
fi
}
}
__copy_data ()
{
local type="$1"
eval eval PART_${type}_MD=\`mdconfig -a -t vnode -f \$PART_${type}_PATH\`
eval eval local mount_src="/dev/\$\{PART_${type}_MD\}"
MDDEVICES="$MDDEVICES ${mount_src#/dev/}"
eval eval PART_${type}_MNT=\`mktemp -d -t make_usb_${type}_mnt\`
eval eval local source_dir="\$\{PART_${type}_MNT\}"
if [ -z "${mount_src#/dev/}" -o -z "$source_dir" ]; then
error "Could not create the logical device."
fi
eval mount -t cd9660 $mount_src $source_dir
if [ $? -ne 0 ]; then
eval eval error "Could not mount cdrom \$PART_${type}_PATH"
fi
MOUNT_POINTS="$MOUNT_POINTS ${source_dir}"
__create_and_copy_dest $type $source_dir
}
copy_linux_data ()
{
__copy_data LINUX
}
copy_mfs_data ()
{
__copy_data MFS
}
copy_dist_data ()
{
__copy_data DIST
}
copy_boot_data ()
{
local type="BOOT_${1}"
local source_dir='/'
local find_args='boot -name "kernel.old" -prune -o \! -name "*.symbols"'
__create_and_copy_dest $type $source_dir "$find_args"
}
copy_boot_1_data ()
{
copy_boot_data 1
}
copy_boot_2_data ()
{
copy_boot_data 2
}
setup_keyboard ()
{
local distribution="$1"
local dest_dir="$2"
if [ -z "$dest_dir" ]; then
error "You must precise the destination directory to setup the keyboard."
fi
if [ -z "$distribution" ]; then
distribution=freebsd
fi
case $distribution in
freebsd)
case $KEYBOARD in
dvorak)
echo 'keymap="us.dvorak"' >> "${dest_dir}/etc/rc.conf";;
esac
;;
linux)
:
;;
esac
}
mungle_mfs ()
{
:
}
mungle_dist ()
{
for i in destroygeom zfsinstall; do
if ! cat $SHARE_DIR/$i > $PART_DIST_DEST/$i; then
error "Could not copy file $i to $PART_DIST_DEST/$i"
fi
done
if ! echo '/dev/ufs/DIST / ufs ro,noatime 1 1' > $PART_DIST_DEST/etc/fstab; then
error "Could not update the fstab."
fi
setup_keyboard freebsd $PART_DIST_DEST
if ! pkg info > $PART_DIST_DEST/pkg.list; then
error "Could not save the list of installed package."
fi
if [ -z "${PACKAGES_DIR}" -o -z "${PART_DIST_DEST}" ]; then
error "Packages dir and part_dist_dest must be definied"
fi
if ! rsync -Wav "${PACKAGES_DIR}" "${PART_DIST_DEST}/"; then
error "Could not rsync from \"${PACKAGES_DIR}\" to \"${PART_DIST_DEST}/\""
fi
if [ "$WANT_PHORONIX_TEST_SUITE" != 'no' ]; then
{
cd $PART_DIST_DEST
fetch http://www.phoronix-test-suite.com/releases/phoronix-test-suite-${WANT_PHORONIX_TEST_SUITE}.tar.gz
}
fi
}
mungle_boot ()
{
eval eval local dest="\$\{PART_BOOT_${1}_DEST\}"
if ! pkg info > $dest/pkg.list; then
error "Could not save the list of installed package."
fi
}
mungle_linux ()
{
if ! cp $PART_LINUX_DEST/boot/grub/grub-*.cfg $PART_LINUX_DEST/boot/grub/grub.cfg; then
error "Could not find the grub configuration."
fi
}
clean_up ()
{
# force sync to wait for usb to fill up
sleep 2
sync
sleep 2
sync
for mnt in $MOUNT_POINTS; do
if ! umount $mnt; then
error "Could not umount $mnt"
fi
done
for md in $MDDEVICES; do
if ! mdconfig -d -u "${md#md}"; then
error "Could not detach device ${md}"
fi
done
}
__create ()
{
local type="$1"
if echo $type | grep -iqv boot; then
eval fetch_${type}_iso
eval eval PART_${type}_SIZE=`get_${type}_size`
fi
if [ -n "$ERASE_DISK" ]; then
erase_disk
create_disk_table
insert_bootcode
fi
create_partition `echo $type | tr '[a-z]' '[A-Z]'`
eval copy_${type}_data
eval mungle_${type}
clean_up
}
create_all ()
{
# fetch_mfs_iso
fetch_dist_iso
fetch_linux_iso
# PART_MFS_SIZE=`get_mfs_size`
PART_DIST_SIZE=`get_dist_size`
PART_LINUX_SIZE=`get_linux_size`
erase_disk
create_disk_table
insert_bootcode
create_partitions BOOT_1
create_partitions BOOT_2
# create_partitions MFS
create_partitions DIST
create_partitions LINUX
#
copy_boot_1_data
copy_boot_2_data
# copy_mfs_data
copy_dist_data
copy_linux_data
mungle_boot 1
mungle_boot 2
# mungle_mfs
mungle_dist
mungle_linux
#
clean_up
}
update ()
{
local dist="$1"
eval fetch_${dist}_iso
eval update_${dist}_data
eval mungle_${dist}
clean up
}
case $1 in
create)
create_all;;
update)
case "$UPDATE_WHAT" in
mfs|boot_1|boot_2|dist|linux)
:
;;
*)
error "When updating you must specify what : msf, boot_1, boot_2, dist, linux"
;;
esac
update $UPDATE_WHAT
;;
*)
error "Valid action are 'create', 'update'"
;;
esac
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment