运行 来自 Jenkins 的服务器上的 ssh 命令

Running ssh command on server from Jenkins

我有一个 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) 上的一些脚本:

redeploy.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,因为需要从 cmd 强制指定日志文件。所以,nohup是ignored/unused,命令变成:

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

另一个问题是终止之前的 jar 进程。非常 carrefour,因为在 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-folderstop.sh 中的 app-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