TeamCity〜通过构建步骤在服务器上启动Docker

时间:2018-11-19 09:38:58

标签: powershell docker teamcity

我正在尝试创建用于创建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'

之前,它似乎忽略了try-catch块,就像在本地版本中一样

具体来说,docker version命令失败,因为我希望它表明Docker尚未完全运行。但是,try-catch块无法像在服务器上本地运行时那样捕获它。

我已经尝试了Format stderr output as:Script execution mode:的两个值,但是结果仍然相同:脚本抛出错误,并且在TeamCity Server上未启动Docker。

现在,我的基本问题是:从技术上讲我正在尝试吗?因为我可以想象TeamCity采用某种保护机制来防止对其运行的服务器进行某些更改。再说一次,我过去曾经成功地使用PowerShell脚本来复制和删除服务器上的文件,所以说实话,在这一点上,我比为什么看起来不起作用更加困惑。

对此表示感谢。

1 个答案:

答案 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无法正常工作,因此,如果有人知道答案,请发表评论。

无论如何,我希望该解决方案对某人有所帮助。