From f81738cf648d9d38b16b148891dfe5eeb351768c Mon Sep 17 00:00:00 2001 From: Silvio Rhatto Date: Sun, 3 Jul 2016 13:47:29 -0300 Subject: Migrate bootless upstream --- doc/todo.rst | 3 - share/hydra/bootless | 412 ++------------------------------------------------- 2 files changed, 14 insertions(+), 401 deletions(-) diff --git a/doc/todo.rst b/doc/todo.rst index bbe16f6..00ce1a6 100644 --- a/doc/todo.rst +++ b/doc/todo.rst @@ -16,6 +16,3 @@ TODO - $APP_BASE/share/{hydra,hydractl} - /usr/local/share/{hydra,hydractl} - {hydra,hydract}-action (like git plugins) -- bootless: - - per-device hash/verification. - - always copy grub.cfg. diff --git a/share/hydra/bootless b/share/hydra/bootless index 67f1b96..e06c1a3 100755 --- a/share/hydra/bootless +++ b/share/hydra/bootless @@ -18,405 +18,21 @@ source $APP_BASE/lib/hydra/functions || exit 1 hydra_config_load -# Set bootless folder -function hydra_bootless_folder { - # Check for a bootless repository - if [ -e "$HYDRA_FOLDER/bootless" ]; then - BOOTLESS_DIR="$HYDRA_FOLDER/bootless" - elif [ -e "$HYDRA_FOLDER/conf/bootless" ]; then - BOOTLESS_DIR="$HYDRA_FOLDER/conf/bootless" - else - echo "Please make a symlink $HYDRA_FOLDER/bootless pointing to your bootless repository." - exit 1 - fi -} +# Parameters +ACTION="$1" +shift -# Sync bootless folder -function hydra_bootless_rsync { - # Exclude git folder and follow git-annex symlinks - $sudo rsync -CLavz --exclude boot $1/ $2/ - - # Make sure there's a symlink to itself - ( cd $2 && ln -s . boot ) -} - -# Make a boot device -function hydra_bootless_make { - # Set folder - hydra_bootless_folder - - # Set sudo config - local sudo device rsync - if [ "`whoami`" != 'root' ]; then - sudo="sudo" - fi - - # Script description - cat < /dev/null ) - if [ $? -ne 0 ]; then - echo "Error: '${BOOTLESS_DIR}' is not a git repository." - exit 1 - fi - - if [ -z "$1" ]; then - echo -n "Target device: " - read device - else - usbdevice=$1 - device="${usbdevice}1" - fi - - if [ "$2" == "--rsync" ]; then - rsync="true" - fi - - # Issue a warning - hydra_bootless_warning ${device} - - if [ "$?" != "0" ]; then - echo "Aborting..." - exit 1 - fi - - hydra_bootless_device ${usbdevice} ${device} - - # Mount - tmpdir=`mktemp --tmpdir=/tmp -d` - $sudo mount ${device} ${tmpdir} - if [ $? != 0 ]; then - echo "Error: failed to mount \"${device}\" filesystem in \"${tmpdir}\" (errno: $?)." - exit 1 - fi - - # Copy data - if [ "$rsync" == "true" ]; then - hydra_bootless_rsync ${BOOTLESS_DIR} ${tmpdir}/boot - else - #$sudo git clone --depth=1 file:///${BOOTLESS_DIR} ${tmpdir}/boot - $sudo git clone file:///${BOOTLESS_DIR} ${tmpdir}/boot - if [ $? != 0 ]; then - echo "Error: failed to clone repository \"${BOOTLESS_DIR}\" in \"${tmpdir}\" (errno: $?)." - exit 1 - fi - - ( - cd ${tmpdir}/boot && $sudo git annex init && \ - $sudo git config annex.sshcaching false && \ - $sudo git annex untrust here && $sudo git annex sync && $sudo git annex get . - ) - - if [ $? != 0 ]; then - echo "Error: failed to get files into repository \"${BOOTLESS_DIR}\" in \"${tmpdir}\" (errno: $?)." - exit 1 - fi - fi - - # Grub legacy - #devicemap=`mktemp` - #grub-mkdevicemap --no-floppy --device-map=${devicemap} - #usbdevice=`echo ${device} | sed -e s/[0-9]\$//` - #grubroot=`grep "${usbdevice}" ${devicemap} | cut -f1` - #grubdevice=`echo ${grubroot} | sed -e s/\)/,0\)/` - #echo "root ${grubdevice} - #setup ${grubroot} - #quit" | grub --device-map=${devicemap} --batch - - # Grub 2 - $sudo grub-install --boot-directory=${tmpdir} --skip-fs-probe --force ${usbdevice} - if [ $? != 0 ]; then - echo "Error: grub-install failed (errno: $?)." - exit 1 - fi - - # TODO: consider an alternative scenario: - # https://www.gnu.org/software/grub/manual/html_node/Installing-GRUB-using-grub_002dinstall.html#Installing-GRUB-using-grub_002dinstall - #sudo losetup /dev/loop0 /dev/sdb1 - #sudo mount /dev/loop0 /media/usb/ - #sudo grub-install --boot-directory=/media/usb/ --allow-floppy --force /dev/loop0 - - # Finalize - #rm -f ${devicemap} - $sudo umount ${tmpdir} - $sudo rm -rf ${tmpdir} -} - -# Update a boot device -function hydra_bootless_update { - # Set folder - hydra_bootless_folder - - # Set sudo config - local sudo - if [ "`whoami`" != 'root' ]; then - sudo="sudo" - fi - - if [ -z "$1" ]; then - echo -n "Target device: " - read device - else - usbdevice=$1 - device="${usbdevice}1" - fi - - # Target device consistency check - if [ ! -b ${device} ]; then - echo "Error: device \"${device}\" not found." - exit 1 - elif [ ! -d "${tmpdir}/boot" ]; then - echo "Error: bootless repository not found at ${device}." - exit 1 - fi - - tmpdir=`mktemp --tmpdir=/tmp -d` - $sudo mount ${device} ${tmpdir} - if [ $? != 0 ]; then - echo "Error: failed to mount \"${device}\" filesystem in \"${tmpdir}\" (errno: $?)." - exit 1 - fi - - # Copy data - if [ -d "${tmpdir}/boot/.git" ]; then - #( cd ${tmpdir}/boot && $sudo git pull origin master ) - ( cd ${tmpdir}/boot && $sudo git annex sync && $sudo git annex get . ) - else - hydra_bootless_rsync ${BOOTLESS_DIR} ${tmpdir}/boot - fi - - # Finalize - $sudo umount ${tmpdir} - $sudo rm -rf ${tmpdir} -} - -# Repository initiator -function hydra_bootless_init { - mkdir -p $HYDRA_FOLDER - - if [ ! -z "$1" ]; then - # Clone from url - git clone $1 $HYDRA_FOLDER/bootless && - ( cd $HYDRA_FOLDER/bootless && git annex init && git config annex.sshcaching false && git annex sync ) - exit $? - fi - - # Create a fresh repository - mkdir -p $HYDRA_FOLDER/bootless/{default,custom,grub} - mkdir -p $HYDRA_FOLDER/bootless/custom/{debian,memtest} - touch $HYDRA_FOLDER/bootless/{default,custom,grub}/.empty - touch $HYDRA_FOLDER/bootless/default/{debian,memtest}/.empty - ( cd $HYDRA_FOLDER/bootless && ln -s . boot) - - if [ -f "/boot/memtest86+.bin" ]; then - cp /boot/memtest86+.bin $HYDRA_FOLDER/bootless/default/memtest - else - echo "No memtest image found. Please install memtest86+ package" - echo "and manually copy /boot/memtest86+.bin if you want memtest support" - fi - - # Grub configuration - cp $HYDRA_FOLDER/config/templates/bootless/grub.cfg $HYDRA_FOLDER/bootless/grub/ - cp $HYDRA_FOLDER/config/templates/bootless/custom.cfg $HYDRA_FOLDER/bootless/custom/ - - # Initialize git repository - ( - cd $HYDRA_FOLDER/bootless - git init - git annex init - git config annex.sshcaching false - git add boot - git add {default,custom,grub}/.empty - git add default/{debian,memtest,ubuntu}/.empty - git add grub/grub.cfg - git annex add . - git commit -a -m "Initial import" - ) - - echo "Now add your boot images and edit $HYDRA_FOLDER/bootless/grub/grub.cfg to suit your needs." -} - -# Git wrapper -function hydra_bootless_git { - # Set folder - hydra_bootless_folder - - ( - cd $BOOTLESS_DIR && git $* - ) -} - -# Create a target device -function hydra_bootless_device { - local device="$1" - local subdevice="$2" - - # Erase disk MBR - # http://askubuntu.com/questions/158299/why-does-installing-grub2-give-an-iso9660-filesystem-destruction-warning - #sudo dd if=/dev/zero of=/dev/${usbdevice} bs=512 seek=1 count=2047 - - # Check if device is mounted - if [ "`mount | grep ${subdevice}`" != "" ]; then - echo "Error: device \"${subdevice}\" is mounted." - exit 1 - fi - - # Target device consistency check - if [ ! -b ${subdevice} ]; then - echo "Error: device \"${subdevice}\" not found." - exit 1 - fi - - # Remove old partitions - for partition in `$sudo parted -s -- ${device} print | awk '/^ / {print $1}'`; do - $sudo parted -s -- ${device} rm $partition - done - - # Create a single partition - $sudo parted -s -- ${device} mkpart primary ext2 2 -1 - $sudo parted -s -- ${device} set 1 boot on - - # Create filesystem - $sudo mke2fs ${subdevice} - if [ $? != 0 ]; then - echo "Error: mke2fs failed in \"${subdevice}\" (errno: $?)." - exit 1 - fi - - # Tune - $sudo tune2fs -c 0 -i 0 ${subdevice} - if [ $? != 0 ]; then - echo "Error: tune2fs failed in \"${subdevice}\" (errno: $?)." - exit 1 - fi -} - -function hydra_bootless_warning { - local device=$1 - local go - - echo "******************" - echo "* ATTENTION!!! *" - echo "******************" - echo "" - echo "If you continue, all data in device \"${device}\" will be destroyed!" - echo "" - echo -n "Are you sure you want to continue? Type uppercase \"YES\": " - read go - - if [ "${go}" != "YES" ]; then - false - else - true - fi -} - -# Generate a bootless disk image -function hydra_bootless_image { - local output="$1" - local device="$2" - - # Fix parameters - if echo ${output} | grep -q "/dev/"; then - output="bootless.img" - device="$1" - elif [ -z "$output" ]; then - output="bootless.img" - fi - - # Set folder - hydra_bootless_folder - - # Set sudo config - local sudo - if [ "`whoami`" != 'root' ]; then - sudo="sudo" - fi - - # Copy data - tmpdir=`mktemp --tmpdir=/tmp -d` - hydra_bootless_rsync ${BOOTLESS_DIR} ${tmpdir}/boot - - # Make rescue disk - grub-mkrescue -o ${output} ${tmpdir} - - # Optionally copy to removable media - if [ ! -z "$device" ]; then - # Issue a warning - hydra_bootless_warning ${device} - - if [ "$?" != "0" ]; then - echo "Skipping copy of ${output} to ${device}..." - else - # Check if device is mounted - if [ "`mount | grep ${device}`" != "" ]; then - echo "Error: device \"${device}\" is mounted." - echo "Skipping copy of ${output} to ${device}..." - else - $sudo dd if=${output} of=${device} - fi - fi - - fi - - # Cleanup - rm -rf ${tmpdir} - - # Finish - if [ -z "$device" ]; then - echo "Image saved at ${output}" - else - echo "Removing image ${output}..." - rm ${output} - fi - - echo "Done." -} - -# Usage -function hydra_bootless_usage { - echo "Usage: `basename $0` [arguments]" - exit 1 -} - -# Check for requirements -for req in parted git-annex; do - hydra_install_package $req -done - -# Parameter verification -if [ -z "$1" ]; then - hydra_bootless_usage -elif [ -z "$HYDRA_FOLDER" ]; then +# Check. +if [ -z "$HYDRA_FOLDER" ]; then echo "Parameter HYDRA_FOLDER not configured." exit 1 -elif [ "$1" == "make" ]; then - shift - hydra_bootless_make $* -elif [ "$1" == "init" ]; then - shift - hydra_bootless_init $* -elif [ "$1" == "update" ]; then - shift - hydra_bootless_update $* -elif [ "$1" == "git" ]; then - shift - hydra_bootless_git $* -elif [ "$1" == "image" ]; then - shift - hydra_bootless_image $* -else - hydra_bootless_usage +elif [ -z "$ACTION" ]; then + echo "usage: hydra $HYDRA bootless " + exit 1 +elif ! which bootless > /dev/null; then + echo "error: bootless not available" + exit fi + +# Dispatch +bootless $ACTION $HYDRA_FOLDER $* -- cgit v1.2.3