Entropy Reduction

Personal log of yet another digital native.


Project maintained by andre-abadi Hosted on GitHub Pages — Theme by mattgraham

Plan

Constraints

Infrastructure

Steps

OS

Format & Mount

MergerFS

Snapraid

Syncthing

Tailscale

Files

snapraid.conf

##############################################$
# SnapRAID configuration for Whitefall$
# Layout: 3 data disks + 1 parity disk$
##############################################$
$
# PARITY DISK$
parity /mnt/disk4/snapraid.parity$
$
# CONTENT FILES (redundant metadata)$
content /mnt/disk1/snapraid.content$
content /mnt/disk2/snapraid.content$
content /mnt/disk3/snapraid.content$
content /mnt/disk4/snapraid.content$
$
# DATA DISKS$
data disk1 /mnt/disk1$
data disk2 /mnt/disk2$
data disk3 /mnt/disk3$
$
# EXCLUDES (recommended)$
exclude *.tmp$
exclude *.bak$
exclude *.swp$
exclude *.DS_Store$
exclude Thumbs.db$
exclude .Trash*/$
exclude .recycle*/$
exclude .cache*/$
exclude .@__thumb*/$
exclude lost+found/$
$
# TUNING$
# Autosave prevents corruption if sync is interrupted$
autosave 100$
$
# Larger blocksize = fewer I/O ops on slow USB disks$
blocksize 256$

maintain.sh

#!/bin/bash

# CONFIG
SYNC_DAYS=1
SCRUB_DAYS=14
LOG=/var/log/snapraid-maint.log
SNAPRAID=/usr/bin/snapraid

# Command-line overrides
FORCE_SYNC=false
FORCE_SCRUB=false

while [[ "$1" != "" ]]; do
    case $1 in
        --force-sync )  FORCE_SYNC=true ;;
        --force-scrub ) FORCE_SCRUB=true ;;
    esac
    shift
done

format_elapsed() {
    local seconds=$1
    local days=$(( seconds / 86400 ))
    local hours=$(( (seconds % 86400) / 3600 ))
    local mins=$(( (seconds % 3600) / 60 ))

    local out=""

    # Only print days if > 0
    [ $days -gt 0 ] && out="${out}${days}d "

    # Only print hours if > 0
    [ $hours -gt 0 ] && out="${out}${hours}h "

    # Only print minutes if > 0 OR if nothing else printed
    if [ $mins -gt 0 ] || [ -z "$out" ]; then
        out="${out}${mins}m"
    fi

    echo "${out%" "}"
}

# Show quick usage help only when run interactively
if [ -t 1 ]; then
    echo "Usage: $0 [--force-sync] [--force-scrub]"
fi

# Start
echo "=== SnapRAID maintenance $(date) ===" | tee -a "$LOG"

# Wait for disks to mount at boot (max 50 seconds)
for i in {1..10}; do
    if mountpoint -q /mnt/disk1; then
        break
    fi
    sleep 5
done

# Ensure disks are mounted
for d in /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4; do
    if ! mountpoint -q "$d"; then
        echo "Disk $d not mounted, aborting." | tee -a "$LOG"
        exit 1
    fi
done

# Extract last sync timestamp safely
LAST_SYNC=$($SNAPRAID status | grep "Sync finished" | sed 's/.*: //')
LAST_SYNC_TS=$(date -d "$LAST_SYNC" +%s 2>/dev/null)
NOW_TS=$(date +%s)

# If no sync has ever run
if [ -z "$LAST_SYNC_TS" ]; then
    echo "No previous sync found — running initial sync." | tee -a "$LOG"
    $SNAPRAID sync 2>&1 | tee -a "$LOG"
    exit 0
fi

# Time calculations
SYNC_AGE=$(( NOW_TS - LAST_SYNC_TS ))
SYNC_AGE_FMT=$(format_elapsed $SYNC_AGE)

SYNC_INTERVAL=$(( SYNC_DAYS * 86400 ))
SYNC_REMAIN=$(( SYNC_INTERVAL - SYNC_AGE ))
SYNC_REMAIN_FMT=$(format_elapsed $SYNC_REMAIN)

if $FORCE_SYNC; then
    echo "Forcing sync (override flag)." | tee -a "$LOG"
    $SNAPRAID sync 2>&1 | tee -a "$LOG"

elif [ $SYNC_AGE -ge $SYNC_INTERVAL ]; then
    echo "Last sync: $SYNC_AGE_FMT ago — running sync." | tee -a "$LOG"
    $SNAPRAID sync 2>&1 | tee -a "$LOG"

else
    echo "Last sync: $SYNC_AGE_FMT ago — next sync in $SYNC_REMAIN_FMT (every $(format_elapsed $((SYNC_DAYS * 86400))))." | tee -a "$LOG"
fi

# Scrub timestamp
LAST_SCRUB=$($SNAPRAID status | grep "Scrub finished" | sed 's/.*: //')
LAST_SCRUB_TS=$(date -d "$LAST_SCRUB" +%s 2>/dev/null)

if [ -z "$LAST_SCRUB_TS" ]; then
    echo "No previous scrub found — running scrub." | tee -a "$LOG"
    $SNAPRAID scrub -p 10 2>&1 | tee -a "$LOG"
    exit 0
fi

# Time calculations
SCRUB_AGE=$(( NOW_TS - LAST_SCRUB_TS ))
SCRUB_AGE_FMT=$(format_elapsed $SCRUB_AGE)

SCRUB_INTERVAL=$(( SCRUB_DAYS * 86400 ))
SCRUB_REMAIN=$(( SCRUB_INTERVAL - SCRUB_AGE ))
SCRUB_REMAIN_FMT=$(format_elapsed $SCRUB_REMAIN)

if $FORCE_SCRUB; then
    echo "Forcing scrub (override flag)." | tee -a "$LOG"
    $SNAPRAID scrub -p 10 2>&1 | tee -a "$LOG"

elif [ $SCRUB_AGE -ge $SCRUB_INTERVAL ]; then
    echo "Last scrub: $SCRUB_AGE_FMT ago — running scrub." | tee -a "$LOG"
    $SNAPRAID scrub -p 10 2>&1 | tee -a "$LOG"

else
    echo "Last scrub: $SCRUB_AGE_FMT ago — next scrub in $SCRUB_REMAIN_FMT (every $(format_elapsed $((SCRUB_DAYS * 86400))))." | tee -a "$LOG"
fi

# End
END_LINE="=== SnapRAID maintenance END $(date) ==="
echo "$END_LINE" | tee -a "$LOG"

crontab

# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
# SnapRAID: burst mode after boot (0, 5, 10, 15 minutes)
@reboot sleep 0   && /usr/local/bin/snapraid-maint
@reboot sleep 300 && /usr/local/bin/snapraid-maint
@reboot sleep 600 && /usr/local/bin/snapraid-maint
@reboot sleep 900 && /usr/local/bin/snapraid-maint

# SnapRAID: steady-state (every 30 minutes)
*/30 * * * * /usr/local/bin/snapraid-maint

fstab

proc            /proc           proc    defaults          0       0$
PARTUUID=7e4022c3-01  /boot/firmware  vfat    defaults          0       2$
PARTUUID=7e4022c3-02  /               ext4    defaults,noatime  0       1$
UUID=15d0b85a-9a5b-4976-9314-6c9519bc595f  /mnt/disk1  ext4  defaults,noatime,nofail,x-systemd.device-timeout=10  0  0$
UUID=93933b41-30b6-4ee1-aaa0-76f3a7ad68d6  /mnt/disk2  ext4  defaults,noatime,nofail,x-systemd.device-timeout=10  0  0$
UUID=272b6924-a2b6-4e05-9cfe-502db41f8501  /mnt/disk3  ext4  defaults,noatime,nofail,x-systemd.device-timeout=10  0  0$
UUID=809dfe56-65e2-4aef-a952-0e1284daa6a0  /mnt/disk4  ext4  defaults,noatime,nofail,x-systemd.device-timeout=10  0  0$
/mnt/disk1:/mnt/disk2:/mnt/disk3 /mnt/array fuse.mergerfs defaults,allow_other,use_ino,category.create=mfs,moveonenospc=true,minfreespace=10G,nofail 0 0$