问题
I'm trying to execute an ansible playbook that has a task utilizing the unarchive module. Because I'm doing this on OSX, I need it to use gnu-tar, instead of the bsd tar that typically comes with OSX, since BSD tar is not officially supported.
I've installed gnu-tar using brew, and placed this package's gnubin folder ahead of other paths in the $PATH variable. However, my playbook still looks for tar in the /usr/bin folder (the location of the original tar), instead of the newly installed gnu-tar.
My question is, how does the unarchive module look for the tar binary, and what would be the best way for me to override this behavior so that it utilizes gnu-tar, instead?
回答1:
I've found the solution.
Before we proceed, this is my code for making sure that the brew-installed gnu-tar takes precedence over the bsd-tar that comes with OSX:
# gnu-tar
export PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
export MANPATH="/usr/local/opt/gnu-tar/libexec/gnuman:$MANPATH"
This code was originally located in my ~/.bash_profile file.
The way that ansible looks up the tar binary is as you'd expect: the $PATH variable, like any other process. However, running a play creates an interactive non-login shell. As explained here, the ~/.bashrc file gets loaded for interactive non-login shells, while ~/.bash_profile gets loaded for login shells.
Since my code was located in the ~/.bash_profile file, it never executes whenever I run a play. Again, this is because running a play creates an interactive non-login shell that does not load ~/.bash_profile. Hence, the code should actually be in ~/.bashrc.
True enough, the moment I moved my code to the ~/.bashrc was when my task started using the installed gnu-tar. I was able to confirm this by creating a task to register which tar into a variable and printing it in another debug task.
回答2:
From the source code it looks like tar is looking for a gtar binary and if not a tar
# Prefer gtar (GNU tar) as it supports the compression options -zjJ
self.cmd_path = self.module.get_bin_path('gtar', None)
if not self.cmd_path:
# Fallback to tar
self.cmd_path = self.module.get_bin_path('tar')
Thus, aliasing your brew installed gnu tar as "gtar" or "tar" should fix the problem
来源:https://stackoverflow.com/questions/50193397/how-does-ansibles-unarchive-module-look-for-the-tar-binary