Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move runtime and state data out of config directory #6769

Open
ManDay opened this issue Apr 4, 2024 · 9 comments
Open

Move runtime and state data out of config directory #6769

ManDay opened this issue Apr 4, 2024 · 9 comments

Comments

@ManDay
Copy link

ManDay commented Apr 4, 2024

What is the issue?

Currently, transmission stores state data such as the resume or torrents files in $XDG_CONFIG_HOME together with the configuration. It would be better if transmission placed these files in configurable places, defaulting to $XDG_STATE_HOME by XDG. It's a not a big bother but unfortunate in enough cases where you may want to separate (possibly sensitive) runtime data from configuration, including backups. Could this be changed?

Which application of Transmission?

transmission-daemon

Which version of Transmission?

No response

@killemov
Copy link

killemov commented Apr 7, 2024

Currently, transmission stores state data such as the resume or torrents files in $XDG_CONFIG_HOME together with the configuration.

Would it be more accurate to state that you or your distro have configured Transmission to store that data in $XDG_CONFIG_HOME?

So reconfigure it to store torrents and resume-files in one place outside of $XDG_CONFIG_HOME and use a symbolic link to the settings.json inside $XDG_CONFIG_HOME. I did something similar with the actual configuration in /etc/transmission-daemon.

@ManDay
Copy link
Author

ManDay commented Apr 11, 2024

Would it be more accurate to state that you or your distro have configured Transmission to store that data in $XDG_CONFIG_HOME?

I don't think so. The documentation seems to be clear about the fact that everything (see Files) is stored in a single folder. While that folder can be moved or chosen, the fact that configuration and state lives together in it seems to be unconfigurable behaviour.

@qu1ck
Copy link
Contributor

qu1ck commented Apr 15, 2024

Well, symlinks are a thing. Move your folder to where you want state to be and then symlink your config from $XDG_CONFIG_HOME into it. Debian package stores config in /etc and data in /var/lib for example.

/var/lib/transmission-daemon/info$ ls -la
total 220
drwxr-xr-x 5 quick quick  4096 Apr 14 23:25 .
drwxr-xr-x 3 quick quick  4096 Aug  8  2022 ..
-rw------- 1 quick quick     2 Feb  4 15:25 bandwidth-groups.json
drwxr-xr-x 2 quick quick  4096 Jul  6  2019 blocklists
-rw------- 1 quick quick   664 Feb  3 20:44 dht.dat
drwxr-xr-x 2 quick quick 94208 Apr 14 23:25 resume
lrwxrwxrwx 1 quick quick    38 Jul  6  2019 settings.json -> /etc/transmission-daemon/settings.json
-rw------- 1 quick quick   168 Apr 14 23:25 stats.json
drwxr-xr-x 2 quick quick 98304 Apr 14 09:20 torrents

@ManDay
Copy link
Author

ManDay commented Apr 15, 2024

Symlinks are a way to work around the issue, yes (and thank you for the suggestion). I would still like to see transmission adhere to the XDG standard and leaving the directories configurable, so that one doesn't have to tinker with symlinks. Compensating for a lack of separation or configurability of a software data store is not the purpose of symlinks and using them in that manner still has downsides.

@qu1ck
Copy link
Contributor

qu1ck commented Apr 15, 2024

I agree that it makes sense to have a separate location for config. However XDG standard would not be right thing to appeal to here because it is for desktop apps and transmission daemon isn't one.

@ManDay
Copy link
Author

ManDay commented Apr 15, 2024

I agree but since I don't know of any other standard which is even remotely-as-established as XDG for these matters, what's to say that transmission shouldn't use it; it's already using .config for that matter.

@stephenboston
Copy link

There is no respectable standard that supports storing configuration and state in the same location. We might want to version config but we don't want to version state.

But never mind. The symlink workaround works okay. It's likely that achieving backwards compatibility for the change is a nightmare and risks destabilizing the app through the release.

@ManDay
Copy link
Author

ManDay commented Apr 20, 2024

The symlink workaround is quite tedious, if done correctly. Just recently, I wrote a script for firefox, which has the same problem, just a dozen times worse, to do that. And in the given form it's probably still missing a handful of cases.

It would be much more sustainable to -- instead of leaving it to each user to "hack around" the issue -- to do the change in transmission-daemon, bringing it to par with other software with state and config, and then write a migration/wrapper script for those who need to rely on the deprecated behaviour. Lest transmission becomes like firefox in that regard.

#!/bin/bash

run_dir="$XDG_RUNTIME_DIR/browser"
config_dir="$XDG_CONFIG_HOME/browser"
cache_dir="$XDG_CACHE_HOME/browser"

# Classes:
# Config: Always persistent (into config_dir)
# Cache: Deleteable after program termination, losing expected functionality (into cache_dir)
# State: Deletable after program termination (into run_dir)

# Will create a profile directory and symlink resources from different sources into place before binary execution
# Will replace config and cache resources by symlinks to their moved versions after binary termination

config_files=(
 "places.sqlite"
 "prefs.js"
 "addons.json"
 "content-prefs.sqlite"
 "logins.json"
 "permissions.sqlite"
 "storage.sqlite"
 "favicons.sqlite"
 "storage/default"
 "storage/permanent"
 "extensions.json"
 "extension-settings.json"
 "extensions"
 "cookies.sqlite"
 "chrome/userContent.css"
)

cache_files=(
)

# state_files=<everything else>

###

assert_dir( ) {
 if ! mkdir -p "$1"
 then
  echo "$1 is not a directory" >&2
 fi
}

symlink_all( ) {
 local d="$1"
 shift 1
 
 for t in "$@"
 do
  if [[ -e "$d/$t" ]]
  then
   mkdir -p "$(dirname "$t")"
   echo "Symlinking '$t' from '$d'" >&2
   ln -s "$d/$t" "$t"
  else
   echo "'$t' not yet in '$d'" >&2
   echo "$t"
  fi
 done
}

move_all( ) {
 local d="$1"
 shift 1
 
 for t in "$@"
 do
  if [[ -f "$t" ]]
  then
   mkdir -p "${d}/$(dirname "$t")"
   echo "Moving '$t' to '$d'" >&2
   mv "$t" "$d/$t"
   ln -s "$d/$t" "$t"
  else
   echo "'$t' not to be moved" >&2
  fi
 done
}

if ! [[ -d "$run_dir" ]]
then
 assert_dir "$run_dir"
 cd "$run_dir"
 
 mapfile -t missing_config < <(symlink_all "${config_dir}" "${config_files[@]}") 
 mapfile -t missing_cache < <(symlink_all "${cache_dir}" "${cache_files[@]}")
else
 missing_config=("${config_files[@]}")
 missing_cache=("${missing_cache[@]}")
fi

export HOME="$run_dir"
firefox --profile "$run_dir" "$@"

move_all "${config_dir}" "${missing_config[@]}"
move_all "${cache_dir}" "${missing_cache[@]}"

@stephenboston
Copy link

stephenboston commented Apr 20, 2024

For back compatibility perhaps all we need to do is set the default directories through new entries in settings.json. Users who want torrents and resume etc in other directories can set them through those entries.

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

No branches or pull requests

4 participants