jenkinsci / docker-plugin

Jenkins cloud plugin that uses Docker
https://plugins.jenkins.io/docker-plugin/
MIT License
490 stars 320 forks source link

Unable to bind mount Windows host volume #754

Open liangming2003 opened 5 years ago

liangming2003 commented 5 years ago

I failed to map the X: drive to drive G: in the container in container settings of Docker plugin 1.1.8.

Anyone know what' wrong with it? Thanks.

X: drive is a remote SMB share on Docker host (Windows server 2019)

DockerPlugin DockerPlugin2

Here is command I run to map the volume. I want to dynamically provision build agent using docker plugins.

docker run -d --name agent-00 --restart=always -v X:\:G: -e JENKINS_MASTER_HOST=docker -e JENKINS_AGENT_ID=WIN_00 -e JENKINS_SECRET=xxxxx jenkins-agent:latest

Here is the error message:

Note: Disabled 29 sec ago due to error. Will re-enable in 4 min 30 sec.
Reason: Template provisioning failed.

java.lang.IllegalArgumentException  at com.github.dockerjava.api.model.Bind.parse(Bind.java:130)Caused: java.lang.IllegalArgumentException: Error parsing Bind 'X:\:G:\'    at com.github.dockerjava.api.model.Bind.parse(Bind.java:134)    at com.nirima.jenkins.plugins.docker.DockerTemplateBase.fillContainerConfig(DockerTemplateBase.java:579)    at com.nirima.jenkins.plugins.docker.DockerTemplate.fillContainerConfig(DockerTemplate.java:224)    at com.nirima.jenkins.plugins.docker.DockerTemplate.doProvisionNode(DockerTemplate.java:547)    at com.nirima.jenkins.plugins.docker.DockerTemplate.provisionNode(DockerTemplate.java:526)  at com.nirima.jenkins.plugins.docker.DockerCloud$1.run(DockerCloud.java:364)    at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)  at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)  at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)  at java.lang.Thread.run(Thread.java:748)
pjdarton commented 5 years ago

The syntax that's expected here is dictated by the docker-java code It's also described in the help-text for that field (press the "?" icon that's to the right of the field - there's a lot of useful information in there). Judging from the help text and the code (i.e. the underlying docker-java library in this case), it expects you to be using : characters as field separators only and not as part of the path. You've got more : characters than the syntax permits. i.e. docker wasn't written with a view to supporting Windows-style paths.

I have no experience of doing docker with Windows so I don't know what other syntactical options you might have available, but it looks like you'll need to figure out a way of saying X:\ to the underlying docker daemon without using the : character. I'm less sure about the \ character - that's universally accepted as being an escape character so you might need \\ ... but a lot of Microsoft stuff is coming around to understanding / these days so you might be able to avoid using \ entirely. You'll have to consult the docs for your docker daemon for that - given that this "host/path:container/path" syntax is part of the official docker specification, I'd hope/expect (and everyone should demand) that there should be a way of using the Windows daemon without breaking the official specification. That said, this is from the company that once said "At Microsoft we like to think that there's no standard we can't improve upon" ... but where by "improve upon" they seem to have really meant "fail to implement correctly", so it might be that this is not possible (yet).

TL;DR: Docker in Windows is very much alpha-ware at present; it's immature technology and it may not be quite ready for prime-time usage yet.

liangming2003 commented 5 years ago

Thanks, @pjdarton

docker-java does not support mounting windows path volume.

Here is the pull request for fixing this issue, but don't know when they gonna release it. https://github.com/docker-java/docker-java/pull/920

It seems that the escaping colon does not work. Any workaround for Docker Plugin to mount windows host volume, thanks.

pjdarton commented 5 years ago

Well, this plugin uses docker-java to talk to the docker daemon - if docker-java doesn't support Windows paths in mounts then this plugin doesn't either and there's not much that can be done about that here (unless you want to submit a PR that switches this plugin to using a different Java docker-API library...) - the answer lies over in the docker-java code.

Get it fixed over there (and released) and then this plugin can move to the new version of docker-java, at which point it should start working.

darkvertex commented 4 years ago

FYI Docker for Windows currently does not support mounting network shares, only local volumes.

There is one exception, if your host is Windows Server version 1709 or later: https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/persistent-storage#smb-mounts

On Windows Server version 1709 and later, feature called "SMB Global Mapping" makes it possible to mount a SMB share on the host, then pass directories on that share into a container.

Otherwise, local disks only. (It sucks, I know..)

pkordes commented 4 years ago

The PR referenced above for docker-java has been merged. While I understand that only local volumes will work, there still doesn't be a way in the plugin to do c:\temp:c:\temp although this is now supported. Please advise if this is possible and what syntax to use or if there is indeed now a fix that can and should be applied to this plugin

pjdarton commented 4 years ago

It looks like it's been closed, not merged. The latest official release is 3.1.5 and that does not look like it includes any fixes on this matter.

The docker-java-api-plugin (which is what provides the docker-java library to this plugin) currently pulls in version 3.0.14 of the docker-java library. The most recent release of that library is 3.1.5 and the difference is this https://github.com/docker-java/docker-java/compare/3.0.13...3.1.5 (best split into two reports) I don't see any commits in there that looks like they're changing the Bind.java code to handle Windows mount points.

I'd be happy to be proven wrong but, right now, I don't think the code changes are available. Also, FYI, the author of the docker-java code was once a major contributor to this plugin but, after disagreements, left (and founded the yet-another-docker-plugin); I'm ignorant of "who said what to whom" but it's a regrettable part of the history of this plugin and, as he said, "best not to mention" this plugin over there.

So, please do check docker-java for where the code changes are and what the minimum (released) version of it is that contains the necessary changes. The moment we've got a released version that contains the changes, we can raise a PR on the docker-java-api-plugin to get it updated, and once that's done we can take advantage of that here.

i.e. 3 steps:

  1. You (or someone else) find out what version of docker-java we need
  2. You (or someone else) raises a PR to get a new version of the docker-java-api-plugin made that provides that version of the docker-java library.
  3. You (or someone else) raises a PR on this plugin to bump to the new docker-java-api-plugin and include whatever other (minor) fixes are required (e.g. to documentation etc).
LukaszKussowski commented 3 years ago

It is fixed in docker-java: https://github.com/docker-java/docker-java/pull/1463

pjdarton commented 3 years ago

Do you know which version of docker-java that went into? FYI changing docker-java versions is often problematic so it helps to only move forwards as little as we have to.

LukaszKussowski commented 3 years ago

It was merged to version 3.2.6

vindiagram commented 3 years ago

Are there any plans to update this plugin to the latest version of docker-java or at least version 3.2.6 to allow support for mounting volumes in Windows.

pjdarton commented 3 years ago

Right now, we (collectively) are struggling to even reach 3.2.2 (see pr #829) as that's blocked by dependency troubles (which I'm trying to reduce with pr #836 and docker-java-api pr 9) If you want to help unblock this, they're where to look.