Bläddra i källkod

add overlaycached

Tobias Simetsreiter 4 år sedan
förälder
incheckning
642684c8dd
1 ändrade filer med 108 tillägg och 0 borttagningar
  1. 108 0
      overlaycached

+ 108 - 0
overlaycached

@@ -0,0 +1,108 @@
+#!/usr/bin/env bash
+
+overlaycached(){
+    set -e
+
+    MOVE=false
+    SSHFS=""
+    DEPTH=1
+    while getopts ":dmS:D:-" opt; do
+        case $opt in
+            d )
+                DEBUG=true
+              ;;
+            m )
+                MOVE=true
+              ;;
+            S )
+                SSHFS="$OPTARG"
+              ;;
+            D )
+                DEPTH="$OPTARG"
+              ;;
+            - )
+                break
+              ;;
+            \? ) cat 1>&2 <<'USAGEEOF'
+
+Usage: <sharxz> [-d] [ -D DEPTH ] [-m | -S SSHFS | LOWER_DIR ] [ UPPER_DIR ] [ MOUNT_DIR ]
+-d DEBUG
+-D DEPTH=1 depth of inotify directory watches
+-S SSHFS mount sshfs for LOWER_DIR
+-m MOVE move MOUNT_DIR to another mount point and mount overlay
+-- stop parsing and pass remaining arguments
+
+USAGEEOF
+                    exit 1
+                  ;;
+                : )
+            echo "Invalid option: $OPTARG requires an argument" 1>&2
+                exit 1
+              ;;
+        esac
+    done
+    shift $((OPTIND -1))
+
+    $MOVE ||
+        [ -z "$SSHFS" ] &&
+            LOWER_DIR="$1" && shift 1
+    UPPER_DIR="$1"
+    MOUNT_DIR="$2"
+    WORK_DIR="$(realpath "$UPPER_DIR").work"
+    mkdir -p "$WORK_DIR"
+    CLEANUP_DIRS=(
+        "$WORK_DIR"
+    )
+    if $MOVE; then
+        LOWER_DIR="$(mktemp -d)"
+        CLEANUP_DIRS+=( "$LOWER_DIR" )
+        set -x
+        mount --move "$MOUNT_DIR" "$LOWER_DIR"
+        set +x
+    elif [ ! -z "$SSHFS" ]; then
+        LOWER_DIR="$(mktemp -d)"
+        CLEANUP_DIRS+=( "$LOWER_DIR" )
+        set -x
+        sshfs "$SSHFS" "$LOWER_DIR"
+        set +x
+    fi
+    show_workdir_contents
+
+    trap cleanup EXIT
+    set -x
+    mount -t overlay -o lowerdir="$LOWER_DIR",upperdir="$UPPER_DIR",workdir="$WORK_DIR" overlay "$MOUNT_DIR"
+    set +x
+    inotify_cmd $MOUNT_DIR |while read DIR EVT FILE;
+    do 
+        echo "$DIR $EVT $FILE"
+        [[ "$EVT" =~ "ISDIR" ]] && continue
+        RELPATH="$(realpath --relative-to=$MOUNT_DIR $DIR)/$FILE"
+        [ ! -f "$UPPER_DIR/$RELPATH" ] && {
+            mkdir -p "$(dirname $UPPER_DIR/$RELPATH)"
+            cp -a "$LOWER_DIR/$RELPATH" "$UPPER_DIR/$RELPATH"
+            sync && mount -o remount "$MOUNT_DIR"
+        }
+    done
+}
+cleanup(){
+    umount "$MOUNT_DIR" 2> /dev/null
+    if $MOVE; then
+        mount --move "$LOWER_DIR" "$MOUNT_DIR"
+    fi
+    if [ -z "$SSHFS" ]; then
+        umount "$LOWER_DIR" 2> /dev/null
+    fi
+    for DIR in ${CLEANUP_DIRS[@]}; do
+        rm -rf "$DIR"
+    done
+}
+show_workdir_contents(){
+    (cd $WORK_DIR;pwd; ls -alsh)
+}
+inotify_cmd(){
+    inotifywait -m -e close_nowrite $(find_dirs $1)
+}
+find_dirs(){
+    find "$1" -maxdepth "$DEPTH" -type d
+}
+overlaycached "$@"