Skip to content
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

config: Allow specifying helper dirs with $BINDIR as base directory #1127

Merged
merged 2 commits into from
Aug 23, 2022

Conversation

filbranden
Copy link
Contributor

This should make it easier to locate helper binaries relative to where the main binary was installed, which should be useful in installations such as Homebrew which install packages under a versioned directory.

Use a $BINDIR magic token as a prefix in the helper path to indicate it should be relative to the directory where the binary is located. This is somewhat familiar to the syntax used in the shell and Makefile and is still quite explicit about the behavior (as opposed to, say, making all relative paths be relative to the directory of the binary.)

Update podman config on Darwin to look for helpers such as gvproxy under $BINDIR/../libexec/podman, which is the ultimate objective of this code change.

Tested: Updated vendored package in podman, built it with podman-remote, copied gvproxy to a libexec/podman at the same level as bin/podman and confirmed that podman machine start worked as expected.

Fixes: containers/podman#12161

Related: PR #946 (cc @ashley-cui)

Signed-off-by: Filipe Brandenburger filbranden@gmail.com

Copy link
Member

@vrothberg vrothberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if path == bindirPrefix || strings.HasPrefix(path, bindirPrefix+string(filepath.Separator)) {
// Calculate the path to the executable first time we encounter a $BINDIR prefix.
if bindirPath == "" && bindirErr == nil {
podman, bindirErr := os.Executable()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This should not be called podman, since this library is used for other tools like buildah.

Just call it executable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure that makes sense, I'm using execPath now.

(It's a bit odd though, since config_darwin.go in this same package uses libexec/podman for the helper directory, but I guess that's perhaps expected since the helpers are somewhat shared between both?)

@rhatdan
Copy link
Member

rhatdan commented Aug 22, 2022

Thanks @filbranden

@@ -1261,6 +1285,9 @@ func (c *Config) FindHelperBinary(name string, searchPATH bool) (string, error)
return exec.LookPath(name)
}
configHint := "To resolve this error, set the helper_binaries_dir key in the `[engine]` section of containers.conf to the directory containing your helper binaries."
if bindirErr != nil {
configHint = fmt.Sprintf("Error looking up path relative to %s: [%s] %s", bindirPrefix, bindirErr, configHint)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a logrus.Warnf instead of a print?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes indeed logging is much nicer!

By not having to track the error result, I ended up refactoring the code considerably, moving bindirPath calculation to a standalone function.

In the new code, I also track whether os.Executable() (or resolving symlinks from it) ever failed, in order to only log about it once.

I hope you still like how the new code looks, let me know if you'd like me to make any changes to it.

@ashley-cui
Copy link
Member

Thanks @filbranden ! A nit from Dan and a nit from me, but other than that, LGTM!

@filbranden
Copy link
Contributor Author

Updated the PR.

One case I had previously missed was that the called binary is actually a symbolic link, now I added a call to filepath.EvalSymlinks to cover this case. I tested this with a symbolic link now and confirmed that this works. (This is the actual Homebrew setup, so I'm glad I caught this now before we merge it.)

Also split it into two separate commits, one with the feature to support the $BINDIR magic, and the second one updating the Darwin config to use the feature to look for helpers in a path relative to the binary itself.

PTAL. Thanks!

@filbranden filbranden force-pushed the bindir1 branch 3 times, most recently from 3b63438 to 8f28dc8 Compare August 22, 2022 20:06
This should make it easier to locate helper binaries relative to where the main
binary was installed, which should be useful in installations such as Homebrew
which install packages under a versioned directory.

Use a `$BINDIR` magic token as a prefix in the helper path to indicate it should
be relative to the directory where the binary is located. This is somewhat familiar
to the syntax used in the shell and Makefile and is still quite explicit about the
behavior (as opposed to, say, making all relative paths be relative to the directory
of the binary.)

Tested: After updating the Darwin config to include a `$BINDIR/../libexec/podman`
directory, updated vendored package in podman, built it with `podman-remote`,
copied `gvproxy` to a `libexec/podman` at the same level as `bin/podman` and
confirmed that `podman machine start` worked as expected. Also confirmed that
having the `podman` in search path be a symlink to a binary elsewhere works as
expected, the searched `../libexec/podman` directory is relative to the actual
binary and not the symlink (which matches the Homebrew use case.)

Signed-off-by: Filipe Brandenburger <filbranden@gmail.com>
Look for helpers such as `gvproxy` under `$BINDIR/../libexec/podman`, which
helps this work on distributions such as Homebrew without the need to hardcode
paths into the binary, which makes a pre-built binary distribution work
regardless of the installation prefix.

Tested: Updated vendored package in podman, built it with `podman-remote`,
copied `gvproxy` to a `libexec/podman` at the same level as `bin/podman` and
confirmed that `podman machine start` worked as expected.

Signed-off-by: Filipe Brandenburger <filbranden@gmail.com>
@rhatdan
Copy link
Member

rhatdan commented Aug 22, 2022

LGTM

@rhatdan
Copy link
Member

rhatdan commented Aug 23, 2022

/approve
/lgtm

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Aug 23, 2022

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: filbranden, rhatdan

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit b3ac39a into containers:main Aug 23, 2022
@filbranden filbranden deleted the bindir1 branch August 23, 2022 14:10
filbranden added a commit to filbranden/homebrew-core that referenced this pull request Aug 31, 2022
…helpers relative to the main binary

PR containers/common Homebrew#1127 (containers/common#1127)
introduced a new feature by which podman is now capable of locating its helpers
(such as `gvproxy`) relative to the main binary location, and by default
enables that feature for MacOS builds.

Apply the patch on top of the current Homebrew tree and enable the feature.

Move `gvproxy` from a bare `libexec` to a `libexec/podman`, since that's the
default path to the binary used in podman.

For Linux builds, use the environment variable consumed by the Makefile to
inject the same binary-relative path to the default helper search list.

Since this change makes this keg relocatable again, drop the
`pour_bottle? only_if:` gate that was causing it to build from source
whenever using a non-standard prefix. Bump up revision number. Installing from
bottles should now work fine, even on a non-standard prefix.

Tested: Rebuilt from source with `brew reinstall -s podman` and confirmed that
`podman machine start` works (that's the operation that depends on the location
of the `gvproxy` binary.) Tested a different directory location to test (on a
Mac) that the Linux change should work as exepcted.
BrewTestBot pushed a commit to Homebrew/homebrew-core that referenced this pull request Aug 31, 2022
…helpers relative to the main binary

PR containers/common #1127 (containers/common#1127)
introduced a new feature by which podman is now capable of locating its helpers
(such as `gvproxy`) relative to the main binary location, and by default
enables that feature for MacOS builds.

Apply the patch on top of the current Homebrew tree and enable the feature.

Move `gvproxy` from a bare `libexec` to a `libexec/podman`, since that's the
default path to the binary used in podman.

For Linux builds, use the environment variable consumed by the Makefile to
inject the same binary-relative path to the default helper search list.

Since this change makes this keg relocatable again, drop the
`pour_bottle? only_if:` gate that was causing it to build from source
whenever using a non-standard prefix. Bump up revision number. Installing from
bottles should now work fine, even on a non-standard prefix.

Tested: Rebuilt from source with `brew reinstall -s podman` and confirmed that
`podman machine start` works (that's the operation that depends on the location
of the `gvproxy` binary.) Tested a different directory location to test (on a
Mac) that the Linux change should work as exepcted.

Closes #109241.

Signed-off-by: Carlo Cabrera <30379873+carlocab@users.noreply.github.com>
Signed-off-by: BrewTestBot <1589480+BrewTestBot@users.noreply.github.com>
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.

podman machine start cannot find gvproxy when brew is not installed in the standard directory
5 participants