@@ -227,6 +227,8 @@ check_dir "${COCOON_ROOT_DIR}/oci/blobs"
227227check_dir " ${COCOON_ROOT_DIR} /oci/boot"
228228check_dir " ${COCOON_ROOT_DIR} /cloudimg/db"
229229check_dir " ${COCOON_ROOT_DIR} /cloudimg/blobs"
230+ check_dir " ${COCOON_ROOT_DIR} /snapshot/db"
231+ check_dir " ${COCOON_ROOT_DIR} /snapshot/localfile"
230232check_dir " ${FIRMWARE_DIR} "
231233check_dir /var/run/netns
232234
@@ -329,7 +331,74 @@ else
329331fi
330332
331333# ---------------------------------------------------------------------------
332- # 9. Upgrade / Install
334+ # 9. Snapshot health
335+ # ---------------------------------------------------------------------------
336+ header " Snapshot health"
337+
338+ SNAP_DB=" ${COCOON_ROOT_DIR} /snapshot/db/snapshots.json"
339+ SNAP_DATA_DIR=" ${COCOON_ROOT_DIR} /snapshot/localfile"
340+
341+ if [ -f " $SNAP_DB " ]; then
342+ if command -v jq & > /dev/null; then
343+ SNAP_COUNT=$( jq ' .snapshots | length' " $SNAP_DB " 2> /dev/null || echo " ?" )
344+ pass " snapshot DB readable ($SNAP_COUNT snapshot(s))"
345+
346+ # Check for stale pending snapshots (pending=true, older than 1 hour).
347+ STALE=$( jq -r '
348+ .snapshots | to_entries[]
349+ | select(.value.pending == true)
350+ | select((.value.created_at // "1970-01-01T00:00:00Z") | fromdateiso8601 < (now - 3600))
351+ | .key' " $SNAP_DB " 2> /dev/null || true)
352+ if [ -n " $STALE " ]; then
353+ for sid in $STALE ; do
354+ warn " stale pending snapshot: $sid (pending > 1 hour, will be GC'd after 24h)"
355+ done
356+ else
357+ pass " no stale pending snapshots"
358+ fi
359+
360+ # Check for orphan data dirs (dirs in localfile/ with no matching DB record).
361+ if [ -d " $SNAP_DATA_DIR " ]; then
362+ ORPHANS=" "
363+ for dir in " $SNAP_DATA_DIR " /* /; do
364+ [ -d " $dir " ] || continue
365+ dir_id=$( basename " $dir " )
366+ if ! jq -e " .snapshots[\" $dir_id \" ]" " $SNAP_DB " & > /dev/null; then
367+ ORPHANS=" ${ORPHANS} ${dir_id} "
368+ fi
369+ done
370+ if [ -n " $ORPHANS " ]; then
371+ for oid in $ORPHANS ; do
372+ warn " orphan snapshot data dir: $oid (no DB record, run 'cocoon gc' to clean)"
373+ done
374+ else
375+ pass " no orphan snapshot data dirs"
376+ fi
377+ fi
378+
379+ # Check for DB records whose data dir is missing.
380+ MISSING_DATA=$( jq -r '
381+ .snapshots | to_entries[]
382+ | select(.value.pending != true)
383+ | select(.value.data_dir != null and .value.data_dir != "")
384+ | select(.value.data_dir)
385+ | "\(.key) \(.value.data_dir)"' " $SNAP_DB " 2> /dev/null || true)
386+ if [ -n " $MISSING_DATA " ]; then
387+ while IFS=' ' read -r sid sdir; do
388+ if [ ! -d " $sdir " ]; then
389+ fail " snapshot $sid : data dir missing: $sdir "
390+ fi
391+ done <<< " $MISSING_DATA"
392+ fi
393+ else
394+ warn " jq not found — skipping snapshot DB inspection"
395+ fi
396+ else
397+ info " no snapshot DB yet (no snapshots created)"
398+ fi
399+
400+ # ---------------------------------------------------------------------------
401+ # 10. Upgrade / Install
333402# ---------------------------------------------------------------------------
334403if $UPGRADE ; then
335404 tmpdir=$( mktemp -d)
0 commit comments