Files
sa-charts/docker-swarm-review/pipeline-script
2026-05-13 15:27:39 +08:00

212 lines
7.1 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.

#!/usr/bin/env groovy
import groovy.json.JsonSlurperClassic
//properties(projectProperties)
def jsonOption = new JsonSlurperClassic().parseText(params.modulesOption)
echo "jsonOption ${jsonOption}"
jsonOption.harbor = "harbor.sino-assist.com"
jsonOption.deploy_server = "192.168.3.132"
jsonOption.profile = "review"
jsonOption.nacos_address = "review-nacos1:8848,review-nacos2:8848,review-nacos3:8848"
jsonOption.namespace = "review"
def branch = params.branch
def DOCKER_CREDENTIAL_ID = 'harbor'
def REGISTRY_URL = jsonOption.harbor
def IMAGE_TAG = params.branch
def deploy_modules = jsonOption.deploy_modules
def deploy_server = jsonOption.deploy_server
def deploy_step = jsonOption.deploy_step
// 根据传入的部署模块配置build的内容
def deploy_project_names = ""
for (module in deploy_modules) {
if (module.o == true) {
deploy_project_names += " ${module.module}:jib "
}
}
node {
def gradleHome = tool 'gradle'
def gradle = "${gradleHome}/bin/gradle"
stage('checkout') {
git branch: branch, credentialsId: 'gitlab', url: 'https://git.sino-assist.com/server/sa-server.git'
}
stage('docker-build-push') {
if (deploy_step.contains("打包镜像")) {
withCredentials([usernamePassword(passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USERNAME', credentialsId: "${DOCKER_CREDENTIAL_ID}",)]) {
sh "docker login $REGISTRY_URL -u '$DOCKER_USERNAME' -p '$DOCKER_PASSWORD'"
}
sh "$gradle $deploy_project_names -x test --parallel --build-cache -Pdocker_hub='$REGISTRY_URL' -Pdocker_version=$IMAGE_TAG -Djib.console=plain"
}
}
if (deploy_step.contains("部署服务")) {
stage('docker-deploy') {
for (final module in deploy_modules) {
if (module.o == true) {
def modules = module.module.split(":")
module.projectName = modules[modules.length - 1]
module.imageTag = IMAGE_TAG
echo "deploy module ${module.module}"
def services = docker_service_param(module, jsonOption)
echo "部署服务"
for (final def svc in services) {
String yml = makeYML(svc)
String serverName = svc.get("serviceName")
String ymlFile = "/data/swarm/${serverName}.yml"
// 添加 SSH 选项: -o StrictHostKeyChecking=no 跳过 host key 检查
String deploy = "sshpass -p 'Sino.2025' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@${deploy_server} \" mkdir -p /data/swarm/ && echo '''${yml}''' > ${ymlFile} && docker stack deploy -c ${ymlFile} ${serverName} --prune --with-registry-auth\""
echo deploy
sh deploy
}
}
}
}
}
}
def makeYML(params) {
return """
version: \\"3.8\\"
services:
svc:
image: ${params.IMAGE}
environment:
- active_profile=${params.profile}
- nacos_address=${params.nacos_address}
- nacos_password=gkxl2024#@
- namespace=${params.namespace}
- project_name=${params.projectName}
- params=${params.params}
- nativeIp=${params.nativeIp}
- reservationsMemory=${params.reservationsMemory}
- limitMemory=${params.limitMemory}
- TZ=Asia/Shanghai
ports:
- '${params.port}:8080'
healthcheck:
test: \\"curl --fail --silent localhost:8080/actuator/health/ping | grep UP || exit 1\\"
interval: 15s
timeout: 5s
retries: 20
volumes:
- ${params.namespace}_logs:/logs
logging:
driver: json-file
options:
max-size: "1G"
max-file: "3"
extra_hosts:
- "hostname:127.0.0.1"
- "open.property.cic.cn:59.46.218.8"
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
order: stop-first
resources:
limits:
cpus: \\"${params.limitCpu}\\"
memory: ${params.limitMemory}
reservations:
cpus: \\"${params.reservationsCpu}\\"
memory: ${params.reservationsMemory}
placement:
constraints:
- "node.hostname==${params.hostname}"
networks:
default:
name: ${params.namespace}
external: true
volumes:
${params.namespace}_logs:
external: true
"""
}
// 转换内存格式0.1G -> 102M, 0.5G -> 512M, 1G -> 1G
def convertMemory(String mem) {
if (mem == null || mem.trim().isEmpty()) {
return "512M"
}
mem = mem.trim().toUpperCase()
// 如果是小数G格式转换为M
if (mem.matches(/^\d+\.\d+G$/)) {
def value = mem.replace("G", "").toDouble()
def mbValue = (value * 1024).intValue()
return "${mbValue}M"
}
return mem
}
def docker_service_param(module, jsonOption) {
def ipHostnameMap = [
'192.168.3.132': 'ZD-BAK-APP2',
'192.168.3.133': 'zd-bak-app3',
'192.168.3.134': 'ZD-BAK-APP1',
]
def projectName = module.projectName
def node = module.node
def cpu = module.cpu.split("-")
def memory = module.memory.split("-")
// 转换内存格式,确保 Java 堆参数有效
def reservationsMemory = convertMemory(memory[0])
def limitMemory = convertMemory(memory[1])
def address = module.address.split("\n")
def services = []
for (final def add in address) {
def addSplit = add.split(":")
def ip = addSplit[0]
def port = addSplit[1]
def hostname = ipHostnameMap.get(ip)
def serviceName = """ss${ip.split("\\.")[3]}_${projectName}"""
def par = """-Dspring.cloud.inetutils.preferredNetworks=10.18"""
services.add([
nacos_address : jsonOption.nacos_address,
namespace : jsonOption.namespace,
projectName : projectName,
IMAGE : "$jsonOption.harbor/sa-server/$projectName:$module.imageTag",
profile : jsonOption.profile,
node : node, // 副本数量
reservationsCpu : cpu[0], // 保留cpu
limitCpu : cpu[1], // 最大cpu
reservationsMemory: reservationsMemory, // 保留内存(已转换格式)
limitMemory : limitMemory, // 最大内存(已转换格式)
serviceName : serviceName,
hostname : hostname,
port : port,
nativeIp : ip,
params : par
])
}
echo "params ${params}"
return services
}
// vim: ft=groovy