diff options
Diffstat (limited to 'share/hydractl/sync-media')
| -rwxr-xr-x | share/hydractl/sync-media | 130 |
1 files changed, 124 insertions, 6 deletions
diff --git a/share/hydractl/sync-media b/share/hydractl/sync-media index 8132315..2373413 100755 --- a/share/hydractl/sync-media +++ b/share/hydractl/sync-media @@ -17,6 +17,7 @@ CACHE="/var/cache/$HOST/media" MEDIA="media.$DOMAIN" INCOMING="$CACHE/incoming" WHOAMI="`whoami`" +LOCK=".sync-media.lock" OPTIONS="$*" # Dependencies @@ -24,6 +25,66 @@ hydra_install_package rsync hydra_install_package unison hydra_install_package git-annex +# Fatal error +# Adapted from borger +function fatal { + info [fatal] $* + exit 1; +} + +# Create lockfile +# Adapted from borger +function sync_media_set_lockfile { + if [ ! -z "$LOCKFILE" ]; then + mkdir -p `dirname $LOCKFILE` + + if ( set -o noclobber; echo "$$" > "$LOCKFILE" ) &> /dev/null; then + trap 'sync_media_unset_lockfile' INT TERM EXIT + else + fatal "Could not create lockfile $LOCKFILE, exiting" + fi + fi +} + +# Remove lockfile +# Adapted from borger +function sync_media_unset_lockfile { + if [ ! -z "$LOCKFILE" ] && [ -e "$LOCKFILE" ]; then + git annex unannex $LOCK &> /dev/null + git rm -f $LOCKFILE &> /dev/null || \ + rm -f $LOCKFILE || echo "Could not remove lockfile $LOCKFILE" + fi +} + +# Check lockfile +# Adapted from borger +function sync_media_check_lockfile { + local pid process + + if [ ! -e ".gitignore" ] || ! grep -q "$LOCK" .gitignore; then + # With git-ignore from git-extras package + #git ignore $LOCK + + # Without git-ignore from git-extras package + echo "$LOCK" >> .gitignore + fi + + if [ ! -z "$LOCKFILE" ] && [ -f "$LOCKFILE" ]; then + pid="`cat $LOCKFILE`" + process="`ps --no-headers -o comm $pid`" + + if [ "$?" == "0" ] && [ "`ps --no-headers -o comm $$`" == "$process" ]; then + echo "Another program is running for $LOCKFILE, skipping" + return 1 + else + echo "Found old lockfile $LOCKFILE, removing it" + sync_media_unset_lockfile + fi + + return 0 + fi +} + # Fix identity function sync_media_identity { if [ -z "`git config --local user.email`" ] || [ -z "`git config --local user.name`" ]; then @@ -54,20 +115,42 @@ function sync_media_add { # Add meta files, making sure they're handled directly by Git function sync_media_add_metadata { + # Metadata state on the annex + # + # * add: metadata is managed in the annex, normally. + # * unlock: managed in the annex, but modifications are tracked as well. + # * unannex: metadata is kept out of the annex, but still tracked by Git. + # + # Usually, they should be regular files trackes by Git, so `git diff` + # works as expected. + # + #metadata_state="add" + #metadata_state="unlock" + metadata_state="unannex" + + # Gitignore + if [ -e ".gitignore" ]; then + git annex $metadata_state .gitignore + git add .gitignore + fi + # Playlist files in the playlist folder if [ -d "playlists" ]; then - find playlists -name '*.m3u' -type l -exec git annex unlock {} \; - find playlists -name '*.m3u' -exec git add {} \; + find playlists -name '*.m3u' -type l -exec git annex $metadata_state {} \; + find playlists -name '*.m3u' -exec git add {} \; + find playlists -name '*.m3u8' -type l -exec git annex $metadata_state {} \; + find playlists -name '*.m3u8' -exec git add {} \; fi # Koreader metadata files - find -name metadata.pdf.lua -type l -exec git annex unlock {} \; + find -name metadata.pdf.lua -type l -exec git annex $metadata_state {} \; + find -name metadata.pdf.lua -type l -exec git annex $metadata_state {} \; find -name metadata.pdf.lua -exec git add {} \; - find -name metadata.pdf.lua.old -type l -exec git annex unlock {} \; + find -name metadata.pdf.lua.old -type l -exec git annex $metadata_state {} \; find -name metadata.pdf.lua.old -exec git add {} \; # Darktable sidecar files - find -name '*.xmp' -type l -not -path '*.git*' -exec git annex unlock {} \; + find -name '*.xmp' -type l -not -path '*.git*' -exec git annex $metadata_state {} \; find -name '*.xmp' -not -path '*.git*' -exec git add {} \; } @@ -171,12 +254,16 @@ if echo $OPTIONS | grep -q -- "--dropunused"; then fi # Set drive config -# Ingore drive/volume if it's set to "local" +# Ignore drive/volume if it's set to "local" if [ ! -z "$REMOTE" ] && [ "$REMOTE" != "local" ] && [ "$REMOTE" != "localhost" ]; then # Check storage media MOUNT="`mount | grep $VOLUME`" + if [ ! -z "$MOUNT" ]; then DRIVE="$(basename `echo $MOUNT | awk '{ print $1 }'`)" + #else + # echo "$BASENAME: volume $MEDIA is not mounted" + # exit 1 fi fi @@ -203,6 +290,8 @@ fi # Iterate over existing repositories in the local cache for folder in $REPOSITORIES; do + LOCKFILE="$CACHE/$folder/$LOCK" + # Sync each repository in the local cache if [ -d "$CACHE/$folder/.git/annex" ]; then if [ "`git -C $CACHE/$folder config sync-media.skip`" == "true" ]; then @@ -211,7 +300,16 @@ for folder in $REPOSITORIES; do ( cd $CACHE/$folder + echo "" echo "Syncing $CACHE/$folder..." + echo "" + + # Lockfile handling + if ! sync_media_check_lockfile; then + continue + else + sync_media_set_lockfile + fi # Ensure the removable volume is in the list of remotes sync_media_ensure_remote $REMOTE $VOLUME/$MEDIA/$folder @@ -244,6 +342,11 @@ for folder in $REPOSITORIES; do # Repository maintenance sync_media_fsck sync_media_dropunused + git prune + git gc + + # Unset the lockfile + sync_media_unset_lockfile ) fi @@ -287,6 +390,7 @@ if [ ! -z "$DRIVE" ] && [ -d "$VOLUME/$MEDIA" ]; then # Iterate over existing repositories in the removable media for folder in $REPOSITORIES; do + LOCKFILE="$VOLUME/$MEDIA/$folder/$LOCK" # Sync each local repository in the removable media if [ -d "$VOLUME/$MEDIA/$folder/.git/annex" ]; then @@ -296,7 +400,16 @@ if [ ! -z "$DRIVE" ] && [ -d "$VOLUME/$MEDIA" ]; then ( cd $VOLUME/$MEDIA/$folder + echo "" echo "Syncing $VOLUME/$MEDIA/$folder..." + echo "" + + # Lockfile handling + if ! sync_media_check_lockfile; then + continue + else + sync_media_set_lockfile + fi sync_media_playlist_perms sync_media_ensure_remote $HOST $CACHE/$folder @@ -311,7 +424,12 @@ if [ ! -z "$DRIVE" ] && [ -d "$VOLUME/$MEDIA" ]; then sync_media_getall $VOLUME/$MEDIA/$folder sync_media_fsck sync_media_dropunused + git gc + git prune #git annex drop --auto --numcopies=2 + + # Unset the lockfile + sync_media_unset_lockfile ) elif [ -d "$CACHE/$folder" ] && [ ! -d "$CACHE/$folder/.git" ]; then # Avoid those configured to be skipped |
