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
cifs volume resolves hostname correctly #46863
cifs volume resolves hostname correctly #46863
Conversation
98a5845
to
d1585d7
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.
Thank you for contributing!
I have a couple of comments.
Could you also amend the commit message and remove the "Fixes #XXX" magic string? We tend to only include these in the PR bodies to avoid Github doing auto-close when commits are merged in forks or other repositories.
volume/local/local_unix.go
Outdated
if err != nil { | ||
return errors.Wrapf(err, "error parsing mount device url") | ||
} | ||
if deviceUrl.Host != "" && net.ParseIP(deviceUrl.Host).To4() == 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 deviceUrl.Host != "" && net.ParseIP(deviceUrl.Host).To4() == nil { | |
if deviceUrl.Host != "" && net.ParseIP(deviceUrl.Host) == nil { |
I know this was just taken from the previous code, but I'm wondering if there is a reason to restrict the lookup to IPv4 addresses only?
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.
Original PR for nfs was #27329
I don't see an immediate mention during review about IPv4, but there was a IsIP()
helper (that was later removed?) #27329 (comment)
And I saw some mention of a complex RegEx that was later removed, so I wonder if the .To4()
was just use as validation for "is it an IP address?")
We should look if we can use IPv6 addresses without issues (or if they need the bracketed ([::1]
) notation or escaping)
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.
Looks like in the cifs case we should be able to resolve to an IPv6 address just fine. I just checked the mount.cifs
userspace helper source and it seems to handle IPv6 addresses: https://github.com/Distrotech/cifs-utils/blob/0b0b81a533a8990d9a19e80b317a320c1d8a09d3/resolve_host.c#L37
The probable reason why the original code has the IPv4 restriction was to match the mount.nfs
behavior which seems to only resolve IPv4 addresses (explicit AF_INET
lookup): https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=blob;f=utils/mount/network.c;h=01ead49f0008ecfaee3fba4671cc9192fa8f9b99;hb=HEAD#l268 (thanks @akerouanton for finding the source!).
c6e6ec5
to
b1592f8
Compare
Adopted your suggestions and it works. @vvoland |
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.
Good work, thanks! Just 2 more things regarding the Host
field.
02ea516
to
5d0afdf
Compare
Incorporated your suggestions. I never stumpled upon CIFS with different than default port.
gives me this error, when running a container using this volume:
I have not enough knowledge about CIFS and its port usage, to comment on this. With default ports it works fine. |
706847f
to
bbde9c4
Compare
With stripping the port before the DNS query, it works with an added port.
|
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.
Thanks! Looks good to me, just needs a rebase on top of the master and dropping the hack/dind
commits.
db68959
to
e4c29df
Compare
Done |
volume/local/local_unix.go
Outdated
if err != nil { | ||
return errors.Wrapf(err, "error resolving passed in network volume address") | ||
} | ||
deviceUrl.Host = net.JoinHostPort(ipAddr.String(), deviceUrl.Port()) |
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.
Was looking at this, and we may need to have a check if deviceUrl.Port()
is not empty; I did a quick check, and it looks like net.JoinHostPort
unconditionally adds a colon (:
), also if there's no port; https://go.dev/play/p/MrZXfaigVRF
package main
import (
"fmt"
"net"
)
func main() {
fmt.Println(net.JoinHostPort("1.2.3.4", ""))
fmt.Println(net.JoinHostPort("::1", ""))
}
Code above prints;
1.2.3.4:
[::1]:
0ae3168
to
4868be7
Compare
4868be7
to
77478c5
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.
Thanks! Looking good, just needs one last touch.
Can you also apply Sebastiaan's suggestion (check if Port is empty)?
#46863 (comment)
Also, please make sure that you squash your commits (so the PR has only one commit).
Co-authored-by: Paweł Gronowski <me@woland.xyz> Signed-off-by: Michael Kebe <michael.kebe@gmail.com>
77478c5
to
8ae94ca
Compare
Done, have fun 😄 |
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.
Thanks, LGTM!
Thanks! changes look good; some things we should look at in a follow-up (perhaps you're interested in working on these?)
|
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
One thing I noticed. Adding a volume with
works. It looks like the port is ignored? |
Yeah, looks like the port is expected to be passed as a separate
Considering that the $ mount -t cifs //example.xyz:1231/adsd /mnt
mount error: could not resolve address for example.xyz:1231: Unknown error doesn't separate the port, perhaps we should do the same and just use the whole Alternatively, we could error out with an explanation that user should pass the |
Yes, perhaps an error would make sense, so that we don't diverge too much from what's expected. If we would do the parsing and conversion ( |
Yes, I wouldn't be in favor of the But, providing an extra, more user friendly warning is probably fine, since it also avoids user confusion and blaming the engine for not connecting to the right port. |
Previously, I had been using a CIFS option, I'm guessing this is intended, but thought I'd share this here in case anyone else ran into this issue. I initially rolled back to v24 and held the package until I could figure out what was going on. This relates to docker --version
Docker version 25.0.0, build e758fe5 |
- What I did
Fixed this issue #46180. There is a old PR which claims to fix this #39250, but is hasn't.
The problem is that, the hostname in NFS and CIFS mounts are at different places.
NFS uses the
addr
value in theMountOpts
.CIFS uses the hostname part of the
MountDevice
URL.- How I did it
Splitted the switch case statement of #39250 for NFS and CIFS. Used the
net/url
Parse
function to extract the hostname. And handled the rest in the same way NFS did.- How to verify it
Create a docker volume using a hostname instead of an IP address.
Start a container using that volume.
- Description for the changelog
CIFS volumes resolving FQDN correctly.
I am not a go hacker, so maybe it's not "go idiomatic".