Skip to content

WIP Read tracks from a mounted library instead of downloading them - #821

Draft
lachlan-00 wants to merge 1 commit into
NeptuneHub:mainfrom
lachlan-00:localfiles
Draft

lachlan-00 wants to merge 1 commit into
NeptuneHub:mainfrom
lachlan-00:localfiles

Conversation

@lachlan-00

Copy link
Copy Markdown

WIP My server has too many files to download and look at files individually so I am mounting the local files in the container using a ro volume

Keeping at draft while i test on my server.

    environment:
      LOCAL_FILE_ACCESS: "true"
      LOCAL_FILE_ROOTS: "/mnt/files-music/albums"
    volumes:
      - /mnt/files-music/albums:/mnt/files-music/albums:ro

Every provider reports the path it holds a track at, so an install whose library is mounted into the container can read the file directly: no HTTP round trip, no second copy of the bytes, and no load on the media server.

Provider-agnostic - it lives in the dispatcher, and all six backends populate Path/FilePath.

Off by default. LOCAL_FILE_ACCESS enables it, LOCAL_FILE_ROOTS allowlists the directories a track may come from, and LOCAL_FILE_PATH_MAP rewrites the server's prefix onto this container's mount point.

Two properties the implementation is built around:

  • The pipeline DELETES whatever download_track returns (the finally in tasks/analysis/album.py), so the library file is never returned. What the caller gets is a link inside TEMP_DIR - a symlink, or a hardlink where symlinks are not permitted - and removing it never touches the target.
  • The path comes from the media server and is therefore untrusted. The REAL location is resolved first, so a symlink planted in the library cannot escape, and anything outside LOCAL_FILE_ROOTS is refused. With no root configured nothing is read at all.

Every failure returns None and the track is downloaded as before, so local access is an optimisation that cannot become a new way for analysis to fail.

AS-IS

TO-BE

Test

Other useful information

Checklist

Type of change:

  • Bug fix
  • New feature
  • Documentation
  • Refactor
  • Breaking change

Tested on architecture:

  • Intel
  • ARM
  • -noavx2
  • NVIDIA image

Tested on media server:

  • Navidrome
  • Jellyfin
  • Emby
  • Lyrion

Updated:

  • Documentation
  • Unit test
  • Integration test

Other:

  • CONTRIBUTING.md read and accepted
  • Checked performance on a big library (> 150k songs) works without issues

Related ISSUE: Closes #xx

Every provider reports the path it holds a track at, so an install whose
library is mounted into the container can read the file directly: no HTTP
round trip, no second copy of the bytes, and no load on the media server.
Provider-agnostic - it lives in the dispatcher, and all six backends
populate Path/FilePath.

Off by default. LOCAL_FILE_ACCESS enables it, LOCAL_FILE_ROOTS allowlists
the directories a track may come from, and LOCAL_FILE_PATH_MAP rewrites the
server's prefix onto this container's mount point.

Two properties the implementation is built around:

* The pipeline DELETES whatever download_track returns (the finally in
  tasks/analysis/album.py), so the library file is never returned. What the
  caller gets is a link inside TEMP_DIR - a symlink, or a hardlink where
  symlinks are not permitted - and removing it never touches the target.
* The path comes from the media server and is therefore untrusted. The
  REAL location is resolved first, so a symlink planted in the library
  cannot escape, and anything outside LOCAL_FILE_ROOTS is refused. With no
  root configured nothing is read at all.

Every failure returns None and the track is downloaded as before, so local
access is an optimisation that cannot become a new way for analysis to fail.
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant