I feel like this should be in a Jenkins Pipeline w/ Containers 101 somewhere, but sadly I can't find it. I'm trying to convert Jenkins Multi-configuration projects that would build on virtual machine based agents to Pipeline script from SCM by using a parameter 'IMAGE_NAME' and launch a given container image. Maybe there is a better approach, happy to hear it. I honestly don't want this to be a parameter, as it requires user interaction, but this is the best solution of which I'm aware. I know that I could switch to "Pipeline script" vs "from SCM", but adding SCM calls into the Pipeline code gets messy with authorization.
Below is what I've tried. Note: If I don't use parameter(s) and replace '${params.IMAGE_NAME}' with 'registry.internal.mycompany.com/myplatform:myversion', it works perfectly.
Pipeline Syntax:
pipeline {
agent none
parameters {
string(name: 'IMAGE_NAME', defaultValue: 'registry.internal.mycompany.com/myplatform:myversion', description: 'Define the [host/]image[:version] for the container image of which to run the build.')
}
stages {
stage('Compile') {
agent {
docker {
image '${params.IMAGE_NAME}'
}
}
steps {
sh 'ls -l'
sh './compile.sh'
}
post {
always {
cleanWs()
}
}
}
}
}
The result:
11:01:58 [Pipeline] withEnv
11:01:58 [Pipeline] {
11:01:59 [Pipeline] }
11:01:59 [Pipeline] // withEnv
11:01:59 [Pipeline] }
11:01:59 [Pipeline] // node
11:01:59 [Pipeline] }
11:01:59 [Pipeline] // stage
11:01:59 [Pipeline] End of Pipeline
11:01:59 ERROR: Name must follow the pattern '^[a-zA-Z0-9] ((\.|_|__|- )[a-zA-Z0-9] )*$'
11:01:59 at hudson.util.FormValidation._errorWithMarkup(FormValidation.java:268)
11:01:59 at hudson.util.FormValidation.errorWithMarkup(FormValidation.java:254)
11:01:59 at hudson.util.FormValidation.error(FormValidation.java:145)
11:01:59 at hudson.util.FormValidation.error(FormValidation.java:170)
11:01:59 at org.jenkinsci.plugins.docker.commons.credentials.ImageNameValidator.validateName(ImageNameValidator.java:289)
11:01:59 at org.jenkinsci.plugins.docker.commons.credentials.ImageNameValidator.validateUserAndRepo(ImageNameValidator.java:115)
11:01:59 at org.jenkinsci.plugins.docker.commons.credentials.ImageNameValidator.checkUserAndRepo(ImageNameValidator.java:141)
11:01:59 at org.jenkinsci.plugins.docker.commons.credentials.ImageNameValidator$checkUserAndRepo.call(Unknown Source)
11:01:59 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
11:01:59 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
11:01:59 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
11:01:59 at org.jenkinsci.plugins.docker.workflow.Docker.check(Docker.groovy:100)
11:01:59 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
11:01:59 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
11:01:59 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11:01:59 at java.base/java.lang.reflect.Method.invoke(Method.java:566)
11:01:59 at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
11:01:59 at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
11:01:59 at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1463)
11:01:59 at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:921)
11:01:59 at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:181)
11:01:59 at org.jenkinsci.plugins.docker.workflow.Docker$Image.methodMissing(Docker.groovy)
11:01:59 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
11:01:59 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
11:01:59 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11:01:59 at java.base/java.lang.reflect.Method.invoke(Method.java:566)
11:01:59 at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)
11:01:59 at groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:951)
11:01:59 at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1279)
11:01:59 at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1227)
11:01:59 at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
11:01:59 at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:68)
11:01:59 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
11:01:59 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
11:01:59 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:169)
11:01:59 at org.jenkinsci.plugins.docker.workflow.Docker$Image.<init>(Docker.groovy:110)
11:01:59 at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
11:01:59 at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
11:01:59 at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
11:01:59 at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
11:01:59 at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
11:01:59 at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
11:01:59 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
11:01:59 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:238)
11:01:59 at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.constructorCall(DefaultInvoker.java:25)
11:01:59 at org.jenkinsci.plugins.docker.workflow.Docker.image(Docker.groovy:75)
11:01:59 at org.jenkinsci.plugins.docker.workflow.declarative.DockerPipelineScript.runImage(DockerPipelineScript.groovy:54)
11:01:59 at org.jenkinsci.plugins.docker.workflow.declarative.AbstractDockerPipelineScript.configureRegistry(AbstractDockerPipelineScript.groovy:63)
11:01:59 at org.jenkinsci.plugins.docker.workflow.declarative.AbstractDockerPipelineScript.run(AbstractDockerPipelineScript.groovy:50)
11:01:59 at org.jenkinsci.plugins.pipeline.modeldefinition.agent.CheckoutScript.checkoutAndRun(CheckoutScript.groovy:61)
11:01:59 at ___cps.transform___(Native Method)
11:01:59 at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:97)
11:01:59 at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:83)
11:01:59 at jdk.internal.reflect.GeneratedMethodAccessor188.invoke(Unknown Source)
11:01:59 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11:01:59 at java.base/java.lang.reflect.Method.invoke(Method.java:566)
11:01:59 at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
11:01:59 at com.cloudbees.groovy.cps.impl.LocalVariableBlock$LocalVariable.get(LocalVariableBlock.java:39)
11:01:59 at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
11:01:59 at com.cloudbees.groovy.cps.impl.LocalVariableBlock.evalLValue(LocalVariableBlock.java:28)
11:01:59 at com.cloudbees.groovy.cps.LValueBlock$BlockImpl.eval(LValueBlock.java:55)
11:01:59 at com.cloudbees.groovy.cps.LValueBlock.eval(LValueBlock.java:16)
11:01:59 at com.cloudbees.groovy.cps.Next.step(Next.java:83)
11:01:59 at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
11:01:59 at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
11:01:59 at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:136)
11:01:59 at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:275)
11:01:59 at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
11:01:59 at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
11:01:59 at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:51)
11:01:59 at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:187)
11:01:59 at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:420)
11:01:59 at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:95)
11:01:59 at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:330)
11:01:59 at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:294)
11:01:59 at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
11:01:59 at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
11:01:59 at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
11:01:59 at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
11:01:59 at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
11:01:59 at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
11:01:59 at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
11:01:59 at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
11:01:59 at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
11:01:59 at java.base/java.lang.Thread.run(Thread.java:829)
11:01:59 Finished: FAILURE
Also found the below to be a viable solution, not requiring a parameter:
pipeline {
agent none
stages {
stage('Checkout') {
agent any
steps {
checkout accurev(depot: 'DEPOT', serverName: 'AccuRev', stream: 'MY_PIPELINE_STREAM', wspaceORreftree: 'none')
}
}
stage('Compile') {
agent {
docker {
image 'registry.internal.mycompany.com/myplatform:myversion'
}
}
steps {
sh 'ls -l'
sh './compile.sh'
}
post {
always {
cleanWs()
}
}
}
}
}
CodePudding user response:
params.IMAGE_NAME
is an object type variable with a member. It is not a literal string, and therefore should not be cast with ''
syntax, nor should it attempt to interpolate within a literal string (this is not allowed in any language):
docker { image params.IMAGE_NAME }