我们有一个类似的需求,需要定期重置MacOS上的USB堆栈,因为Mac的USB堆栈不可靠(在Linux或Windows上完美运行的Android设备)。
我们有一个先决任务,有以下选项:
- 在同一代理上运行构建
- 在依赖失败时:使构建失败无法启动
- 在启动失败/取消依赖时:使构建失败无法启动
该任务运行了 'shutdown -r now' 命令,并立即使用 'echo #teamcity...' 系统向服务器报告成功,试图捕捉重启实际开始和发送到服务器的回显之间的小时间差。
不幸的是,在脚本完成和代理实际重新启动之间有一个短暂的时间,当TeamCity尝试在代理上启动新作业时,我们会有大量的中止构建 - 它们会重新启动,所以它们并不会真正破坏任何东西,但会混乱日志。
我们尝试用以下方法替换它,将代理标记为正在重新启动,然后将关机命令委托给一个后台任务,在TeamCity任务完成之前等待再发出关机命令:
echo "Running: '/sbin/shutdown -r shortly'"
echo rebooting=yes >> $HOME/buildAgent/conf/buildAgent.properties
CONFIG_PROPERTIES=$(grep teamcity.configuration.properties.file $TEAMCITY_BUILD_PROPERTIES_FILE | cut -d= -f2)
TC_SERVER=$(grep teamcity.serverUrl $CONFIG_PROPERTIES | cut -d= -f2)
BUILD_ID=$(grep teamcity.build.id $CONFIG_PROPERTIES | cut -d= -f2)
STATUS=$( echo "${TC_SERVER}/guestAuth/app/rest/builds/id:${BUILD_ID}"|tr -d \\ )
echo Polling $STATUS in background until parent task cannot be confirmed still running.
((
while true; do
sleep 5
if curl -s $STATUS | xmllint --xpath "//build/@running" - | grep true ; then
:
else
echo "passw0rd" | /usr/bin/sudo -p "" -S /sbin/shutdown -r now
fi
done
) 2>/dev/null >/dev/null &)&
我在机器的重新启动过程中添加了一步,以便在代理重新启动之前的某个时刻删除“重新启动”参数。 (这是一台Mac电脑,所以我在/Library/LaunchDemon中添加了一个plist文件运行)
/usr/bin/sed -i~ -e /rebooting=yes/d /Users/qa/buildAgent/conf/buildAgent.properties
已经将日志文件目录费尽心思地设置为适当用户可写 - 否则 plist 将默默失败...)
不幸的是,TeamCity 在新的 9.1 版本中似乎没有注意到 'rebooting' 参数,因此我们不得不在此重新启动步骤和实际任务之间添加额外的依赖关系:这个新任务简单地等待,直到在配置文件中无法看到 'rebooting' 参数,而其中一半的时间它会被取消并重新安排 - 这没关系,因为它可以使 'cancelled' 消息不出现在主构建日志中,这正是我们想要的:
echo This task runs after the reboot script, as a buffer between the reboot script and the real reboot.
echo That is, THIS task will get all the INTERRUPTED errors, not the real scripts.
echo Uptime:
uptime
echo Infinite loop until machine reboot, unless reboot is already complete:
while grep rebooting=yes $HOME/buildAgent/conf/buildAgent.properties; do
echo $(date) Awaiting reboot to interrupt task and clear rebooting=yes from buildAgent.properties file.
sleep 15
done
显然,复制buildAgent.properties文件,然后将副本移动到原始文件上方,使9.x代理程序注意到更改,从而避免了这个中间步骤的需要,只要您的后续构建任务知道等待引导过程删除'rebooting=yes'参数。我没有尝试过,但那肯定是更可取的。