-
Bug
-
Resolution: Unresolved
-
Minor
-
None
I am using the EC2 API to add/update SlaveTemplates.
It seems the cloud.addTemplate() function forgets to set the "parent" field in the new template.
In turn an exception is thrown when trying to provision a new node based on that template.
13:19:12 Also: org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: a700b4b5-d1e3-413c-9d91-7aa07891c7aa*13:19:12* Also: Also: org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: 6ac176d9-ade3-41eb-9f8a-148a0e749a92*13:19:12* java.lang.NullPointerException: Cannot invoke "hudson.plugins.ec2.EC2Cloud.connect()" because the return value of "hudson.plugins.ec2.SlaveTemplate.getParent()" is null*13:19:12* java.lang.NullPointerException: Cannot invoke "hudson.plugins.ec2.EC2Cloud.connect()" because the return value of "hudson.plugins.ec2.SlaveTemplate.getParent()" is null*13:19:12* at hudson.plugins.ec2.SlaveTemplate.getImage(SlaveTemplate.java:1380)13:19:12 at hudson.plugins.ec2.SlaveTemplate.provision(SlaveTemplate.java:932)13:19:12 at hudson.plugins.ec2.EC2Cloud.getNewOrExistingAvailableSlave(EC2Cloud.java:728)13:19:12 at hudson.plugins.ec2.EC2Cloud.provision(EC2Cloud.java:817)13:19:12 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)13:19:12 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)13:19:12 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)13:19:12 at java.base/java.lang.reflect.Method.invoke(Method.java:569)13:19:12 at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:98)13:19:12 at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)13:19:12 at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1225)13:19:12 at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)13:19:12 at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)13:19:12 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)13:19:12 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)13:19:12 at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:180)13:19:12 at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)13:19:12 at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:163)13:19:12 at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:178)13:19:12 at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:182)13:19:12 at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)13:19:12 at org.jenkinsci.plugins.workflow.cps.LoggingInvoker.methodCall(LoggingInvoker.java:105)13:19:12 at WorkflowScript.run(WorkflowScript:162)
Please see below code for reference:
def test_tmpl_name = "${target_ami_base_name}-test-worker";
def test_tmpl = findWorkerTemplate(test_tmpl_name);
if(test_tmpl == null)
{{{}}
println("creating new ${test_tmpl_name} with ${new_ami}");
test_tmpl = new hudson.plugins.ec2.SlaveTemplate(
(String)new_ami, // String ami,
reference_tmpl.zone, // String zone,
(SpotConfiguration)reference_tmpl.spotConfig, // SpotConfiguration spotConfig,
reference_tmpl.securityGroups, // String securityGroups,
reference_tmpl.remoteFS, // String remoteFS,
reference_tmpl.type, // com.amazonaws.services.ec2.model.InstanceType type,
reference_tmpl.ebsOptimized, // boolean ebsOptimized,
(String)test_tmpl_name, // String labelString,
reference_tmpl.mode, // Node.Mode mode,
(String)test_tmpl_name, // String description,
reference_tmpl.initScript, // String initScript,
reference_tmpl.tmpDir, // String tmpDir,
reference_tmpl.userData, // String userData,
"1", // String numExecutors,
reference_tmpl.remoteAdmin, // String remoteAdmin,
(AMITypeData)reference_tmpl.amiType,// AMITypeData amiType,
reference_tmpl.javaPath, // String javaPath,
reference_tmpl.jvmopts, // String jvmopts,
reference_tmpl.stopOnTerminate, // boolean stopOnTerminate,
reference_tmpl.subnetId, // String subnetId,
(List<EC2Tag>)reference_tmpl.tags, // List<EC2Tag> tags,
"5", // String idleTerminationMinutes,
0, // int minimumNumberOfInstances,
0, // int minimumNumberOfSpareInstances,
"1", // String instanceCapStr,
reference_tmpl.iamInstanceProfile, // String iamInstanceProfile,
true, // boolean deleteRootOnTermination,
reference_tmpl.useEphemeralDevices, // boolean useEphemeralDevices,
reference_tmpl.launchTimeoutStr, // String launchTimeoutStr,
reference_tmpl.associatePublicIp, // boolean associatePublicIp,
reference_tmpl.customDeviceMapping, // String customDeviceMapping,
reference_tmpl.connectBySSHProcess, // boolean connectBySSHProcess,
reference_tmpl.monitoring, // boolean monitoring,
reference_tmpl.t2Unlimited, // boolean t2Unlimited,
reference_tmpl.connectionStrategy, // ConnectionStrategy connectionStrategy,
1, // int maxTotalUses,
(List<? extends NodeProperty<?>>)reference_tmpl.nodeProperties, // List<? extends NodeProperty<?>> nodeProperties
reference_tmpl.hostKeyVerificationStrategy, // HostKeyVerificationStrategyEnum hostKeyVerificationStrategy,
reference_tmpl.tenancy, // Tenancy tenancy,
reference_tmpl.ebsEncryptRootVolume, // EbsEncryptRootVolume ebsEncryptRootVolume,
reference_tmpl.metadataEndpointEnabled, // Boolean ebsEncryptRootVolume,
reference_tmpl.metadataTokensRequired, // Boolean metadataTokensRequired,
reference_tmpl.metadataHopsLimit, // Integer metadataHopsLimit,
true // Boolean metdataSupported
);
cloud.addTemplate(test_tmpl);
}
else
{{{}}
println("updating existing ${test_tmpl_name} from ${test_tmpl.ami} to ${new_ami}");
test_tmpl.ami = new_ami;
}
println("using template ${test_tmpl.description}");
cloud.provision(test_tmpl, 1);