Jenkins 在配置 Amazon EC2 云时出错

Jenkins gives error on configuring Amazon EC2 cloud

我正在尝试使用 EC2 插件设置 Jenkins 服务器,以便所有构建都由充当主服务器代理的 EC2 实例执行。

尝试在 Jenkins 主服务器中保存 'Amazon EC2' 云的云配置时,失败并出现异常。检查 Jenkins 日志,我看到这个异常:

Caught unhandled exception with ID f6d45d51-fb00-4d1c-a474-0a55dd5ee710
org.kohsuke.stapler.WrongTypeException: Got type array but no lister class found for type class java.lang.String
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:724)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:478)
        at org.kohsuke.stapler.RequestImpl.instantiate(RequestImpl.java:787)
    Caused: java.lang.IllegalArgumentException: Failed to convert the instanceCapStr parameter of 
the constructor public hudson.plugins.ec2.AmazonEC2Cloud
(java.lang.String,boolean,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.util.List,java.lang.String,java.lang.String)
        at org.kohsuke.stapler.RequestImpl.instantiate(RequestImpl.java:789)
        at org.kohsuke.stapler.RequestImpl.access0(RequestImpl.java:83)
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:678)
    Caused: java.lang.IllegalArgumentException: Failed to instantiate class hudson.plugins.ec2.AmazonEC2Cloud from 
{
    "cloudName":"ec2-cloud",
    "includeUser":["false","false"],
    "credentialsId":"",
    "useInstanceProfileForCredentials":true,
    "altEC2Endpoint":"",
    "region":"eu-west-1",
    "sshKeysCredentialsId":"jenkins-slave-ssh-key",
    "instanceCapStr":["",""],
    "noDelayProvisioning":false,
    "roleArn":"",
    "roleSessionName":"",
    "templates":{
        "description":"Amazon Linux 2 AMI",
        "ami":"ami-0bb3fad3c0286ebd5",
        "type":"T2Micro",
        "ebsOptimized":true,
        "monitoring":true,
        "t2Unlimited":false,
        "zone":"",
        "securityGroups":"",
        "remoteFS":"/var/lib/jenkins",
        "remoteAdmin":"ec2-user",
        "":"0",
        "amiType":{
            "rootCommandPrefix":"",
            "slaveCommandPrefix":"",
            "slaveCommandSuffix":"",
            "sshPort":"22",
            "stapler-class":"hudson.plugins.ec2.UnixData",
            "$class":"hudson.plugins.ec2.UnixData"
        },
        "labelString":"ec2",
        "mode":"EXCLUSIVE",
        "idleTerminationMinutes":"30",
        "initScript":"",
        "tmpDir":"",
        "userData":"",
        "numExecutors":"",
        "jvmopts":"",
        "stopOnTerminate":false,
        "subnetId":"",
        "useDedicatedTenancy":false,
        "name":"","value":""
        },
    "minimumNumberOfInstances":"0",
    "minimumNumberOfSpareInstances":"0",
    "iamInstanceProfile":"arn:aws:iam::xxxxxxxxxxxx:instance-profile/jenkins_server_role",
    "deleteRootOnTermination":true,
    "useEphemeralDevices":true,
    "customDeviceMapping":"",
    "launchTimeoutStr":"",
    "associatePublicIp":false,
    "connectionStrategy":"PRIVATE_IP",
    "connectBySSHProcess":false,
    "hostKeyVerificationStrategy":"CHECK_NEW_HARD",
    "maxTotalUses":"-1",
    "nodeProperties":{"stapler-class-bag":"true"}
},"stapler-class":"hudson.plugins.ec2.AmazonEC2Cloud","$class":"hudson.plugins.ec2.AmazonEC2Cloud"}
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:681)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:478)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:474)
        at hudson.model.Descriptor.newInstance(Descriptor.java:598)

我确实在 Jenkins UI 的两个不同位置看到 属性 'Instance cap'。我的理解是,一个是配置最大限制整个云中允许的实例总数, 另一个 属性 描述了特定 AMI. 实例数量的最大限制

这是 Jenkins 的问题吗?还是我提供的配置有问题?

注意:我同意以代码形式提供配置而不是通过 Jenkins UI。如果有人能够通过代码提供相同的配置,那也很好。

我最终使用 Jenkins UI 的 脚本控制台 中的 groovy 脚本 运行 配置了它。我使用的 groovy 脚本是:

import hudson.model.*
import jenkins.model.*
import hudson.plugins.ec2.*
import com.amazonaws.services.ec2.model.InstanceType
  
def instance = Jenkins.getInstance()

def ec2_cloud_name = 'ec2-cloud'
def ec2_instance_cap = 5

def worker_description = 'jenkins-slave running in ec2 instance'
def worker_label_string = 'ec2-slave'

def ami_id = 'ami-xxxxxxxxxxxxxxxxx'
def security_groups = 'sg-xxxxxxxxxxxxxxxxxx'
def subnet_id = 'subnet-xxxxxxxx'
def instance_type = 't2.micro'
def instance_profile_arn = 'arn:aws:iam::xxxxxxxxxxxx:instance-profile/jenkins_server_role'

def number_of_executors = 2

def ec2_tags = [
  new EC2Tag('Name', 'jenkins-slave-instance')
]

def priv_key_txt = '''
-----BEGIN RSA PRIVATE KEY-----
<My Private key>
-----END RSA PRIVATE KEY-----
'''

def worker_ami = new SlaveTemplate(
   // String ami
  ami_id,
  // String zone
  '',
  // SpotConfiguration spotConfig
  null,
  // String securityGroups
  security_groups,
  // String remoteFS
  '',
  // InstanceType type
  InstanceType.fromValue(instance_type),
  // boolean ebsOptimized
  false,
  // String labelString
  worker_label_string,
  // Node.Mode mode
  Node.Mode.NORMAL,
  // String description
  worker_description,
  // String initScript
  '',
  // String tmpDir
  '',
  // String userData
  '',
  // String numExecutors
  "${number_of_executors}",
  // String remoteAdmin
  '',
  // AMITypeData amiType
  new UnixData(null, null, null, null),
  // String jvmopts
  '',
  // boolean stopOnTerminate
  false,
  // String subnetId
  subnet_id,
  // List<EC2Tag> tags
  ec2_tags,
  // String idleTerminationMinutes
  '30',
  // int minimumNumberOfInstances
  0,
  // int minimumNumberOfSpareInstances
  0,
  // string instanceCapStr
  '3',
  // string iamInstanceProfile
  'arn:aws:iam::xxxxxxxxxxxx:instance-profile/jenkins_server_role',
  // boolean deleteRootOnTermination
  true,
  // boolean useEphemeralDevices
  true,
  // boolean useDedicatedTenancy
  false,
  // String launchTimeoutStr
  '1800',
  // boolean associatePublicIp
  false,
  // String customDeviceMapping
  '',
  // boolean connectBySSHProcess
  false,
  // boolean monitoring
  false,
  // boolean t2Unlimited
  false,
  // Enum connectionStrategy
  ConnectionStrategy.PRIVATE_IP,
  // int maxTotalUses
  3,
  // List<? extends NodeProperty<?>> nodeProperties
  [],
  // HostKeyVerificationStrategyEnum 
  HostKeyVerificationStrategyEnum.CHECK_NEW_HARD
)

def new_cloud = new AmazonEC2Cloud(
   // String cloudName
  ec2_cloud_name,
  // boolean useInstanceProfileForCredentials
  true,
  // String credentialsId
  '',
  // String region
  'eu-west-1',
  // String privateKey
  priv_key_txt,
  // String sshKeysCredentialsId
  'jenkins-slave-ssh-key',
  // String instanceCapStr
  "3",
  // List<? extends SlaveTemplate> templates
  [worker_ami],
  // String roleArn
  null,
  // String roleSessionName
  null
)

instance.clouds.add(new_cloud)

奇怪的是,通过 运行ning 这个脚本创建配置后,现在 我可以通过 Jenkins [=21] 编辑和保存创建的配置=].