#!/bin/bash # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public # License along with this program. If not, see # . # Loader function bootless_load { local dest local base # Determine if we are in a local or system-wide install. if [ -h "$0" ]; then dest="$(readlink $0)" # Check again as the caller might be a symlink as well if [ -h "$dest" ]; then base="`dirname $dest`" dest="$(dirname $(readlink $dest))" else base="`dirname $0`" dest="`dirname $dest`" fi # Deal with relative or absolute links if [ "`basename $dest`" == "$dest" ]; then export APP_BASE="$base" else export APP_BASE="$dest" fi else export APP_BASE="`dirname $0`" fi } # Usage function bootless_usage { echo "Usage: `basename $0` [arguments]" exit 1 } # Sync bootless folder function bootless_rsync { # Exclude git folder and follow git-annex symlinks rsync -CLavz --exclude boot $1/ $2/ # Make sure there's a symlink to itself ( cd $2 && ln -s . boot ) } # Repository initiator function bootless_init { if [ -e "$BOOTLESS_DIR" ]; then echo "folder $BOOTLESS_DIR already exists" exit 1 fi if [ ! -z "$1" ]; then # Clone from url git clone $1 $BOOTLESS_DIR # Support for git-annex #( cd $BOOTLESS_DIR && git annex init && git config annex.sshcaching false && git annex sync ) exit $? fi # Create a fresh repository mkdir -p $BOOTLESS_DIR/{default,custom,grub} mkdir -p $BOOTLESS_DIR/custom/{debian,memtest} touch $BOOTLESS_DIR/{default,custom,grub}/.empty touch $BOOTLESS_DIR/default/{debian,memtest}/.empty ( cd $BOOTLESS_DIR && ln -s . boot) if [ -f "/boot/memtest86+.bin" ]; then cp /boot/memtest86+.bin $BOOTLESS_DIR/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 $APP_BASE/templates/grub.cfg $BOOTLESS_DIR/grub/ cp $APP_BASE/templates/custom.cfg $BOOTLESS_DIR/custom/ # Initialize git repository #( #cd $BOOTLESS_DIR #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/or edit $BOOTLESS_DIR/custom/custom.cfg to suit your needs." } function 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 bootless_image { local output="$1" local device="$2" if [ ! -d "$BOOTLESS_DIR" ]; then echo "missing $BOOTLESS_DIR folder, please initialize first" exit 1 fi # Fix parameters if echo ${output} | grep -q "/dev/"; then output="bootless.iso" device="$1" elif [ -z "$output" ]; then output="bootless.iso" fi # Set sudo config local sudo if [ "`whoami`" != 'root' ]; then sudo="sudo" fi # Copy data tmpdir=`mktemp --tmpdir=/tmp -d` 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 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 "Checking for changes in upstream grub.cfg, in which case you might want to update it..." diff -Naur $APP_BASE/templates/grub.cfg $BOOTLESS_DIR/grub/grub.cfg echo "Done." } # Check image/device integrity function bootless_check { echo "Not implemented yet :(" exit 1 } # Load bootless_load $* # Config NAME="bootless" BOOTLESS_VERSION="0.0.1" BOOTLESS_ACTION="$1" BOOTLESS_DIR="$2" # Output name and version echo "$NAME $BOOTLESS_VERSION" # Parameter verification if [ -z "$BOOTLESS_DIR" ]; then bootless_usage elif [ "$BOOTLESS_ACTION" == "init" ]; then shift 2 bootless_init $* elif [ "$BOOTLESS_ACTION" == "image" ]; then shift 2 bootless_image $* elif [ "$BOOTLESS_ACTION" == "check" ]; then shift 2 bootless_check $* else bootless_usage fi