ipn/{ipnserver,ipnlocal}: support incoming Taildrop on QNAP

Signed-off-by: Denton Gentry <dgentry@tailscale.com>
pull/5165/head
Denton Gentry 2 years ago committed by Denton Gentry
parent 1cae618b03
commit d17849461c

@ -174,11 +174,11 @@ type LocalBackend struct {
// same as the Network Extension lifetime and we can thus avoid
// double-copying files by writing them to the right location
// immediately.
// It's also used on Synology & TrueNAS, but in that case DoFinalRename
// is also set true, which moves the *.partial file to its final
// name on completion.
// It's also used on several NAS platforms (Synology, TrueNAS, etc)
// but in that case DoFinalRename is also set true, which moves the
// *.partial file to its final name on completion.
directFileRoot string
directFileDoFinalRename bool // false on macOS, true on Synology & TrueNAS
directFileDoFinalRename bool // false on macOS, true on several NAS platforms
// statusLock must be held before calling statusChanged.Wait() or
// statusChanged.Broadcast().

@ -772,7 +772,7 @@ func New(logf logger.Logf, logid string, store ipn.StateStore, eng wgengine.Engi
dg := distro.Get()
switch dg {
case distro.Synology, distro.TrueNAS:
case distro.Synology, distro.TrueNAS, distro.QNAP:
// See if they have a "Taildrop" share.
// See https://github.com/tailscale/tailscale/issues/2179#issuecomment-982821319
path, err := findTaildropDir(dg)
@ -1123,6 +1123,8 @@ func findTaildropDir(dg distro.Distro) (string, error) {
return findSynologyTaildropDir(name)
case distro.TrueNAS:
return findTrueNASTaildropDir(name)
case distro.QNAP:
return findQnapTaildropDir(name)
}
return "", fmt.Errorf("%s is an unsupported distro for Taildrop dir", dg)
}
@ -1163,6 +1165,28 @@ func findTrueNASTaildropDir(name string) (dir string, err error) {
return "", fmt.Errorf("shared folder %q not found", name)
}
// findQnapTaildropDir checks if a Shared Folder named "Taildrop" exists.
func findQnapTaildropDir(name string) (string, error) {
dir := fmt.Sprintf("/share/%s", name)
fi, err := os.Stat(dir)
if err != nil {
return "", fmt.Errorf("shared folder %q not found", name)
}
if fi.IsDir() {
return dir, nil
}
// share/Taildrop is usually a symlink to CACHEDEV1_DATA/Taildrop/ or some such.
fullpath, err := filepath.EvalSymlinks(dir)
if err != nil {
return "", fmt.Errorf("symlink to shared folder %q not found", name)
}
if fi, err = os.Stat(fullpath); err == nil && fi.IsDir() {
return dir, nil // return the symlink, how QNAP set it up
}
return "", fmt.Errorf("shared folder %q not found", name)
}
func loadExtraEnv() (env []string, err error) {
if runtime.GOOS != "windows" {
return nil, nil

Loading…
Cancel
Save