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
Не выключать до $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
Не выключать до $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 """
| Стенды: | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| Стенд | Административный интерфейс admin/admin | Чат на сайте | Номер сборки | Пользователь | Нода | Порт шины | Файловое Хранилище | Порт консула | Не отключать |
| ${idx+1} | https://nccbranch${idx+1}.nsd.naumen.ru/workplace.html#/login | https://nccbranch${idx+1}.nsd.naumen.ru/chatOnSite/ | ${prop.BUILD_ID} | ${prop.BUILD_USER} | nccbranch${idx+1}.sd.naumen.ru | 1010${idx+1} | https://nccbranch${idx+1}.nsd.naumen.ru/fx | 800${idx+1} | ${prop.NOT_OFF} |
| Last updated: ${nowTime()} | |||||||||