【问题标题】:Running ssh command on server from Jenkins从 Jenkins 在服务器上运行 ssh 命令
【发布时间】:2020-12-29 20:49:24
【问题描述】:

我有一个 Jenkins 阶段:

stage("Deploy on Server") {
   steps {
      script {
          sh 'sshpass -p "password" ssh -o "StrictHostKeyChecking=no" username@server "cd ../../to/app/path; sh redeploy.sh && exit;"'
      }
   }
}

以及我的服务器(centos)上的一些脚本:

重新部署.sh:

declare -i result=0
...
sh restart.sh
result+=$?
echo "Step 6: result = " $result

# 7. if restart fail, restart /versions/*.jar "sh restart-previous.sh"
if [ $result != "0" ]
  then
    sh restart-previous.sh
    result+=$?
fi

echo "Deploy done. Final result: " $result

restart.sh

nohup java -Xms8g -Xmx8g -jar app-name-1.0-allinone.jar &

因为我从 Jenkins 执行 redeploy.sh 脚本,所以问题是它会紧贴 Jenkins 控制台并在那里记录所有应用程序事件,而不是在部署我的应用程序的补丁中创建一个 nohup 文件。

在一些例子中我发现推荐在ssh命令中直接使用nohup,但是我不能这样做,因为我需要执行一个脚本(有所有的步骤,nohup不能这样做)而不是直接一个命令。

exit cmd 将被忽略,因为之前的命令永远不会关闭。

谢谢

【问题讨论】:

  • 您使用的是声明式管道吗? restart.sh 在詹金斯控制台输出中打印数据有什么问题?我建议您让它在Console Output 中打印,但找到一种方法来屏蔽包含敏感数据的参数,以便在詹金斯控制台输出中显示为******。我还建议您使用像 sh ''' echo "This is my shell script" ''' 这样的 shell 语法,如下所述:参考:jenkins.io/doc/pipeline/tour/running-multiple-steps
  • 我找到了一种方法......需要从 cmd 强制登录到日志文件,如“nohup java -Xms8g name.jar /null>> logfile.log 2>&1 &”。这是在centos服务器中。但是,问题是当我尝试终止现有进程时,因为在 jenkins 中返回错误 255,即使命令执行成功:def statusCode = sh returnStatus: true, script 'sshpass -p password username@server sh redeploy.嘘'

标签: jenkins ssh server centos


【解决方案1】:

最后,我找到了解决方案。一个问题出现在restart.sh,因为需要从 cmd 强制指定日志文件。因此,nohup 被忽略/未使用,命令变为:

java -Xms8g -Xmx8g -jar app-name-1.0-allinone.jar </dev/null>> logfile.log 2>&1 &

另一个问题是杀死之前的 jar 进程。非常家乐福,因为在 jenkins 脚本中使用项目名称作为路径,这将为您的用户创建一个新进程,并且在您想要停止应用程序时会被意外杀死:

def statusCode = sh returnStatus: true, script: 'sshpass -p "password" ssh -o "StrictHostKeyChecking=no" username@server "cd ../../to/app/path/app-folder; sh redeploy.sh;"'

if (statusCode != 0) {
   currentBuild.result = 'FAILURE'
   echo "FAILURE"
}

stop.sh

if pgrep -u username -f app-name
  then 
    pkill -u username -f app-name
fi
# (app-name is a string, some words from the running cmd to open tha application)

因为来自 Jenkins 脚本的 app-folder 和来自 stop.shapp-name 是相等的(甚至 app-folder 包含 app-name 值),当你试图杀死 app-name process 时,你会不小心杀死ssh 连接,Jenkins 会得到255 status code,但是来自服务器的redeploy.sh 脚本会成功完成,因为它将独立执行。

解决方案很简单,但很难被发现。您应该确保为您的搜索命令提供一个明确的名称,该名称将且仅找到您的应用程序的进程 ID。

最后,stop.sh 必须为:

if pgrep -u username -f my-app-v1.0.jar
  then 
    pkill -u username -f my-app-v1.0.jar
fi

【讨论】:

    猜你喜欢
    • 2014-05-04
    • 2014-08-17
    • 2021-11-27
    • 2023-03-16
    • 2019-05-20
    • 1970-01-01
    • 2020-11-22
    • 2020-10-30
    相关资源
    最近更新 更多