Page tree
Skip to end of metadata
Go to start of metadata

Bash with slack notifications

#!/usr/bin/env bash
readonly Server="https://teamcity.example.com" # teamcity url
readonly TeamcityBaseBackupPath="/docker-volumes/teamcity.example.com/data/backup" # Default backup path
readonly BaseBackupPath="/mnt/dbbackup/teamcity/teamcity.example.com" # Where to store backups.
readonly Token=eyJ0eXAiOiAiVENWMiJ9.UzZ2TGZSN2GMtZjI3MS00ZTQyLgzMmtBUkFaX2RoWnhZ.MWM5YzI1ZWIxNWMtYTc0TJvazNQVMGFmMzRhMjcz # teamcity user token
readonly SLACKPOST="/usr/local/bin/slackpost"
readonly SLACK_CHANNEL="alerts"
readonly SLACK_WEBHOOK="https://hooks.slack.com/services/TV37PNA3P/B01/nKYt6uytxZ22LFpxAW4ThP0K16PKU2YW"

readonly AddTimestamp=true # backup parameter
readonly IncludeConfigs=true # backup parameter
readonly IncludeDatabase=true # backup parameter
readonly IncludeBuildLogs=false # backup parameter
readonly IncludePersonalChanges=true # backup parameter
readonly FileName="TeamCity_Backup_" # backup parameter
readonly TeamCityURL="$Server/app/rest/server/backup?addTimestamp=$AddTimestamp&includeConfigs=$IncludeConfigs&includeDatabase=$IncludeDatabase&includeBuildLogs=$IncludeBuildLogs&includePersonalChanges=$IncludePersonalChanges&fileName=$FileName"
readonly Timeout=30 #minutes

SleepTime=$((60 * $Timeout / 5))
backupFileName=$(curl --location --request POST "$TeamCityURL" --header "Authorization: Bearer $Token")

if ! [[ $backupFileName =~ ^$FileName ]]
then
message="Backup aborted: invalid operation."
$SLACKPOST -c $SLACK_CHANNEL -h $SLACK_WEBHOOK -i teamcity -p disable -u Teamcity -m "$message"
exit 1
fi

st=0
until [ -f $TeamcityBaseBackupPath/$backupFileName ]
do
((st++))
echo "working $st"
if [ "${st}" -gt "${SleepTime}" ]; then
message="Backup aborted on timeout!"
fi
sleep 5
done
mv $TeamcityBaseBackupPath/$backupFileName $BaseBackupPath
backupSize=$(stat --printf="%s" $BaseBackupPath/$backupFileName | numfmt --to=iec)
message="Backup successful. File size: $backupSize"
$SLACKPOST -c $SLACK_CHANNEL -h $SLACK_WEBHOOK -i teamcity -p disable -u Teamcity -m "$message"


Windows Task scheduler

CreateTeamcityBackup.ps1
$server = "https://teamcity.example.com" # teamcity url
$teamcityBaseBackupPath = "C:\ProgramData\JetBrains\TeamCity\backup" # Default backup path
$baseBackupPath = "C:\Backup\srv\teamcity" # Where to store backups. Can be network location (\\servername\share\path)
$addTimestamp = $true # backup parameter
$includeConfigs = $true # backup parameter
$includeDatabase = $true # backup parameter
$includeBuildLogs = $false # backup parameter
$includePersonalChanges = $true # backup parameter
$fileName = "TeamCity_Backup_" # backup parameter
$username = "builduser" # Must be a TeamCity Admin
$password = "ZseUB2zcssafbbJn" # teamcity user password

function Execute-HTTPPostCommand() {
    param(
        [string] $url,
        [string] $username,
        [string] $password
    )
 
    $authInfo = $username + ":" + $password
    $authInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::Default.GetBytes($authInfo))
 
    $webRequest = [System.Net.WebRequest]::Create($url)
    $webRequest.ContentType = "text/html"
    $PostStr = [System.Text.Encoding]::Default.GetBytes("")
    $webrequest.ContentLength = $PostStr.Length
    $webRequest.Headers["Authorization"] = "Basic " + $authInfo
    $webRequest.PreAuthenticate = $true
    $webRequest.Method = "POST"
 
    $requestStream = $webRequest.GetRequestStream()
    $requestStream.Write($PostStr, 0, $PostStr.length)
    $requestStream.Close()
 
    [System.Net.WebResponse] $resp = $webRequest.GetResponse();
    $rs = $resp.GetResponseStream();
    [System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs;
    [string] $results = $sr.ReadToEnd();
 
    return $results;
}
 
function Execute-TeamCityBackup() {
    param(
        [string] $server,
        [string] $addTimestamp,
        [string] $includeConfigs,
        [string] $includeDatabase,
        [string] $includeBuildLogs,
        [string] $includePersonalChanges,
        [string] $fileName,
  	[string] $userName,
		[string] $password
    )
    $TeamCityURL = [System.String]::Format("{0}/httpAuth/app/rest/server/backup?addTimestamp={1}&includeConfigs={2}&includeDatabase={3}&includeBuildLogs={4}&includePersonalChanges={5}&fileName={6}",
                                            $server,
                                            $addTimestamp,
                                            $includeConfigs,
                                            $includeDatabase,
                                            $includeBuildLogs,
                                            $includePersonalChanges,
                                            $fileName);
 
    Execute-HTTPPostCommand $TeamCityURL $username $password
}

$backupResult = $(Execute-TeamCityBackup $server $addTimestamp $includeConfigs $includeDatabase $includeBuildLogs $includePersonalChanges $fileName $username $password)
while (!(Test-Path "$teamcityBaseBackupPath\$backupResult")) { Start-Sleep 5 }
Move-Item "$teamcityBaseBackupPath\$backupResult" $baseBackupPath

General

Triggers - new

Actions - new


Teamcity job

После бекапа должны быть шаги отправки бекапа в хранилище и очистка старых бекапов. Также при запуске teamcity server в docker можно примонтировать шару с бекапами напрямую к серверу, пробросить volume в контейнер и класть бекапы сразу туда.

Step backup: powershell

function Execute-HTTPCommand() {
    param(
        [string] $method,
        [string] $url,
        [string] $username,
        [string] $password
    )

    $authInfo = $username + ":" + $password
    $authInfo = [System.Convert]::ToBase64String([System.Text.Encoding]::Default.GetBytes($authInfo))

    $webRequest = [System.Net.WebRequest]::Create($url)
    $webRequest.ContentType = "text/html"
    $PostStr = [System.Text.Encoding]::Default.GetBytes("")
    $webrequest.ContentLength = $PostStr.Length
    $webRequest.Headers["Authorization"] = "Basic " + $authInfo
    $webRequest.PreAuthenticate = $true
    $webRequest.Method = $method

    if ($method -ne "GET")
    {
        $requestStream = $webRequest.GetRequestStream()
        $requestStream.Write($PostStr, 0, $PostStr.length)
        $requestStream.Close()
    }

    [System.Net.WebResponse] $resp = $webRequest.GetResponse();
    $rs = $resp.GetResponseStream();
    [System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs;
    [string] $results = $sr.ReadToEnd();

    return $results;
}

function Execute-TeamCityBackup() {
    param(
        [string] $server,
        [string] $addTimestamp,
        [string] $includeConfigs,
        [string] $includeDatabase,
        [string] $includeBuildLogs,
        [string] $includePersonalChanges,
        [string] $fileName,
        [string] $username,
        [string] $password
    )
    $TeamCityURL = [System.String]::Format("{0}/httpAuth/app/rest/server/backup?addTimestamp={1}&includeConfigs={2}&includeDatabase={3}&includeBuildLogs={4}&includePersonalChanges={5}&fileName={6}",
                                            $server,
                                            $addTimestamp,
                                            $includeConfigs,
                                            $includeDatabase,
                                            $includeBuildLogs,
                                            $includePersonalChanges,
                                            $fileName);

    Write-Host "Starting TeamCity backup"

    Execute-HTTPCommand "POST" $TeamCityURL $username $password
}

function Wait-TeamCityBackup() {
    param(
        [string] $server,
        [string] $username,
        [string] $password
    )

    $GetBackupStatusUrl = [System.String]::Format("{0}/httpAuth/app/rest/server/backup",
                                            $server);

    do {
        Start-Sleep -Seconds 1
        $backupStatus = Execute-HTTPCommand "GET" $GetBackupStatusUrl $username $password
        Write-Host $backupStatus
    } while ($backupStatus -eq 'Running')

}

$server = %env.SERVER_URL%
$addTimestamp = $true
$includeConfigs = $true
$includeDatabase = $true
$includeBuildLogs = $false
$includePersonalChanges = $true
$fileName = "TeamCity_Backup_"
$username = %env.USER_NAME%
$password = %env.USER_PASSWORD%

Execute-TeamCityBackup $server $addTimestamp $includeConfigs $includeDatabase $includeBuildLogs $includePersonalChanges $fileName $username $password
Wait-TeamCityBackup $server $username $password

Step clear backup dir: command line

forfiles -p C:\TeamCity\backup -s -m *.* /D -15 /C "cmd /c del @path"

Step clear storage dir: command line

pushd \\192.168.0.21\backup\teamcity\
forfiles  -m *.zip -d -15 -c "cmd /c del @path"
popd
  • No labels