init
This commit is contained in:
+215
@@ -0,0 +1,215 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
GITLAB_URL = 'https://gitlab.xpaas.lenovo.com'
|
||||
GITLAB_REPO = 'artificial-intelligence-platform/lenovo-ipc'
|
||||
GITLAB_CREDENTIALS_ID = 'git-ipc'
|
||||
|
||||
REGISTRY_URL = '10.128.62.130:8843'
|
||||
REGISTRY_CREDENTIALS_ID = 'docker-registry-130'
|
||||
|
||||
IMAGE_NAME = 'more_dots'
|
||||
FULL_IMAGE_NAME = "${REGISTRY_URL}/${IMAGE_NAME}"
|
||||
|
||||
SKIP_BUILD = 'false'
|
||||
K8S_NAMESPACE = 'more-dots'
|
||||
|
||||
CLUSTER_CONFIG_ID = 'k3s-cluster1-config'
|
||||
CLUSTER_NAME = 'cluster1'
|
||||
}
|
||||
|
||||
parameters {
|
||||
choice(name: 'DEPLOY_ENV', choices: ['dev', 'staging', 'prod'], description: '选择部署环境')
|
||||
choice(name: 'BUILD_POLICY', choices: ['auto', 'force_build', 'skip_build'], description: '构建策略:auto=按代码变更判断')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
git(
|
||||
url: "${GITLAB_URL}/${GITLAB_REPO}.git",
|
||||
credentialsId: GITLAB_CREDENTIALS_ID,
|
||||
branch: 'master'
|
||||
)
|
||||
script {
|
||||
env.GIT_COMMIT = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
|
||||
env.SOURCE_TREE = sh(script: 'git rev-parse HEAD:more_dots', returnStdout: true).trim()
|
||||
env.IMAGE_TAG = env.SOURCE_TREE.take(12)
|
||||
|
||||
echo "GIT_COMMIT: ${env.GIT_COMMIT}"
|
||||
echo "SOURCE_TREE: ${env.SOURCE_TREE}"
|
||||
echo "IMAGE_TAG: ${env.IMAGE_TAG}"
|
||||
echo "FULL_IMAGE_NAME: ${FULL_IMAGE_NAME}:${env.IMAGE_TAG}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Check Code Changes') {
|
||||
steps {
|
||||
script {
|
||||
if (params.BUILD_POLICY == 'force_build') {
|
||||
env.SKIP_BUILD = 'false'
|
||||
echo "BUILD_POLICY=force_build,强制构建"
|
||||
} else if (params.BUILD_POLICY == 'skip_build') {
|
||||
env.SKIP_BUILD = 'true'
|
||||
echo "BUILD_POLICY=skip_build,跳过构建"
|
||||
} else {
|
||||
def prev = env.GIT_PREVIOUS_SUCCESSFUL_COMMIT ?: ''
|
||||
if (!prev?.trim()) {
|
||||
echo "未找到上次成功构建提交,默认执行构建"
|
||||
env.SKIP_BUILD = 'false'
|
||||
} else {
|
||||
int rc = sh(
|
||||
script: "git diff --quiet ${prev} HEAD -- more_dots",
|
||||
returnStatus: true
|
||||
)
|
||||
env.SKIP_BUILD = (rc == 0) ? 'true' : 'false'
|
||||
}
|
||||
}
|
||||
|
||||
echo "代码变更检查结果: SKIP_BUILD=${env.SKIP_BUILD}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build Docker Image') {
|
||||
when {
|
||||
expression { env.SKIP_BUILD != 'true' }
|
||||
}
|
||||
steps {
|
||||
dir('more_dots') {
|
||||
sh """
|
||||
docker build --progress=plain \
|
||||
--build-arg PIP_OPTIONS=\"--no-hash-check\" \
|
||||
-t ${IMAGE_NAME}:${env.IMAGE_TAG} .
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Push to Registry') {
|
||||
when {
|
||||
expression { env.SKIP_BUILD != 'true' }
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: REGISTRY_CREDENTIALS_ID,
|
||||
usernameVariable: 'REGISTRY_USER',
|
||||
passwordVariable: 'REGISTRY_PASS'
|
||||
)]) {
|
||||
sh '''
|
||||
set -eux
|
||||
echo "登录到镜像仓库 ${REGISTRY_URL}..."
|
||||
printf '%s' "$REGISTRY_PASS" | docker login "$REGISTRY_URL" -u "$REGISTRY_USER" --password-stdin
|
||||
'''
|
||||
}
|
||||
|
||||
sh '''
|
||||
set -eux
|
||||
echo "打标签: ${IMAGE_NAME}:${IMAGE_TAG} -> ${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
docker tag "${IMAGE_NAME}:${IMAGE_TAG}" "${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
|
||||
echo "推送镜像到仓库..."
|
||||
docker push "${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
|
||||
echo "镜像推送完成: ${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy to k3s') {
|
||||
steps {
|
||||
script {
|
||||
if (!fileExists('more_dots/k8s/deployment.yaml')) {
|
||||
error "错误: more_dots/k8s/deployment.yaml 文件不存在于代码仓库中"
|
||||
}
|
||||
|
||||
def fullImageWithTag = "${FULL_IMAGE_NAME}:${env.IMAGE_TAG}"
|
||||
deployToCluster(CLUSTER_CONFIG_ID, fullImageWithTag, params.DEPLOY_ENV)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
sh '''
|
||||
docker logout "${REGISTRY_URL}" || true
|
||||
docker rmi "${FULL_IMAGE_NAME}:${IMAGE_TAG}" || true
|
||||
'''
|
||||
}
|
||||
cleanWs()
|
||||
echo "构建结束。镜像标签: ${env.IMAGE_TAG}"
|
||||
echo "完整镜像: ${FULL_IMAGE_NAME}:${env.IMAGE_TAG}"
|
||||
echo "是否跳过构建: ${env.SKIP_BUILD}"
|
||||
echo "部署环境: ${params.DEPLOY_ENV}"
|
||||
echo "目标集群: ${CLUSTER_NAME}"
|
||||
}
|
||||
failure {
|
||||
echo "构建失败,请检查日志"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def deployToCluster(String clusterConfigId, String fullImageWithTag, String deployEnv) {
|
||||
withCredentials([
|
||||
file(credentialsId: clusterConfigId, variable: 'KUBECONFIG'),
|
||||
usernamePassword(credentialsId: REGISTRY_CREDENTIALS_ID,
|
||||
usernameVariable: 'REGISTRY_USER',
|
||||
passwordVariable: 'REGISTRY_PASS')
|
||||
]) {
|
||||
sh '''
|
||||
set -eux
|
||||
|
||||
KUBECTL_PATH=$(command -v kubectl 2>/dev/null || true)
|
||||
if [ -z "$KUBECTL_PATH" ]; then
|
||||
for p in /usr/local/bin/kubectl /usr/bin/kubectl /bin/kubectl; do
|
||||
if [ -x "$p" ]; then
|
||||
KUBECTL_PATH="$p"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$KUBECTL_PATH" ]; then
|
||||
echo "kubectl 未找到,请检查 Jenkins 节点环境"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "使用kubectl路径: $KUBECTL_PATH"
|
||||
echo "部署到集群: ${CLUSTER_NAME}"
|
||||
echo "部署环境: ${DEPLOY_ENV}"
|
||||
echo "镜像: ${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
echo "命名空间: ${K8S_NAMESPACE}"
|
||||
|
||||
k() {
|
||||
sudo "$KUBECTL_PATH" --kubeconfig="$KUBECONFIG" "$@"
|
||||
}
|
||||
|
||||
k get namespace "${K8S_NAMESPACE}" || k create namespace "${K8S_NAMESPACE}"
|
||||
|
||||
k create secret docker-registry regcred-130 \
|
||||
--docker-server="${REGISTRY_URL}" \
|
||||
--docker-username="${REGISTRY_USER}" \
|
||||
--docker-password="${REGISTRY_PASS}" \
|
||||
--namespace="${K8S_NAMESPACE}" \
|
||||
--dry-run=client -o yaml | k apply -f -
|
||||
|
||||
sed -e "s|image:.*more_dots:.*|image: ${FULL_IMAGE_NAME}:${IMAGE_TAG}|g" \
|
||||
-e "s|value: \".*\"|value: \"${DEPLOY_ENV}\"|g" \
|
||||
more_dots/k8s/deployment.yaml > /tmp/deployment-${K8S_NAMESPACE}.yaml
|
||||
|
||||
k apply -f /tmp/deployment-${K8S_NAMESPACE}.yaml -n "${K8S_NAMESPACE}"
|
||||
|
||||
echo "等待部署完成..."
|
||||
k rollout status deployment/more-dots -n "${K8S_NAMESPACE}" --timeout=300s
|
||||
|
||||
echo "部署完成,查看pod状态:"
|
||||
k get pods -n "${K8S_NAMESPACE}" -l app=more-dots
|
||||
'''
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
GITLAB_URL = 'https://gitlab.xpaas.lenovo.com'
|
||||
GITLAB_REPO = 'artificial-intelligence-platform/lenovo-ipc'
|
||||
GITLAB_CREDENTIALS_ID = 'git-ipc'
|
||||
|
||||
REGISTRY_URL = '10.128.62.130:8843'
|
||||
REGISTRY_CREDENTIALS_ID = 'docker-registry-130'
|
||||
|
||||
IMAGE_NAME = 'more_dots'
|
||||
FULL_IMAGE_NAME = "${REGISTRY_URL}/${IMAGE_NAME}"
|
||||
|
||||
SKIP_BUILD = 'false'
|
||||
K8S_NAMESPACE = 'more-dots'
|
||||
|
||||
CLUSTER_CONFIG_ID = 'k3s-cluster2-config'
|
||||
CLUSTER_NAME = 'cluster2'
|
||||
}
|
||||
|
||||
parameters {
|
||||
choice(name: 'DEPLOY_ENV', choices: ['dev', 'staging', 'prod'], description: '选择部署环境')
|
||||
choice(name: 'BUILD_POLICY', choices: ['auto', 'force_build', 'skip_build'], description: '构建策略:auto=按代码变更判断')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
git(
|
||||
url: "${GITLAB_URL}/${GITLAB_REPO}.git",
|
||||
credentialsId: GITLAB_CREDENTIALS_ID,
|
||||
branch: 'master'
|
||||
)
|
||||
script {
|
||||
env.GIT_COMMIT = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
|
||||
env.SOURCE_TREE = sh(script: 'git rev-parse HEAD:more_dots', returnStdout: true).trim()
|
||||
env.IMAGE_TAG = env.SOURCE_TREE.take(12)
|
||||
|
||||
echo "GIT_COMMIT: ${env.GIT_COMMIT}"
|
||||
echo "SOURCE_TREE: ${env.SOURCE_TREE}"
|
||||
echo "IMAGE_TAG: ${env.IMAGE_TAG}"
|
||||
echo "FULL_IMAGE_NAME: ${FULL_IMAGE_NAME}:${env.IMAGE_TAG}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Check Code Changes') {
|
||||
steps {
|
||||
script {
|
||||
if (params.BUILD_POLICY == 'force_build') {
|
||||
env.SKIP_BUILD = 'false'
|
||||
echo "BUILD_POLICY=force_build,强制构建"
|
||||
} else if (params.BUILD_POLICY == 'skip_build') {
|
||||
env.SKIP_BUILD = 'true'
|
||||
echo "BUILD_POLICY=skip_build,跳过构建"
|
||||
} else {
|
||||
def prev = env.GIT_PREVIOUS_SUCCESSFUL_COMMIT ?: ''
|
||||
if (!prev?.trim()) {
|
||||
echo "未找到上次成功构建提交,默认执行构建"
|
||||
env.SKIP_BUILD = 'false'
|
||||
} else {
|
||||
int rc = sh(
|
||||
script: "git diff --quiet ${prev} HEAD -- more_dots",
|
||||
returnStatus: true
|
||||
)
|
||||
env.SKIP_BUILD = (rc == 0) ? 'true' : 'false'
|
||||
}
|
||||
}
|
||||
|
||||
echo "代码变更检查结果: SKIP_BUILD=${env.SKIP_BUILD}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build Docker Image') {
|
||||
when {
|
||||
expression { env.SKIP_BUILD != 'true' }
|
||||
}
|
||||
steps {
|
||||
dir('more_dots') {
|
||||
sh """
|
||||
docker build --progress=plain \
|
||||
--build-arg PIP_OPTIONS=\"--no-hash-check\" \
|
||||
-t ${IMAGE_NAME}:${env.IMAGE_TAG} .
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Push to Registry') {
|
||||
when {
|
||||
expression { env.SKIP_BUILD != 'true' }
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
withCredentials([usernamePassword(
|
||||
credentialsId: REGISTRY_CREDENTIALS_ID,
|
||||
usernameVariable: 'REGISTRY_USER',
|
||||
passwordVariable: 'REGISTRY_PASS'
|
||||
)]) {
|
||||
sh '''
|
||||
set -eux
|
||||
echo "登录到镜像仓库 ${REGISTRY_URL}..."
|
||||
printf '%s' "$REGISTRY_PASS" | docker login "$REGISTRY_URL" -u "$REGISTRY_USER" --password-stdin
|
||||
'''
|
||||
}
|
||||
|
||||
sh '''
|
||||
set -eux
|
||||
echo "打标签: ${IMAGE_NAME}:${IMAGE_TAG} -> ${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
docker tag "${IMAGE_NAME}:${IMAGE_TAG}" "${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
|
||||
echo "推送镜像到仓库..."
|
||||
docker push "${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
|
||||
echo "镜像推送完成: ${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy to k3s') {
|
||||
steps {
|
||||
script {
|
||||
if (!fileExists('more_dots/k8s/deployment.yaml')) {
|
||||
error "错误: more_dots/k8s/deployment.yaml 文件不存在于代码仓库中"
|
||||
}
|
||||
|
||||
def fullImageWithTag = "${FULL_IMAGE_NAME}:${env.IMAGE_TAG}"
|
||||
deployToCluster(CLUSTER_CONFIG_ID, fullImageWithTag, params.DEPLOY_ENV)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
sh '''
|
||||
docker logout "${REGISTRY_URL}" || true
|
||||
docker rmi "${FULL_IMAGE_NAME}:${IMAGE_TAG}" || true
|
||||
'''
|
||||
}
|
||||
cleanWs()
|
||||
echo "构建结束。镜像标签: ${env.IMAGE_TAG}"
|
||||
echo "完整镜像: ${FULL_IMAGE_NAME}:${env.IMAGE_TAG}"
|
||||
echo "是否跳过构建: ${env.SKIP_BUILD}"
|
||||
echo "部署环境: ${params.DEPLOY_ENV}"
|
||||
echo "目标集群: ${CLUSTER_NAME}"
|
||||
}
|
||||
failure {
|
||||
echo "构建失败,请检查日志"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def deployToCluster(String clusterConfigId, String fullImageWithTag, String deployEnv) {
|
||||
withCredentials([
|
||||
file(credentialsId: clusterConfigId, variable: 'KUBECONFIG'),
|
||||
usernamePassword(credentialsId: REGISTRY_CREDENTIALS_ID,
|
||||
usernameVariable: 'REGISTRY_USER',
|
||||
passwordVariable: 'REGISTRY_PASS')
|
||||
]) {
|
||||
sh '''
|
||||
set -eux
|
||||
|
||||
KUBECTL_PATH=$(command -v kubectl 2>/dev/null || true)
|
||||
if [ -z "$KUBECTL_PATH" ]; then
|
||||
for p in /usr/local/bin/kubectl /usr/bin/kubectl /bin/kubectl; do
|
||||
if [ -x "$p" ]; then
|
||||
KUBECTL_PATH="$p"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$KUBECTL_PATH" ]; then
|
||||
echo "kubectl 未找到,请检查 Jenkins 节点环境"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "使用kubectl路径: $KUBECTL_PATH"
|
||||
echo "部署到集群: ${CLUSTER_NAME}"
|
||||
echo "部署环境: ${DEPLOY_ENV}"
|
||||
echo "镜像: ${FULL_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
echo "命名空间: ${K8S_NAMESPACE}"
|
||||
|
||||
k() {
|
||||
sudo "$KUBECTL_PATH" --kubeconfig="$KUBECONFIG" "$@"
|
||||
}
|
||||
|
||||
k get namespace "${K8S_NAMESPACE}" || k create namespace "${K8S_NAMESPACE}"
|
||||
|
||||
k create secret docker-registry regcred-130 \
|
||||
--docker-server="${REGISTRY_URL}" \
|
||||
--docker-username="${REGISTRY_USER}" \
|
||||
--docker-password="${REGISTRY_PASS}" \
|
||||
--namespace="${K8S_NAMESPACE}" \
|
||||
--dry-run=client -o yaml | k apply -f -
|
||||
|
||||
sed -e "s|image:.*more_dots:.*|image: ${FULL_IMAGE_NAME}:${IMAGE_TAG}|g" \
|
||||
-e "s|value: \".*\"|value: \"${DEPLOY_ENV}\"|g" \
|
||||
more_dots/k8s/deployment.yaml > /tmp/deployment-${K8S_NAMESPACE}.yaml
|
||||
|
||||
k apply -f /tmp/deployment-${K8S_NAMESPACE}.yaml -n "${K8S_NAMESPACE}"
|
||||
|
||||
echo "等待部署完成..."
|
||||
k rollout status deployment/more-dots -n "${K8S_NAMESPACE}" --timeout=300s
|
||||
|
||||
echo "部署完成,查看pod状态:"
|
||||
k get pods -n "${K8S_NAMESPACE}" -l app=more-dots
|
||||
'''
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user