mirror of https://github.com/vitalif/grive2
Add user systemd units
The units can be used to automatically sync a folder in the users home dir * every 3 minutes * on local file changes (requires inotify-tools). To enable the units for `~/google-drive/`: ``` systemctl --user enable grive-timer@google-drive.timer systemctl --user start grive-timer@google-drive.timer systemctl --user enable grive-changes@google-drive.service systemctl --user start grive-changes@google-drive.service ``` The units can be enabled multiple timespull/143/head
parent
4b6cf69cbb
commit
d996989c29
|
@ -1,5 +1,7 @@
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
# Grive version. remember to update it for every new release!
|
# Grive version. remember to update it for every new release!
|
||||||
set( GRIVE_VERSION "0.5.1-dev" )
|
set( GRIVE_VERSION "0.5.1-dev" )
|
||||||
|
|
||||||
|
@ -7,5 +9,7 @@ set( GRIVE_VERSION "0.5.1-dev" )
|
||||||
add_definitions( -DVERSION="${GRIVE_VERSION}" )
|
add_definitions( -DVERSION="${GRIVE_VERSION}" )
|
||||||
add_definitions( -D_FILE_OFFSET_BITS=64 -std=c++0x )
|
add_definitions( -D_FILE_OFFSET_BITS=64 -std=c++0x )
|
||||||
|
|
||||||
|
add_subdirectory( systemd )
|
||||||
add_subdirectory( libgrive )
|
add_subdirectory( libgrive )
|
||||||
add_subdirectory( grive )
|
add_subdirectory( grive )
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
SET(GRIVE_SYNC_SH_BINARY "${CMAKE_INSTALL_PREFIX}/lib/grive/grive-sync.sh")
|
||||||
|
|
||||||
|
CONFIGURE_FILE(grive-changes@.service.in grive-changes@.service @ONLY)
|
||||||
|
CONFIGURE_FILE(grive-timer@.service.in grive-timer@.service @ONLY)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
${CMAKE_BINARY_DIR}/systemd/grive-changes@.service
|
||||||
|
${CMAKE_BINARY_DIR}/systemd/grive-timer@.service
|
||||||
|
DESTINATION
|
||||||
|
lib/systemd/user
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
grive-timer@.timer
|
||||||
|
DESTINATION
|
||||||
|
lib/systemd/user
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
PROGRAMS
|
||||||
|
grive-sync.sh
|
||||||
|
DESTINATION
|
||||||
|
lib/grive
|
||||||
|
)
|
|
@ -0,0 +1,11 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Google drive sync (changed files)
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=@GRIVE_SYNC_SH_BINARY@ listen "%i"
|
||||||
|
Type=simple
|
||||||
|
Restart=always
|
||||||
|
RestartSec=30
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
|
@ -0,0 +1,118 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (C) 2009 Przemyslaw Pawelczyk <przemoc@gmail.com>
|
||||||
|
# (C) 2017 Jan Schulz <jasc@gmx.net>
|
||||||
|
##
|
||||||
|
## This script is licensed under the terms of the MIT license.
|
||||||
|
## https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Fail on all errors
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# We always start in the current users home directory so that names always start there
|
||||||
|
cd ~
|
||||||
|
|
||||||
|
|
||||||
|
### ARGUMENT PARSING ###
|
||||||
|
SCRIPT=${0}
|
||||||
|
|
||||||
|
if [[ -z ${2} ]] || [[ ! -d ${2} ]] ; then
|
||||||
|
echo "Need a directory name in the current users home directory as second argument. Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DIRECTORY=$2
|
||||||
|
|
||||||
|
if [[ -z ${1} ]] ; then
|
||||||
|
echo "Need a command as first argument. Aborting."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
if [[ "sync" == "${1}" ]] ; then
|
||||||
|
COMMAND=sync
|
||||||
|
elif [[ "listen" == "${1}" ]] ; then
|
||||||
|
COMMAND=listen
|
||||||
|
else
|
||||||
|
echo "Unknown command. Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
### LOCKFILE BOILERPLATE ###
|
||||||
|
LOCKFILE="/run/user/$(id -u)/$(basename $0)_${DIRECTORY//\//_}"
|
||||||
|
LOCKFD=99
|
||||||
|
|
||||||
|
# PRIVATE
|
||||||
|
_lock() { flock -$1 $LOCKFD; }
|
||||||
|
_no_more_locking() { _lock u; _lock xn && rm -f $LOCKFILE; }
|
||||||
|
_prepare_locking() { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }
|
||||||
|
|
||||||
|
# ON START
|
||||||
|
_prepare_locking
|
||||||
|
|
||||||
|
# PUBLIC
|
||||||
|
exlock_now() { _lock xn; } # obtain an exclusive lock immediately or fail
|
||||||
|
exlock() { _lock x; } # obtain an exclusive lock
|
||||||
|
shlock() { _lock s; } # obtain a shared lock
|
||||||
|
unlock() { _lock u; } # drop a lock
|
||||||
|
|
||||||
|
### SYNC SCRIPT ###
|
||||||
|
# Idea: only let one script run, but if the sync script is called a second time
|
||||||
|
# make sure we sync a second time, too
|
||||||
|
|
||||||
|
sync_directory() {
|
||||||
|
_directory=${1}
|
||||||
|
if ping -c1 -W1 -q accounts.google.com >/dev/null 2>&1; then
|
||||||
|
true
|
||||||
|
# pass
|
||||||
|
else
|
||||||
|
echo "Google drive server not reachable..."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
reset_timer_and_exit() { echo "Retriggered google drive sync" && touch -m $LOCKFILE && exit; }
|
||||||
|
|
||||||
|
exlock_now || reset_timer_and_exit
|
||||||
|
|
||||||
|
TIME_AT_START=0
|
||||||
|
TIME_AT_END=1
|
||||||
|
while [[ ${TIME_AT_START} -lt ${TIME_AT_END} ]]; do
|
||||||
|
echo "Syncing ${_directory}..."
|
||||||
|
TIME_AT_START=$(stat -c %Y $LOCKFILE)
|
||||||
|
grive -p ${_directory} 2>&1 | grep -v -E "^Reading local directories$|^Reading remote server file list$|^Synchronizing files$|^Finished!$"
|
||||||
|
TIME_AT_END=$(stat -c %Y $LOCKFILE)
|
||||||
|
echo "Sync of ${_directory} done."
|
||||||
|
done
|
||||||
|
|
||||||
|
# always exit ok, so that we never go into a wrong systemd state
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
### LISTEN TO DIRECTORY CHANGES ###
|
||||||
|
|
||||||
|
|
||||||
|
listen_directory() {
|
||||||
|
_directory=${1}
|
||||||
|
|
||||||
|
type inotifywait >/dev/null 2>&1 || { echo >&2 "I require inotifywait but it's not installed. Aborting."; exit 1; }
|
||||||
|
|
||||||
|
echo "Listening for changes in ~/${_directory}"
|
||||||
|
|
||||||
|
while true #run indefinitely
|
||||||
|
do
|
||||||
|
# Use a different call to not need to change exit into return
|
||||||
|
inotifywait -q -r -e modify,attrib,close_write,move,create,delete --exclude ".grive_state|.grive" ${_directory} > /dev/null 2>&1 && ${SCRIPT} sync ${_directory}
|
||||||
|
done
|
||||||
|
|
||||||
|
# always exit ok, so that we never go into a wrong systemd state
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ${COMMAND} == listen ]] ; then
|
||||||
|
listen_directory ${DIRECTORY}
|
||||||
|
else
|
||||||
|
sync_directory ${DIRECTORY}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# always exit ok, so that we never go into a wrong systemd state
|
||||||
|
exit 0
|
|
@ -0,0 +1,6 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Google drive sync
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=@GRIVE_SYNC_SH_BINARY@ sync "%i"
|
|
@ -0,0 +1,11 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Google drive sync (fixed intervals)
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*:0/5
|
||||||
|
OnBootSec=3min
|
||||||
|
OnUnitActiveSec=5min
|
||||||
|
Unit=grive-timer@%i.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
Loading…
Reference in New Issue