SkiffOS
SkiffOS copied to clipboard
WSL: pass-through PATH variable to the SkiffOS environment
The WSL build doesn't bring over the Windows paths as is typical of WSL distros. More info here:
https://docs.microsoft.com/en-us/windows/wsl/wsl-config (Look at example wsl.conf)
I have tried forcing it using edits in the wsl.conf file, but as the default for that string is true
, I have been unsuccessful in getting that to work.
@clayauld I think this comes down to two issues:
- If you store wsl.conf in SkiffOS, WSL won't see it.
- Some paths (?) are not bind-mounted into the system.
This is because of how the SkiffOS system starts up:
- WSL "boots" skiff-init-squashfs.
- skiff-init-squashfs mounts the SkiffOS root FS from a SquashFS.
- skiff-init-squashfs creates a tmpfs overlay on top of #2.
- skiff-init-squashfs creates a PID namespace and chroots into #2.
- skiff-init-squashfs hands off control of PID 1 to systemd.
It's easy to mount paths into the SkiffOS /
with bind-mounts (this is done for /wslinit and /run).
WSL is reading /etc/wsl.conf
from the initial filesystem, not the one that skiff-init-squashfs
sets up.
The only workaround I can think of is to bind-mount wsl.conf into the target FS. But then, the changes made to wsl.conf in the SkiffOS image wont' apply.
It would have to do something like this:
- Mount the SkiffOS root image with skiff-init-squashfs and bind-mount /etc/wsl.conf
- Copy the contents of the SkiffOS wsl-conf into /etc/wsl.conf
... but then WSL wouldn't read wsl.conf until the next reboot.
What are the extra windows paths that don't appear? Are they always mounted into WSL distributions or is this something configured with wsl.conf?
The extra windows paths for my WSL distro(s) are as follows:
/mnt/c/Program Files (x86)/Common Files/Oracle/Java/javapath /mnt/c/windows/system32 /mnt/c/windows /mnt/c/windows/System32/Wbem /mnt/c/windows/System32/WindowsPowerShell/v1.0/ /mnt/c/Program Files/Git/cmd /mnt/c/windows/System32/OpenSSH/ /mnt/c/Program Files (x86)/WinSCP/ /mnt/c/Program Files (x86)/PuTTY/ /mnt/c/Program Files/dotnet/ /mnt/c/Program Files/Docker/Docker/resources/bin /mnt/c/ProgramData/DockerDesktop/version-bin /mnt/c/Users/CAuld/AppData/Local/Microsoft/WindowsApps /mnt/c/Users/CAuld/AppData/Local/Programs/Microsoft VS Code/bin
It appears it is taken from the Windows PATH variable and translated over to the Linux equivalent, referencing everything in the C:\
drive to /mnt/c/
.
Based on the order of how the PATH variable comes in to WSL is the base PATH for Linux is first (/etc/profile
, /etc/profile.d/
, etc), then the Windows PATH, and then any user paths set up in user locations (.bashrc
, .bash_profile
, etc).
There is a workaround here, of course. I could just have the Skiff Core user manually set the PATH, and things should work just fine. However, I didn't know if there was a way to use the "standard" way of WSL appending the paths.
Hmm, I feel like I had configured it to bind mount /mnt/ including mnt/c - will check.
/mnt/c and all other drives are certainly bound to /mnt so that part does work as expected.
@clayauld Do I understand correctly: in other WSL distros $PATH is correctly updated to include the /mnt/c paths but here they are reset by SkiffOS during the systemd boot process? In that case it should be possible to add a workaround which stores PATH somewhere and loads it back after systemd starts.
That is a good summary of what is occurring. I was thinking of a workaround similar to your suggestion by storing the PATH variables in a file somewhere then pulling them in after Skiff and systemd start.
I wasn't sure what stage of the startup process would need to do this, but I think that's a good way to address this.
I think it's going to have to be something like...
- Configure skiff-init-squashfs to dump environment to a file
- Add a skiff-init script which reads that file
- Filter any PATH entries that don't have
/mnt/c/
prefix - Add to
/etc/profile.d/01-wsl-path.sh
something likeexport PATH=$PATH:/mnt/c...
with the paths
That sounds like it should work to me and makes sense. The Skiff Core container could also use that file to load the PATH variables.
I'm using custom docker containers now for Skiff Core so that part should be straightforward and the Core user can source that file and add the directories to the PATH.
Interesting development on systemd in WSL.
https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/
Looks like systemd is getting official support soon. Not sure how this changes the WSL config for SkiffOS.
Let me know what I can do if there is rework necessary when this support comes out of beta testing.
I think we can support either way - right now, the skiff-init-wsl binary checks if an existing systemd instance is running.
So we can, without any changes, add skiff-init-wsl as the init binary (instead of systemd).
Then;
- if wsl supports it, systemd will start right away as init
- otherwise systemd will start when the first wsl.exe shell starts (current behavior)
I'll take a look at this & other WSL related things soon - also having a look at submitting it to the WSL store.