VSCode - what exactly --user-data-dir is specifiying - linux

What exactly is --user-data-dir specifiying?
From --help parameter:
--user-data-dir <dir> Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.
Is it storing some temporary files there?
Is it about the access path to config files?
I am asking as I want to run VSCode (or Codium to be more exact) with sudo (I want to edit system config file that is read restricted) which requires this parameter for reasons unclear to me.

Since sudo-ing VS Code at command-line launch is only a thing on Linux, this question assumes you're on Linux, and restricts its context to Linux.
TL;DR
To answer your question directly: the user-data-dir parameter points to a folder where all personalisation except extensions resides — unique to each user.
Why does sudo-ing Code need --user-data-dir?
In typical installations of either OS and VS Code, this folder owned by the regular user cannot be accessed by the superuser.
Hence a VS Code session running with effective UID=0 tries but fails to write to the invoking user's (not the superuser's) config folder. This is what the error message prevents from happening, by forcing the user to provide an explicit root-accessible folder.
Detailed Explanation
There are two main folders that VS Code uses to store configuration data:
An extensions folder (self explanatory) — contained in ~/.vscode[1]
user-data-dir; a folder for all other personalisable things (settings, keybindings, GitHub/MS account credential caches, themes, tasks.json, you name it)[2]
On Linux the latter is located in ~/.config/Code, and has file permissions mode 0700 (unreadable and unwritable by anybody other than the owner).
This causes issues, as VS Code tries and fails to access said directory. The logical solution is to either modify the permissions (recursively) of ~/.config/Code to allow root access, or — arguably saner and objectively more privacy-respecting — to use a separate directory altogether for the sudo'ed VS Code to access.
The latter strategy is what the community decided to adopt at large; this commit from 2016 started making it compulsory to pass an explicit --user-data-dir when sudo-ing VS Code on Linux.
Should You be Doing This in the First Place?
Probably not! If your goal is to modify system config files, then you could stick to an un-elevated instance of Code, which would prompt you to Save as Admin... when you try to save. See this answer on Ask Ubuntu on why you probably want to avoid elevating VS Code without reason (unless you understand the risks and/or have to), and this one on the same thread on what you could do instead.
However, if the concerned file is read-restricted to root as well, as in the O.P’s case, then you hardly have a choice 😕; sudo away! 😀
[1] & [2]: If you want to know more about the above two folder paths on different OSes, see [1] and [2]
Hope this was helpful!

It might be helpful to easily find the default location of the user-data-dir on any OS. It can be found with this command:
Developer: Open User Data Folder
workbench.action.openUserDataFolder
which is in the Insiders Build v1.75 now, Stable soon. Opens your OS file explorer app to the location.

Related

Pygame will not import in python 3.8 [duplicate]

I'm probably just being very thick here, but it's not clear to me where I'm supposed to install 'new' user-specific programs on Windows 7 (and presumably Vista too, though I've not specifically looked at that scenario yet).
Under Windows XP (rightly or wrongly) we always installed our programs into folders under 'Program Files' and accepted that they'd be kind-of available to everyone. From what I can gather under Windows 7 I'm supposed to install my software under the user's AppData folder (possibly AppData\Local\MyApp). That makes a degree of sense, but the fact that this folder is 'hidden' by default means that we're going to have 'fun' talking our users through support stuff.
I want to install our software so that it's user specific (the Users bit in Windows 7 makes perfect sense) but I do want the user to be able to access it if required. Our program also includes a 'data' subdirectory which it needs to write into while it's running (embedded database), but as the program is intended to be single-user/standalone, the data folder being inside a user-specific folder isn't going to be a problem.
My problem is just that whole 'hidden folder' aspect of AppData. As much as I've trawled the MSDN, I can't work out where else I'm supposed to install user-specific programs. Taken one way it would seem to be something like AppData\Local\MyApp, and another way it would seem to be just as valid under the user's My Documents\MyApp equivalent.
Has anyone got a clear guide for where all this stuff goes? I found the MSDN docs confusing. :-)
Not really.
The directory that serves as a common
repository for application-specific
data for the current roaming user.
AppData is, surprisingly, for application data, not for installation (Click Once/Silverlight applications aside). You can, and should still install into Program Files, just don't expect to write into that folder.
You can install software into AppData if you want it to follow a user about in an Active Directory environment, which happens if you put it in AppData\Roaming (the SpecialFolder.ApplicationData location).
You can also install into AppData if you want the software to be available to just the user that installs it. This can be useful if, for example, you have multiple users on the same machine, who all want to run different versions of the software in complete isolation.
If you want settings to only apply on the local machine then you use AppData\Local, which is SpecialFolders.LocalApplicationData - this will make AD administrators very happy as the roaming profile size won't suddenly jump up 50Mb or whatever the size of your software is.
If you wanted to create settings which apply to all users then you're looking at SpecialFolders.CommonApplicationData
You should remember never to rely on the actual name of the directory - localisation issues mean this can change and the location does change with OS versions two. You should be using the special folder enumeration in your software, or the equivalent in your installer.
Could you not install into Program Files, but use AppData as it's supposed to be used, and store your database in there?
Windows 7 added the FOLDERID_UserProgramFiles known folder and by default this maps to %LOCALAPPDATA%\Programs. This is used by MSI when ALLUSERS=2 & MSIINSTALLPERUSER=1.
On Vista and earlier there is no canonical per-user application folder but just using %LOCALAPPDATA% is pretty common. Sadly MSI will just use %ProgramFiles% on these systems.
It's 2019, and I just installed Visual Studio Code (a Microsoft product) in the default folder of
%userprofile%\AppData\Local\Programs\Microsoft VS Code
This is probably for getting around the requirement to have an administrator or UAC prompt authorise the installation
Windows 7 folder structure is deeply inspired on Unix structure:
/usr/ -> C:\Program Files\ -> binaries: executables and dynamically linked
/etc/ -> C:\ProgramData\ -> global settings
/home/ -> C:\Users\ -> a folder for each user
~/.* -> C:\Users\Hikari\AppData\Roaming\ -> settings for each user
Windows has more folder, like My Documents for files with content produced by user, AppData Local and Roaming (which Unix usually handles with NFS).
It's about time for us developers to start using these structures. We must separate at least binary files that don't need to be replicated, global and user settings.
When a setup is installing an app, this setup should expect to have permission to write on Program Files. Once the setup is finished, Program Files should be writable only for other setups aiming to update binaries to other versions.
Please install executable files to the %programfiles% folder in Windows - a simple MSI based install package can perform an active setup for any new user who logs onto the machine to create the user specific files and folders in their profiles %appdata% folder. You see this behaviour for Internet Explorer, Adobe reader, etc. - It's the little MSI installer window that pops up the first time you log onto a machine which has those applications installed. - Thanks - a system admin :)
My opinion, for what it's worth, is that user-specific program files is just asking for trouble and is a damn stupid thing to do.
A much more sensible approach is to install different versions of your program to:
\Program Files\Your Program\Program_v0.1\Program.exe
\Program Files\Your Program\Program_v0.2\Program.exe
\Program Files\Your Program\Program_v0.3\Program.exe
\Program Files\Your Program\Program_v0.4\Program.exe
I would then place a bootstrapping launcher at:
\Program Files\Your Program\ProgramLauncher.exe
Then, the user application data folder will only contain data, including an INI/XML/Settings file that indicates the version of the program that this user is working with.
Such an approach satisfies the core tenant of keeping data and executing code separate, allows every user to run a specific version of the code, and offers a small amount of de-duplication by ensuring the same executable code is not copied multiple times across user folders.
Otherwise, go right ahead with installing programs to AppData and undoing the years it has taken us to achieve clean separation of code and data. I found this thread because I noticed that Chromium and DropBox are installing code to AppData. I'm going to uninstall those program, and change the permissions on my AppData folder to exclude execution to ensure I can easily spot other programs attempting the same BS.

Recommendations/best practices on custom node.js CLI tool config files: location & naming?

I'll try to keep this question short, but it is in 2 parts, please:
Where should config files for nodejs/npm CLI tools be saved?
What should they be called?
Let's say I write a node.js CLI tool that, for example, grabs today's weather and displays it in terminal. I call it weather-getter. Note, the main goal is not to be called programmatically, but typed into terminal like BASH. It is intended to be run by typing its simple name after installing globally, or via a directory in the user's local /bin. (Sudo is not required for its install.)
This project would be installed normally via npm. It can receive a zipcode via an argument like:
gavin#localhost:~$ weather-getter -z "12345"
OK the program works fine like this. My next step would be to allow the user to save a config file somewhere, and pull from that config file for defaults. Similar to a .vimrc file. This config might look like this:
{
"zipcode": "12345",
"language": "en",
"unit": "fahrenheit"
}
I suppose it should begin with a dot. I also suppose it should be located in the npm module install, and not in ~/. Or should I consider using ~/ or /etc/ or ~/.config or ~/.local like many other programs? Should node programs try to use a common directory, such as ~/.config/node/ or ~/.config/npm/? And if the file is in there, should it begin without the dot?
Note: My question is not about reading/writing a file with node.js, just recommendations on the config location and naming convention. Thank you!
Since this is a generic CLI application (which only so happens to be implemented in Node.js) installed into the system path, you should follow the best practices or rules established for the target operating system.
Unix/Linux/OS X, similar
In order of priority, these would be (but are not limited to):
~ (User's home folder) - many programs store user-level config in their home directory, usually in a dot-prefixed file, followed by the application's name (or similar) - i.e. ~/.weather-getter
/usr/local/etc, /etc - system-level configuration files. These should generally apply to all users in the system and thus should take less precedence than settings in home folder. The difference between these two etc paths is usually that the former is used for user-installed programs, whereas the latter is for system-level programs (this is especially true for Mac users using Homebrew). This distinction is, however, not always respected and therefore both locations should be checked for config files (preferrably with the /etc directory having lesser priority).
Your application's root - these should be the default settings for your application, a fallback when no user or system config has been found.
Other locations may be considered if needed.
Windows
This is usually somewhere within %APPDATA% directory if your app allows GUI or at least CLI configuration management, or the Windows registry (using winreg, for example). I have personally little experience with Windows development/CLI so I welcome any further comments or answers on this topic. I believe using the user's homefolder would also be acceptable as long as the file can be marked as hidden (so it does not clutter the view).
Some general considerations
Many CLI applications install their default configurations into one of the mentioned locations so the user has a good starting point when configuring your app
The way your configuration options are treated when multiple configuration files are present (are they merged in some order? Is only one used? Which one takes precedence?) is completely up to you, but you should make it clear in your documentation, perhaps even mention it in the configuration files themselves
If your application requires multiple configuration files it is preferred that they are grouped in their own folder
Update about dotfiles
The reason why some files or folders are prefixed with a dot is to hide them from users' normal view (i.e. when browsing their home directory via a GUI). It is therefore common practice to use dot-prefixed file/folder names when storing configuration files in directories where users normally operate, but not do so when storing config files in system-level folders.
The ospath package has a function data() which returns a sensible location for such files for each of the major platforms.

source code location for debugging multiple instance of an application

Hi have an application running separateley (1 instance for customer) in different folders, 1 per each customer.
Each customer is a separate user on my machine.
At the moment I have the source code in each of these folders where I rebuild the code per each instance. Would it be better if I do something like the following?
create a shared folder where I build the code
deploy the binary in each user folder.
allow permission for each user to access the source code in READ ONLY mode.
when it is time to debug, by using gdb in each user folder will allow to read the source code and debug will happen.
Do you think that this could be a better approach or there are better practice?
My only concern is that each user has the chance to read the source code, but since the user will not access directly his folder (it is in my control) this should not trouble me.
I am using CENTOS 6.4, SVN and G++/GDB.
in different folders
There are no "folders" on UNIX, they are called directories.
I rebuild the code per each instance
Why would you do that?
Is the code identical (it sounds like it is)? If so, build the application once. There is no reason at all to have multiple copies of the resulting binary, or the sources.
If you make the directory with sources and binaries world-readable, then every user will be able to debug it independently.

Creating a menu item generically in Linux

For part of a large university project I have built a large java based application. To make "installation" cleaner I am aiming to write a script to copy the jar to a hidden file in the users home directory then add a menu &/Or desktop launcher.
Since I do not know what platform the markers shall be using it seems sensible to make this generic so I was going to build a shell script and a batch file.
The shell script starts off simple, check the directory doesnt already exist, make it and copy the file accross.
Then it comes to making a launcher of some kind. I presume each desktop environment shall do things differently.
After 10 minutes with google it seems everything suggested is autotools but since I have no knowledge of this it seems a bit overkill.
Is there an easy way to achieve what i need?
Thanks
These days, basically all of the desktop environments uses desktop files. For the specification for those files, see the Desktop Entry Specification.
Normally, they're put in /usr/share/applications on the system. Those files are then read and used to construct the menu.
If you have the ability to write to the system /usr/share/applications directory, that's obviously simplest, but if you had that, you would probably be putting the JAR file somewhere other than a hidden directory in the user's home directory.
If not, the path that's supposed to be honored is ~/.local/share/applications. If you drop a desktop file in there, it should show up for the user. (This is somewhat newer; I don't think GNOME 2 supports, it for example. Older desktop environments had various special places for these files.)
Then, the problem basically reduces to figuring out what to write for the Exec line in the desktop file. (See the desktop files on your system in /usr/share/applications for some examples.) If you're lucky, you can get away with just sticking a java command in there, but the details will depend on your application.

Escalating privileges on linux programmatically

I am creating a graphical installer that should run on Linux. Installing should consist of copying files to some places in /usr. Currently the installer is written in Python.
How can I escalate the privileges of my installer when I need to copy files? I looked at PolicyKit but
a) there doesn't seem to be a generic "install files" action-id for PolicyKit
b) of the action ids I can use, I don't think they are standard across distros
I also looked at PAM and I have code that uses libpam but I can't seem to do anything with it. After authenticating my user (by providing username and password) I don't have write access to /usr. I tried changing my user with os.setuid(0) after authentication but I get an error from the OS.
Also, strangely, it doesn't seem to matter what service I provide to pam_start. As long as the username and password are correct I can pass anything I want. I see I have /etc/pam.d/sudo. The below code is simplified, the password is correctly stored in a pam_conversation object and I do pass a handle object.
pam_start("my_user", "my_pass", "sudo_garbage_12345");
works just as well as
pam_start("my_user", "my_pass", "sudo");
That is, they both succeed.
As a last resort I can probably execute gksudo or kdesudo but I don't want to be tied to those programs. Requiring users to invoke my installer with sudo is a (very) last resort.
You might be better off wrapping RPM with a front end that takes the user options and invokes RPM to do the hard work. This also gives you infrastructure for managing dependencies and plays nicely with the existing package management system. If you need to run on a .deb based system (Debian or Ubuntu) you may also need to consturct a .deb and put some mechanism in the front end that works out which package management system is active.
Granting random users access to root privilege is generally viewed as bad form on Linux or Unix systems (or any multi-user system for that matter) as it is a significant security risk. However you do have the option of letting the user install it under their home directory (~/bin) if they don't have root access or sudo permissions that allow them to write to system areas. In this case you can require them to install it as root if they want to install in /usr/bin but permit them to install it under their home directory for their own use if they don't have root privileges.
For a graphical installer, stick with a graphical environment. Use gksudo or kdesudo if they are available, otherwise fail with an error dialog saying they need root. People (newbies in particular) will download your installer and double-click to launch it from their desktop, and you need a graphical way to ask them for their password. You don't want to pop open a terminal on them.
Given that, don't do sudo for them even if they are running from the terminal. Just output an error saying you need root and exit. If the user is already at the command prompt (like I most likely would be), I already know how to sudo or su myself into root if I want to do so. I promise you you will most likely ruffle some feathers if you attempt to make an experienced user root when they can do it themselves.
If you INSIST on doing a sudo yourself from within your installer, for God's sake please force a 'sudo -K' before you do to remove the previous timestamp. If you don't do this, and I have sudo'd recently, you will run your installer with me as root without my knowledge (since I don't expect that to happen). A 'sudo -K' will force a prompt that I can then decide whether I want to proceed as root or not.
The best way in this case is to use su within your program. Redirect inputs/outputs and you're good to go!

Resources