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…