Skip to content

Use short path for LIMA_HOME on windows #955

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

Closed
wants to merge 1 commit into from

Conversation

afbjorklund
Copy link
Member

Other commands such as qemu-system-x86_64.exe don't work with
C:\Users\AndersBjörklund, they need to use C:\Users\ANDERS~1

In theory they could have supported using UNC paths such as
\\?\C:\Users\AndersBjörklund, but in practice they do not...

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getshortpathnamew

A long file name is considered to be any file name that exceeds the short MS-DOS (also called 8.3) style naming convention.

GOOS=linux (host)

=== RUN   TestShortNameShort
    shortname_test.go:20: /tmp/foo => /tmp/foo
--- PASS: TestShortNameShort (0.00s)
=== RUN   TestShortNameLong
    shortname_test.go:31: /tmp/baaaaaaaaaar => /tmp/baaaaaaaaaar
--- PASS: TestShortNameLong (0.00s)
PASS

GOOS=windows (wine)

=== RUN   TestShortNameShort
    shortname_test.go:20: C:\users\anders\Temp\foo => C:\users\anders\Temp\foo
--- PASS: TestShortNameShort (0.00s)
=== RUN   TestShortNameLong
    shortname_test.go:31: C:\users\anders\Temp\baaaaaaaaaar => C:\users\anders\Temp\BAAA~MWI
--- PASS: TestShortNameLong (0.00s)
PASS

@AkihiroSuda
Copy link
Member

C:\Users\AndersBjörklund, they need to use C:\Users\ANDERS~1

What if your home directory is like C:\Users\Björklund or C:\Users\漢字 ?

@jandubois
Copy link
Member

jandubois commented Jul 13, 2022

What if your home directory is like C:\Users\Björklund or C:\Users\漢字 ?

GetShortPathName will automatically translate them to 8.3 format (if the file exists; there is no way to generate a short name before creating the file, as the short name depends on what other files already exist in the directory). dir /x shows both the short and long names:

C:\Users\Jan\Names>dir /x
 Volume in drive C has no label.
 Volume Serial Number is 5C37-CD74

 Directory of C:\Users\Jan\Names

07/12/2022  10:10 PM    <DIR>                       .
07/12/2022  10:10 PM    <DIR>                       ..
07/12/2022  10:08 PM    <DIR>          BJRKLU~1     Björklund
07/12/2022  10:08 PM    <DIR>          ED60~1       漢字
               0 File(s)              0 bytes
               4 Dir(s)  41,248,669,696 bytes free

C:\Users\Jan\Names>perl -MWin32 -E "say Win32::GetShortPathName('Björklund')"
BJRKLU~1

Note that the creation of 8.3 short names can be disabled by NTFS on a per-volume basis (search for HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation and fsutil 8dot3name). In that case GetShortPathName will still return the long name and not set an error.

@jandubois
Copy link
Member

Other commands such as qemu-system-x86_64.exe don't work with C:\Users\AndersBjörklund, they need to use C:\Users\ANDERS~1

BTW, are you sure the problem is the long pathname and not some code page problem? It doesn't really matter though, as the short name algorithm always returns ASCII compatible strings, so you don't have to worry about encodings (unless people enable HKLM\System\CurrentControlSet\Control\FileSystem\NtfsAllowExtendedCharacterIn8dot3Name in which case they can only blame themselves).

@afbjorklund
Copy link
Member Author

afbjorklund commented Jul 13, 2022

Actually I think the problem is related to how Go handles paths in the exec.Command, when running from a prompt it seems to work. Unfortunately each program is required to handle parsing in Windows, and it seems to fail with the long names.

It could definitely be the unicode as well as the length, but the "fix" (workaround) would be the same either way. I'm not really a Windows person, I just saw this issue happening when it was run on a computer connected to the Active Directory.

@afbjorklund
Copy link
Member Author

afbjorklund commented Jul 13, 2022

There is some confusion between $HOME and os.UserHomeDir, but the plan is to go with the windows default (%HOMEDRIVE%HOMEPATH%)

i.e. for MSYS2 it will use something like C:\msys64\home\AndersBjörklund for the $HOME variable (in bash)

But for MinGW64 it will use C:\Users\AndersBjörklund and Command Prompt doesn't even have a %HOME%.

For corner cases, the user can override with $LIMA_HOME - maybe need something similar for the ssh variables (SSH_HOME?)


EDIT: Updated to use the proper dos variables

@jandubois
Copy link
Member

There is some confusion between $HOME and os.UserHomeDir, but the plan is to go with the windows default %HOMEPATH%

Note that %HOMEPATH% does not include the drive; you would need %HOMEDRIVE%%HOMEPATH%. However, I think you want to use %USERPROFILE% here, which is where application settings are stored. Homedrive/path often point to the same location, but don't have to.

On second thoughts, %LOCALAPPDATA%\Lima is where LIMA_HOME should live by default. Do not use %APPDATA%, which is the location of the roaming profile; it will be copied back and forth to the domain controller on login/logout, which will take forever to copy the full VM; it is only meant for small config files, like editor settings.

@afbjorklund
Copy link
Member Author

afbjorklund commented Jul 13, 2022

I was suspecting that "appdata" and friends had the same concern on Windows as on macOS, so didn't use them.

Didn't expect home to fail too, but here we are.

@jandubois
Copy link
Member

jandubois commented Jul 13, 2022

Actually I think the problem is related to how Go handles paths in the exec.Command, when running from a prompt it seems to work.

This seems to confirm that the issue is an encoding problem, and not the long filenames.

I found this possible workaround (codepage 65001 is utf-8), but haven't tested it:

cmd := exec.Command("powershell.exe", "-c", "chcp", "65001", ">", "$null", ";", command)

Maybe even more gross than using short names. 😄

@afbjorklund
Copy link
Member Author

For myself, I only care about MSYS2 and MinGW64...

It is nice if the old school Command Prompt works too (if it isn't too much hassle, like a simple .bat file or something)

But I will not bother with Powershell, if the user is interested in Linux containers then I assume they have a decent shell.

Something like this: https://dilbert.com/strip/1995-06-24

@afbjorklund
Copy link
Member Author

However, I think you want to use %USERPROFILE% here, which is where application settings are stored.

Actually, that is what is being done: https://pkg.go.dev/os#UserHomeDir

On Unix, including macOS, it returns the $HOME environment variable. On Windows, it returns %USERPROFILE%. On Plan 9, it returns the $home environment variable.

The rest was just my own guesses, based on variables (which I botched)

@jandubois
Copy link
Member

But I will not bother with Powershell

This is not about the user using Powershell; it is just a way to switch the codepage before running the command. You can probably do the same thing with cmd.exe. Anyways, I don't really care; was just trying to provide some additional background info. I'm out of here now. 😄

@jandubois
Copy link
Member

However, I think you want to use %USERPROFILE% here, which is where application settings are stored.

Actually, that is what is being done: https://pkg.go.dev/os#UserHomeDir

I still think for this particular case %LOCALAPPDATA%\Lima is the right choice (which will typically be just %USERPROFILE%\AppData\Local\Lima. You don't want %USERPROFILE%\.lima because dot files are not a thing on Windows (they are not hidden by default). OTOH, if you only care about MSYS and MinGW64, then maybe dot files are the way to go... 🤷

Other commands such as qemu-system-x86_64.exe don't work with
C:\Users\AndersBjörklund, they need to use C:\Users\ANDERS~1

In theory they could have supported using UNC paths such as
\\?\C:\Users\AndersBjörklund, but in practice they do not...

Signed-off-by: Anders F Björklund <anders.f.bjorklund@gmail.com>
@afbjorklund
Copy link
Member Author

afbjorklund commented Jul 13, 2022

We can have a poll later, but it is something nice about using the same path on all platforms ?

Also, we are not using the proper XDG directories on linux either - but polluting the home dir...

It was the same problem with ~/.docker/machine.

And also with other traditional tools, like ~/.ccache.


So I will stick with ~/.lima. Splitting up config and data can get very tricky, for these things.

Note that we are using the system cache directory (which is in AppData). os.UserCacheDir

So at least the downloads will end up there.

https://pkg.go.dev/os#UserCacheDir

@afbjorklund afbjorklund marked this pull request as draft November 19, 2022 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants