Skip to content
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

Windows 'invalid volume specification' #666

Closed
5 tasks done
thecoshman opened this issue Jun 27, 2018 · 7 comments
Closed
5 tasks done

Windows 'invalid volume specification' #666

thecoshman opened this issue Jun 27, 2018 · 7 comments

Comments

@thecoshman
Copy link

thecoshman commented Jun 27, 2018

Please don't use the issue tracker to ask questions, join jenkins-users mailing list.

If you get some troubles with docker-plugin, please report

  • docker-plugin version you use - 1.1.4
  • jenkins version you use - 2.107.3
  • docker engine version you use - 17.06.2-ee-6 build e75fdb8 (On Windows host)
  • details of the docker container(s) involved and details of how the docker-plugin is connecting to them - using microsoft/dotnet:2.1-slim with pipeline file requesting agent
  • stack trace / logs / any technical details that could help diagnose this issue - During logs get an error saying 'invalid volume specification'

Seems whatever way this plugin is building the command for 'docker run' it is not happy for docker on Windows. I have seen that for docker-compose there is an option to convert to Windows paths.

@pjdarton
Copy link
Member

FYI the plugin doesn't build a command to docker run - it talks direct to the docker API. i.e. the docker client software is Java code, not a native command that's execed.

Much as I hate to dampen your enthusiasm, I think that this one is going to be non-trivial to sort. The existing jenkinsci infrastructure (used to test this plugin) does not provide us with Windows executors that have docker installed, so we can't put in unit-tests to ensure that docker-on-Windows works.
Secondly, I don't have a Windows environment with docker on it where I am either (my personal dev machine is a nice and old-but-stable Windows 7 machine) and so I'm not familiar with Microsoft's implementation at all.
Lastly, 99% of my experience with the docker-plugin is using it to provide slaves defined in templates (in the Manage Jenkins -> Configure System area), not with Jenkins pipeline builds.
i.e. the best I can do is to ask questions and hopefully guide you to the answer.

So, with that in mind, I'd suggest that we start with details of the pipeline you're running. i.e. the code.
By all means strip out what's being done within the Pipeline (maybe replace stuff with echo) to avoid publishing information you'd like to keep private, but we'll need to know the exact syntax you're using that's invoking the plugin.
Secondly, a stack-trace would be very useful. You'll find those in the logs.

Lastly, before we go delving into the nerdy details, one thing I would suggest that you check is proper "escaping" of backslashes. I have a heterogeneous environment at work with a mix of Windows and unix and if I had a pound/dollar for every time someone had written C:\newfolder in code and then expressed surprise that they'd got C:newlineewfolder as a result then I would have retired to a tropical island by now (whoever thought that a backslash would make for a good file/folder separator character should be shot).

@thecoshman
Copy link
Author

Regarding your usage pattern, I've actually not used docker in the way form Jenkins. I am not sure if it was this plugin I was using before, but I was able to use a pipeline, like below, and Jenkins would take care of creating the container for me; it even supported having a 'dockerfile' within your repo and just building it on demand as part of the pipeline. That behaviour is all following what is described on the Jenkins piepline documentation. Again there is a chance that I am simply using a different plugin compared to what I was using before.

There is no escaping for me to check, as the volume mounting of the workspace into the container is managed automatically.

Here is the pipeline that I've been testing this with. As you can see, it's very basic, I'm only looking to get the container started at this stage.

pipeline {
    agent {
        docker {
            image 'microsoft/dotnet:2.1-sdk'
        }
    }
    stages {
        stage('Build') {
            steps {
                echo 'hi'
            }
        }
    }
}

And here is the stack trace for the error that I get.

java.io.IOException: Failed to run image 'microsoft/dotnet:2.1-sdk'. Error: docker: Error response from daemon: invalid bind mount spec "E:\\Slave\\workspace\\myjob:E:\\Slave\\workspace\\myjob:rw,z": invalid volume specification: 'E:\Slave\workspace\myjob:E:\Slave\workspace\myjob:rw,z'.
See 'docker run --help'.
  at org.jenkinsci.plugins.docker.workflow.client.DockerClient.run(DockerClient.java:133)
  at org.jenkinsci.plugins.docker.workflow.WithContainerStep$Execution.start(WithContainerStep.java:184)
  at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:229)
  at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:153)
  at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:108)
  at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
  at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
  at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
  at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:19)
  at org.jenkinsci.plugins.docker.workflow.Docker$Image.inside(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/docker-workflow/WEB-INF/lib/docker-workflow.jar!/org/jenkinsci/plugins/docker/workflow/Docker.groovy:135)
  at org.jenkinsci.plugins.docker.workflow.Docker.node(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/docker-workflow/WEB-INF/lib/docker-workflow.jar!/org/jenkinsci/plugins/docker/workflow/Docker.groovy:66)
  at org.jenkinsci.plugins.docker.workflow.Docker$Image.inside(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/docker-workflow/WEB-INF/lib/docker-workflow.jar!/org/jenkinsci/plugins/docker/workflow/Docker.groovy:123)
  at org.jenkinsci.plugins.pipeline.modeldefinition.agent.impl.DockerPipelineScript.runImage(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/agent/impl/DockerPipelineScript.groovy:57)
  at org.jenkinsci.plugins.pipeline.modeldefinition.agent.impl.AbstractDockerPipelineScript.configureRegistry(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/agent/impl/AbstractDockerPipelineScript.groovy:67)
  at org.jenkinsci.plugins.pipeline.modeldefinition.agent.impl.AbstractDockerPipelineScript.run(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/agent/impl/AbstractDockerPipelineScript.groovy:53)
  at org.jenkinsci.plugins.pipeline.modeldefinition.agent.CheckoutScript.checkoutAndRun(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/pipeline-model-extensions/WEB-INF/lib/pipeline-model-extensions.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/agent/CheckoutScript.groovy:66)
  at org.jenkinsci.plugins.pipeline.modeldefinition.agent.CheckoutScript.doCheckout(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/pipeline-model-extensions/WEB-INF/lib/pipeline-model-extensions.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/agent/CheckoutScript.groovy:42)
  at org.jenkinsci.plugins.pipeline.modeldefinition.agent.impl.LabelScript.run(jar:file:/C:/Program%20Files%20(x86)/Jenkins/plugins/pipeline-model-definition/WEB-INF/lib/pipeline-model-definition.jar!/org/jenkinsci/plugins/pipeline/modeldefinition/agent/impl/LabelScript.groovy:44)
  at ___cps.transform___(Native Method)
  at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
  at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
  at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
  at sun.reflect.GeneratedMethodAccessor238.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
  at com.cloudbees.groovy.cps.impl.ClosureBlock.eval(ClosureBlock.java:46)
  at com.cloudbees.groovy.cps.Next.step(Next.java:83)
  at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
  at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
  at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
  at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
  at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
  at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:19)
  at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:35)
  at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:32)
  at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
  at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:32)
  at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:331)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:82)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:243)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:231)
  at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
  at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
  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
Copy link
Member

pjdarton commented Jul 2, 2018

Hmm, yes, I can see that the pipeline code is fairly basic.
The thing that puzzles me is that there isn't anything in the plugin code which is choosing to use E:\Slave\workspace - the plugin code doesn't know anything about Windows so it's not going to be choosing to specify E:\anything.
I can see that, within the plugin code, if the user (that's "you") does not specify a remoteFs value (which you didn't) then the plugin interrogates the image's configuration to ask it what it's working directory is, and it'll then use that as the remoteFs value. However, while that would explain where E:\Slave came from (it will have come from the microsoft/dotnet:2.1-sdk image itself), that doesn't explain why the complaint is about binding mount specs...

So I took a (brief) look at the docker hub page for the microsoft/dotnet:2.1-sdk image and it says that it is "designed to be used both as a throw away container (mount your source code and start the container to start your app)".
While the first part of that statement tells me that we're probably on the right track, it's the bit in the brackets that makes me suspect that Microsoft's idea of standard docker usage and everyone else's idea of standard docker usage may be very different (because I would not expect to have to mount anything in order to use a standard docker image).
So, my guess is that, in order to use this image, it may be necessary customise the image's mount-spec, i.e. the reason for this error could be because we're trusting Microsoft's default settings to be correct ;-)

...that said, I delved deeper into the dotnet docker documentation by going to its source repository, then following the 2.1-sdk link which looks like it's 100% unix and nothing from Windows at all, which makes me question the idea that the E: stuff could be coming from the docker image.

What kind of docker daemon is Jenkins talking to?
Are you telling Jenkins to talk to a Windows docker daemon? Could that be the source of this E: nonesense?

@thecoshman
Copy link
Author

Well, the way I've used pipelines before, I've never had to do anything special regarding volumes. It was always Jenkins that was looking that the path to the workspace where the build was started, and then sharing that into the image at the exact same path. I believe there is a variable that Jenkins manges that set's what the workspace path is.

This could be some issue that image I am using is not design for running on Windows, I am new to this aspect. I have a suspicion that you might need to ensure that the image you are using is designed from the ground up to be run as a Windows image, not a Linux image.

@patrickbussmann
Copy link

I have the same issue.

Jenkins is running on Ubuntu / Linux.
Docker is running on Windows Server 2016.

I test with this.

node {
	stage('Example') {
		docker.withServer('tcp://docker.example.org:2375') {
			docker.image('stefanscherer/node-windows:10').inside {
				sh 'node --version'
			}
		}
	}
}

And get this error.

java.io.IOException: Failed to run image 'stefanscherer/node-windows:10'. Error: docker: Error response from daemon: invalid volume specification: '/var/lib/jenkins/workspace/Docker Test:/var/lib/jenkins/workspace/Docker Test:rw,z'.
See 'docker run --help'.
	at org.jenkinsci.plugins.docker.workflow.client.DockerClient.run(DockerClient.java:133)

@jtnord
Copy link
Member

jtnord commented Jan 25, 2019

org.jenkinsci.plugins.docker.workflow is from docker-workflow-plugin not the docker-plugin

@pjdarton
Copy link
Member

...well, that would explain why I didn't recognize any of what was being discussed :-)
...and it's issues like this which inspired the last line in 89dad4f#diff-04c6e90faac2675aa89e2176d2eec7d8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants