Files
demo/jenkins/branch_ncc.groovy
Pavel Guzaev 431b4f5cfd all demo
2024-03-09 17:36:50 +05:00

406 lines
15 KiB
Groovy
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import java.text.SimpleDateFormat
import groovy.transform.Field
// import java.time.*
// import hudson.model.Computer.ListPossibleNames
@Field int NUMBER_OF_STANDS = 4
@Field String STAND_NAME_TEMPLATE = "nccbranch"
pipeline {
agent {
node {
label 'ncc-apps'
customWorkspace '/opt/ncc/'
}
}
parameters {
choice(
name: 'ACTION',
choices: ['Deploy', 'Prolong', 'Stop'],
description: 'Выбор действия'
)
choice(
name: 'STAND',
choices: "${getStandsNames()}",
description: 'Выбор стенда'
)
string(
name: 'VERSION',
defaultValue: '7.5',
description: 'Номер версии NCC'
)
string(
name: 'NOT_OFF',
defaultValue: getParamNotOff(),
description: 'Не выключать до указанного времени, например, "31/01 20-00"'
)
booleanParam(
name: 'clearDB',
defaultValue: false,
description: "Очистить базу данных"
)
}
options {
timestamps()
buildDiscarder(logRotator(numToKeepStr: '10'))
skipDefaultCheckout()
timeout(time: 40, unit: 'MINUTES')
}
environment {
BUILD_USER = getBuildUser()
CHAT_PORT = getPort("${STAND}")
DIR_STAND = "/opt/ncc/${STAND}"
CURRENT_DATE = new Date().format( 'dd.MM.yy_HHmm' )
COMPOSE_INTERACTIVE_NO_CLI = 1
COMPOSE_HTTP_TIMEOUT = 180
}
triggers{
parameterizedCron('''
02 3 * * * %STAND=nccbranch4;ACTION=Deploy;BUILD_USER=Jenkins
''')
}
stages {
stage('Stop') {
when {
beforeAgent true
environment name: 'ACTION', value: 'Stop'
}
steps {
dir("${DIR_STAND}/ncc-compose/") {
sh '''
docker version
docker-compose --ansi never version
docker-compose --ansi never ps && docker-compose --ansi never down --remove-orphans --volumes || exit 0
'''
}
}
}
stage('PrepareDB') {
when {
beforeAgent true
environment name: 'clearDB', value: 'false'
not { environment name: 'VERSION', value: '' }
environment name: 'ACTION', value: 'Deploy'
}
steps {
dir("${DIR_STAND}/ncc-compose/") {
sh '''
docker version
docker-compose --ansi never version
docker login -u user -p 123 sd-docker-registry2.naumen.ru
docker login -u pavykeka -p pesogane33145713 ncc-75.nau.team
rm -rf ./createdb/*.bak || true
'''
}
dir("${DIR_STAND}") {
sh '''
echo "BUILD_ID=${BUILD_ID}" > build.properties
echo "BUILD_USER=${BUILD_USER}" >> build.properties
echo "VERSION=${VERSION}" >> build.properties
echo "NOT_OFF=${NOT_OFF}" >> build.properties
'''
}
updateDesc()
}
}
stage('Prepare') {
when {
beforeAgent true
environment name: 'clearDB', value: 'true'
not { environment name: 'VERSION', value: '' }
environment name: 'ACTION', value: 'Deploy'
}
steps {
dir("${DIR_STAND}/ncc-compose/") {
sh '''
docker version
docker-compose --ansi never version
docker-compose --ansi never ps && docker-compose --ansi never down --remove-orphans --volumes || exit 0
docker login -u user -p 123 sd-docker-registry2.naumen.ru
docker login -u pavykeka -p pesogane33145713 ncc-75.nau.team
sudo chown -R administrator. ./
'''
}
dir("${DIR_STAND}") {
deleteDir()
gitClone("master")
sh '''
echo "BUILD_ID=${BUILD_ID}" > build.properties
echo "BUILD_USER=${BUILD_USER}" >> build.properties
echo "VERSION=${VERSION}" >> build.properties
echo "NOT_OFF=${NOT_OFF}" >> build.properties
mkdir ./ncc-compose/dbdata
sudo chown -R 100 ./ncc-compose/consul-data
sudo chown -R 777 ./ncc-compose/dbdata
sudo chown -R 777 ./ncc-compose/spool
sudo chown -R 777 ./ncc-compose/createdb
'''
}
updateDesc()
}
}
stage('Deploy') {
when {
beforeAgent true
not { environment name: 'VERSION', value: '' }
environment name: 'ACTION', value: 'Deploy'
}
steps {
script {
currentBuild.description = "${STAND} <- $VERSION <br> Не выключать до $NOT_OFF"
}
dir("${DIR_STAND}/ncc-compose/") {
writeFile file:".env_tmp", text:getEnvFile()
sh '''
cat .env_tmp > .env
docker-compose --ansi never config
docker-compose --ansi never up --build -d
sudo chown -R 777 spool
'''
}
dir("${DIR_STAND}/ncc-compose/") {
sh 'docker-compose --ansi never ps || exit 0'
}
}
}
stage('Prolong') {
when {
beforeAgent true
environment name: 'ACTION', value: 'Prolong'
}
steps {
script {
currentBuild.description = "${STAND} <- Prolong <br> Не выключать до $NOT_OFF"
}
dir("${DIR_STAND}") {
sh 'sed -i -r "s|(NOT_OFF=).*|\\1${NOT_OFF}|" build.properties'
}
}
}
}
post {
always {
updateDesc()
emailext (
subject: "${currentBuild.currentResult}: Pipeline ${currentBuild.fullDisplayName}",
body: "${currentBuild.currentResult} Pipeline: ${currentBuild.fullDisplayName}:\n${currentBuild.absoluteUrl}",
recipientProviders: [[$class: 'RequesterRecipientProvider']]
)
}
}
}
// def node = jenkins.model.Jenkins.instance.getNode( "ncc-ci" )
// def node_ip = node.computer.getChannel().call(new ListPossibleNames())
// println "${node_ip}"
def getParamNotOff() {
return new Date().plus(1).format( 'dd/MM ' ) + "20-00"
// LocalDateTime t = LocalDateTime.now();
// return t as String
}
def getBuildUser() {
return currentBuild.rawBuild.getCause(Cause.UserIdCause)?.getUserId()
}
def getProjectDirectory() {
return fileExists("${DIR_STAND}") ? "${DIR_STAND}" : "${DIR_STAND}"
}
def getPort(String stand) throws NumberFormatException {
int initialPort = 10000
return initialPort + (stand - STAND_NAME_TEMPLATE).toInteger()
}
def getEnvFile() {
String stand = "${STAND}"
int initialDbPort = 54320
int initalNCCPort = 10100
int initalNCCFPort = 10110
int initialCONSULPort = 8000
int initialWSPort = 10800
int NCCPort = initalNCCPort + (stand - STAND_NAME_TEMPLATE).toInteger()
int CONSULPort = initialCONSULPort + (stand - STAND_NAME_TEMPLATE).toInteger()
int NCCFPort = initalNCCFPort + (stand - STAND_NAME_TEMPLATE).toInteger()
int WSPort = initialWSPort + (stand - STAND_NAME_TEMPLATE).toInteger()
int dbPort = initialDbPort + (stand - STAND_NAME_TEMPLATE).toInteger()
return """
COMPOSE_PROJECT_NAME=${stand}
COMPOSE_FILE=docker-compose.yaml
chatOnSite=https://${stand}.nsd.naumen.ru/chatOnSite/
URL=https://${stand}.nsd.naumen.ru/workplace.html#/login
CHAT_PORT=${CHAT_PORT}
NCC_PORT=${NCCPort}
NCCF_PORT=${NCCFPort}
DB_PORT=${dbPort}
CONSUL_PORT=${CONSULPort}
WS_PORT=${WSPort}
"""
}
def gitClone(String stand) {
checkout poll: false, scm: [
$class: 'GitSCM',
branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false,
userRemoteConfigs: [[url: 'git@gitsd.naumen.ru:ops/compose.git']]
]
}
def updateDesc() {
def d = [BUILD_ID: '', BUILD_USER: '', VERSION: '', NOT_OFF: '']
def props = []
for (int i = 1; i <= NUMBER_OF_STANDS; i++) {
prop = readProperties defaults: d, file: "/opt/ncc/nccbranch${i}/build.properties"
props << prop
}
println props
def item = Jenkins.instance.getItemByFullName("${JOB_NAME}")
item.setDescription("${getDescTemplate(props)}")
}
def nowTime() {
return new Date().format( 'yyyy-MM-dd HH:mm' )
}
def getStandStatus(String notOff) {
if (!(notOff =~ /^[0-9][0-9]?\/[0-9][0-9] [0-9][0-9]?[-:][0-9][0-9]/)) {
standStatus = ''
} else {
yy = new Date().format( 'yyyy' )
fullDate = yy + ' ' + notOff
till = new SimpleDateFormat("yyyy dd/MM HH-mm").parse(fullDate).getTime()
now = new Date().getTime()
standStatus = (till > now) ? 'stand_busy' : 'stand_free'
}
return standStatus
}
def getDescTemplate(List props) {
return """
<?xml version="1.0" encoding="UTF-8"?><html>
<body>
<b>Задача обновляет один из стендов из ветки</b>
<div style="font-wight:bold;">
Если сборка не прошла, то обращаться в ТПиВИ
</div>
<style>
.stand_table { margin:15px 0; /*border: 1px solid #cdcdcd;*/ border:none; border-collapse:collapse; border-spacing:0; font-size:100%; width: 90%;}
.stand_table th, .stand_table td { padding:3px 4px; border: 1px solid #cdcdcd; }
.stand_table th { text-align:center; font-weight:bold; border: 1px solid #cdcdcd; background:#f9efcf; }
.stand_table .last_update { text-align:right; font-size:75%; border:none; }
.stand_table .stand:hover { background:#f6faf2; }
.stand_table .col_title { width:120px; }
.stand_table .col_date { width:150px; }
.stand_table .col_link { width:120px; }
.stand_free { background:#B4EEA1; color:#349714; }
.stand_busy { background:#FF8282; color:#B21818; }
</style>
<table class="stand_table">
<tr>
<th colspan="8" style="text-align:left;">Стенды:</th>
</tr>
<tr>
<th abbr="stand">Стенд</th>
<th abbr="link">Административный интерфейс admin/admin</th>
<th abbr="chatOnSite">Чат на сайте</th>
<th abbr="buildnum">Номер сборки</th>
<th abbr="userid">Пользователь</th>
<th abbr="ip">Нода</th>
<th abbr="ncc_port">Порт шины</th>
<th abbr="fx_url">Файловое Хранилище</th>
<th abbr="consul_port">Порт консула</th>
<th abbr="notoff">Не отключать</th>
</tr>
${props.collect { prop ->
def idx = props.findIndexOf { it.equals(prop) }
return """ <tr class="stand">
<td abbr="stand">${idx+1}</td>
<td abbr="link">
<a href="https://nccbranch${idx+1}.nsd.naumen.ru/workplace.html#/login">https://nccbranch${idx+1}.nsd.naumen.ru/workplace.html#/login</a>
</td>
<td abbr="chatOnSite">
<a href="https://nccbranch${idx+1}.nsd.naumen.ru/chatOnSite/">https://nccbranch${idx+1}.nsd.naumen.ru/chatOnSite/</a>
</td>
<td abbr="buildnum">${prop.BUILD_ID}</td>
<td abbr="userid">${prop.BUILD_USER}</td>
<td abbr="ip">nccbranch${idx+1}.sd.naumen.ru</td>
<td abbr="ncc_port">1010${idx+1}</td>
<td abbr="fx_url">
<a href="https://nccbranch${idx+1}.nsd.naumen.ru/fx">https://nccbranch${idx+1}.nsd.naumen.ru/fx</a>
</td>
<td abbr="consul_port">800${idx+1}</td>
<td abbr="notoff" class="${getStandStatus(prop.NOT_OFF)}">${prop.NOT_OFF}</td>
</tr>"""
}.join('')}
<tr>
<td align="right" abbr="lastupd" COLSPAN="8" class="last_update">Last updated: ${nowTime()}</td>
</tr>
</table>
<br/>
<br/>
<br/>При запуске необходимо выбрать стенд для обновления и указать параметры:
<br/>
<ul>
<li>
<b>ACTION</b> - выполняемое действие (Deploy, Prolong, Stop)
<ul>
<li>
<b>Deploy</b> - развертывание стенда. Используемые параметры: VERSION, NOT_OFF, крыжик clearDB (пересоздаст с настройками по умолчанию)
</li>
<li>
<b>Prolong</b> - продление стенда. Используемые параметры: NOT_OFF
</li>
<li>
<b>Stop</b> - остановить стенд. По просьбе тестирования, для эмуляции сбоя. Последующий запускс стенда через Delpoy
</li>
</ul>
</li>
<li>
<b>STAND</b> - имя стенда
</li>
<li>
<b>VERSION</b> - версия системы, заложено на будущее, а настоящее время, интеграция тестировалась только на версии 7.5
</li>
<li>
<b>Не отключать</b> - указать время и дату, до которой нужен стенд (поле информативное, стенд не будет автоматически выключен)
</li>
<li>
<b>Нода</b> - данные указать в поле Адрес сервера при настройке интеграции со стороны NSD
</li>
<li>
<b>Порт шины</b> - данные для поля порт при настройке интеграции со стороны NSD
</li>
<li>
<b>Файловое хранилище</b> - Пишем в поле файлового хранилища при настроке интеграции со стороны NSD
</li>
<li>
<b>Логины к чату на сайте</b> - Логины в системе: <b>portal1...portal8</b> (под портальные бранчи), <b>test1...test4</b> (под ncc). Пароли для всех <b>123</b>. Менять, добавлять, логины к витринам: <b>http://nccbranch1.sd.naumen.ru:8001/</b>.
</li>
</ul>
</body>
</html>
"""
}
def getStandsNames() {
def standsNames = ''
for (int i = 1; i <= NUMBER_OF_STANDS; i++) {
standsNames += "nccbranch${i}"
standsNames += "${i.equals(NUMBER_OF_STANDS) ? "" : "\n"}"
}
return standsNames
}