Skip to content

Instantly share code, notes, and snippets.

@olomor
Created February 12, 2022 06:36
Show Gist options
  • Save olomor/1dcf5f973fc93ae63cbdf0b97d267042 to your computer and use it in GitHub Desktop.
Save olomor/1dcf5f973fc93ae63cbdf0b97d267042 to your computer and use it in GitHub Desktop.
rclone tool wrapper script to auto-mount and control the cloud disk at graphical user logon using systemd.
#!/bin/bash
# rclone.wrapper
Arg1=${1}
Arg2=${2}
export PATH=/usr/local/bin:/usr/bin
help()
{
cat << EOF | more
#=================================================================================
# rclone.wrapper script v1.0 / fev2022 (developed by github:@romol0s)
#=================================================================================
Usage notes
===========
${0} [Action] [ConfigSection]
Actions:
start - Manual startup application, recomended use of 'systemctl stop ...'
stop - Manual stop application, recomended use of 'systemctl stop ...'
restart - Run "stop" and so "start" at sequence.
status - Check application running state.
help - Shows this document.
install - Creante and/or install the systemd service for autostart over current user.
First, review section "setup instructions" below.
uninstall - Remove the systemd service.
Setup instructions
==================
1. Setup RClone using his product documentation
-----------------------------------------------
https://rclone.org/drive/#making-your-own-client-id
2. Create additional child section
----------------------------------
At config file "~/.config/rclone/rclone.conf", we will add
two new parameters: source_dir (at clouddisk) and targer_dir (local path).
The child section, shloud contains an alias in format alphanum only.
This will be used by systemd script to search the parameters.
In the below sample config, has:
alias: work2
source_dir: /work2 <-- path at GoogleDrive
target_dir: /home/user1/GoogleDrive <-- the local mount path
Example:
[romolo_gmail]
type = drive
client_id = 00000000-u3u1uaaaaah24p4nkbbbbbb8m9e5.apps.googleusercontent.com
client_secret = GOCCOS-BjuDyzk7q3Lnrsi53Yr-kgvVMZCPD
scope = drive
token = {"access_token":"ya29.A0ARrdaM_SiJktinHGIXk_M5yoiwnfoeuiqwnfieyq8fQ6GVac
quiiuqwe82fAf2W5i-biuwhiowhfoja0sas9idf0sfXOsX6yYOIsaQa02iIVufvIe1fp",
"token_type":"Bearer","refresh_token":"1//piojsdspofreapwSNwFSx60-8Eacoo
pasdGQmtlS-xASODAosAOPsdAPOsi_M8Dr0923rhwef098u2AtWs0",
"expiry":"2022-02-12T03:40:25.249160077-03:00"}
team_drive =
[romolo_gmail:work2]
source_dir = /work2
target_dir = /home/user1/GoogleDrive
3. Create the systemd service and start
---------------------------------------
#> ${0} install romolo_gmail-work2
Please be attention:
The child section name is defined with ':' character, and
the "alias" for service, replaces ':' by '-' on execute.
EOF
}
ParameterValue()
{
sed -n "/^.${ConfigName}./,/(^$|^\[)/p" ${ConfigFile} |grep -E "^${1}" |sed -r "s/(^${1})( = )(.*)/\3/g" |tr -d '\n'
}
execStartPre()
{
for PathName in /var/log/rclone /run/rclone
do
[[ ! -d ${PathName} ]] && sudo mkdir -p ${PathName}
sudo chmod 777 ${PathName}
done
[[ ! -d "${Target}" ]] && mkdir -p "${Target}"
}
execStart()
{
execStartPre
rclone mount ${ConfigName%%:*}:${Source} ${Target} \
--vfs-cache-mode full \
--vfs-read-chunk-size 1Mi \
--write-back-cache \
--log-file ${LogFile} \
--daemon \
&& \
ps -C rclone -o pid,cmd \
|grep -v -E '.*PID ' \
|grep ${ConfigName%%:*} \
|awk '{print $1}' >${PidFile}
${ScriptFile} status ${Arg2}
}
execStop()
{
/usr/bin/fusermount -u ${Target}
[[ -e ${PidFile} ]] && {
PidNum=$(cat ${PidFile})
ps -P ${PidNum} |grep rclone \
&& kill ${PidNum}
rm -f ${PidFile}
}
}
execStatus()
{
#---
running=false
[[ -e ${PidFile} ]] && {
PidNum=$(cat ${PidFile})
ps -P ${PidNum} |grep rclone >/dev/null \
&& running=true
}
#---
df |grep "${Target}" >/dev/null && mounted=true || mounted=false
#---
[[ $running == false || $mounted == false ]] && { echo "Stopped"; [[ -e "${PidFile}" ]] && rm -fv "${PidFile}"; exit; }
echo "Running at pid ${PidNum} and mounted at ${Target}."
}
serviceCreateScript()
{
[[ -e ~/.local/share/systemd/user/rclone@.service ]] || {
[[ -d ~/.local/share/systemd/user ]] || mkdir -p ~/.local/share/systemd/user
cat << EOF >~/.local/share/systemd/user/rclone@.service
[Unit]
Description=rclone systemd startup for %i
[Service]
Type=simple
RemainAfterExit=false
PIDFile=/run/rclone/%i.pid
ExecStart=/usr/local/bin/rclone.wrapper start %i
ExecStop=/usr/local/bin/rclone.wrapper stop %i
[Install]
WantedBy=default.target
EOF
}
}
serviceInstall()
{
failed=false
grep "^\[${ConfigName}\]" "${ConfigFile}" >/dev/null || {
echo "Failed: Section '${ConfigName}' does not exists in the config file '${ConfigFile}'." >&2
failed=true
}
[[ -z "${Source}" ]] && {
echo "Failed: parameter 'source_dir' not defined over section '${ConfigName}' in the config file '${ConfigFile}'" >&2
failed=true
}
[[ -z "${Target}" ]] && {
echo "Failed: parameter 'target_dir' not defined over section '${ConfigName}' in the config file '${ConfigFile}'" >&2
failed=true
}
[[ $failed == true ]] && exit 1
systemctl --user is-enabled rclone@${Arg2}.service && {
echo "Service 'rclone@${Arg2}.service' already installed/enabled."
} || {
serviceCreateScript
systemctl --user --enable --now rclone@${Arg2}.service
systemctl --user status rclone@${Arg2}.service
}
}
serviceRemove()
{
systemctl --user stop rclone@${Arg2}.service
systemctl --user disable rclone@${Arg2}.service
}
ScriptFile="${0}"
ConfigName="${Arg2//-/:}"
ConfigFile=/home/${USER}/.config/rclone/rclone.conf
PidFile="/run/rclone/${Arg2}.pid"
LogFile="/var/log/rclone/${Arg2}.log"
Source="$( ParameterValue source_dir )"
Target="$( ParameterValue target_dir )"
case ${Arg1} in
restart) execStop; execStart;;
stop) execStop;;
start) execStart;;
status) execStatus;;
install) serviceInstall;;
uninstall) serviceRemove;;
*) help;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment