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

Include Homebrew bin when searching for Docker binaries #3481

Closed

Conversation

lukas-vlcek
Copy link
Contributor

@lukas-vlcek lukas-vlcek commented May 31, 2022

Signed-off-by: Lukáš Vlček lukas.vlcek@aiven.io

Description

When docker and docker-compose are installed using brew then the /bin location is different (compared to manual binaries installation). This commit extends possible locations that are searched when checking if docker is available on Mac family Os machines.

Issues Resolved

Closes #3476

Check List

  • New functionality includes testing.
    • All tests pass
  • New functionality has been documented.
    • New functionality has javadoc added
  • Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@lukas-vlcek lukas-vlcek requested review from a team and reta as code owners May 31, 2022 12:33
@opensearch-ci-bot
Copy link
Collaborator

❌   Gradle Check failure 94b4fe0160c5fbd2c287517bb49b69473571ebc6
Log 5680

Reports 5680

@opensearch-ci-bot
Copy link
Collaborator

✅   Gradle Check success 84d81208ccb7854f60cb38ef3e123bb0796c309f
Log 5681

Reports 5681

Copy link
Collaborator

@nknize nknize left a comment

Choose a reason for hiding this comment

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

Thanks for doing this. Just left a quick question if we should make this more homebrew specific? Or do we think there will be other macOS specific urls?

@@ -68,17 +69,30 @@ public abstract class DockerSupportService implements BuildService<DockerSupport
// Defines the possible locations of the Docker CLI. These will be searched in order.
private static String[] DOCKER_BINARIES_UNIX = { "/usr/bin/docker", "/usr/local/bin/docker" };

// On Mac you can install docker and docker-compose via brew adding more options where the binaries can be located.
private static String[] DOCKER_BINARIES_MACOS = Stream.concat(
Copy link
Collaborator

Choose a reason for hiding this comment

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

/opt isn't mac specific. Not sure we need the DOCKER_BINARIES_MACOS. Maybe make this DOCKER_BINARIES_HOMEBREW and add /opt/homebrew/bin/docker, and /home/linuxbrew/.linuxbrew per the homebrew documentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nknize I think this is fair point. Let me update the PR.

Copy link
Contributor Author

@lukas-vlcek lukas-vlcek Jun 2, 2022

Choose a reason for hiding this comment

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

@nknize Thinking more about this, depending on how robust we want to make it but why don't we simply use which docker and which docker-compose on Linux and MacOS based systems instead? My gut tells me there can be always some edge case where docker (or other binary in general) can be installed in custom location...

What is the chance that which docker fails (i.e. gives no useful answer) if the docker is installed on the system? (Edit: maybe if the system runs in very light container that does not include which?)

If I understand the code correctly then the only change/implication would be that the paths to search in would not be static class members but they will have to be evaluated only after the ExecOperations execOperations is injected into the SupportService ctor. That shouldn't be a big deal... WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I like that idea. How about using the static variables as a fall back if which docker does fail? And since OS X is unix based anyway, you should just be able to add the new homebrew paths to the existing DOCKER_BINARIES_UNIX variable instead of a new DOCKER_BINARIES_MACOS?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @nknize,

I updated my PR and I think it is ready for review.

I decided to not include the which functionality into this PR for now because it turns out to be more complicated. Basically the which output can differ based on host systems quite a lot (these are more or less corner cases but we need to deal with them as well, things like "aliases" or "shell functions"). This would lead to more complex parsing of the host output than I like for this PR. I will open a new ticket to enable discussion about it and provide some of the findings I made. In the end I think we will need to add functionality where users will define their own path to container engine anyway (think about people who have both the docker and podman installed at the same time [yes, I do believe we will have podman build compatibility in the future 😄 ]).

For now, let this PR address only the Homebrew locations.

@lukas-vlcek lukas-vlcek force-pushed the 3476_docker_brew branch 2 times, most recently from 26fb2e6 to 1d90335 Compare June 6, 2022 17:21
@@ -66,13 +67,17 @@ public abstract class DockerSupportService implements BuildService<DockerSupport

private static Logger LOGGER = Logging.getLogger(DockerSupportService.class);
// Defines the possible locations of the Docker CLI. These will be searched in order.
private static String[] DOCKER_BINARIES_UNIX = { "/usr/bin/docker", "/usr/local/bin/docker" };
private static String[] LINUX_BIN_LOCATIONS = { "/usr/local/bin", "/usr/bin", "/opt/homebrew/bin", "/home/linuxbrew/.linuxbrew/bin" };
Copy link
Collaborator

Choose a reason for hiding this comment

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

"/home/linuxbrew/.linuxbrew/bin" this one is unclear: basically we are pointing to the home folder of the linuxbrew user which basically should fail the lookup unless run under linuxbrew user or root. Or I am missing something?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure anything will fail here unless the Docker CLI can't be found at all? I think like the PATH env variable it will search folders even if they don't exist and only throw an error if the binaries are not present? Might verify?

Aside from that technical nuance, I think I agree that we should leave the ~linuxbrew user out of the path here. Users can always create a /usr/local/bin softlink to the linuxbrew home directory if this is their configuration.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks @nknize , I think "fail" is indeed too strong, I would rephrase that as "unsuccessful lookup" since we attaching to particular user, thank you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps we should add one or two debug messages here as well? If I am not mistaken right now user does not know which location is used.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps we should add one or two debug messages here as well?

Debug verbosity here would be good! Anything to help users understand what's going on is a great thing. I'll keep an eye on the PR and review when ready.

@opensearch-ci-bot
Copy link
Collaborator

❌   Gradle Check failure 26fb2e62ee73496b8c7a60f4c2a559d518223b04
Log 5805

Reports 5805

@opensearch-ci-bot
Copy link
Collaborator

✅   Gradle Check success 1d903357b6a7bb1358b9295a0a80a6a9696474c5
Log 5806

Reports 5806

@nknize
Copy link
Collaborator

nknize commented Jun 29, 2022

Just checking in on this @lukas-vlcek. I think there was one outstanding item?

Perhaps we should add one or two debug messages here as well? If I am not mistaken right now user does not know which location is used.

@lukas-vlcek
Copy link
Contributor Author

@nknize Yes, thanks for pinging me. I will be finishing this by the end of the week for sure.

@github-actions
Copy link
Contributor

github-actions bot commented Jul 1, 2022

Gradle Check (Jenkins) Run Completed with:

- This commit adds location of docker binaries when installed via Homebrew on MacOS
- Making initialization of the DockerAvailability thread-safe

Notice that Homebrew can also be used on Linux, but we are not listing this default bin location for now. This means Linux users using brew to install docker will need to create a suitable alias as a workaround.

Closes opensearch-project#3476

Signed-off-by: Lukáš Vlček <lukas.vlcek@aiven.io>
@lukas-vlcek lukas-vlcek requested review from nknize and reta July 1, 2022 16:47
@github-actions
Copy link
Contributor

github-actions bot commented Jul 1, 2022

Gradle Check (Jenkins) Run Completed with:

@lukas-vlcek
Copy link
Contributor Author

Interesting, why is github-actions bot trying to use the old commitID?
I did force push into my branch and the new commit should be 2385dd3 and not cb26cfb.

@prudhvigodithi
Copy link
Member

I see .pull_request.head.sha does not give the force commit sha
Found some related issue.
https://gh.neting.ccmunity/t/github-actions-how-to-to-get-pr-merge-commit-sha-in-push/209044
@lukas-vlcek can you do a dummy commit and do a normal push again please?
Also just curious did u use --force-with-lease or --force while pushing ?

@lukas-vlcek
Copy link
Contributor Author

lukas-vlcek commented Jul 1, 2022

@prudhvigodithi I used just -f.

I added one more commit. Lowered the logging level to DEBUG (so not really a "dummy" commit).

See opensearch-project#3476

Signed-off-by: Lukáš Vlček <lukas.vlcek@aiven.io>
@bbarani
Copy link
Member

bbarani commented Jul 1, 2022

Thanks. The gradle check job has picked up the new commit now.

@github-actions
Copy link
Contributor

github-actions bot commented Jul 1, 2022

Gradle Check (Jenkins) Run Completed with:

@prudhvigodithi
Copy link
Member

prudhvigodithi commented Jul 1, 2022

@prudhvigodithi I used just -f

Thanks @lukas-vlcek I have raised this as a bug to investigate on force commits.
Thank you

@lukas-vlcek
Copy link
Contributor Author

Thank you @prudhvigodithi !

@dblock
Copy link
Member

dblock commented Jul 5, 2022

@nknize you're good with this?

// Check that we can execute a privileged command
lastResult = runCommand(dockerPath, "images");
// Gradle BuildService implementations must be thread-safe
synchronized (this) {
Copy link
Collaborator

@reta reta Jul 5, 2022

Choose a reason for hiding this comment

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

This is interesting, I think we discussed that @lukas-vlcek offline, the volatile + synchronized definitely make sense to keep implementation thread safe, I am not sure it is worth doing that here: at worst, the getDockerAvailability() may be called a few times, but this is no data race and the outcome would be the same (since the environment is the same).

@dblock wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

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

...this is no data race and the outcome would be the same

I'm not as familiar with the distro tests here. Does this logic path need to be atomic? Could not synchronizing be trappy such that gradle parallel execution cause a concurrency issue where one build thread changes state and impacts another? Not just with distro tests today but with future contributions?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@nknize the logic is atomic (the state is a single pointer), the Docker detection logic could run a few times (potentially) which is the only issue I see here, marking getDockerAvailability() as synchronized would address that (no need for volatile or double check locking) but I have never seen an issue with this service in any builds.

@opensearch-trigger-bot
Copy link
Contributor

This PR is stalled because it has been open for 30 days with no activity. Remove stalled label or comment or this will be closed in 7 days.

@opensearch-trigger-bot opensearch-trigger-bot bot added the stalled Issues that have stalled label Jul 13, 2023
@opensearch-trigger-bot
Copy link
Contributor

This PR was closed because it has been stalled for 7 days with no activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stalled Issues that have stalled
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] Docker & Docker compose installed from Homebrew not recognized
7 participants