LCOW: Prepare work for bind mounts#34258
Conversation
8800647 to
dad6c6d
Compare
|
Hmm this breaks many dockerfiles with volumes. I suppose we should have a different parsing mechanism for volume paths in dockerfiles (which by nature should only contain a target path and should be validated elsewise) |
|
@jhowardmsft PTAL |
volume/volume_windows.go
Outdated
There was a problem hiding this comment.
It seems to me that this validation should be context sensitive. I.e. we should only perform Windows validation when handling mounts for Windows containers, and we should only perform Linux validation when handling mounts for Linux containers.
In the latter case, it would be nice to reuse the existing Linux validation code rather than rewrite it here, although of course that means the shared Linux code would need to use path instead of filepath.
There was a problem hiding this comment.
Yes, after having seen CI test failures, I agree that we must do different parsing / validation logic to handle linux containers and windows containers.
However, we can´t leverage existing linux parsing/validation completely, as the source path is still windows style, and the linux parsing code is based on the assumption that : is a forbidden character in a file path...
There was a problem hiding this comment.
So, I think that after all we need a far more invasive change, and we could take the occasion to refactor a bit the volume package.
I'd like to introduce a volume.Parser interface that would expose methods to parse/validate mount specs, with a constructor taking a platform string. We would have 3 implementaions (linuxParser, windowsParser, lcowParser) that would certainly share some amount of code, instead of relying on conditional compilation and current tricks (for exemple the convertSlashes doing the exact oposite on windows and linux is SO confusing on code maintenance mode...)
dad6c6d to
c749525
Compare
|
@johnstep, @jhowardmsft, I just completely changed the approach, with a complete volume refactoring (that will require some refinements), where parsing/validation logic depends on the containerPlatform and the host OS. I also removed static compilation switches, to have an easier code reading experience (there were some dirty tricks behind compilation switches), and make it easier to share more code in the future. |
e8af7c3 to
c6d2cf9
Compare
|
Ok, latest CI failures where essentially stuff related to existing |
|
I talked to @adburch and simple paths such as Paths containing non-Windows allowed characters and |
|
I am running 10.0.16257.1 |
6abd361 to
5c68181
Compare
runconfig/config.go
Outdated
There was a problem hiding this comment.
delete commented out code and the above comment?
volume/parser.go
Outdated
There was a problem hiding this comment.
I believe the return value here could be just error, it seems that false is only returned with error, so it doesn't need to have both values. It could be just ValidateVolumeName(name string) error.
I realize this was previously implemented this way, but probably doesn't hurt to fix it now that this is being refactored?
There was a problem hiding this comment.
Yes I agree, I'll just have to check on error type instead of the combination of both bool and error (which is confusing)
volume/parser.linux.go
Outdated
There was a problem hiding this comment.
This surprised me. There are definitely restrictions for the volume name on linux (must be at least 3 characters and start with a letter, I believe).
Is that validation happening somewhere else? Maybe we can fix that here as well?
There was a problem hiding this comment.
I think I followed the codepath correctly on this one. I'll double check (the code paths were very complicated before)
volume/parser.go
Outdated
There was a problem hiding this comment.
I was really surprised to find such a large interface, but after looking over the rest of the PR I see that this logic really is scattered all over so there's no easy way to reduce this interface. Hopefully over time we can refactor the callers and reduce the size of this interface.
There was a problem hiding this comment.
Yes I agree. I started with 2 methods, and I progressively had to add a lot of stuff in it...
volume/parser.lcow.go
Outdated
There was a problem hiding this comment.
Normally I believe underscores are used in go filenames instead of .. I'm guessing this was done because parser_linux.go would imply a linux build tag (which we don't want). Maybe parser_lcow.go and parser_linux_volume.go ?
There was a problem hiding this comment.
Yes, I used dots to avoid automatic conditional compilation
|
Also, I really like this approach! Design LGTM |
dnephin
left a comment
There was a problem hiding this comment.
couple other small comments/question on implementation
container/container.go
Outdated
There was a problem hiding this comment.
Do you think it would make sense to move this default into NewParser() ?
I guess a lot of code is calling NewParser(runtime.GOOS), but it could call NewParser("") instead and handle the default case there.
NewParser() would check if the passed parameter is the empty string, and default to runtime.GOOS.
There was a problem hiding this comment.
I initially forced the parameter passing to identify where the volume package was called and to try to identify where there could be problems (especially code validating mounts config where we don't yet have access to the image target OS).
daemon/oci_linux.go
Outdated
There was a problem hiding this comment.
nit: move this down to line 511 so it's next to the code that uses it, instead of stranded up here near unrelated code
runconfig/config.go
Outdated
There was a problem hiding this comment.
Outside of the context of this PR this comment isn't going to make any sense to the reader. I think it should be removed.
volume/parser.go
Outdated
There was a problem hiding this comment.
These are operating systems. A platform carries architecture, as well.
We'll have to be careful about how we export this model.
There was a problem hiding this comment.
Agreed. I suppose volume parsing logic will only be os-specific and architectures should not be taken into account. I'll rename those accordingly.
7f50dae to
039450c
Compare
|
Unfortunately for various legal complications I can't. However @johnstep now has one. |
|
Can you squash your commits, then cherry-pick microsoft@b9abc83 from branch https://github.com/Microsoft/docker/tree/lcow-mounts. This also depends on a revendor of HCSShim in #34771 (status 4/merge currently). One word of caution when testing - due to a bug in opengcs (being tracked by microsoft/opengcs#131), the contents of any mapped directory will be deleted on the host on container exit currently. Example of bind-mounting a read-only directory: |
039450c to
81a8e70
Compare
|
@jhowardmsft done. Effectively the final rm -rf stuff is a bit brutal |
|
LGTM |
|
@simonferquel A few minor nits, but generally LGTM. And works :) |
container/container.go
Outdated
There was a problem hiding this comment.
I think we should (I have made a start in another PR) use "operatingSystem" or "os" rather than platform to indicate in the code base that it's not platform in the fuller sense os/arch/variant. Certainly not plat though.
volume/parser_lcow_impl.go
Outdated
There was a problem hiding this comment.
Don't use lcow in an error message. Linux containers on Windows do not...
volume/parser_lcow_impl.go
Outdated
There was a problem hiding this comment.
The file naming here seems very strange. I don't think we have a precedent for this type of naming anywhere else.
There was a problem hiding this comment.
The thing is that for future-proof multi-arch/os system, this PR makes all flavors of the parser available on all OS. I also wanted file ordering make different parsers appear together (so they all have a parser_ prefix. However, if I chose to keep names as parser_linux.go / parser_windows.go it would have triggered conditional compilation, so I had to add a new suffix for avoiding it to happen.
There was a problem hiding this comment.
Another workaround is - instead of _ but that is inconsistent with most of the file names in the project. Yet another is to modify the platform name so it will not match exactly, but I can't come up with a satisfactory modification.
If not for the file ordering issue, which seems minor to me, I would name them lcow_parser.go, linux_parser.go, and windows_parser.go, since that is closer to the respective type names.
There was a problem hiding this comment.
@johnstep @jhowardmsft just did that. With the small number of files in this package, I suppose it is ok to have them not grouped together.
|
@jhowardmsft, I fixed the items in your comments, thanks! |
360a228 to
26fd079
Compare
|
LGTM (can you squash/tidy the commits again please) |
26fd079 to
266fea1
Compare
|
@jhowardmsft, just rebased and squashed |
|
Errors seem related to the manifest list stuff... should I rebase once again ? |
|
@simonferquel If possible can you do a rebase against the master? I think the Jenkins errors has been fixed in #34837. Once the PR is rebased it should be ready to merge. |
|
I restarted PPC/Z. They should now pick up and apply this change on top of master. |
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
|
@jhowardmsft sorry john, I didn't see your comment, I just pushed a rebase against master |
This PR modifies mounts validation logic on Windows to accept both
windows container style and linux style destination path (allowing to
run things like
docker run -v c:\data:/data alpine ls /dataon lcow)- What I did
Changed a bit the validation of bind mounts specification to accept both windows and linux style destination paths on windows
- How I did it
Changed a bit some regular expressions, tried to be clever about when calling convertFromSlash
- How to verify it
Unit tests are updated accordingly
- Note
Current LCOW implementation does not seem to be able to do bind-mounts for now though. Here is the result of
docker run --rm -it -v c:\users:/data busybox: