简体   繁体   English

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

[英]TeamCity ~ Start Docker on Server via Build Step

I am trying to create a TeamCity build configuration for creating a Docker Image. 我正在尝试创建用于创建Docker映像的TeamCity构建配置。

For redundancy, I want the first Build Step to check whether Docker is running on the TeamCity server, and start it if necessary. 为了实现冗余,我希望第一个构建步骤检查TeamCity服务器上是否正在运行Docker,并在必要时启动它。

I have created the following PowerShell script that does exactly that. 我创建了下面的PowerShell脚本来实现这一目的。 The script even waits until Docker is fully functional before finishing. 该脚本甚至会等到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 ""
}

This script works fine when executed locally on the TeamCity server. 在TeamCity服务器上本地执行时,此脚本可以正常工作。 However, when I attempt to run it as a BuildStep, it appears to ignore the try-catch block like it did in my local version before I set the $ErrorActionPreference = 'Stop' 但是,当我尝试将其作为BuildStep运行时,在设置$ErrorActionPreference = 'Stop'之前,它似乎忽略了本地版本中的try-catch块$ErrorActionPreference = 'Stop'

Specifically, the docker version command fails as I intended it to to indicate that Docker is not yet fully running. 具体来说, docker version命令失败,因为我希望它指示Docker尚未完全运行。 However, the try-catch block fails to catch it as it does when run locally on the server. 但是,try-catch块无法像在服务器上本地运行时那样捕获它。

I have already tried both values of Format stderr output as: as well as Script execution mode: , but the result remains the same: The script throws an error, and Docker is not started on the TeamCity Server. 我已经将Format stderr output as:两个值都尝试Format stderr output as:以及Script execution mode: ,但是结果仍然相同:脚本抛出错误,并且在TeamCity Server上未启动Docker。

Now, my basic question is: Is what I'm trying even technically possible? 现在,我的基本问题是:在技术上我还能尝试什么? Because I could imagine that TeamCity employs some sort of safeguard mechanism that prevents certain changes on the Server it's run from. 因为我可以想象TeamCity采用某种保护机制来防止对其运行的服务器进行某些更改。 Then again, I have in the past successfully employed PowerShell scripts to copy and delete files on the Server, so honestly, at this point I'm more confused than anything about why this doesn't seem to work. 再说一次,我过去曾经成功地使用PowerShell脚本来复制和删除服务器上的文件,因此,老实说,在这一点上,我比为什么看起来不起作用更加困惑。

Any input on this would be greatly appreciated. 任何对此的投入将不胜感激。

Okay, so I tried around a lot, and eventually found a solution that allows me to check if Docker is running via a TeamCity build step and successfully start it if not. 好的,我尝试了很多,最终找到了一个解决方案,该解决方案使我可以通过TeamCity构建步骤检查Docker是否正在运行,如果没有,请成功启动。

This actually turned out to be a two-tier problem, with two separate things having to be done in order to make it work: 事实证明,这实际上是一个两层的问题,必须进行两个单独的操作才能使其起作用:

1.) Run the TeamCity Build Agent Service as an elevated local account 1.)以提升的本地帐户身份运行TeamCity Build Agent Service

In my case, I had the TeamCity Build Agent Service running under the SYSTEM account. 就我而言,我的TeamCity Build Agent Service在SYSTEM帐户下运行。 I switched it to an Administrator account using: 我使用以下命令将其切换为管理员帐户:

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

2.) Use a "clean" skript that does not rely on try-catch to see if Docker is running 2.)使用不依赖try-catch的“干净” skript来查看Docker是否正在运行

The final PowerShell Skript that I'm using now and that works nicely looks like this: 我现在正在使用并且可以正常运行的最终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
        }
    }
}

I still have no idea why try-catch isn't working in TeamCity, so if someone knows the answer to that, please comment. 我仍然不知道为什么try-catch在TeamCity中不起作用,因此,如果有人知道答案,请发表评论。

Anyway, I hope this solution is helpful to someone. 无论如何,我希望这种解决方案对某人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用于在TeamCity中禁用构建步骤或在特定步骤中开始运行的脚本 - Script to disable build steps in TeamCity or start run at a specific step TeamCity构建日志用于单个构建步骤 - TeamCity buildlog for a single build step 开始过程:系统找不到在TeamCity Build步骤中指定的文件,但在本地运行良好 - Start-Process : The system cannot find the file specified from TeamCity Build step but works fine locally 如何在Teamcity构建步骤中在Windows服务器上运行后台运行Dotnet - How to run Dotnet run in background on windows server from Teamcity build step TeamCity 8 构建步骤中的 PowerShell 退出代码始终为 0 - PowerShell exit code is always 0 in TeamCity 8 build step 通过API [TeamCity]将构建配置附加到模板 - Attaching build configuration to template via API [TeamCity] TeamCity PowerShell脚本运行器构建步骤在两个项目中的运行方式不同 - TeamCity PowerShell script runner build step runs differently in two projects 由TeamCity触发的构建步骤始终构建 - 即使没有更改 - Build step triggered by TeamCity always builds - even when there are no changes 有没有一种方法可以将TeamCity中构建步骤中的错误添加到电子邮件通知中? - Is there a way to add errors from build step in TeamCity to the email notification? 如何在 powershell 构建步骤中获取 TeamCity 工作目录 - How to get the TeamCity working dir in a powershell build step
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM