我正在尝试创建用于创建Docker映像的TeamCity构建配置。
为了实现冗余,我希望第一个构建步骤检查Docker是否正在TeamCity服务器上运行,并在必要时启动它。
我已经创建了以下执行此操作的PowerShell脚本。该脚本甚至要等到Docker完全运行后才能完成。
# This File checks if docker is running, and starts it if necessary, waiting until it has finished starting up before exiting
# ---------
# VARIABLES
# ---------
$TimeoutInterval = 10 #Timeout interval for checking whether docker has finished starting, in seconds
$DockerPath = "C:\Program Files\Docker\Docker\Docker for Windows.exe"
# ---------
# FUNCTIONS
# ---------
Function ProcessRunning([string] $ProcessName) {
[bool] $Return = $False
if ( Get-Process | Where-Object {$_.Name -like $ProcessName} ) {
$Return = $True
}
Return $Return
}
# -------
# PROGRAM
# -------
# Enables Error Action Preference to stop to enable try-catches
$ErrorActionPreference = 'Stop'
if(ProcessRunning("Docker for Windows")){
echo "Docker is running"
echo ""
docker version
}else{
echo "Docker is not running"
echo ""
echo "Starting Docker"
echo ""
Start-Process $DockerPath
#Waits while Docker has not finished starting up
$dockerStarting = $true
while($dockerStarting){
try{
docker version
$dockerStarting = $false
}catch{
echo ""
echo "Docker is still starting up..."
echo ""
$dockerStarting = $true
Wait-Event -Timeout $TimeoutInterval
}
}
echo ""
echo "Docker has finished starting up!"
echo ""
}
在TeamCity服务器上本地执行时,此脚本可以正常工作。但是,当我尝试将其作为BuildStep运行时,在设置$ErrorActionPreference = 'Stop'
具体来说,docker version
命令失败,因为我希望它表明Docker尚未完全运行。但是,try-catch块无法像在服务器上本地运行时那样捕获它。
我已经尝试了Format stderr output as:
和Script execution mode:
的两个值,但是结果仍然相同:脚本抛出错误,并且在TeamCity Server上未启动Docker。
现在,我的基本问题是:从技术上讲我正在尝试吗?因为我可以想象TeamCity采用某种保护机制来防止对其运行的服务器进行某些更改。再说一次,我过去曾经成功地使用PowerShell脚本来复制和删除服务器上的文件,所以说实话,在这一点上,我比为什么看起来不起作用更加困惑。
对此表示感谢。
答案 0 :(得分:0)
好的,所以我尝试了很多,最终找到了一个解决方案,该解决方案使我可以通过TeamCity构建步骤检查Docker是否正在运行,如果没有,请成功启动它。
实际上这是一个两层的问题,必须做两个单独的事情才能使其起作用:
1。)作为提升的本地帐户运行TeamCity Build Agent Service
就我而言,我在SYSTEM
帐户下运行了TeamCity Build Agent Service。我使用以下命令将其切换为管理员帐户:
Services
↳TeamCity Build Agent
↳Log On>Log on as
↳◉This account: .\Administrator
2。)使用不依赖try-catch的“干净” skript来查看Docker是否正在运行
我现在正在使用且运行良好的最终PowerShell Skript看起来像这样:
# This File checks if docker is running, and starts it if necessary, waiting until it has finished starting up before exiting
# ---------
# VARIABLES
# ---------
$TimeoutInterval = 10 #Timeout interval for checking whether docker has finished starting, in seconds
$DockerPath = "C:\Program Files\Docker\Docker\Docker for Windows.exe"
# ---------
# FUNCTIONS
# ---------
Function ProcessRunning([string] $ProcessName) {
[bool] $Return = $False
if ( Get-Process | Where-Object {$_.Name -like $ProcessName} ) {
$Return = $True
}
Return $Return
}
# Determines if a Service exists with a name as defined in $ServiceName.
Function ServiceExists([string] $ServiceName) {
[bool] $Return = $False
if ( Get-Service "$ServiceName*" -Include $ServiceName ) {
$Return = $True
}
Return $Return
}
# Determines if a Service with a name as defined in $ServiceName exists and is running
Function ServiceRunning([string] $ServiceName) {
[bool] $Return = $False
Write-Host "Checking if Service "$ServiceName" exists and is running"
Write-Host ""
if ( Get-Service "$ServiceName*" -Include $ServiceName ) {
$arrService = Get-Service -Include $ServiceName
if ( $arrService.Status -eq "Running" ) {
Write-Host "Service "$ServiceName" exists, and is running!"
Write-Host ""
$Return = $True
}else{
Write-Host "Service "$ServiceName" exists, but is not running!"
Write-Host ""
}
}else{
Write-Host "Service "$ServiceName" does not exist!"
Write-Host ""
}
Return $Return
}
# -------
# PROGRAM
# -------
if(ProcessRunning("Docker for Windows")){
Write-Host "Docker is running"
Write-Host ""
docker version
}else{
Write-Host "Docker is not running"
Write-Host ""
Write-Host "Starting Docker"
Write-Host ""
Start-Process $DockerPath
#Waits while Docker has not finished starting up
$dockerStarting = $true
while($dockerStarting){
if((ServiceRunning("com.docker.service")) -and (ServiceRunning("docker"))){
Write-Host ""
Write-Host "Docker has finished starting up!"
Write-Host ""
docker version
$dockerStarting = $false
}else{
Write-Host ""
Write-Host "Docker is still starting up..."
Write-Host ""
#Attempts to start the relevant services
if(!(ServiceRunning("com.docker.service"))){
if(ServiceExists("com.docker.service")){
Start-Service "com.docker.service"
}
}
if(!(ServiceRunning("docker"))){
if(ServiceExists("docker")){
Start-Service "docker"
}
}
$dockerStarting = $true
Wait-Event -Timeout $TimeoutInterval
}
}
}
我仍然不知道为什么TeamCity中的try-catch无法正常工作,因此,如果有人知道答案,请发表评论。
无论如何,我希望该解决方案对某人有所帮助。