cifs volume resolves hostname correctly#46863
Conversation
98a5845 to
d1585d7
Compare
There was a problem hiding this comment.
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.
| 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.
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.
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 |
vvoland
left a comment
There was a problem hiding this comment.
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. |
vvoland
left a comment
There was a problem hiding this comment.
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.
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
vvoland
left a comment
There was a problem hiding this comment.
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 😄 |
|
Thanks! changes look good; some things we should look at in a follow-up (perhaps you're interested in working on these?)
|
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 errordoesn'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
addrvalue in theMountOpts.CIFS uses the hostname part of the
MountDeviceURL.- How I did it
Splitted the switch case statement of #39250 for NFS and CIFS. Used the
net/urlParsefunction 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".