Sumy kontrolne sum kontrolnych i scenariusz z ograniczeniami

Najczęstszy scenariusz wykorzystania sum kontrolnych plików to:

  • pobrać plik właściwy,
  • wyliczyć sumę kontrolną,
  • pobrać plik z sumą kontrolną,
  • porównać sumy,
  • jak sumy nie są zgodne, to pobrać plik właściwy ponownie.

Owszem, mamy XXI wiek na przykład dla obrazów iso:

http://download.opensuse.org/tumbleweed/iso/openSUSE-Tumbleweed-DVD-x86_64-Current.iso.magnet
http://download.opensuse.org/tumbleweed/iso/openSUSE-Tumbleweed-DVD-x86_64-Current.iso.torrent

który rozwiązuje, powyższy problem (może raczej makes it obsolete)*, *ale życie to życie.

**Mój scenariusz
**
Mam prosty router z alternatywnym firmware, na którym mam serwer ftp z kilkoma plikami. Jednym z tych plików jest Tumbleweed JeOS (link dla niewtajemniczonych) i chciałbym, by był on po mojej stronie zawsze aktualny.

Na zdalnym serwerze, z którego router będzie pobierał jeosa, są dwa pliki:

openSUSE-Tumbleweed-JeOS.x86_64-kvm-and-xen.qcow2 # **alias do najnowszego snapszotu dysku dla wirtualnej maszyny**
openSUSE-Tumbleweed-JeOS.x86_64-kvm-and-xen.qcow2.sha256 # **alias do sumy kontrolnej tego snapszotu**

Czyli jak pojawia się nowy snapszot jeosa, to alias pokazuje właśnie na tę odświeżoną wersję (podlinkowuję serwer, by samodzielnie przejrzeć zawartość ftp.gwdg.de/pub/linux/suse/opensuse/tumbleweed/appliances).

W zasadzie sprawa jest prosta:

  • piszę skrypt, w którym posługuję się dwoma linkami: do aliasu snapszotu i sumy kontrolnej,
  • pobieram plik z sumą kontrolną,
  • wyliczam sumę kontrolną istniejącego lokalnie snapszotu jeosa,
  • jak suma kontrolna, w tym wypadku sha256, się nie zgadza, to muszę podmienić lokalny snapszot jeosa,
  • wrzucam skrypt do crona
  • i mam pewność, że lokalnie mam zawsze aktualny snapszot jeosa z tumbleweedem do różnych testów.

**Nic z tego

**I tu pojawiają się moje ograniczenia.

Po pierwsze na routerze mam słaby procesor i nie chcę go cyklicznie, przypominam: poprzez crona, stresować liczeniem sum kontrolnych większych plików. Przy okazji warto wspomnieć, że nawet jak ktoś ma odruch sprawdzania sumy kontrolnej pliku, który pobrał, to i tak po sprawdzeniu nie przechowuje potem lokalnie sumy kontrolnej tegoż pliku. Nie róbmy tak!

Po drugie na routerze nie mam polecenia sha256sum, a jeos tumbleed jest dostarczany z sumą kontrolną sha256.

Co z tym zrobiłem

Ale przecież mogę przechowywać lokalnie plik z sumą kontrolną i co jakiś czas pobierać nowy plik z sumą kontrolną, a następnie porównywać ich zawartość. Jak zawartość się nie zgadza, to dopiero wtedy pobrać odnowiony snapszot jeosa, by nadpisać stary.

Czyli:

SOURCE="$(cat ${TMPDIR}/${FILENAME}.sha256 | cut -f1 -d' ')"
TARGET="$(cat ${TARGETDIR}/${FILENAME}.sha256 | cut -f1 -d' ')"

A sam test:

 ${SOURCE} = ${TARGET} ]

I tyle.

**Wersja dla nienormalnych

Zastanawiam się, czy jest jakiekolwiek uzasadnienie dla użycia poniżej wersji:
**

SOURCE="$(sha1sum ${TMPDIR}/${FILENAME}.sha256 | cut -f1 -d' ')"
TARGET="$(sha1sum ${TARGETDIR}/${FILENAME}.sha256 | cut -f1 -d' ')"

Nie mam pojęcia. Wygląda ciekawie. Być może w jakimś innym scenariuszu takie podejście da się wykorzystać. Zostawiam więc pod ręką do wygodnej krytyki.

Co mi wyszło

#!/bin/sh

# a script to keep tumbleweed jeos image fresh
# v0.1; 01/05/2022

SCRIPTNAME=$0
FILENAME="openSUSE-Tumbleweed-JeOS.x86_64-kvm-and-xen.qcow2"
WEBRESOURCE="http://ftp.gwdg.de/pub/linux/suse/opensuse/tumbleweed/appliances"
TARGETDIR="/tmp/mnt/sda1/ftp/pub/linux/suse/opensuse/tumbleweed/appliances"
TMPDIR="/tmp/mnt/sda1/tmp"
LOG="/tmp/mnt/sda1/var/log/$(echo ${SCRIPTNAME} | sed 's/.*\///').log"

function _log () {
    echo "$(date +"%Y%m%d.%H%M%S") :: ${SCRIPTNAME} :: $*" >> ${LOG}
}

RET=1
while  $RET -eq 1 ]; do
         ! -f ${TMPDIR}/${FILENAME}.sha256 ] ||  ! -f ${TMPDIR}/${FILENAME} ]
         $? -eq 0 ] && RET=0
        rm -f ${TMPDIR}/${FILENAME}* && _log "${TMPDIR} cleaned"
done

wget ${WEBRESOURCE}/${FILENAME}.sha256 -P ${TMPDIR}/
 $? -ne 0 ] && _log "Failed to download ${WEBRESOURCE}/${FILENAME}.sha256" && exit 1

SOURCE="$(cat ${TMPDIR}/${FILENAME}.sha256 | cut -f1 -d' ')"
TARGET="$(cat ${TARGETDIR}/${FILENAME}.sha256 | cut -f1 -d' ')"

if  ${SOURCE} = ${TARGET} ]; then
        rm -f ${TMPDIR}/${FILENAME}*
        _log "No changes to ${FILENAME}" && exit 0
else
        wget ${WEBRESOURCE}/${FILENAME} -P ${TMPDIR}/

        mv ${TMPDIR}/${FILENAME}.sha256 ${TARGETDIR}/${FILENAME}.sha256
        mv ${TMPDIR}/${FILENAME} ${TARGETDIR}/${FILENAME}
        _log "${FILENAME} updated" && exit 0
fi

_log "End of the script reached" && exit 1

**Co mi się podoba
**
Standardowo kończę skrypt, kiedy ja tego chcę. Dodatkowo budowanie logiki wokół warunku:

 fałsz ] ||  fałsz ]

łatwo odwrócić na:

 ! fałsz ] ||  ! fałsz ]

co pozwala na bardziej zrozumiałe przechwycenie kodu wyjścia.

**Co jest dziwne
**
Polecenia while użyłem dość bezsensownie. Prawdziwa cnota…