I'm writing this here mostly to suggest the improvements to this wiki article. The instructions from that article should still work fine with this version.
I stumbled upon the article itself a while ago and found the service template there way too cumbersome. Later, when I had free time I wrapped my head around it, found the way to cut down and improve it.
Here's the result:
[Unit]
Description=RClone mount of %u's remote %i
Documentation=http://rclone.org/docs/
After=network-online.target
[Service]
Type=notify
Environment=REMOTE_PATH=
Environment=MOUNT_TARGET=%h/%i
Environment=RCLONE_CONFIG=%E/rclone/rclone.conf
# Override defaults globally.
EnvironmentFile=-%E/rclone/systemd/global.env
#Overwrite default environment settings with settings from the file if present
EnvironmentFile=-%E/rclone/systemd/%i.env
ExecStartPre=sh -c 'rclone listremotes | grep -q "^%i:$"'
ExecStartPre=sh -c 'test -w "${MOUNT_TARGET}" || mkdir -p "${MOUNT_TARGET}"'
ExecStart=rclone mount "%i:${REMOTE_PATH}" "${MOUNT_TARGET}"
ExecStartPost=-/bin/sh -c "${POST_MOUNT_SCRIPT}"
ExecStopPost=-fusermount -z -u "${MOUNT_TARGET}"
# Restart info
RestartPreventExitStatus=7
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
And this is all that's required.
Why it became so short:
A quote from rclone manuals:
To find the name of the environment variable, first, take the long option name, strip the leading
--
, change-
to_
, make upper case and prependRCLONE_
.
So, no need to use the --flags
, and thus no need to explicitly state all the possible defaults inside the service template, e.g. RCLONE_CONFIG
here is an equivalent of --config
flag.
What are the other percent values:
Those can be found in systemd.unit(5) manual, the ones used here:
%h
resolves to the home directory of the user running the service manager instance, /home/usrname
in most distros.
%E
resolves to the configuration directory root, for user instances this is $XDG_CONFIG_HOME
if set, or %h/.config
%u
resolves to the username of the user running the service manager instance.
Why use these percent values? For portability, not all linux distros have user homes in /home
, not all distros may store user config files in ~/.cofing
, etc.
The pre-start checks:
ExecStartPre=sh -c 'rclone listremotes | grep -q "^%i:$"'
will fail if rclone binary is not available, will fail if rclone.conf is not available (no need to check for these two explicitly), will fail if the requested mount name is not configured.
ExecStartPre=sh -c 'test -w "${MOUNT_TARGET}" || mkdir -p "${MOUNT_TARGET}"'
will fail if directory does not exist, is not writable and can't be created. No need to check for everything separately. If the directory does not exist but can be created, it will be created here.
ExecStartPost
should not fail the whole unit (imo), so the =-
should be used.
ExecStop=fusermount -u "${MOUNT_TARGET}"
is identical in effect to just sending SIGTERM to the rclone mount process, which systemd does if no ExecStop
command is specified, so I omitted it.
ExecStopPost=-fusermount -z -u "${MOUNT_TARGET}"
is to make sure that the mount target becomes usable to any new processes. rclone mount process when interrupted does not make sure the fuser actually unmounts properly, if there are processes that keep the mount busy, the mount becomes unaccessible and can't be remounted, lazy unmount solves that. If the "${MOUNT_TARGET}"
was already unmounted properly, nothing will happen, fusermount
checks that the specified target exists in /etc/mtab
before trying to unmount.
Without this one, I kept ending up in a situation where I stopped the mount that was still accessed by some process, had to stop that process and then manually unmount the "stuck" mount point.
RestartPreventExitStatus=7
is there because according to the rclone manual the exit status '7' is a fatal error, one that more retries won't fix.