-
Bug
-
Resolution: Unresolved
-
Minor
-
None
-
Jenkins 2.203
docker-plugin 1.1.8 (same with 1.1.6)
I am successfully using docker slaves with custom images using the Attach method. The images are not based on jenkins/jnlp-slave but do have java. They have CMD set to ["/bin/sh", "-c"] and ENTRYPOIINT is null.
I've attempted to switch to the JNLP method and cannot get it to work despite spending many hours trying all sorts of combinations. According to the inline help, I should be able to pass a command in the "EntryPoint Arguments" field. I've tried the command suggested there:
sh -c "wget ${JENKINS_URL}jnlpJars/slave.jar && java -jar slave.jar -jnlpUrl ${JENKINS_URL}computer/${NODE_NAME}/slave-agent.jnlp -secret ${JNLP_SECRET}"
as well as a dozen others. The above doesn't work with openjdk:8-jdk image or any others I've tried.
I've also built images with slave.jar and /usr/local/bin/jenkins-agent scripts taken from jenkins/jnlp-slave, and even that doesn't work. No matter what I enter in the field, I always get the following error:
com.github.dockerjava.api.exception.InternalServerErrorException: {"message":"OCI runtime create failed: container_linux.go:345: starting container process caused \"exec: \\\"sh -c wget \\\\\\\"http://HIDDEN:8080/jnlpJars/slave.jar && java -jar slave.jar -jnlpUrl http://HIDDEN:8080/computer/docker-test-direct-005eaqzw6pw6b/slave-agent.jnlp -secret HIDDEN\\\\\\\"\\\": stat sh -c wget \\\"http://HIDDEN:8080/jnlpJars/slave.jar && java -jar slave.jar -jnlpUrl http://HIDDEN:8080/computer/docker-test-direct-005eaqzw6pw6b/slave-agent.jnlp -secret HIDDEN\\\": no such file or directory\": unknown"} at com.github.dockerjava.netty.handler.HttpResponseHandler.channelRead0(HttpResponseHandler.java:109) at com.github.dockerjava.netty.handler.HttpResponseHandler.channelRead0(HttpResponseHandler.java:33) at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:241) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284) at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138) at java.lang.Thread.run(Thread.java:748)
I can run the above manually just fine via docker run:
docker run -it --rm openjdk:8-jdk sh -c "...."
Of course manually the secrets are wrong, but I can create a slave entry manually via the UI and then my docker container started this way actually connects to jenkins.
Summary
From what I can tell, only images that have the ENTRYPOINT set up exactly like jenkins/jnlp-slave can be used with JNLP this way. My conclusion is that the inline help is wrong:
- Either the ENTRYPOINT cannot be overridden here
- Or there is a bug
- Also, Quoting is missing on the example sh -c command (should be sh -c "xxxx")
It's quite possible that the online help needs correcting; feel free to suggest (specific) changes to make it better (or, ideally, submit a PR that makes such changes).
The official jnlp-slave image has a peculiar API in that it runs a script which expects specific arguments ... the JNLP connector code can (or at least, should, as of https://github.com/jenkinsci/docker-plugin/pull/654 ) be able to override the defaults and specify anything you like ... as long as you don't mess up the whitespace (each line turns into one argument; it's easy to mess it up if you don't expand the multi-line string every time).
You may also need to take care with the advanced docker container settings in the template too.
I'd suggest that you try putting the agent jar into your custom image so that you can omit the wget command; that'll simplify things a bit and make it easier to get things working.