Release new version 0.6.1
[grml-rescueboot.git] / update-grml-rescueboot
1 #!/bin/bash
2 # Simple script to download a Grml ISO image to use with grml-rescueboot
3 # Needs the Debian keyring, gpgv + wget
4 # Licensed under GPL v2+
5
6 set -eu -o pipefail
7
8 # defaults
9 isotype=full
10 bitwidth=auto
11 force=0
12 retrieved_iso=0
13
14 declare -A bin_to_pkg=( [update-grub]=grub-pc [wget]=wget [gpgv]=gpgv )
15 declare -a missing_packages=()
16 for binary in "${!bin_to_pkg[@]}" ; do
17   if ! which "${binary}" &>/dev/null ; then
18     echo "ERROR: Binary $binary not found." >&2
19     missing_packages+=( ${bin_to_pkg[$binary]} )
20   fi
21 done
22
23 if ! [ -r /usr/share/keyrings/debian-keyring.gpg ] ; then
24   echo "ERROR: File /usr/share/keyrings/debian-keyring.gpg not found." >&2
25   missing_packages+=( debian-keyring )
26 fi
27
28 if [ ${#missing_packages[@]} -ne 0 ] ; then
29   echo "TIP: Try running \`apt install ${missing_packages[*]}\` to fix this." >&2
30   exit 1
31 fi
32
33 usage() {
34   echo "Usage: $(basename "$0") [-f] [-a <32|64|96>] [-t <small|full>]"
35 }
36
37 while getopts ":a::t::f:h" opt ; do
38   case ${opt} in
39     a)
40       if [ "${OPTARG}" = 32 ] || [ "${OPTARG}" = 64 ] || [ "${OPTARG}" = 96 ] ; then
41         bitwidth="$OPTARG"
42       else
43         echo "ERROR: Invalid value '${OPTARG}'. Supported values: 32, 64, 96" >&2
44         usage >&2 ; exit 1
45       fi
46       ;;
47     t)
48       if [ "${OPTARG}" = "full" ] || [ "${OPTARG}" = "small" ] ; then
49         isotype="${OPTARG}"
50       else
51         echo "ERROR: Invalid value '${OPTARG}'. Supported values: small, full" >&2
52         usage >&2 ; exit 1
53       fi
54       ;;
55     f)
56       force=1
57       ;;
58     h)
59       usage ; exit 0
60       ;;
61     \?)
62       echo "ERROR: Invalid Option: -${OPTARG}" >&2
63       usage >&2 ; exit 1
64       ;;
65     :)
66       echo "ERROR: Option -${OPTARG} requires an argument." >&2
67       ;;
68   esac
69 done
70
71 if [ "${bitwidth}" = auto ] ; then
72   arch="$(uname -m)"
73   case ${arch} in
74     i?86)
75       bitwidth=32
76       ;;
77     x86_64)
78       bitwidth=64
79       ;;
80     *)
81       echo "ERROR: Unknown architecture '${arch}', please specify -a flag." >&2
82       usage >&2
83       exit 1
84       ;;
85   esac
86 fi
87
88 echo "Finding out latest ISO image..."
89 date=$(wget --quiet -O- http://download.grml.org/ | sed --regex -n 's/.*grml[0-9]{2}-(full|small)_([0-9]{4}\.[0-9]{2})\.iso.*/\2/p' | sort | tail -1)
90
91 if [ -z "${date}" ] ; then
92   echo "ERROR: Could not find out latest ISO." >&2
93   exit 1
94 fi
95
96 output_directory="/boot/grml"
97 mkdir -p "${output_directory}"
98
99 diskfree=$(df --output=avail /boot/grml | tail -1)
100 if [ -z "${diskfree}" ] ; then
101   echo "ERROR: couldn't calculate free disk space in /boot." >&2
102   exit 1
103 fi
104
105 if [ "${isotype}" = "full" ] && [ "${diskfree}" -lt 1048576 ] ; then
106   if [ "${force}" = "1" ] ; then
107     echo "WARN: There might not be enough free disk space in /boot, continuing anyway as requested via -f."
108   else
109     echo "ERROR: there doesn't seem to be enough free disk space in /boot." >&2
110     echo "Note: >=1GB for grml-full recommended (use -f to force download anyway)."
111     exit 1
112   fi
113 elif [ "${isotype}" = "small" ] && [ "${diskfree}" -lt 524288 ] ; then
114   if [ "${force}" = "1" ] ; then
115     echo "WARN: There might not be enough free disk space in /boot, continuing anyway as requested via -f."
116   else
117     echo "ERROR: there doesn't seem to be enough free disk space in /boot." >&2
118     echo "Note: >=512MB for grml-small recommended (use -f to force download anyway)."
119     exit 1
120   fi
121 fi
122
123 isoname="grml${bitwidth}-${isotype}_${date}.iso"
124
125 if [ "${force}" = "1" ] || ! [ -f "${output_directory}/${isoname}" ] ; then
126   echo "Downloading Grml ISO to '${output_directory}/${isoname}'."
127   wget -O "${output_directory}/${isoname}" "http://download.grml.org/${isoname}"
128   retrieved_iso=1
129 elif [ -f "${output_directory}/${isoname}" ] ; then
130   echo "Found local ${output_directory}/${isoname}, skipping download (use -f to force download)."
131 fi
132
133 if [ "${retrieved_iso}" = "1" ] ; then
134   sig="$(mktemp)"
135   echo "Verifying ISO..."
136   wget --quiet -O "${sig}" "http://download.grml.org/${isoname}.asc"
137
138   if ! gpgv --keyring /usr/share/keyrings/debian-keyring.gpg "${sig}" "${output_directory}/${isoname}" ; then
139     echo "ERROR: ISO file will be left in '${output_directory}/${isoname}.untrusted'." >&2
140     mv "${output_directory}/${isoname}" "${output_directory}/${isoname}.untrusted"
141     rm "${sig}"
142     exit 1
143   fi
144
145   rm "${sig}"
146
147   echo "ISO file is OK."
148 fi
149
150 echo "Invoking 'update-grub' now."
151 update-grub
152
153 echo "Sucessfully finished grml-rescueboot integration."