diff options
author | P. J. McDermott <pj@pehjota.net> | 2014-12-05 18:56:18 (EST) |
---|---|---|
committer | P. J. McDermott <pj@pehjota.net> | 2014-12-05 18:56:18 (EST) |
commit | 7cd5e68c665836da8a62c8684b1471eea8e90d8f (patch) | |
tree | b3ebf0b2a820fe28cf83004ca73fa2ef7a00bd14 |
Initial commit
-rw-r--r-- | debeagle.sh | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/debeagle.sh b/debeagle.sh new file mode 100644 index 0000000..dad40db --- /dev/null +++ b/debeagle.sh @@ -0,0 +1,202 @@ +#!/bin/sh +# +# debeagle - Install Debian on a Beagle SBC +# +# Copyright (C) 2014 Patrick "P. J." McDermott +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +set -u + +main() +{ + local opt= + local mirror= + local suite= + local target= + + while getopts 'm:' opt; do + case ${opt} in + m) mirror="${OPTARG}";; + ?) + print_usage >&2 + exit 1 + ;; + esac + done + shift $(($OPTIND - 1)) + + case ${#} in + 1) + suite="${1}" + target='' + ;; + 2) + suite="${1}" + target="${2}" + ;; + *) + print_usage >&2 + exit 1 + ;; + esac + + if [ "x${target}" = 'x' ]; then + target="/dev/$(prompt_block_dev)" + elif [ -e "/sys/block/${target#/dev/}" ]; then + printf 'Installing to %s\n' \ + "$(get_block_dev_name "${target#/dev/}")" + else + printf 'Device %s not found\n' "${target}" >&2 + exit 1 + fi +} + +print_usage() +{ + printf 'Usage: %s [-m <mirror>] <suite> [<target>]\n' "${0}" +} + +error() +{ + local status=${1} + local fmt="${2}" + shift 2 + + printf "Error: ${fmt}\n" "${@}" >&2 + + exit ${status} +} + +_select() +{ + # Field width of the prompt numbers. + select_width=$(expr ${#} : '.*') + + select_i= + + while :; do + case "${select_i}" in + '') + select_i=0 + for select_word in "${@}"; do + select_i=$(expr ${select_i} + 1) + printf "%${select_width}d) %s\\n" \ + ${select_i} "${select_word}" \ + >&2 + done + ;; + *[!0-9]*) + printf 'Please enter a number in range.\n' >&2 + ;; + *) + if [ ${select_i} -gt 0 ] && \ + [ ${select_i} -le ${#} ]; then + shift $(expr $select_i - 1) + select_result="${1}" + break + fi + printf 'Please enter a number in range.\n' >&2 + ;; + esac + + # Prompt and read input. + printf '%s' "${PS3-#? }" >&2 + read -r select_i || exit + done +} + +pretty_print_size_dec() +{ + local size="${1}" + + awk -v size=${size} 'BEGIN { + split("B KB MB GB TB", units, " "); + i=1; + while (size >= 1000) { + size /= 1000; + ++i; + }; + printf("%.2f %s\n", size, units[i]); }' +} + +pretty_print_size_bin() +{ + local size="${1}" + + awk -v size=${size} 'BEGIN { + split("B KiB MiB GiB TiB", units, " "); + i=1; + while (size >= 1024) { + size /= 1024; + ++i; + }; + printf("%.2f %s\n", size, units[i]); }' +} + +get_block_dev_name() +{ + local dev="${1}" + local vendor= + local model= + + if [ -e "/sys/block/${dev}/device/vendor" ]; then + vendor="$(cat "/sys/block/${dev}/device/vendor")" + model="$(cat "/sys/block/${dev}/device/model")" + name="${vendor} ${model}" + else + name="$(cat "/sys/block/${dev}/device/name")" + fi + + printf '%s' "${name}" +} + +prompt_block_dev() +{ + local dev= + local name= + local size= + local size_s= + local desc= + local devs= + + set -- + for dev in /sys/block/*; do + dev="${dev#/sys/block/}" + case "${dev}" in + loop*|sr*) continue;; + esac + name="$(get_block_dev_name "${dev}")" + size="$(cat "/sys/block/${dev}/size")" + size="$(expr ${size} \* 512)" + size_s="$(pretty_print_size_dec "${size}")" + size_s="${size_s} ($(pretty_print_size_bin "${size}"))" + desc="$(printf '%s (%s) - %s\n' "${name}" "${dev}" "${size_s}")" + set -- "${@}" "${desc}" + devs="$(printf '%s\n%s\t%s\n' "${devs}" "${desc}" "${dev}")" + done + + printf 'Select a block device:\n' >&2 + _select "${@}" + + while IFS=' ' read -r desc dev; do + if [ "x${desc}" = "x${select_result}" ]; then + printf '%s\n' "${dev}" + fi + done <<-EOF + ${devs} + EOF +} + +main "${@}" |