【问题标题】:jenkins pipeline execute ssh command in loop詹金斯管道循环执行ssh命令
【发布时间】:2018-09-01 20:15:04
【问题描述】:

我创建了一个管道并希望在多个服务器上运行一个 shell 脚本,我正在从一个 txt 文件中读取服务器列表,我编写了代码来迭代该列表并为该列表中的每个服务器运行 shell 脚本。

问题是循环没有超过第一次执行。如果我只打印服务器名称而不执行 ssh 命令,它会打印所有服务器名称,这意味着循环工作正常,但不能按预期使用 ssh 命令工作。我也试过 for 循环,但同样的问题。

stage('execute script') {
   steps {
        script {

           ....some code here

           def absoluteFilePath = "${WORKSPACE}/serversList.txt"
           def fileContent = readFile(absoluteFilePath)
           listOfServers = fileContent.split('\n')
        }
        iterateOverList(listOfServers, "${WORKSPACE}/")
   }
}

@NonCPS 
def iterateOverList(list, workSpacePath) {
    //iterate over servers list and execute shell script on it.
    list.each { hostServer ->
        sh "ssh -t -o StrictHostKeyChecking=no -o 'UserKnownHostsFile /dev/null' -i /var/lib/user/.ssh/id_rsa user@${hostServer} 'sudo bash -s' <  ${workSpacePath}myShellScript.sh"
    }
}

【问题讨论】:

    标签: bash jenkins ssh jenkins-pipeline


    【解决方案1】:

    实际上,在 Jenkins 流水线中存在一些带有 groovy 闭包的未解决错误,例如 JENKINS-46749JENKINS-46747

    所以使用简单的 Java 循环来遍历您的列表:

    for (int i = 0; i < list.size(); i++) {
        sh "ssh -t -o StrictHostKeyChecking=no -o 'UserKnownHostsFile /dev/null' -i /var/lib/user/.ssh/id_rsa user@${list[i]} 'sudo bash -s' <  ${workSpacePath}myShellScript.sh"
    }
    

    【讨论】:

    • 得到错误:org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:脚本不允许使用 staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods 执行 java.lang.String
    • 对不起,我关于 Pipeline DSL 的错误上下文的建议是完全错误的。实际上,Jenkins 管道中存在 groovy 闭包的错误,所以我更新了我的答案。
    • 谢谢! @Alexey Prudnikov,但我在问题中提到我已经尝试过 For 循环,但结果相同,循环不会超过第一次迭代。不确定,但可能是 ssh 命令的第一次迭代必须返回一些代码来通知第一个 ssh 命令执行时没有错误(只是猜测)。