【问题标题】:TeamCity ~ Start Docker on Server via Build StepTeamCity ~ 通过构建步骤在服务器上启动 Docker
【发布时间】:2018-11-19 09:38:57
【问题描述】:

我正在尝试创建用于创建 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 运行时,它似乎忽略了 try-catch 块,就像在我设置 $ErrorActionPreference = 'Stop'

之前在我的本地版本中所做的那样

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

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

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

对此的任何意见将不胜感激。

【问题讨论】:

    标签: powershell docker teamcity


    【解决方案1】:

    好的,所以我尝试了很多,最终找到了一个解决方案,让我可以通过 TeamCity 构建步骤检查 Docker 是否正在运行,如果没有,则成功启动它。

    这实际上是一个两层问题,必须完成两件不同的事情才能使其发挥作用:

    1.) 作为提升的本地帐户运行 TeamCity 构建代理服务

    就我而言,我在 SYSTEM 帐户下运行了 TeamCity 构建代理服务。我使用以下方法将其切换为管理员帐户:

    Services
    ↳TeamCity Build Agent
     ↳Log On>Log on as
      ↳◉This account: .\Administrator
    

    2.) 使用不依赖 try-catch 的“干净”脚本来查看 Docker 是否正在运行

    我现在使用的最终的 PowerShell 脚本如下所示:

    # 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
            }
        }
    }
    

    我仍然不知道为什么 try-catch 在 TeamCity 中不起作用,所以如果有人知道答案,请发表评论。

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

    【讨论】:

    • try/catch Powershell 块仅适用于 Powershell cmdlet,不适用于外部应用程序/exe 等。要捕获此类程序的错误,您必须检查 $LASTEXITCODE 并使用 'throw' 关键字,如果 $ LATEXITCODE -ne 0
    猜你喜欢
    • 2013-09-22
    • 2014-09-13
    • 1970-01-01
    • 2014-02-24
    • 2015-04-12
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多