TeamCity ~ Запустите Docker на сервере с помощью шага сборки - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь создать конфигурацию сборки TeamCity для создания образа Docker.

Для обеспечения избыточности я хочу, чтобы на первом этапе сборки был проверен ли 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:, но результат остается тем же: скрипт выдает ошибку, и Docker не запускается на сервере TeamCity.

Теперь мой основной вопрос: возможно ли то, что я пытаюсь сделать технически? Потому что я мог представить, что TeamCity использует какой-то механизм защиты, который предотвращает определенные изменения на сервере, с которого он запускается. Опять же, в прошлом я успешно использовал сценарии PowerShell для копирования и удаления файлов на Сервере, поэтому, честно говоря, на данный момент я больше смущен, чем все это, почему это не работает.

Любая информация по этому вопросу будет принята с благодарностью.

1 Ответ

0 голосов
/ 23 ноября 2018

Хорошо, поэтому я много пробовал и в итоге нашел решение, позволяющее мне проверить, работает ли Docker через шаг сборки TeamCity, и успешно запустить его, если нет.

На самом деле это оказалосьпроблема двухуровневая, для выполнения которой необходимо выполнить две разные вещи:

1.) Запустить службу агента TeamCity Build от имени учетной записи с повышенными правами

В моем случае служба агента TeamCity Build работала под учетной записью SYSTEM.Я переключил его на учетную запись администратора, используя:

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, поэтому, если кто-то знает,ответ на этот вопрос, пожалуйста, прокомментируйте.

В любом случае, я надеюсь, что это решение кому-то пригодится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...