代码之家  ›  专栏  ›  技术社区  ›  Chris F

groovy.lang.missingMethodException:在groovy中测试aws cli命令时,方法sh()的签名不适用于参数类型

  •  4
  • Chris F  · 技术社区  · 8 年前
    $ 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)
    

    有人能解释一下这个神秘的错误信息吗?谢谢!

    注意,代码在jenkinsfile中执行时有效,因此我特别询问了cli groovy。

    2 回复  |  直到 8 年前
        1
  •  7
  •   Szymon Stepniak    8 年前

    您将无法仅使用groovy在本地运行此脚本,因为它由于缺少 sh 方法。这个 嘘 方法是Jenkins Pipeline DSL库提供的步骤- https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#code-sh-code-shell-script

    我建议你运行你的本地詹金斯-最简单的方法是使用现有的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
    

    我可以通过哪个靴子进入詹金斯 http://localhost:8080 在这个本地实例中,我可以在groovy沙箱中测试管道脚本,也可以设置脚本管道。

    备选方案:jenkinspipelineunit测试库

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

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

    这意味着每次与 嘘 步骤被计数,但它不会触发用 script: '' 财产。

    我想说,建立自己的本地jenkins沙箱,在那里你可以玩jenkinsfile脚本是最简单的方式开始。

        2
  •  1
  •   storm_m2138    7 年前

    再加上@szymon stepniak的答案——一旦运行了一个jenkins实例

    • 新项目
    • 类型:pipeline(可能依赖于pipeline:job/pipeline:groovy插件)
    • 配置管道脚本