#!/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/default/{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