运行 来自 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-folder
和 stop.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
我有一个 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-folder
和 stop.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