-
Notifications
You must be signed in to change notification settings - Fork 202
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
LookPath like impelementations for OS specific executable searches #1131
LookPath like impelementations for OS specific executable searches #1131
Conversation
I don't really understand this. Probably unix + windows implementations are not enough and it needs _unsupported fallback as well. 🤔 |
98e98f3
to
b76b4c6
Compare
1c98dcd
to
fbebd13
Compare
LGTM |
could we directly use |
The changes LGTM, but would like to hear the answer to @giuseppe 's question before merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why this adds so much complexity? It should be enough to check for the windows extensions inside the dirList loop in FindHelperBinary. Just add a small helper function which does the check on windows and make it a noop on unix.
Just for consistency with how LookPath works - I considered this as the most complete reference.
I would like to do so. But language package doesn't provide this. LookPath only provides searching in environment defined PATH, but here we are trying to lookup a binary in specific non system provided path. For me it looks like this should be a part of os/exec and then LookPath (like it is now) should be implemented by the means of this function just provided to it the environment variable expanded. I'm open trying to make it a suggestion for Go lang, but this looks like a whole level more complex process, though this still looks to me as correct path to take. This is not a blocker for any known workload (workarounds are mentioned in issue linked). This was just to make things more consistent (subject to personal opinion). The added amount of code probably doesn't justify that improved consistency. I'm open for discarding/archiving this PR, keeping the original issue open for reference purposes and trying getting the support at os/exec level. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed copyright for now, they have BSD attribution header, I don't know what is the right way to preserve it the right way
Just so that it isn’t forgotten, this is a blocker.
I agree with this. (Or not even a function, just a global variable of suffixes to iterate over, set to It would be nice not to sign up to the perpetual responsibility to keep up with the upstream And doing the simple thing, although not entirely correct about things like
Also, please read https://github.com/containers/common/blob/main/CONTRIBUTING.md#sign-your-prs . The DCO is a serious matter. |
@mtrmac Could you give me the heads ups on how one could use BSD sources in APL2 project? It will not happen for this MR, probably, but just to not step in the same pitfall once again. Thanks in advance! |
Thank you all for your input! I will move it into a draft and will rework into a simpler implementation, because now I can clearly see you reasoning and it is up to maintainers to tell what they are fine to support longterm. Might take a week or smth, because I'm a bit overloaded now. |
I don’t immediately know. It might well be possible, or it might be a problem. I don’t think I’m qualified to make a recommendation or decide whether a particular licensing arrangement is acceptable. I think it’s just easier to work around this so that we don’t rely on the answer on this question. (But I do feel rather confident in saying that removing copyright notices is basically never OK.) |
8ef712d
to
e90ecd2
Compare
@giuseppe @TomSweeneyRedHat yes, after all we actually could, I just didn't know how that time. |
e90ecd2
to
0f6f68d
Compare
pkg/config/config.go
Outdated
if fi, err := os.Stat(fullpath); err == nil && fi.Mode().IsRegular() { | ||
return fullpath, nil | ||
} | ||
abspath, err := filepath.Abs(fullpath) | ||
if err == nil { | ||
if lp, err := exec.LookPath(abspath); err == nil { | ||
return lp, nil | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this. If we have absolute path then use builtin machinery, but as a fallback use old implementation.
if fi, err := os.Stat(fullpath); err == nil && fi.Mode().IsRegular() { | |
return fullpath, nil | |
} | |
abspath, err := filepath.Abs(fullpath) | |
if err == nil { | |
if lp, err := exec.LookPath(abspath); err == nil { | |
return lp, nil | |
} | |
} | |
if filepath.IsAbs(fullpath) { | |
if lp, err := exec.LookPath(fullpath); err == nil { | |
return lp, nil | |
} | |
} else { | |
if fi, err := os.Stat(fullpath); err == nil && fi.Mode().IsRegular() { | |
return fullpath, nil | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand either solution, this function by definition should not lookup in $PATH unless searchPATH
was set to true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From experiments, LookPath doesn't traverse the PATH records if absolute path is given as input (or even if it does, then it is still using given absolute instead of filepath.Join). For Windows OS it still extends the search from C:\something\executablename
to C:\something\executablename.exe
, C:\something\executablename.bat
, etc. And then return the updated version (with the extension) as an output, if one is found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can put it behind if runtime.GOOS = "windows"
as it seems this doesn't really change the behavior of the current implementation for non-Windows OSes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The end goal is to make it understand that "C:\Program Files\Red Hat\Podman\gvproxy" should resolve to "C:\Program Files\Red Hat\Podman\gvproxy.exe". So, that it will be possible to use the same binary name gvproxy
(which is now hardcoded, and it looks fine to have it this way) w/o any conditional code in Podman, because this method will behave more like a LookPath, which is capable of understanding that for example ssh
is actually ssh.exe
on Windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But can't you just remove
If we filter directories, which are not given as absolute paths or use filepath.Abs and ignore error cases (I don't know if here we could satisfy the conditions for this to fail, but we have to take into account the error case). Because now it gives potential escape via relative path from the PWD, but if we pass relative ones into LookPath it is a wired range of path escapes. And not-validated for being absolute path CONTAINERS_HELPER_BINARY_DIR is the first candidate to be a trouble maker:
if dir, found := os.LookupEnv("CONTAINERS_HELPER_BINARY_DIR"); found {
dirList = append([]string{dir}, dirList...)
}
Not related to this PR, but it now looks to me that CONTAINERS_HELPER_BINARY_DIR deserves some sanity checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will revisit the changes this weekend and will do extended testing on non-Windows hosts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
passing the full path to LookupPath() should also work on linux/unix?
Yes, that seems to be a good approach: Always do filepath.Abs(filepath.Join(…))
+ exec.LookPath
. There would be not much extra cost on Unix (filepath.Abs
is just os.Getwd
+ some in-memory manipulation).
The returned path from this function could now be absolute in most cases, but that’s hardly a bad thing.
Either way, the LookupEnv
call does need a quite verbose comment explaining that this is important to preserve, because on Windows it turns a command name into an executable path (handling $PATHEXT
) — perhaps even with an example.
Otherwise someone like me would be pretty likely to remove it in a few months.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will revisit the changes this weekend and will do extended testing on non-Windows hosts.
Having a unit test (at least a single case combining a path + a fictitious executable t.Tempdir()
) would be nice as well. OTOH the test would have to be, annoyingly, platform-specific.
(I have no opinion on whether the unit test should be a required part of this PR.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplified implementation (always use Abs + LookPath) and added comments.
Proofs that LookPath always short circuits for absolute paths:
- Windows https://github.com/golang/go/blob/213495a4a67c318a1fab6e76093e6690c2141c0e/src/os/exec/lp_windows.go#L82
- Unix https://github.com/golang/go/blob/213495a4a67c318a1fab6e76093e6690c2141c0e/src/os/exec/lp_unix.go#L57
This implementation is slightly superior to original one on Unix in the form that it taxed into account executable bit and on Windows it correctly loops through PATHEXT, when needed.
I'm not sure if this needs unit test then, because golang repo looks like a more appropriate way to place them (we want to validate platform behavior).
ca495c3
to
ba89abf
Compare
Implementation details: Unix:
Windows:
The biggest overhead here will be So, the implementation will work in a very optimized way in the majority of cases. |
I rebased to latest main, there are linter failures, but they don't look related to this PR
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@Luap99 ?
(The test failures need to be resolved before merging, but probably not in this PR, and quite possibly by someone else.)
exec.LookPath seems to handle absolute paths gracefully. On Windows this allows to additionally check for all known executable alternatives when only name is provided. Signed-off-by: Arthur Sengileyev <[email protected]>
ba89abf
to
0c2ecb0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: arixmkii, Luap99 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
LGTM . Now, who can understand and fix the test failure? |
I rerun the test, I don't understand what is wrong but I think this is a flake. |
/lgtm |
/hold cancel |
Fixes #1123
Additionally tries
exec.LookPath
over Absolute path, when searching in predefined directories.exec.LookPath
could handle absolute paths - verified on Windows and macOS.On Windows was tested with
my.bat
file inC:\Temp
, which is obviously not referenced by PATH variable.Test program (my.go):
Run as
go run my.go
and outputs.Signed-off-by: Arthur Sengileyev [email protected]