The documentation at https://www.packer.io/docs/extending/plugins#installing-plugins describes that, on windows, packer searches for plugins at:
Once the plugin is named properly, Packer automatically discovers plugins in the following directories in the given order. If a conflicting plugin is found later, it will take precedence over one found earlier.
- The directory where packer is, or the executable directory.
- The $HOME/.packer.d/plugins directory, if $HOME is defined (unix)
- The %APPDATA%/packer.d/plugins if %APPDATA% is defined (windows)
- The %USERPROFILE%/packer.d/plugins if %USERPROFILE% is defined (windows)
...
But in reality, it only checks in %USERPROFILE% as you can see with this procmon capture:
This is either a bug in the documentation or in packer.
1.6.1
Thanks for bubbling this up @rgl. This looks like a bug or maybe a documentation update as the code will return once it finds one of the paths; starting with $HOME. I'm curious does your system have a HOME environment variable set to C:\Users\Vagrant
?
I forgot to mention that packer is started from inside a msys2 bash.
And indeed, it has %HOME%
defined. From a win32 app, it appears like you've deduced:
vagrant@mssql ~/Desktop/windows-vagrant
# cmd /c 'echo %HOME%'
C:\Users\vagrant
Okay good to know. Thanks for the quick follow up. As a workaround you could use the packer.config file to set a custom path for the windows-update provisioner example and it should read from both locations. If I am not mistaken.
{
"provisioners": {
"windows-update": "/tmp/packer-provisioner-windows-update"
}
}
I do use that json when developing the plugin, but this issue relates to installing the plugin into the end-user machine. In concrete, I'm fixing the chocolatey package to install into %USERPROFILE%
. After doing that, packer can now find the plugin:
2020/08/20 21:52:48 [DEBUG] Discovered plugin: windows-update = C:\Users\vagrant\packer.d\plugins\packer-provisioner-windows-update.exe
Please note that at some point in the past, packer was loading from %APPDATA%, but at another point, packer stopped looking there, and hence this issue.
Looking at this it looks like it's caused here:
setting 'HOME' takes precedence over the rest and the doc seems to be wrong.
Edit: Jumping in the time machine to make sure I am right.
Edit 2: It seems from the docs that we are not expecting the HOME var to be ever set on windows:
2. The `$HOME/packer.d/plugins` directory, if `$HOME` is defined (unix)
Windows.
3. The `%APPDATA%/packer.d/plugins` if `%APPDATA%` is defined (windows)
I think it would be better to search inside of all those environment variables regardless of the OS. And do that each time a plug-in needs to be found. At least the documentation would be easier to understand and hopefully the implementation would be easier do reason about.
Until a better solution is implemented, maybe swapping https://github.com/hashicorp/packer/blob/0785c2f6fca9c22bf25528e0176042799dd79df9/packer/config_file.go#L24-L32 would be good enough for now?
That is:
if home := os.Getenv("APPDATA"); home != "" {
return home, nil
}
// Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470
if home := os.Getenv("HOME"); home != "" {
return home, nil
}
That way it should work on windows and linux.
@rgl, yes I think this would be a great solution. Do you have the time to open a new PR ?
I've created it at #9830.
I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
I think it would be better to search inside of all those environment variables regardless of the OS. And do that each time a plug-in needs to be found. At least the documentation would be easier to understand and hopefully the implementation would be easier do reason about.