-
Notifications
You must be signed in to change notification settings - Fork 561
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
Fixed volume mount issue(759) for Windows #924
base: main
Are you sure you want to change the base?
Conversation
go.mod
Outdated
@@ -118,6 +118,7 @@ require ( | |||
github.com/mitchellh/go-homedir v1.1.0 // indirect | |||
github.com/mitchellh/mapstructure v1.4.3 // indirect | |||
github.com/moby/locker v1.0.1 // indirect | |||
github.com/moby/moby v20.10.13+incompatible // indirect |
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'm not sure should we add a full moby dependency here?
pkg/mountutil/mountutil_freebsd.go
Outdated
@@ -66,3 +74,65 @@ func ProcessFlagTmpfs(s string) (*Processed, error) { | |||
func ProcessFlagMount(s string, volStore volumestore.VolumeStore) (*Processed, error) { | |||
return nil, errdefs.ErrNotImplemented | |||
} | |||
func ProcessSplit(s string, volStore volumestore.VolumeStore) (Processed, error) { |
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 ProcessSpllit
code is as same as the code in mountutil_linux.go
. FYI https://github.com/containerd/nerdctl/pull/924/files#diff-ab0f47dd8154315baddf1347290f120ed5e9975a660c4bfb838d17dcd2418c50R434
Maybe we can add a new file named mountutils_otthers.go
and add //go:build !windows
at the top of the code and move ProcessSpllit
here
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.
Or maybe we can keep the conditions of ProcessSplit for linux and freebsd in mountutil.go and keep the windows one as it is.
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.
Yes, I think it's a better choice
pkg/mountutil/mountutil_freebsd.go
Outdated
|
||
var ( | ||
res Processed | ||
src, dst string |
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.
IMHO, I think using global mutable variables here would not be the best choice.
Would you mind telling me why we need global mutable variables here?
"runtime" | ||
"strings" | ||
|
||
"github.com/containerd/containerd/errdefs" | ||
"github.com/containerd/containerd/oci" |
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.
Fix the lint error plz
fab7e61
to
47d33bd
Compare
f15f961
to
15d243b
Compare
Please remove irrelevant commits and squash your ones. |
9340c9b
to
6a6bc2e
Compare
79ddf50
to
f913684
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.
Maybe we got some rebase issue here?
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.
Maybe we got some rebase issue here?
cmd/nerdctl/build.go
Outdated
@@ -75,7 +75,7 @@ func newBuildCommand() *cobra.Command { | |||
} | |||
|
|||
func getBuildkitHost(cmd *cobra.Command) (string, error) { | |||
if cmd.Flags().Changed("buildkit-host") { | |||
if cmd.Flags().Changed("buildkit-host") || os.Getenv("BUILDKIT_HOST") != "" { |
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.
IMHO, The piece of code here is may belong to the #932
Maybe we got some rebase issue here?
0b52580
to
09b85d6
Compare
@@ -439,3 +451,52 @@ func NetworkFromNative(n *native.Network) (*Network, error) { | |||
|
|||
return &res, nil | |||
} | |||
|
|||
type Specs struct { |
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.
pkg/mountutil/mountutil_linux.go
Outdated
@@ -422,3 +422,7 @@ func getTmpfsSize(size int64) string { | |||
|
|||
return fmt.Sprintf("size=%d%s", size, suffix) | |||
} | |||
func ProcessSplit(s string, volStore volumestore.VolumeStore, res Processed, src string, dst string, options []string) (string, string, []string, error) { |
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.
Needs godoc
pkg/mountutil/mountutil_windows.go
Outdated
@@ -68,3 +71,81 @@ func ProcessFlagTmpfs(s string) (*Processed, error) { | |||
func ProcessFlagMount(s string, volStore volumestore.VolumeStore) (*Processed, error) { | |||
return nil, errdefs.ErrNotImplemented | |||
} | |||
|
|||
func ProcessSplit(s string, volStore volumestore.VolumeStore, res Processed, src string, dst string, options []string) (string, string, []string, error) { |
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.
Needs godoc.
Also, can we have unit tests?
09b85d6
to
d7cd274
Compare
6384e3f
to
53bc54e
Compare
@@ -106,7 +106,7 @@ type Container struct { | |||
// TODO: SizeRw *int64 `json:",omitempty"` | |||
// TODO: SizeRootFs *int64 `json:",omitempty"` | |||
|
|||
// TODO: Mounts []MountPoint | |||
Mounts []specs.Mount |
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 should be []MountPont
, not []specs.Mount
for Docker compatibility
https://github.com/moby/moby/blob/f0014860c1b3345e1fcc7ed81c491298de2633fb/api/types/types.go#L416-L427
https://github.com/opencontainers/runtime-spec/blob/6969a0a09ab162a574cafcc9ac814e498962c943/specs-go/config.go#L110-L120
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.
Addressed in #822
fe9fbb6
to
637d289
Compare
"github.com/docker/go-connections/nat" | ||
"github.com/moby/moby/api/types" |
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.
We do not import this package. Please see other struct definitions and keep the coding style consistent.
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.
Okay.
@@ -195,12 +196,26 @@ type NetworkEndpointSettings struct { | |||
|
|||
// ContainerFromNative instantiates a Docker-compatible Container from containerd-native Container. | |||
func ContainerFromNative(n *native.Container) (*Container, error) { | |||
var mounts *specs.Spec | |||
// for unmarshalling mount details | |||
err := json.Unmarshal(n.Container.Spec.Value, &mounts) |
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.
We already have specs.Spec
. Please see the if sp, ok := n.Spec.(*specs.Spec); ok {
line below.
53bc54e
to
a61f22c
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.
sorry for the delay, been on PTO for a couple weeks.
pkg/mountutil/mountutil.go
Outdated
if runtime.GOOS == "windows" { | ||
sr, ds, optns, err := ProcessSplit(s, volStore, res, src, dst, options) |
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.
Why are adding a check for goos if we are doing the process split logic in os specific files? it feels strange to have the case statements tucked away for Windows but for other OS (linux) process split is in this file especially since process split doesn't do anything for linux/freebsd and are exactly the same
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 will just keep the process split logic to respective os files and remove the os logic.
pkg/mountutil/mountutil_freebsd.go
Outdated
func ProcessSplit(s string, volStore volumestore.VolumeStore, res Processed, src string, dst string, options []string) (string, string, []string, error) { | ||
var x []string | ||
return "", "", x, 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.
freebsd implementation is the same as linux, why do we have it duplicated? (see other comment about the goos check for processsplit in mountutil.go)
"-v", fmt.Sprintf("%s:C:\\mnt3", rwVolName), | ||
"-v", fmt.Sprintf("%s:C:\\mnt4ro", roVolName), | ||
imageName).AssertOK() | ||
base.Cmd("container", "inspect", containerName).AssertOK() |
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 asserts that the container created, do we also want to make sure that the volume is actually there (maybe with something in it)? How is this tested on Linux?
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.
TestRunAnonymousVolume and TestRunNamedVolume checks whether the volume is mounted or not. For linux, we havent added any test as the problem was with the windows part.
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 guess we some coverage that the volume is created. Another thing noticed now, is it seem like we are also testing read/write behavior here. I would think we want to verify that the in the test.
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.
For verifying the read/write behavior, inspect should print the details regarding it. But in inspect for windows, it doesn't work.
D:\GolandProjects\github.com\nerdctlmst\cmd\nerdctl>nerdctl inspect 1f44fa83de
[
{
"Id": "1f44fa83de31867ec49d2639a15f4d04fa6003765660afb9e50c51e887e89815",
"Created": "2022-04-28T11:03:48.0466636Z",
"Path": "c:\\windows\\system32\\cmd.exe",
"Args": null,
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Pid": 25496,
"ExitCode": 0,
"FinishedAt": "2022-04-28T11:03:50.2407926Z"
},
"Image": "mcr.microsoft.com/windows/nanoserver:20H2",
"ResolvConfPath": "",
"HostnamePath": "",
"LogPath": "",
"Name": "nanoserver-1f44f",
"Driver": "windows",
"Platform": "windows",
"AppArmorProfile": "",
"Mounts": [
{
"Source": "C:\\ProgramData\\nerdctl\\052055e3\\volumes\\default\\testVolume\\_data",
"Destination": "C:\\src",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
"NetworkSettings": {
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"MacAddress": "",
"Networks": {}
}
}
]
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 is the output Im getting.
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 the inspect output for the volume is there but the rw/ro info isn't valid? Does the actual directory in the container have the correct attributes? If it is just inspect that isn't return properly lets create an issue to resolve later.
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 issue is only with windows where I cant get the output for read/write behavior.
8d3f808
to
e2764b8
Compare
pkg/mountutil/mountutil_freebsd.go
Outdated
|
||
// ProcessSplit splits volume mount information received through command line into respective source, destination | ||
// and optsRaw fields according to the volume type chosen and returns them accordingly. | ||
func ProcessSplit(s string, volStore volumestore.VolumeStore, res *Processed, src string, dst string, options []string) (string, string, []string, error) { |
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 function is exactly the same for freebsd and linux. Can we reduce this so the code isn't copy pasted in two places?
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.
Okay
options = append(options, "rbind") | ||
} | ||
res.Mount = specs.Mount{ | ||
Type: fstype, |
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.
Why is this being dropped? I don't see it moved anywhere.
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.
Because of this the mounted type during inspect was null. Now I get this output:
D:\GolandProjects\github.com\nerdctl\cmd\nerdctl>nerdctl inspect 3c46c12ed1f1
[
{
"Id": "3c46c12ed1f1f6272b4ab3f93996a19e2e52667313c2a2cbbf94f87b08350dad",
"Created": "2022-05-06T09:54:49.1905099Z",
"Path": "c:\\windows\\system32\\cmd.exe",
"Args": null,
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"Pid": 10928,
"ExitCode": 0,
"FinishedAt": "2022-05-06T09:54:51.2735242Z"
},
"Image": "mcr.microsoft.com/windows/nanoserver:20H2",
"ResolvConfPath": "",
"HostnamePath": "",
"LogPath": "",
"Name": "nanoserver-3c46c",
"RestartCount": 0,
"Driver": "windows",
"Platform": "windows",
"AppArmorProfile": "",
"Mounts": [
{
"Type": "volume",
"Name": "500907e8f1465b04f132f5a49b76c59c1e41f18aa9063faffa5c2bb7fc2e72a5",
"Source": "C:\\ProgramData\\nerdctl\\052055e3\\volumes\\default\\500907e8f1465b04f132f5a49b76c59c1e41f18aa9063faffa5c2bb7fc2e72a5\\_data",
"Destination": "C:\\src",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
"NetworkSettings": {
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"MacAddress": "",
"Networks": {}
}
}
]
Please check.
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.
is only printing null
an issue on Windows? I am concerned this change affects something on freebsd or linux. The tests aren't failing but maybe we are missing coverage here
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 we pass "none" as fstype for windows, it gives this error: "time="2022-05-12T12:13:13+05:30" level=fatal msg="invalid OCI spec - Type 'none' not supported: unknown"".
why are we passing nullfs or none, when we are already passing mount types like bind, volume or tmps while splitting the source and destination.
I don't know why none/nullfs is passed here. @AkihiroSuda do you have any insight?
16ad204
to
f369883
Compare
options = append(options, "rbind") | ||
} | ||
res.Mount = specs.Mount{ | ||
Type: fstype, |
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.
is only printing null
an issue on Windows? I am concerned this change affects something on freebsd or linux. The tests aren't failing but maybe we are missing coverage here
pkg/mountutil/process_split.go
Outdated
@@ -0,0 +1,100 @@ | |||
//go:build freebsd || linux |
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 file should be named mountutil_others.go
or mountutil_linux.go
to stay consistent that this a function that is specific to runtimes related to mountutil.
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 we pass "none" as fstype for windows, it gives this error: "time="2022-05-12T12:13:13+05:30" level=fatal msg="invalid OCI spec - Type 'none' not supported: unknown"".
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.
why are we passing nullfs or none, when we are already passing mount types like bind, volume or tmps while splitting the source and destination.
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.
These comments look to have landed on the wrong thread. I've responded here: #924 (comment)
006f7fb
to
17119fa
Compare
Signed-off-by: Raymond Mathew <raymond.mathew@click2cloud.net>
I think we've gotten pretty far on this. I would be inclined to merge and iterate. The last comment I have a concern on is https://github.com/containerd/nerdctl/pull/924/files#r871565970. @AkihiroSuda do you know what that |
res.Opts = append(res.Opts, specOpts...) | ||
default: | ||
return nil, fmt.Errorf("failed to parse %q", s) | ||
src, dst, options, err = ProcessSplit(s, volStore, &res, src, dst, options) |
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.
Looking at the implementations, src
, dst
, and options
are never consumed, so should probably not be parameters, but local vars in ProcessSplit
. That would allow simplifying this call slightly to src, dst, options, err := ProcessSplit(s, volStore, &res)
, trimming the top-of-function var
lines, rather than growing them.
Also, does it need to be public? processSplit
seems like it should work, all uses are in pkg/mountutil AFAICT, and it seems slightly safer to hide platform-split functions to control the blast radius in case of future divergence.
Fixed issue #759 :
When using nerdctl + containerd on Windows, I am able to mount volumes or bind mount to a new windows container.
Signed-off-by: Raymond Mathew click2cloud-lamda@click2cloud.net
Signed-off-by: Dasara Nagaraju dasara.nagaraju@click2cloud.net