-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Change docker context to default in MacOS #19046
base: main
Are you sure you want to change the base?
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: vyasgun The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
04366c5
to
1bd8e4c
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.
cmd/podman-mac-helper/service.go
Outdated
// Run the command | ||
err = cmd.Run() | ||
if err != nil && !errors.Is(err, exec.ErrNotFound) { | ||
fmt.Print(fail) |
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.
Question: I am largely unfamiliar with this helper but it seems strange to suppress the errors.
What happens if errors.Is(err, exec.ErrNotFound)
? Is it intentional to return success?
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 added this check because docker binary not existing in any of the paths might not be considered an error but on second thought, maybe it shouldn't be suppressed.
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 see how this can even work, this is a privileged helper AFAICT so you would execute docker as root here and not in the correct user context. If this is really need AFAICT it must happen in pkg/machine/qemu were it connects to the claim helper. cc @n1hility
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.
Right we should avoid running this as root. It needs to be done outside of the privileged helper, and ran on behalf of the user's account. It should live in the podman machine docker sock network setup logic
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.
So is it a feasible solution to redirect$HOME/.docker/run/docker.sock
as well in the podman-mac-helper service?
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 think the approach of changing the context is still the right one, just we should do that in podman machine start (as well as a future on the fly dynamic command if added) instead. (see my other comment here: #19046 (comment))
Why do we touch any docker config at all? Redirecting a socket is one thing but actively changing docker config on each startup without user consent seems like a bad idea? Reading #16548 this asks for redirecting the But my biggest problem is that there is not user documentation about how this helper works. The package installer installs this service by default which means users will have no clue about what is happening if we start chaning the docker context behind there backs. There are no docs about this tool so users are just left on its own to figure out why we broke his docker install. |
@Luap99 thanks for the review. The main issue is that the user doesn't want to run into an error while using docker commands but wants them to be directed to podman. This is resolved by changing the context to default as podman-mac-helper is already linking the default docker socket and the podman socket. |
Right IMO we should not mess with $HOME/.docker/run/docker.sock as it would make a running docker unusable (e.g. no ability to copy between the two), and likely bother users.
The underlying problem is that if users installed one particular old version of docker desktop, it generated config pointing to the non-common global location (There are other conditions that can happen, but in the default and most common case the context points to the default /var/run/docker.sock). So I suggested that if the user is starting podman machine, and we are already claiming the socket, they likely intend this to work, so we could just "fix" the context. A context of default works on both Docker and Podman machine (unless they did a custom setup that disabled /var/rundocker.sock) We probably should have a flag that can disable taking it back in case it does get annoying, but IMO its most likely what people want. |
@n1hility That sounds good to me. I will update the PR accordingly. |
1bd8e4c
to
df2372a
Compare
@@ -79,7 +83,23 @@ func start(_ *cobra.Command, args []string) error { | |||
if err := vm.Start(vmName, startOpts); err != nil { | |||
return err | |||
} | |||
if err := changeDockerContext(); err != 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.
If there is a agreement on this solution, there are few point which I think should be done:
- This should be only done for users who want this, maybe additional hidden flag ? Then
podman-desktop
can use this hidden flag by default--change-docker-context
? or something like that. - After that should this be only done if
docker desktop
exists on host and has a version>=4.13
? Not for everybody since problem only persists for new users ?
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.
If there is a agreement on this solution, there are few point which I think should be done:
- This should be only done for users who want this, maybe additional hidden flag ? Then
podman-desktop
can use this hidden flag by default--change-docker-context
? or something like that.
I agree that we at least need a way to limit/disable the behavior, not sure on opt-in vs opt-out. There is also a few other ways we could go about this:
- podman machine start detects and warns but does not fix. This wouldn't help podman desktop though, so it would likely mean that desktop would need to have its own detection. One benefit of that is that podman desktop could have a pop-up to ask if the context should be corrected
- Instead of doing this in start(), we move the check/fix to the respective installers (mac + brew). The advantage here is that 90+% of the time this is a one-time fix, so this would save wasted CPU cycles on likely unnecessary checks
- We don't address it all, and instead Podman Desktop handles this.
- After that should this be only done if
docker desktop
exists on host and has a version>=4.13
? Not for everybody since problem only persists for new users ?
Basically everyone is affected that ever installed 4.13.0 is broken forever until they change it back. 4.13.1 and onward works fine on fresh installs. The other way this can happen is an advanced install where the symlink is disabled.
In short the only way we can detect it is to examine the current context (either parsing the file or via the docker CLI)
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 the suggestion about moving the check/fix from start to installers. As Docker Desktop changes the context to $HOME/.docker/run/docker.sock each time it starts, it seems more convenient to me to have the context change command executed when the user starts the Podman machine.
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.
In all the versions I looked at this setting is only set during install / first launch. On all current versions, if you go with the defaults the docker cli will use /var/run/docker.sock (which symlinks to the user home sock), If you ever installed 4.13.0 though, it would have written a different current context value to the ~/.docker/config.json, which sticks around until it's removed or changed. The other scenario which sets the context is if you pick Advanced settings and you disable /var/run/docker sock, at which point it will also write a context value to config.json.
df2372a
to
7f97614
Compare
cmd/podman/machine/start.go
Outdated
} | ||
path := os.Getenv("PATH") | ||
path = strings.Join([]string{path, "/usr/bin", "/usr/local/bin"}, ":") | ||
os.Setenv("PATH", path) |
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.
Instead of changing the PATH globally for the whole process (which can cause side-effects on other areas of the code-base), a better approach would be to search a list of paths, which also has the added benefit to verify that docker binary exists before invoking it. Once found, the fully qualified joined absolute path could be used to invoke the specific location without needing a PATH change.
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 made the suggested change
@vyasgun Thanks for working on this! |
7f97614
to
b5d287a
Compare
pathList := strings.Split(os.Getenv("PATH"), ":") | ||
var dockerBinaryPath string | ||
for _, path := range pathList { | ||
dockerPath := filepath.Join(path, "docker") | ||
if info, err := os.Stat(dockerPath); err == nil && info.Mode().IsRegular() { | ||
dockerBinaryPath = dockerPath | ||
break | ||
} | ||
} | ||
if dockerBinaryPath == "" { | ||
return fmt.Errorf("docker binary not found") | ||
} | ||
|
||
cmd := exec.Command(dockerBinaryPath, "context", "use", "default") |
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 this? Why do we not directly execute docker
, exec.Command()
will already search PATH.
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.
This will prevent the binary not found error as we will only invoke it when we find it in the path.
Fixes: containers#1654 Signed-off-by: vyasgun <vyasgun20@gmail.com>
b5d287a
to
4a5582b
Compare
A friendly reminder that this PR had no activity for 30 days. |
@vyasgun whats up with 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.
Friendly ping. What should we do with the PR?
podman-mac-helper maps requests coming to
/var/run/docker.sock
(or the default context) to the podman socket. Docker context should be set todefault
for this to work. Added the code to change context to default duringmachine start
in case of MacOS.Fixes: #16548
Does this PR introduce a user-facing change?
No