After running
into
problems trying to get git-annex
to run on an SMB
share
on my Synology
DS216+,
prompted by the git-annex
author,
and an example with an earlier Synology
NAS I
decided to install the standalone version of
git-annex
directly on my Synology DS216+.
My approach was similar to the earlier "Synology NAS and git annex"
tip,
but the DS216+ uses an x86_64
CPU:
ewen@nas01:/$ grep "model name" /proc/cpuinfo | uniq
model name : Intel(R) Celeron(R) CPU N3060 @ 1.60GHz
ewen@nas01:/$
and I chose a slightly different approach to getting everything
working, in part based on my experience setting up the standalone
git-annex
on a Mac OS X
server.
I am using Synology DSM "DSM 6.1.1-15101 Update 4", which is the latest
release as I write (released 2017-05-25).
To install git-annex
:
In the Synology web interface (DSM) enable the "SSH Service", in Control Panel -> Terminal, by ticking "Enable SSH Service", and verify that you can ssh to your Synology NAS. Only accounts in the administrators group can use the ssh service, so you will need to create an administrator account to use if you do not already have one. (If your Synology NAS is exposed to the Internet directly now would be a very good time to ensure you have a strong password on the account; mine is behind a separate firewall.)
In the Synology web interface (DSM) go to the Package Center and search for "Git Server" (
git
) from Synology and install that package. It should install in a few seconds, and currently appears to installgit
2.8.0:ewen@nas01:/$ git --version git version 2.8.0 ewen@nas01:/$
which while not current (eg my laptop has
git
2.13.0), is only about a year old. It is a symlink (in/usr/bin/git
) into theGit
package in/var/packages/Git/target/bin/git
.Verify that you can now reach the necessary parts of the git package:
for FILE in git git-shell git-receive-pack git-upload-pack; do which "${FILE}" done
should produce something like:
/bin/git /bin/git-shell /bin/git-receive-pack /bin/git-upload-pack
Download the latest
git-annex
standalone x86-64 tarball, and gpg signatureVerify the
git-annex
gpg signature (as with previous installs):gpg --verify git-annex-standalone-amd64.tar.gz.sig
which should report a "Good signature" from the "git-annex distribution signing key" (DSA key ID 89C809CB, Primary key fingerprint: 4005 5C6A FD2D 526B 2961 E78F 5EE1 DBA7 89C8 09CB).
If you have not already verified that key is the right signature key it can be verified against, eg, keys in the Debian keyring as Joey Hess is a former Debian Developer.
Once you are happy with
git-annex
tarball you downloaded, copy it onto the NAS somewhere suitable, eg on the NAS:sudo mkdir /volume1/thirdparty sudo mkdir /volume1/thirdparty/archives sudo chown "$(id -nu):$(id -ng)" /volume1/thirdparty/archives
then from wherever you downloaded the
git-annex
archive:scp -p git-annex-standalone-amd64.tar.gz* nas01.em.naos.co.nz:/volume1/thirdparty/archives/
Extract the archive on the NAS:
cd /volume1/thidparty sudo tar -xzf archives/git-annex-standalone-amd64.tar.gz
The extracted archive is about 160MB, because of bundling all the required tools:
ewen@nas01:/volume1/thirdparty$ du -sm git-annex.linux/ 161 git-annex.linux/ ewen@nas01:/volume1/thirdparty$
to make it a stand alone version (as well as static linking everything).
Symlink
git-annex
into/usr/local/bin
so we have a common placeto reference these binaries:
cd /usr/local/bin sudo ln -s /volume1/thirdparty/git-annex.linux/git-annex .
In a normal login shell
/usr/local/bin
will be on thePATH
, and:which git-annex
should print:
/usr/local/bin/git-annex
and you should be able to run
git-annex
by itself and have it print out the basic help text.Unfortunately this does not work for non-interactive shells, because the Synology NAS uses the "
/bin/sh
" symlink tobash
, which means that non-interactive shells do not process~/.bashrc
, and non-interactive shells also do not read/etc/profile
(which is where/usr/local/bin/
is added to thePATH
). So we have to add some more work arounds, with symlinks into/usr/bin/
later (see below).For reference, this is my
/etc/passwd
entry created by the Synology NAS web interface (DSM):ewen@nas01:~$ grep "$(id -un):" /etc/passwd ewen:x:1026:100:Ewen McNeill:/var/services/homes/ewen:/bin/sh ewen@nas01:~$
To fix the warning:
warning: /bin/sh: setlocale: LC_ALL: cannot change locale (en_US.utf8)
we have to pre-create the
locales
directory that thegit-annex
runshell
script tries to write the locales into, with permissions that a regular user can write into, and then rungit-annex
once.sudo mkdir /volume1/thirdparty/git-annex.linux/locales sudo chown "$(id -un):$(id -gn)" /volume1/thirdparty/git-annex.linux/locales
On the Synology NAS, with the default locale:
ewen@nas01:~$ set | egrep "LANG|LC_ALL" LANG=en_US.utf8 LC_ALL=en_US.utf8 ewen@nas01:~$
this should create:
ewen@nas01:~$ ls /volume1/thirdparty/git-annex.linux/locales/en_US.utf8/ LC_ADDRESS LC_IDENTIFICATION LC_MONETARY LC_PAPER LC_COLLATE LC_MEASUREMENT LC_NAME LC_TELEPHONE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME ewen@nas01:~$
And then we can revert the file permissions to root owned:
sudo chown -R root:root /volume1/thirdparty/git-annex.linux/locales
Note that it is possible to change the interactive locale by setting
LANG
andLC_ALL
in, eg,~/.bash_profile
(but this will not work for non-interactive shells).git-annex
only supportsutf8
locales, but that is probably the most useful modern choice anyway. (I chose not to bother asen_US.utf8
is close enough to my usual locale --en_NZ.utf8
-- that it did not really matter at present; the main difference would be the date format, and I do not expect to usegit-annex
interactively on the Synology NAS often enough for that to be an issue. I just wanted the warning message gone, as it turns up repeatedly in interactive use.)To usefully use
git-annex
you probably also want to enable the "User Home" feature, so that the home directory for your user is created and you can store things likessh
keys; this also enables a per-user share via (CIFS, etc). To do this, in the Synology web interface (DSM) go to Control Panel -> User -> User Home and tick "Enable user home service", and hit Apply. This will create a/volume1/homes
directory, a directory for each user, and a/var/services/homes
symlink pointing at/volume1/homes
so that the shell directories are reachable.Once that is done, when you
ssh
into the NAS, the message about your home directory being missing:Could not chdir to home directory /var/services/homes/ewen: No such
file or directory
should be gone, and you should arrive in your home directory at login:
ewen@nas01:~$ pwd /var/services/homes/ewen ewen@nas01:~$
If you do have a home directory, you might also want to do some common git setup:
git config --global user.email ... # Insert your email address git config --global user.name ... # Insert your name
which should run without any complaints, creating a
~/.gitconfig
file with the values you supply.Assuming you do have a user home directory you can usefully run the next step to have
git-annex
auto-generate a couple of necessary helper scripts in${HOME}/.ssh/
-- which cannot be automatically created otherwise (but see the contents below if you want to try to create them by hand).To create the helper scripts automatically run:
/volume1/thirdparty/git-annex.linux/runshell
which will start a new shell, with
/volume1/thirdparty/git-annex.linux/bin
in the "${PATH}
" so you can interactively use thegit-annex
versions of tools (eg, for testing).It also creates the two helper scripts that we need:
$ ls -l ${HOME}/.ssh total 8 -rwxrwxrwx 1 ewen users 241 May 28 11:20 git-annex-shell -rwxrwxrwx 1 ewen users 74 May 28 11:20 git-annex-wrapper $
Since (a) these scripts are not user specific and (b) "
${HOME}/.ssh
" is not on thePATH
by default, it is much more useful to move these scripts into, eg,/usr/local/bin/
, so they are in a central location.To do this:
cd /usr/local/bin sudo mv "${HOME}/.ssh/git-annex-shell" . sudo mv "${HOME}/.ssh/git-annex-wrapper" . sudo chown root:root git-annex-shell git-annex-wrapper sudo chmod 755 git-annex-shell git-annex-wrapper
This should give you two trivial shell scripts, which hard code the path to where you unpacked
git-annex
:ewen@nas01:/usr/local/bin$ ls -l git-annex-* -rwxr-xr-x 1 root root 241 May 28 11:20 git-annex-shell -rwxr-xr-x 1 root root 74 May 28 11:20 git-annex-wrapper ewen@nas01:/usr/local/bin$ cat git-annex-shell #!/bin/sh set -e if [ "x$SSH_ORIGINAL_COMMAND" != "x" ]; then exec '/volume1/thirdparty/git-annex.linux/runshell' git-annex-shell -c "$SSH_ORIGINAL_COMMAND" else exec '/volume1/thirdparty/git-annex.linux/runshell' git-annex-shell -c "$@" fi ewen@nas01:/usr/local/bin$ cat git-annex-wrapper #!/bin/sh set -e exec '/volume1/thirdparty/git-annex.linux/runshell' "$@" ewen@nas01:/usr/local/bin$
(which gives you enough to create them by hand if you need to, substituting the path where you unpacked the
git-annex
standalone archive for/volume1/thirdparty/
).To be able to run these helper scripts, and
git-annex
itself, from a non-interactive shell -- such as whengit-annex
itself is trying to run the remotegit-annex
, we need to ensure thatgit-annex
,git-annex-shell
andgit-annex-wrapper
are reachable via a directory that is in the defaultPATH
. That defaultPATH
is very minimal, containing:ewen@ashram:~$ ssh nas01.em.naos.co.nz 'set' | grep PATH PATH=/usr/bin:/bin:/usr/sbin:/sbin ewen@ashram:~$
Since
/bin
and/sbin
are both symlinks anyway:ewen@nas01:~$ ls -l /bin lrwxrwxrwx 1 root root 7 May 21 18:57 /bin -> usr/bin ewen@nas01:~$ ls -l /sbin lrwxrwxrwx 1 root root 8 May 21 18:57 /sbin -> usr/sbin ewen@nas01:~$
that gives us only two choices --
/usr/bin
and/usr/sbin
-- which are on the default PATH. Given thatgit-annex
is not a system administration tool, only/usr/bin
makes sense.To do symlink them into
/usr/bin
:cd /usr/bin sudo ln -s /usr/local/bin/git-annex* .
I am expecting that this step may need to be redone periodically, as various Synology updates update
/usr/bin
, which is why I have a "master" copy in/usr/local/bin
and just symlink it into/usr/bin
. Forgit-annex
this is a chain of two symlinks:ewen@nas01:~$ ls -l /usr/bin/git-annex lrwxrwxrwx 1 root root 24 May 28 11:57 /usr/bin/git-annex -> /usr/local/bin/git-annex ewen@nas01:~$ ls -l /usr/local/bin/git-annex lrwxrwxrwx 1 root root 45 May 28 11:01 /usr/local/bin/git-annex -> /volume1/thirdparty/git-annex.linux/git-annex ewen@nas01:~$
which is slightly inefficient, but still convenient for restoring later.
Now is a convenient time to set up ssh key access to the Synology NAS, by creating
${HOME}/.ssh/authorized_keys
as usual. Since we do not need a special key to trigger a special hard coded path togit-annex-shell
(because it is on thePATH
) you can use your regular key if you want rather than a dedicated "git-annex on Synology NAS" key.Ensure that the permissions on the
${HOME}/.ssh
directory and theauthorized_keys
file are appropriately locked down so thatsshd
will trust them, eg:cd chmod go-w . chmod 2700 .ssh chmod 400 .ssh/authorized_keys
and then you should be able to ssh to the NAS with key authentication; if it does not work use "
ssh -v ...
" to figure out the error, which is most likely a permissions problem like:debug1: Remote: Ignored authorized keys: bad ownership or modes for directory /volume1/homes/ewen
because the permissions on the default created directories are very permissive (and would allow anyone to create a ssh authorized key entry), so
sshd
will not trust the files until the permissions are corrected.All going well at this point you should be able to verify that you can reach all the necessary programs from a non-interactive ssh session with something like:
for FILE in git-annex git-annex-shell git-annex-wrapper git git-shell git-receive-pack git-upload-pack; do ssh NAS "which ${FILE}" done
and get back answers like:
/usr/bin/git-annex /usr/bin/git-annex-shell /usr/bin/git-annex-wrapper /usr/bin/git /usr/bin/git-shell /usr/bin/git-receive-pack /usr/bin/git-upload-pack
if one or more of those is missing from the output you will want to figure out why before continuing.
To centralise my
git-annex
storage, I created an "annex" share through the Synology NAS web interface (DSM) in Control Panel -> Shared Folder. This created a/volume1/annex
directory.To make that easily accessible, I created a top level symlink to it:
sudo ln -s /volume1/annex /
giving:
ewen@nas01:~$ ls -l /annex lrwxrwxrwx+ 1 root root 14 May 28 12:10 /annex -> /volume1/annex ewen@nas01:~$
This matches the pattern I use on some other machines.
Once all these setup is done, git-annex
can be used effectively
like any other Linux/Unix machine. For instance you can "push a
clone" onto the
NAS
using "git bundle
" and "git clone
" from the bundle, and then
add that as a "git remote" and use "
git annex sync" and "
git
annex copy
...`" to copy into it.
The "standalone git-annex
" will probably need updating periodically
(for bug/security fixes, new features, etc), but it should be possible
to do that simply by replacing the unpacked tarfile contents as required;
everything else points back to that directory. (Possibly the locale
generation step might need to be done by hand again.)
Finally for future reference, it is also possible to run a Debian chroot on the Synology NAS, which would open up even more possibilities for using the NAS as a more general purpose machine.
ETA 2017-06-25: Beware that (certain?) Synology updates will rebuild the root file system, and/or clean out unexpected symlinks. So after an update, or reboot, it is necessary to redo:
sudo ln -s /volume1/annex /
cd /usr/bin
sudo ln -s /usr/local/bin/git-annex* .
before git-annex-shell
will be automatically found, and
the nas01:/annex/...
paths will work again
I have worked around this by creating /usr/local/bin/activate-git-annex
containing:
#! /bin/sh
# Relink git-annex paths onto the Synology root file system
#
if [ -e /annex ]; then
:
else
sudo ln -s /volume1/annex /
fi
cd /usr/bin && for FILE in /usr/local/bin/git-annex*; do
if [ -e "$(basename ${FILE})" ]; then
:
else
sudo ln -s "${FILE}" .;
fi
done
So that, when git-annex
breaks after an upgrade, I can just run:
activate-git-annex
from an interactive shell and it will all work again. (/usr/local/bin
seems to survive upgrades, but unfortunately, as noted above, is not
in the default path for a non-interactive shell, so it is not a complete
solution. However it is in the default path for an interactive shell
hence the simple command above.)
ETA 2017-07-16: Fixed up logic of "check if already done" test in
/usr/local/bin/activate-git-annex
. It appears that will need to be
run every time that the Synology is updated, at least in a way that
will cause it to reboot.
ETA 2018-06-08: Due to a git-annex
security
advisory,
I updated the git-annex
standalone version on my Synology DS216+ NAS
by moving /volume1/thirdparty/git-annex.linux
to another name, and then
unpacking a fresh download of the git-annex
Linux standalone
version,
following the instructions above.
Unfortunately I ran into a problem with the locale
creation/parsing
which resulted in the amd64
(x86_64
) standalone build of
git-annex
not running after the locales had been built with the
error message:
sh: loadlocale.c:129: _nl_intern_locale_data: Assertion `cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' failed.
error: git-annex died of signal 6
but based on a comment from Joey a couple of months ago on that
issue,
I instead tried the "ancient kernels" i386
build,
and that seemd to work. Per my comment on the
issue
I expect the issue is with libc
and locale
tool versions, rather
than the kernel -- but it appears at present the i386-archaic
version is still built with an old enough version of a Linux
environment to work.
ETA 2018-09-08: Unfortunately the work around of using the
"Ancient i386 build" stopped working on the Synology DS216+ NAS
after upgrading the firmware to DSM 6.2-23739 Update
2. Every attempt to run git annex
after upgrading
then failed with:
git-annex: timer_create: Bad address
as I reported in a git-annex
bug.
timer_create
is a Linux kernel function, used by Haskell programs for threading.
I initially suspected that maybe Synology had removed that from
their kernel (historically Microsoft WSL did not implement
timer_create
which
caused similar issues).
However after filing Synology ticket 2082132, they gave me the hint that it was probably a linking issue, so I guessed possibly the kernel/libraries on the Synology were now too new/changed from what the "Ancient i386 standalone build" expected.
So I moved back to trying the 64-bit version again -- having seen
others run into the LC_TIME
issue (noted above) elsewhere and now
having a better idea how to work around it. I downloaded the latest
git-annex standalone build
for x86-64
, and installed that (as described above/earlier), but I
did find that the locales
were not being built by the git-annex
scipts... which possibly explains the LC_TIME
issues, if it is trying
to access the system's locale
information with a different libc
linked in (it looks like the LC_TIME
structure changed in size).
After some experimentation the easiest sufficient fix seemed to be:
LC_ALL=C git-annex version
which did work:
ewen@nas01:~$ set | egrep 'LANG|LC_'
LANG=en_US.utf8
LC_ALL=en_US.utf8
ewen@nas01:~$ LC_ALL=C git-annex version
git-annex version: 6.20180807-g48d11a5df
build flags: Assistant Webapp Pairing S3(multipartupload)(storageclasses) WebDAV Inotify DBus DesktopNotify ConcurrentOutput TorrentParser MagicMime Feeds Testsuite
dependency versions: aws-0.19 bloomfilter-2.0.1.0 cryptonite-0.25 DAV-1.3.2 feed-1.0.0.0 ghc-8.2.2 http-client-0.5.13 persistent-sqlite-2.8.1.2 torrent-10000.1.1 uuid-1.3.13 yesod-1.6.0
key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL
remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar hook external
operating system: linux x86_64
supported repository versions: 3 5 6
upgrade supported from repository versions: 0 1 2 3 4 5
ewen@nas01:~$
so to make that work automatically, I edited the shell script wrappers of:
git-annex
git-annex-shell
git-annex-wrapper
to add some lines saying:
# 2018-09-08 - work around for LC_TIME mismatch in locales
LC_ALL=C
export LC_ALL
near the top of each shell script, to override the Synology DS216+
default value (LC_ALL=en_US.utf8
).
Particularly for running git-annex
I am quite happy with the historic
"C" formatting of things, and because those are compiled in rather
than loaded from a file, I do not run into the LC_TIME
issues on
trying to load the locales from a file.
Thankfully this means git-annex
works again for me, and I can close
the Synology ticket. I've also posted a comment on the git-annex
bug
to hopefully give others a hint on how to get it working again.
ETA 2023-07-19: The Synology DS216+ NAS still seems to need the:
# 2018-09-08 - work around for LC_TIME mismatch in locales
LC_ALL=C
export LC_ALL
work around for the git-annex x86_64 stand alone build, but otherwise git annex 10.20230408 seems to run on the Synology DS216+ (at least with the older Synology OS; I still have not upgraded to the later 2021/2022 OS major release on this old NAS). The 10.20230408 seems to be the "current" stand alone release, even though there was a git annex 10.20230626 release, and the "current" release files are from 2023-06-26. So my Synology NAS install is not completely current, but is at least much closer to current now.
ewen@nas01:~$ git annex version
git-annex version: 10.20230408-g5b1e8ba77
build flags: Assistant Webapp Pairing Inotify DBus DesktopNotify TorrentParser MagicMime Benchmark Feeds Testsuite S3 WebDAV
dependency versions: aws-0.22.1 bloomfilter-2.0.1.0 cryptonite-0.29 DAV-1.3.4 feed-1.3.2.1 ghc-9.0.2 http-client-0.7.13.1 persistent-sqlite-2.13.1.0 torrent-10000.1.1 uuid-1.3.15 yesod-1.6.2.1
key/value backends: SHA256E SHA256 SHA512E SHA512 SHA224E SHA224 SHA384E SHA384 SHA3_256E SHA3_256 SHA3_512E SHA3_512 SHA3_224E SHA3_224 SHA3_384E SHA3_384 SKEIN256E SKEIN256 SKEIN512E SKEIN512 BLAKE2B256E BLAKE2B256 BLAKE2B512E BLAKE2B512 BLAKE2B160E BLAKE2B160 BLAKE2B224E BLAKE2B224 BLAKE2B384E BLAKE2B384 BLAKE2BP512E BLAKE2BP512 BLAKE2S256E BLAKE2S256 BLAKE2S160E BLAKE2S160 BLAKE2S224E BLAKE2S224 BLAKE2SP256E BLAKE2SP256 BLAKE2SP224E BLAKE2SP224 SHA1E SHA1 MD5E MD5 WORM URL X*
remote types: git gcrypt p2p S3 bup directory rsync web bittorrent webdav adb tahoe glacier ddar git-lfs httpalso borg hook external
operating system: linux x86_64
supported repository versions: 8 9 10
upgrade supported from repository versions: 0 1 2 3 4 5 6 7 8 9 10
ewen@nas01:~$