ActiveState/appdirs

Getting write permission to site directories?

k4kfh opened this issue · 4 comments

k4kfh commented

Sorry to ask a question in an issue, but I'm new to this and haven't had any luck asking in other places.

I'm trying to package a CLI app, and I want it to have a "site-wide" data file. In other words, I want to install it on a system, and whenever any user calls it, they'll be operating with the same set of data. I'll be doing this on Ubuntu Linux, so site_data_dir is /usr/local/share/MyApp. That's fine, but how do I get write permission to that directory?

Also, in the event that you had two installations of the same app in two different virtualenvs, wouldn't they be using the same directories and interfere with one another?

Again, terribly sorry for using your Issues page like a Q&A, I'm just thoroughly stuck...

Looks like /usr/local/share is typically owned by root:root. I think you'd need to install your data files in there as part of installing your system package (assuming you've made a .deb). If you want to gain access from within the script, well, you'd probably need to do a sudo mkdir in a subprocess or similar, and then hope the user has root permissions and also make some decisions about ownership for your new directory. Do you need an application account or group created as part of setting up your app? All these solutions are a bit more involved than perhaps you wanted to be, but I think that's the reality of trying to have a directory that potentially any user could write to.

@micahculpepper is basically correct, files in /usr/local/ are root-owned, same as /usr/ — the difference is that /usr/local/ is permitted to be written to by local (root-privileged) users installing ad-hoc packages, whereas /usr/ should only ever contain files managed by the system's package management. You'd still have to sudo make install to create files in /usr/local/, though.

If your application just needs to create a data file in /usr/local/share/appname at install time, then that'd be the way to do it. (You had to be root to install your binary into /usr/local/bin/, after all...)

If your application needs write access AFTER install (IOW, the data file is going to be modified at runtime, by the application running under a user account), then /usr/local/share/ is not the correct location. Read-write data should be stored in /var/, /run/, or $HOME/.local/share/. /usr(/local)/share is meant to hold static, read-only data files that are only modified by specialized root-privileged processes (think update-mime-database or desktop-file-install.)

@micahculpepper is basically correct

Sorry, that came out wrong. You are correct, not "basically" — what I was trying to say was something more along the lines of, "micah's comment is pretty much the whole story". The only thing I really had to add was the bit about .../share/ being reserved for non-volatile data.

On this:

Also, in the event that you had two installations of the same app in two different virtualenvs, wouldn't they be using the same directories and interfere with one another?

Well, yes, but that's what you said you want. If you have multiple user instances of your app sharing the same data, then that implies managing that data outside of the virtualenv — multiple separate users aren't going to be running the app from the same virtualenv, "shared venvs" aren't a thing.

It just means that if you want multiple versions/configurations/etc. of your app to coexist, each with its own shared data file, then you have to manage that yourself. Something like multiple /usr/share/appname/version_or_some_id/ directories.