groovy.lang.MissingMethodException:没有方法签名:sh()适用于在Groovy中测试AWS CLI命令时的参数类型

时间:2018-06-06 13:40:45

标签: groovy jenkins-pipeline

$ groovy --version
Groovy Version: 2.4.15 JVM: 1.8.0_171 Vendor: Oracle Corporation OS: Mac OS X

我希望在Groovy中执行一些AWS CLI命令,最终在Jenkins文件中运行Jenkins文件当然。

但是对于原型设计,我想在我的Mac上编码并将其作为一个普通的Groovy脚本执行。所以我有这个,例如。

#!/usr/bin/env groovy

def getEBSVolumes(awsRegion) {
  def regions
  if (awsRegion == "all") {
    regions = sh(returnStdout: true, script: """#!/usr/bin/env bash
                   aws ec2 describe-regions --output text|awk '{print \$3}'
                 """
                )
  }
  else {
    regions = awsRegion
  }
  echo "Regions: regions"
}

getEBSVolumes("all")

当我执行它时,我得到了

$ ./x.groovy 
Caught: groovy.lang.MissingMethodException: No signature of method: x.sh() is applicable for argument types: (java.util.LinkedHashMap) values: [[returnStdout:true, script:#!/usr/bin/env bash
                   aws ec2 describe-regions --output text|awk '{print $3}'
                 ]]
Possible solutions: use([Ljava.lang.Object;), is(java.lang.Object), run(), run(), any(), each(groovy.lang.Closure)
groovy.lang.MissingMethodException: No signature of method: x.sh() is applicable for argument types: (java.util.LinkedHashMap) values: [[returnStdout:true, script:#!/usr/bin/env bash
                   aws ec2 describe-regions --output text|awk '{print $3}'
                 ]]
Possible solutions: use([Ljava.lang.Object;), is(java.lang.Object), run(), run(), any(), each(groovy.lang.Closure)
    at x.getEBSVolumes(x.groovy:9)
    at x$getEBSVolumes.callCurrent(Unknown Source)
    at x.run(x.groovy:20)

有人可以解释一下神秘的错误信息吗?谢谢!

注意代码在Jenkins文件中执行时有效,因此我特别询问了CLI Groovy。

2 个答案:

答案 0 :(得分:7)

您无法仅使用Groovy在本地运行此脚本,因为它会因脚本中缺少sh方法而失败。此sh方法是Jenkins Pipeline DSL库提供的步骤 - https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#code-sh-code-shell-script

我建议您运行本地Jenkins - 最简单的方法是使用现有的Docker镜像。我使用例如docker-compose.yml文件:

jenkins:
  image: jenkins:2.60.3-alpine
  container_name: jenkins
  ports:
    - 8080:8080
  volumes:
    - ./home:/var/jenkins_home

每当我想运行我的本地Jenkins时,我就去了我存储此文件的目录,例如。

cd ~/workspace/jenkins

我只是致电

docker-compose up -d

引导Jenkins我可以通过http://localhost:8080访问在这个本地实例中,我能够在Groovy Sandbox中测试管道脚本,或者通过设置脚本管道。

替代方案:JenkinsPipelineUnit测试库

如果要对管道脚本进行单元测试,可以使用JenkinsPipelineUnit库,它允许您对管道流进行单元测试。但是在这种情况下,您必须注册自己的sh方法,因为BasePipelineTest类使用NOOP进行模拟:

helper.registerAllowedMethod("sh", [Map.class], null)

这意味着每个与sh步骤的交互都会被计算,但它不会触发使用script: ''属性定义的脚本。

我想说,设置你自己的本地Jenkins沙箱,你可以在其中使用Jenkinsfile脚本是最简单的开始。

答案 1 :(得分:1)

通过@ Szymon-Stepniak添加答案-一旦运行了jenkins实例

  • 新商品
  • 类型:管道(可能取决于管道:作业/管道:Groovy插件)
  • 配置管道脚本