Skip to content

Instantly share code, notes, and snippets.

@blockpane
Last active Dec 4, 2021
Embed
What would you like to do?
FIO Snapshots Script
#!/bin/bash
#CONTAINER=fixme
#ZPOOL=fixme
#CHAIN_NAME=fixme
#OUT_DIR=fixme
#URL=fixme
#API=fixme
# Uses ZFS snapshots to minimize node downtime when creating history node archives:
#
# - needs root
# - needs producer API enabled in config.ini
# - needs curl installed in container, needs 'pixz' on host.
# - expects the FIO home to be in the only docker volume for the container.
# - executes a nodeos state snapshot from inside the container
# - stops the container
# - takes ZFS snapshot of the entire docker volume
# - restarts the container
# - mounts the ZFS snapshot
# - creates 3 files: tar and compresses (maintains sparseness)
# 1. just the snapshot
# 2. snapshot and blocks.log
# 3. full archive of the data directory and history directory. (includes state)
# - destroys the ZFS snapshot
# always exit when something fails
#set -e
# uncomment to debug
set -x
[ $(id -u) -eq 0 ] || { echo "must be root"; kill 0; }
# ensure the container gets started and snapshot removed just in case of an error, these can fail silently.
function cleanup(){
docker start "${CONTAINER}" >/dev/null 2>&1 || true
cd /
umount "/mnt/${CONTAINER}" >/dev/null 2>&1 || true
/usr/sbin/zfs destroy "${ZPOOL}@${CONTAINER}" >/dev/null 2>&1 || true
}
#trap 'cleanup' err exit
trap 'cleanup' exit
TODAY=$(date +%Y%m%d)
SNAP=$(curl -s -m 300 -XPOST "${API}/v1/producer/create_snapshot" \
| jq -r .snapshot_name | awk -F/ '{print $NF}') || exit 1
[ "$SNAP" == "null" ] && exit 1
docker stop "${CONTAINER}"
/usr/sbin/zfs snapshot "${ZPOOL}@${CONTAINER}"
docker start "${CONTAINER}"
docker exec "${CONTAINER}" rm -f data/snapshots/${SNAP} || true
mkdir -p /mnt/${CONTAINER}
mount -t zfs "${ZPOOL}@${CONTAINER}" /mnt/${CONTAINER}
cd /mnt/${CONTAINER}/data/snapshots || exit 1
tar -cS -I'pixz -9' -f "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-snap.txz.INCOMPLETE" "${SNAP}"
mv "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-snap.txz.INCOMPLETE" "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-snap.txz"
cp "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-snap.txz" "${OUT_DIR}/${CHAIN_NAME}-latest-snap.txz.INCOMPLETE"
mv "${OUT_DIR}/${CHAIN_NAME}-latest-snap.txz" "${OUT_DIR}/${CHAIN_NAME}-previous-snap.txz"
mv "${OUT_DIR}/${CHAIN_NAME}-latest-snap.txz.INCOMPLETE" "${OUT_DIR}/${CHAIN_NAME}-latest-snap.txz"
cd /mnt/${CONTAINER}
tar -cS -I'pixz' -f "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-blocks.txz.INCOMPLETE" data/blocks "data/snapshots/${SNAP}"
mv "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-blocks.txz.INCOMPLETE" "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-blocks.txz"
cp "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-blocks.txz" "${OUT_DIR}/${CHAIN_NAME}-latest-blocks.txz.INCOMPLETE"
mv "${OUT_DIR}/${CHAIN_NAME}-latest-blocks.txz" "${OUT_DIR}/${CHAIN_NAME}-previous-blocks.txz"
mv "${OUT_DIR}/${CHAIN_NAME}-latest-blocks.txz.INCOMPLETE" "${OUT_DIR}/${CHAIN_NAME}-latest-blocks.txz"
tar -cS -I'pixz' -f "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-history.txz.INCOMPLETE" data/ history/ history_index/
mv "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-history.txz.INCOMPLETE" "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-history.txz"
cp "${OUT_DIR}/${CHAIN_NAME}-${TODAY}-history.txz" "${OUT_DIR}/${CHAIN_NAME}-latest-history.txz.INCOMPLETE"
mv "${OUT_DIR}/${CHAIN_NAME}-latest-history.txz" "${OUT_DIR}/${CHAIN_NAME}-previous-history.txz"
mv "${OUT_DIR}/${CHAIN_NAME}-latest-history.txz.INCOMPLETE" "${OUT_DIR}/${CHAIN_NAME}-latest-history.txz"
# cleanup old snapshots
find "${OUT_DIR}" -name "${CHAIN_NAME}-202*txz" -mtime +14 -exec rm {} \;
echo '<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>snapshots</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="bootstrap.css"></head>
<body>
<div class="container-fluid">
<div class="w-65 mx-auto" style="max-width: 1200px;">' > "${OUT_DIR}/${CHAIN_NAME}-index.html"
echo "<h3>${CHAIN_NAME} snapshots:</h3><br />" >> "${OUT_DIR}/${CHAIN_NAME}-index.html"
cd $OUT_DIR
ls -1 | grep "${CHAIN_NAME}-.*txz" | sort -r | while read f; do
echo "<a href=\"${URL}/$(echo $f |awk '{print $NF}')\"><pre>${f}</pre></a>" >> "${OUT_DIR}/${CHAIN_NAME}-index.html"
done
echo '</div>
</div>
<script src="jquery.min.js"></script>
<script src="bootstrap.min.js"></script>
</body>
</html>' >> "${OUT_DIR}/${CHAIN_NAME}-index.html"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment