-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Minor
-
Component/s: ec2-plugin
-
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);