diff --git a/.gitignore b/.gitignore index 3cff429..2e451e2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ *~ #Images this tool downloads -images/* +images/*/*/cache diff --git a/README.md b/README.md index 083fc00..3df98fe 100644 --- a/README.md +++ b/README.md @@ -5,50 +5,50 @@ It has the added benefit as it also gives users a verbose output showing for exa ## Install -Instillation is easy: +Installation is easy: - # Clone this repo - git clone https://github.com/moebrowne/RPi-Image-Manager - - # Change directory - cd RPi-Image-Manager - - # Set the image manager as executable - chmod u+x manager.sh +```bash +# Clone this repo +git clone https://github.com/moebrowne/RPi-Image-Manager -## Usage - -This tool takes 2 parameters like so: - - # Execute! - ./manager.sh {IMAGE_NAME} {DEVICE_PATH} +# Change directory +cd RPi-Image-Manager +``` -Where `{IMAGE_NAME}` is one of the images listed below and `{DEVICE_PATH}` is the path to the block device you wish to write the image to - -## Parameters +## Usage -There is a single parameter the tool can take: +This tool is completely interactive so just needs executing: - -l or --list-images List out all the images +```bash +# Execute! +./manager.sh +``` -## Supported Images +## Images -The following images can be installed just by using their names: +You can either write a file from your local disk or download one of the inbuilt ones: -- Raspbian +- Raspbian Jessie +- Raspbian Jessie Lite +- Minbian - Ubuntu Snappy -- OPENELEC +- OpenELEC +- LibreELEC - OSMC - Pidora - RISC OS -- Retro Pi (For RPi 1 & 2) +- MATE +- Weather Station +- RetroPie ## Dependencies There is only a single package required which is non-standard; pv. It's easily installed whatever Distro you're using: - # Ubuntu / Debian - apt-get install pv - - # RHEL / CentOS - yum install pv +``` +# Ubuntu / Debian +apt-get install pv + +# RHEL / CentOS +yum install pv +``` diff --git a/images/LibreELEC/7.0.2/URL b/images/LibreELEC/7.0.2/URL new file mode 100644 index 0000000..4ca866d --- /dev/null +++ b/images/LibreELEC/7.0.2/URL @@ -0,0 +1 @@ +http://releases.libreelec.tv/LibreELEC-RPi.arm-7.0.2.img.gz diff --git a/images/LibreELEC/7.0.2/hash b/images/LibreELEC/7.0.2/hash new file mode 100644 index 0000000..3de64de --- /dev/null +++ b/images/LibreELEC/7.0.2/hash @@ -0,0 +1 @@ +06f15c73029ee676007234ddf4409a6dec8ae9fb diff --git a/images/MATE/16.04.2/URL b/images/MATE/16.04.2/URL new file mode 100644 index 0000000..014cd31 --- /dev/null +++ b/images/MATE/16.04.2/URL @@ -0,0 +1 @@ +https://ubuntu-mate.org/raspberry-pi/ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz diff --git a/images/Minbian/2016-03-12/URL b/images/Minbian/2016-03-12/URL new file mode 100644 index 0000000..81854d7 --- /dev/null +++ b/images/Minbian/2016-03-12/URL @@ -0,0 +1 @@ +http://downloads.sourceforge.net/project/minibian/2016-03-12-jessie-minibian.tar.gz diff --git a/images/Minbian/2016-03-12/hash b/images/Minbian/2016-03-12/hash new file mode 100644 index 0000000..86493d6 --- /dev/null +++ b/images/Minbian/2016-03-12/hash @@ -0,0 +1 @@ +43558a173420108408bb8c1c6731ed5812c06971 diff --git a/images/OSMC/20160621/URL b/images/OSMC/20160621/URL new file mode 100644 index 0000000..b0a7258 --- /dev/null +++ b/images/OSMC/20160621/URL @@ -0,0 +1 @@ +http://download.osmc.tv/installers/diskimages/OSMC_TGT_rbp2_20160621.img.gz diff --git a/images/OSMC/20160621/hash b/images/OSMC/20160621/hash new file mode 100644 index 0000000..0bb1653 --- /dev/null +++ b/images/OSMC/20160621/hash @@ -0,0 +1 @@ +e1c40d35e723c9815e4058b44a079921a874e71f diff --git a/images/OpenELEC/6.0.3/URL b/images/OpenELEC/6.0.3/URL new file mode 100644 index 0000000..121c913 --- /dev/null +++ b/images/OpenELEC/6.0.3/URL @@ -0,0 +1 @@ +http://releases.openelec.tv/OpenELEC-RPi2.arm-6.0.3.img.gz diff --git a/images/OpenELEC/6.0.3/hash b/images/OpenELEC/6.0.3/hash new file mode 100644 index 0000000..dd5436c --- /dev/null +++ b/images/OpenELEC/6.0.3/hash @@ -0,0 +1 @@ +31082d36c369f49a6223776f776db967b6c48a48 diff --git a/images/Pidora/2014-R3/URL b/images/Pidora/2014-R3/URL new file mode 100644 index 0000000..25a2cb7 --- /dev/null +++ b/images/Pidora/2014-R3/URL @@ -0,0 +1 @@ +http://pidora.ca/pidora/releases/20/images/Pidora-2014-R3.zip diff --git a/images/Pidora/2014-R3/hash b/images/Pidora/2014-R3/hash new file mode 100644 index 0000000..5c0acb1 --- /dev/null +++ b/images/Pidora/2014-R3/hash @@ -0,0 +1 @@ +00f85ca01a6555d4b0843054090c222239898b7c diff --git a/images/RISC OS/2017-04-20/URL b/images/RISC OS/2017-04-20/URL new file mode 100644 index 0000000..cf0eb9a --- /dev/null +++ b/images/RISC OS/2017-04-20/URL @@ -0,0 +1 @@ +https://www.riscosopen.org/zipfiles/platform/raspberry-pi/riscos-2017-04-13.15.zip \ No newline at end of file diff --git a/images/Raspbian Jessie Lite/2017-02-16/URL b/images/Raspbian Jessie Lite/2017-02-16/URL new file mode 100644 index 0000000..9afe8d4 --- /dev/null +++ b/images/Raspbian Jessie Lite/2017-02-16/URL @@ -0,0 +1 @@ +https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-02-27/2017-02-16-raspbian-jessie-lite.zip \ No newline at end of file diff --git a/images/Raspbian Jessie Lite/2017-02-16/hash b/images/Raspbian Jessie Lite/2017-02-16/hash new file mode 100644 index 0000000..b7cd189 --- /dev/null +++ b/images/Raspbian Jessie Lite/2017-02-16/hash @@ -0,0 +1 @@ +5fbae9e1f941648d1011d0d8b98db011f3ab3a4f \ No newline at end of file diff --git a/images/Raspbian Jessie Lite/2017-03-02/URL b/images/Raspbian Jessie Lite/2017-03-02/URL new file mode 100644 index 0000000..e67aa59 --- /dev/null +++ b/images/Raspbian Jessie Lite/2017-03-02/URL @@ -0,0 +1 @@ +https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-03-03/2017-03-02-raspbian-jessie-lite.zip \ No newline at end of file diff --git a/images/Raspbian Jessie Lite/2017-03-02/hash b/images/Raspbian Jessie Lite/2017-03-02/hash new file mode 100644 index 0000000..8dfcb37 --- /dev/null +++ b/images/Raspbian Jessie Lite/2017-03-02/hash @@ -0,0 +1 @@ +1778584c419208d919ca85e92a5cae16d1676090 \ No newline at end of file diff --git a/images/Raspbian Jessie Lite/2017-04-10/URL b/images/Raspbian Jessie Lite/2017-04-10/URL new file mode 100644 index 0000000..e7449ba --- /dev/null +++ b/images/Raspbian Jessie Lite/2017-04-10/URL @@ -0,0 +1 @@ +https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-04-10/2017-04-10-raspbian-jessie-lite.zip \ No newline at end of file diff --git a/images/Raspbian Jessie Lite/2017-04-10/hash b/images/Raspbian Jessie Lite/2017-04-10/hash new file mode 100644 index 0000000..7b47db4 --- /dev/null +++ b/images/Raspbian Jessie Lite/2017-04-10/hash @@ -0,0 +1 @@ +c24a4c7dd1a5957f303193fee712d0d2c0c6372d \ No newline at end of file diff --git a/images/Raspbian Jessie/2017-02-16/URL b/images/Raspbian Jessie/2017-02-16/URL new file mode 100644 index 0000000..bd71c66 --- /dev/null +++ b/images/Raspbian Jessie/2017-02-16/URL @@ -0,0 +1 @@ +https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-02-27/2017-02-16-raspbian-jessie.zip \ No newline at end of file diff --git a/images/Raspbian Jessie/2017-02-16/hash b/images/Raspbian Jessie/2017-02-16/hash new file mode 100644 index 0000000..ef9035a --- /dev/null +++ b/images/Raspbian Jessie/2017-02-16/hash @@ -0,0 +1 @@ +e4968fe20b87da50377ccabbe95d0c07a0b9cb41 \ No newline at end of file diff --git a/images/Raspbian Jessie/2017-03-02/URL b/images/Raspbian Jessie/2017-03-02/URL new file mode 100644 index 0000000..9ca516d --- /dev/null +++ b/images/Raspbian Jessie/2017-03-02/URL @@ -0,0 +1 @@ +https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-03-03/2017-03-02-raspbian-jessie.zip \ No newline at end of file diff --git a/images/Raspbian Jessie/2017-03-02/hash b/images/Raspbian Jessie/2017-03-02/hash new file mode 100644 index 0000000..bcdcb81 --- /dev/null +++ b/images/Raspbian Jessie/2017-03-02/hash @@ -0,0 +1 @@ +b4c0dedd56c2cfb7913322cadb9ba81e19b6daee \ No newline at end of file diff --git a/images/Raspbian Jessie/2017-04-10/URL b/images/Raspbian Jessie/2017-04-10/URL new file mode 100644 index 0000000..3288d54 --- /dev/null +++ b/images/Raspbian Jessie/2017-04-10/URL @@ -0,0 +1 @@ +https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-04-10/2017-04-10-raspbian-jessie.zip \ No newline at end of file diff --git a/images/Raspbian Jessie/2017-04-10/hash b/images/Raspbian Jessie/2017-04-10/hash new file mode 100644 index 0000000..d287f38 --- /dev/null +++ b/images/Raspbian Jessie/2017-04-10/hash @@ -0,0 +1 @@ +6d7b11bb3d64524203edf6c80c499456fb5fef53 \ No newline at end of file diff --git a/images/RetroPie/4.2/URL b/images/RetroPie/4.2/URL new file mode 100644 index 0000000..a96f6c6 --- /dev/null +++ b/images/RetroPie/4.2/URL @@ -0,0 +1 @@ +https://github.com/RetroPie/RetroPie-Setup/releases/download/4.2/retropie-4.2-rpi2_rpi3.img.gz \ No newline at end of file diff --git a/images/Snappy/15.04/URL b/images/Snappy/15.04/URL new file mode 100644 index 0000000..3524534 --- /dev/null +++ b/images/Snappy/15.04/URL @@ -0,0 +1 @@ +http://cdimage.ubuntu.com/ubuntu-snappy/15.04/stable/latest/ubuntu-15.04-snappy-armhf-raspi2.img.xz diff --git a/images/Snappy/15.04/hash b/images/Snappy/15.04/hash new file mode 100644 index 0000000..b1a60c7 --- /dev/null +++ b/images/Snappy/15.04/hash @@ -0,0 +1 @@ +2d32d93e0086593fe34b8c07d4af7227c79addd3 diff --git a/images/Snappy/16/URL b/images/Snappy/16/URL new file mode 100644 index 0000000..8a86512 --- /dev/null +++ b/images/Snappy/16/URL @@ -0,0 +1 @@ +http://cdimage.ubuntu.com/ubuntu-core/16/stable/current/ubuntu-core-16-pi3.img.xz \ No newline at end of file diff --git a/images/Snappy/16/hash b/images/Snappy/16/hash new file mode 100644 index 0000000..629191a --- /dev/null +++ b/images/Snappy/16/hash @@ -0,0 +1 @@ +940657a1798f0e4dfab5852c8a253f82edee2477 \ No newline at end of file diff --git a/images/Weather Station/2016-03-24/URL b/images/Weather Station/2016-03-24/URL new file mode 100644 index 0000000..4cab83f --- /dev/null +++ b/images/Weather Station/2016-03-24/URL @@ -0,0 +1 @@ +https://downloads.raspberrypi.org/weather_station/images/weather_station-2016-03-24/WeatherStation.zip diff --git a/images/Weather Station/2016-03-24/hash b/images/Weather Station/2016-03-24/hash new file mode 100644 index 0000000..514a115 --- /dev/null +++ b/images/Weather Station/2016-03-24/hash @@ -0,0 +1 @@ +9eed5f9f5366faa1f2757c0e7ca81107a81ce249 diff --git a/manager.sh b/manager.sh index f3fd771..3a69b33 100755 --- a/manager.sh +++ b/manager.sh @@ -1,8 +1,4 @@ -#!/bin/bash - -echo "-----------------------------------------" -echo " Raspberry Pi Image Manager (RIM) v0.3.6 " -echo "-----------------------------------------" +#!/usr/bin/env bash # Get the source directory DIR="${BASH_SOURCE%/*}" @@ -14,76 +10,13 @@ LIBRARY_PATH_ROOT="$DIR/utils" # Include the generic libraries . "$LIBRARY_PATH_ROOT/generic.sh" . "$LIBRARY_PATH_ROOT/colours.sh" - -# Set default options -IMAGE_LIST=false - -# Get any params defined -for i in "$@" -do -case $i in - -l|--list-images) IMAGE_LIST=true ;; - -*) echo "UNKNOWN PARAMETER ${i#*=}"; exit ;; -esac -done - -declare -A Images - -Images['Raspbian-Whezzy']="https://downloads.raspberrypi.org/raspbian/images/raspbian-2015-05-07/2015-05-05-raspbian-wheezy.zip" -Images['Raspbian-Jessie']="https://downloads.raspberrypi.org/raspbian/images/raspbian-2016-05-31/2016-05-27-raspbian-jessie.zip" -Images['Raspbian-Jessie-Lite']="https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2016-05-31/2016-05-27-raspbian-jessie-lite.zip" -Images['Minbian']="http://downloads.sourceforge.net/project/minibian/2016-03-12-jessie-minibian.tar.gz" -Images['Snappy']="http://cdimage.ubuntu.com/ubuntu-snappy/15.04/stable/latest/ubuntu-15.04-snappy-armhf-raspi2.img.xz" -Images['OpenELEC']="http://releases.openelec.tv/OpenELEC-RPi.arm-6.0.3.img.gz" -Images['OpenELECPi2']="http://releases.openelec.tv/OpenELEC-RPi2.arm-6.0.3.img.gz" -Images['LibreELEC']="http://releases.libreelec.tv/LibreELEC-RPi.arm-7.0.2.img.gz" -Images['LibreELECPi2']="http://releases.libreelec.tv/LibreELEC-RPi.arm-7.0.2.img.gz" -Images['OSMC']="http://download.osmc.tv/installers/diskimages/OSMC_TGT_rbp1_20160621.img.gz" -Images['OSMCPi2']="http://download.osmc.tv/installers/diskimages/OSMC_TGT_rbp2_20160621.img.gz" -Images['Pidora']="http://pidora.ca/pidora/releases/20/images/Pidora-2014-R3.zip" -Images['RISCOS']="https://www.riscosopen.org/zipfiles/platform/raspberry-pi/riscos-2015-02-17.14.zip" -Images['RetroPi']="https://github.com/RetroPie/RetroPie-Setup/releases/download/3.6/retropie-v3.6-rpi1_zero.img.gz" -Images['RetroPi2']="https://github.com/RetroPie/RetroPie-Setup/releases/download/3.6/retropie-v3.6-rpi2_rpi3.img.gz" -Images['MATE']="https://ubuntu-mate.r.worldssl.net/raspberry-pi/ubuntu-mate-15.10.3-desktop-armhf-raspberry-pi-2.img.xz" -Images['Weather-Station']="https://downloads.raspberrypi.org/weather_station/images/weather_station-2016-03-24/WeatherStation.zip" - - -declare -A ImagesSHA1 - -ImagesSHA1['Raspbian-Whezzy']="cb799af077930ff7cbcfaa251b4c6e25b11483de" -ImagesSHA1['Raspbian-Jessie']="64c7ed611929ea5178fbb69b5a5f29cc9cc7c157" -ImagesSHA1['Raspbian-Jessie-Lite']="03b6ea33efc3bb4d475f528421d554fc1ef91944" -ImagesSHA1['Minbian']="43558a173420108408bb8c1c6731ed5812c06971" -ImagesSHA1['Snappy']="2d32d93e0086593fe34b8c07d4af7227c79addd3" -ImagesSHA1['OpenELEC']="4dbcabd10d92f046c090f8fb68c0b5edcc78cd60" -ImagesSHA1['OpenELECPi2']="31082d36c369f49a6223776f776db967b6c48a48" -ImagesSHA1['LibreELEC']="aab1e74c764bd9321ecba19f27411edd3a0e841b" -ImagesSHA1['LibreELECPi2']="06f15c73029ee676007234ddf4409a6dec8ae9fb" -ImagesSHA1['OSMC']="6e22abb05d7713d5b078ddfa3823293ee28d610f" -ImagesSHA1['OSMCPi2']="e1c40d35e723c9815e4058b44a079921a874e71f" -ImagesSHA1['Pidora']="00f85ca01a6555d4b0843054090c222239898b7c" -ImagesSHA1['RISCOS']="9c28ce57a23692cd70e90cfe9fa24e2014501a05" -#ImagesSHA1['RetroPi']="" -#ImagesSHA1['RetroPi2']="" -ImagesSHA1['MATE']="58565911bef09d95734b2e971833452a50f536a4" -ImagesSHA1['Weather-Station']="9eed5f9f5366faa1f2757c0e7ca81107a81ce249" - -# If the list flag has been raised, list the images -if [ $IMAGE_LIST = true ]; then - echo "Images:" - for i in "${!Images[@]}" - do - echo -e "- $COLOUR_PUR$i$COLOUR_RST" - done - exit -fi +. "$LIBRARY_PATH_ROOT/download.sh" +. "$LIBRARY_PATH_ROOT/select.sh" +. "$LIBRARY_PATH_ROOT/hashCheck.sh" #Regex -regexETag="ETag: \"([a-z0-9\-]+)\"" -regexSize="Content-Length: ([0-9]+)" -regexLastMod="Last-Modified: ([a-zA-Z0-9\/ :,-]+)" -regexFileName="Content-Disposition: attachment; filename=([a-zA-Z0-9\.-]+)" regexHTTPCode="HTTP/[0-9].[0-9] ([0-9]+) ([a-zA-Z0-9\. -]+)" +regexSize="Content-Range: bytes [0-9]+-[0-9]+/([0-9]+)" # Check the script is being run as root if [[ $EUID -ne 0 ]]; then @@ -91,38 +24,25 @@ if [[ $EUID -ne 0 ]]; then exit 1 fi -# Define the image name -IMAGE_NAME="$1" - -# Check a image name was specified -if [ "$IMAGE_NAME" = "" ]; then - echo "Please specify an image name"; - exit -fi - -#Determine which image to download -IMAGE_URL="${Images[$IMAGE_NAME]}" +# Get the device to write the image to +echo "Where do you want to write the image?" -# Check we could find the requested image -if [ "$IMAGE_URL" = "" ]; then - echo "Could not find an image with the name '$IMAGE_NAME'. Use the --list-images flag for a list."; - exit -fi +while read -ep "Path: " devicePath; do + # Check a device was specified + if [ "$devicePath" = "" ]; then + echo "Please specify a device path to write to"; + continue + fi -#Get the device to write the image to -DEVICE_PATH="$2" - -# Check a device was specified -if [ "$DEVICE_PATH" = "" ]; then - echo "Please specify a device to write to"; - exit -fi + # Check if the device specified is a block device + if [ ! -b "$devicePath" ]; then + echo "The specified path is not a block device" + continue + fi -#Check if the device specified is a block device -if [ ! -b "$DEVICE_PATH" ]; then - echo "$DEVICE_PATH: Not a block device" - exit -fi + DEVICE_PATH="$devicePath" + break +done #Check if the device is mounted if [ `mount | grep -c "$DEVICE_PATH"` -gt 0 ]; then @@ -136,91 +56,60 @@ if [ `mount | grep -c "$DEVICE_PATH"` -gt 0 ]; then exit fi -echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Determining if we have the latest version" - -#Get the actual download URL of the image -IMAGE_URL=`curl -sIL "$IMAGE_URL" -o /dev/null -w %{url_effective}` - -#Get the HTTP headers for the image -IMAGE_HEADERS=`curl -sI "$IMAGE_URL"` - -#Get the HTTP response code -[[ $IMAGE_HEADERS =~ $regexHTTPCode ]] -IMAGE_RESPONSE_CODE="${BASH_REMATCH[1]}" -IMAGE_RESPONSE_MSG="${BASH_REMATCH[2]}" - -if [ "$IMAGE_RESPONSE_CODE" != 200 ]; then - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Download Error [HTTP $IMAGE_RESPONSE_CODE $IMAGE_RESPONSE_MSG]" - exit -fi - -#Get the date this image was last modified -[[ $IMAGE_HEADERS =~ $regexLastMod ]] -IMAGE_LASTMOD="${BASH_REMATCH[1]}" -IMAGE_LASTMOD=`date --date="$IMAGE_LASTMOD" +%s` - -#Get the image size -[[ $IMAGE_HEADERS =~ $regexSize ]] -IMAGE_SIZE="${BASH_REMATCH[1]}" - -#Get the image type -[[ $IMAGE_HEADERS =~ $regexType ]] -IMAGE_TYPE="${BASH_REMATCH[1]}" - -#Get the image name -[[ $IMAGE_HEADERS =~ $regexFileName ]] -IMAGE_FILENAME="${BASH_REMATCH[1]}" - -#Check we could found a file name -if [ "$IMAGE_FILENAME" = "" ]; then - #default to the requested name - IMAGE_FILENAME="$IMAGE_NAME" -fi +distroSelected=$(selectDistro) -#Set the image paths -IMAGE_DIR="images/$IMAGE_NAME/$IMAGE_LASTMOD" -IMAGE_FILE="$IMAGE_DIR/$IMAGE_FILENAME" +if [[ "$distroSelected" == "Local File" ]]; then -#Check if we already have this version -if [ ! -f "$IMAGE_FILE" ]; then - #Make the directory to store the image - mkdir -p "$IMAGE_DIR" + # Get the local path to the image file + echo "Where is the image file located?" - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Downloading $IMAGE_FILENAME" + while read -ep "Path: " imageFilePath; do - #Download the image - curl -sL "$IMAGE_URL" | pv -s "$IMAGE_SIZE" -cN "Download" > "$IMAGE_FILE" + # Check a file was specified + if [ ! -f "$imageFilePath" ]; then + echo "Selected path doesn't appear to be a file"; + continue + fi + break + done else - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST We have the latest version of $IMAGE_FILENAME" -fi - -# Check the file was created -if [ ! -f "$IMAGE_FILE" ]; then - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Something went wrong.. The image wasn't downloaded" - exit -fi - -# Check if a SHA1 hash has been defined for this image -IMAGE_HASH="${ImagesSHA1[$IMAGE_NAME]}" - -if [ "$IMAGE_HASH" != "" ]; then - - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Checking image hash" - - # Hash the downloaded image - IMAGE_HASH_ACTUAL=$(sha1sum "$IMAGE_FILE" | grep -Eo "^([^ ]+)") - - # Check the hashes match - if [ "$IMAGE_HASH" != "$IMAGE_HASH_ACTUAL" ]; then - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Hash mismatch! [$IMAGE_HASH != $IMAGE_HASH_ACTUAL]" - exit 1; - else - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Image hash OK [$IMAGE_HASH]" - fi + distroVersionSelected="$(selectDistroVersion "$distroSelected")" + imageMetaPath="images/$distroSelected/$distroVersionSelected" + imageCacheDir="$imageMetaPath/cache" + imageFilePath="$imageCacheDir/image" + + # Check the cache directory exists + if [[ ! -d "$imageCacheDir" ]]; then + mkdir "$imageCacheDir" + fi + + # Check if the image we want is already cached + if [ ! -f "$imageFilePath" ]; then + # Download the image + download $(<"$imageMetaPath/URL") "$imageFilePath" + else + echo "Using image from cache" + fi + + if [[ $? == 1 ]]; then + echo "Download failed" + exit 1 + fi + + if [[ -f "$imageMetaPath/hash" ]]; then + checkImageHash "$imageFilePath" $(<"$imageMetaPath/hash") + + if [[ $? == 1 ]]; then + echo "Hash Mismatch" + exit 1 + fi + else + echo "Not checking image hash" + fi fi #Get the images file type data -IMAGE_TYPE_DATA=`file "$IMAGE_FILE"` +IMAGE_TYPE_DATA=`file "$imageFilePath"` if [[ $IMAGE_TYPE_DATA =~ "Zip archive data" ]]; then @@ -232,7 +121,7 @@ if [[ $IMAGE_TYPE_DATA =~ "Zip archive data" ]]; then #Determine the decompressed size of the archive REGEX="([0-9]+)[ ]+" - [[ `unzip -l "$IMAGE_FILE"` =~ $REGEX ]] + [[ `unzip -l "$imageFilePath"` =~ $REGEX ]] IMAGE_ARCHIVE_SIZE="${BASH_REMATCH[1]}" fi @@ -246,7 +135,7 @@ if [[ $IMAGE_TYPE_DATA =~ "gzip compressed data" ]]; then #Determine the decompressed size of the archive REGEX="[ ]+[0-9]+[ ]+([0-9]+)" - [[ `zcat -l "$IMAGE_FILE"` =~ $REGEX ]] + [[ `zcat -l "$imageFilePath"` =~ $REGEX ]] IMAGE_ARCHIVE_SIZE="${BASH_REMATCH[1]}" fi @@ -261,26 +150,26 @@ fi # Check if were able to determine what type of file the image is if [[ "$IMAGE_ARCHIVE_TYPE" = "" ]]; then - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Couldn't determine the file type of the image: '$IMAGE_TYPE_DATA'" + echo "Couldn't determine the file type of the image: '$IMAGE_TYPE_DATA'" exit fi # Check if the image is compressed if [ "$IMAGE_ARCHIVE_TYPE" = "NONE" ]; then # No compression, write straight to disk - pv -pabeWcN "Writing" "$IMAGE_FILE" | dd bs=4M of="$DEVICE_PATH" conv=fdatasync + pv -pabeWcN "Writing" "$imageFilePath" | dd bs=4M of="$DEVICE_PATH" conv=fdatasync else - echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST The image is compressed" + echo "The image is compressed" - # Check if the command to extract the image is avaliable + # Check if the command to extract the image is available command_exists_exit "$IMAGE_ARCHIVE_TOOL" # The image is compressed, write it to the disk as we're decompressing it to save time - pv -pabeWcN "Extracting $IMAGE_ARCHIVE_TYPE" "$IMAGE_FILE" | $IMAGE_ARCHIVE_TOOL | pv -pabeWcN "Writing" -s "$IMAGE_ARCHIVE_SIZE" | dd bs=4M of="$DEVICE_PATH" conv=fdatasync + pv -pabeWcN "Extracting $IMAGE_ARCHIVE_TYPE" "$imageFilePath" | $IMAGE_ARCHIVE_TOOL | pv -pabeWcN "Writing" -s "$IMAGE_ARCHIVE_SIZE" | dd bs=4M of="$DEVICE_PATH" conv=fdatasync fi # Persist any buffers sync # Give a complete notice -echo -e "$COLOUR_PUR$IMAGE_NAME:$COLOUR_RST Image write complete!" +echo "Image write complete!" diff --git a/utils/download.sh b/utils/download.sh new file mode 100644 index 0000000..11dc21b --- /dev/null +++ b/utils/download.sh @@ -0,0 +1,47 @@ +function download() { + + local imageDownloadURL="$1" + local imageSavePath="$2" + + echo -n "Fetching meta data..." + + #Get the actual download URL of the image + imageDownloadURL=$(curl -sLr 0-0 "$imageDownloadURL" -o /dev/null -w %{url_effective}) + + #Get the HTTP headers for the image + IMAGE_HEADERS=$(curl -sir 0-0 "$imageDownloadURL") + + #Get the HTTP response code + [[ $IMAGE_HEADERS =~ $regexHTTPCode ]] + IMAGE_RESPONSE_CODE="${BASH_REMATCH[1]}" + IMAGE_RESPONSE_MSG="${BASH_REMATCH[2]}" + + if [[ "$IMAGE_RESPONSE_CODE" -gt 300 ]]; then + echo " FAIL" + echo "Download Error [HTTP $IMAGE_RESPONSE_CODE $IMAGE_RESPONSE_MSG]" + exit + else + echo " OK" + fi + + #Get the image size + [[ $IMAGE_HEADERS =~ $regexSize ]] + IMAGE_SIZE="${BASH_REMATCH[1]}" + + # Download the image + if [[ ! "$IMAGE_SIZE" -gt 0 ]]; then + echo "Unable to determine image size" + curl -s "$imageDownloadURL" | pv -cN "Download" > "$imageSavePath" + else + curl -s "$imageDownloadURL" | pv -s "$IMAGE_SIZE" -cN "Download" > "$imageSavePath" + fi + + # Check the file was created + if [ ! -f "$imageSavePath" ]; then + return 1 + fi + + # All okay! + return 0 + +} diff --git a/utils/hashCheck.sh b/utils/hashCheck.sh new file mode 100644 index 0000000..c90279a --- /dev/null +++ b/utils/hashCheck.sh @@ -0,0 +1,16 @@ + +function checkImageHash() { + + local imageFilePath="$1" + local imageHashCompare="$2" + + # Hash the downloaded image + local IMAGE_HASH_ACTUAL=$(pv -paeWcN "Checking Hash (SHA1)" "$imageFilePath" | sha1sum | grep -Eo "^([^ ]+)") + + # Check the hashes match + if [ "$imageHashCompare" != "$IMAGE_HASH_ACTUAL" ]; then + return 1 + else + return 0 + fi +} \ No newline at end of file diff --git a/utils/select.sh b/utils/select.sh new file mode 100644 index 0000000..451fbe3 --- /dev/null +++ b/utils/select.sh @@ -0,0 +1,58 @@ + +function selectDistro() { + + local distros # The array of distro names + local distroSelected # The name of the distro the user selects + local distroName + + # Add a custom 'distro' + distros+=("Local File") + + while read -r distroName; do + distroName="${distroName/images/}" + distroName="${distroName///}" + distros+=("$distroName") + done < <(ls -1d images/*/) + + echo "Select distro: " >&2 + + select opt in "${distros[@]}"; do + distroSelected="${distros[$(($REPLY-1))]}" + + if [[ "$distroSelected" = "" ]]; then + echo "Invalid selection" >&2 + else + break + fi + done + + echo "$distroSelected" +} + +function selectDistroVersion() { + + local distroName="$1" # Which distro to get the versions for + local distroVersions # The array of versions available for this distro + local distroVersion + local distroVersionSelected + + echo "Select $distroName version:" >&2 + + while read -r distroVersion; do + distroVersion="${distroVersion/images\/$distroName/}" + distroVersion="${distroVersion///}" + distroVersions+=("$distroVersion") + done < <(ls -1d images/"$distroName"/*/) + + select opt in "${distroVersions[@]}"; do + distroVersionSelected="${distroVersions[$(($REPLY-1))]}" + + if [[ "$distroVersionSelected" = "" ]]; then + echo "Invalid selection" >&2 + else + break + fi + done + + echo "$distroVersionSelected" +} \ No newline at end of file