代码之家  ›  专栏  ›  技术社区  ›  Kira Resari

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

  •  1
  • Kira Resari  · 技术社区  · 6 年前

    我正在尝试创建TeamCity构建配置,以创建Docker映像。

    我创建了下面的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服务器上本地执行时工作正常。但是,当我尝试将其作为构建步骤运行时,它似乎忽略了try-catch块,就像我在设置 $ErrorActionPreference = 'Stop'

    docker version 命令失败,因为我打算用它来表示Docker尚未完全运行。但是,try-catch块在服务器上本地运行时无法捕获它。

    Format stderr output as: 以及 Script execution mode: ,但结果保持不变:脚本抛出错误,并且TeamCity服务器上没有启动Docker。

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

    如果您对此有任何意见,我们将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Kira Resari    6 年前

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

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

    SYSTEM 账户我使用以下方式将其切换到管理员帐户:

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

    2.)使用不依赖于try catch的“干净”skcript来查看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不起作用,所以如果有人知道答案,请发表评论。

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

    推荐文章