tl;dr: rsync --usermap=dst:src --groupmap=src:dst --chmod=F664 $from $to
for a years i have the media
alias in my shell, that just scp given file to a
www-root, and copy a direct link to the clipboard. i might simply run "media
config.yaml" from anywhere in filesystem, and in just a second thers is a
direct, non-expiring link to a file, right in my system clipboard.
it was implemented in the most straitforward way: scp
to copy files to a
remote, and urlencode
(from url-tools zsh plugin) to make a properly escaped
url from a filesystem path.
until recently it works just fine, but now the syncthings daemon watches the same directory. it appears that i have to unify the permissions, to make files accessible by the web-server, and read-writable by syncthing.
the naive solution would be to add something like this to a script:
# ...
scp $src web-server:/var/www/media/
ssh web-server "chmod 0664 /var/www/media/$src; \
chown www-data:www-data /var/www/media/$src"
...
but that feels like an ugly solution, and i don't want to open one more ssh connection, just because of time it takes.
it appeared that rsync
fits perfectly for this case. by defualt, rsync will
keep the source's files owner and permissions, even if no such user or group
exists on the remote. but we have an options to instruct rsync to remap, or even
override owner and permissions on a remote.
we going to use three flags:
--usermap='*:www-data'
, which reads as "any source's owner becomes www-data on a
remote machine",
--groupmap='*:www-data
which is the same as above, but for groups, and
--chmod=F664
, which tells rsync to apply 0664 permissions to destenation
files.
the updated version of the media
script below:
if [[ "$1" == "" ]]; then
echo "Usage: media file/to/upload"
return 1
fi
file=$(echo $1 | awk -F "/" '{print $NF}')
rsync --progress --chmod=F664 \
--usermap='*:www-data' \
--groupmap='*:www-data' \
"$1" web-server:/var/www/media/
result="https://media.nikonov.tech/$(urlencode $file)"
echo "Done! Link copied to the clipboard\n$result"
echo -n $result | pbcopy
refer to man 1 rsync for details