aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/todo.rst3
-rwxr-xr-xshare/hydra/bootless412
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 <<EOF
-Bootless Install Script
-=======================
-
-This script installs a bootable copy of the bootless repository in a device
-partition. It will ask for a device partition, clone the repository in the
-partition and make the device bootable.
-
-Press any key to continue, or ^C to abort.
-EOF
-
- read tmp
-
- # Git repo consistency check
- ( cd ${BOOTLESS_DIR} && git status > /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` <action> [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 <params>"
+ exit 1
+elif ! which bootless > /dev/null; then
+ echo "error: bootless not available"
+ exit
fi
+
+# Dispatch
+bootless $ACTION $HYDRA_FOLDER $*