You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins动态用户输入使用JsonSlurper报错求助

解决Jenkins动态流水线镜像标签下拉选择的两个问题:解析失败与标签过滤

核心问题分析

你遇到的两个问题本质是:

  1. 云CLI命令输出非标准JSON(可能包含ANSI颜色码、日志前缀等冗余内容),导致JsonSlurper解析失败
  2. 未从CLI输出中提取纯标签字段,导致下拉菜单显示完整镜像名

分步解决方案

1. 确保CLI输出纯净的JSON

首先检查你的云CLI命令是否支持输出JSON格式,绝大多数云厂商的CLI都提供--output json或-o json参数。如果输出仍包含冗余内容(比如颜色代码),用管道命令清理:

  • 清理ANSI颜色码:| sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g"
  • 过滤仅保留JSON结构:| grep -E '^\{|\[.*\]$'

以阿里云容器镜像服务CR为例,完整命令如下:

aliyun cr ListImageTags --RepoNamespace your-namespace --RepoName your-repo --output json | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | grep -E '^\{|\[.*\]$'

2. 安全解析JSON并提取纯标签

在Jenkinsfile中,先捕获清理后的CLI输出,再用JsonSlurper解析,最后提取标签字段(不同云厂商的JSON结构字段名不同,需调整)。

3. 动态生成纯标签下拉菜单

将提取的标签列表传入input步骤的choice参数,即可实现仅显示标签的下拉选择。

完整Jenkinsfile示例

pipeline {
    agent any
    environment {
        // 从Jenkins凭证中读取敏感信息,避免硬编码
        ALIYUN_AK = credentials('aliyun-access-key-id')
        ALIYUN_SK = credentials('aliyun-access-key-secret')
        REPO_NAMESPACE = 'your-project'
        REPO_NAME = 'your-app-image'
    }
    stages {
        stage('Fetch Image Tags') {
            steps {
                script {
                    // 1. 获取并清理CLI输出
                    def rawOutput = sh(
                        script: """aliyun cr ListImageTags \
                            --RepoNamespace ${REPO_NAMESPACE} \
                            --RepoName ${REPO_NAME} \
                            --output json \
                            | sed -r "s/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" \
                            | grep -E '^\{|\[.*\]$'""",
                        returnStdout: true
                    ).trim()

                    // 2. 解析JSON并提取标签
                    def jsonParser = new groovy.json.JsonSlurper()
                    def tagData = jsonParser.parseText(rawOutput)
                    // 阿里云CR的标签在Tags数组的Tag字段,其他厂商需调整字段名
                    def tagList = tagData.Tags.collect { it.Tag }
                    // 可选:去重并按语义化版本排序
                    tagList = tagList.unique().sort { a, b -> compareVersions(a, b) }

                    // 3. 生成下拉选择框
                    def selectedTag = input(
                        message: '选择要部署的镜像标签',
                        parameters: [
                            choice(
                                name: 'TARGET_TAG',
                                choices: tagList.join('\n'),
                                description: '可用镜像标签'
                            )
                        ]
                    )

                    // 保存选择结果到环境变量
                    env.SELECTED_TAG = selectedTag
                }
            }
        }
        stage('Deploy to Target Env') {
            steps {
                echo "部署镜像: ${REPO_NAMESPACE}/${REPO_NAME}:${env.SELECTED_TAG}"
                // 替换为你的部署命令,比如K8S部署
                // sh "kubectl set image deployment/my-app app-container=${REPO_NAMESPACE}/${REPO_NAME}:${env.SELECTED_TAG}"
            }
        }
    }
}

// 辅助函数:语义化版本比较(可选)
def compareVersions(String v1, String v2) {
    def parts1 = v1.split('\\.').collect { it.isInteger() ? it.toInteger() : it }
    def parts2 = v2.split('\\.').collect { it.isInteger() ? it.toInteger() : it }
    def minLen = Math.min(parts1.size(), parts2.size())
    for (int i = 0; i < minLen; i++) {
        def p1 = parts1[i], p2 = parts2[i]
        if (p1 instanceof Integer && p2 instanceof Integer) {
            if (p1 != p2) return p1 < p2 ? -1 : 1
        } else {
            def cmp = p1.compareTo(p2)
            if (cmp != 0) return cmp
        }
    }
    return parts1.size() < parts2.size() ? -1 : (parts1.size() > parts2.size() ? 1 : 0)
}

注意事项

  • 适配不同云厂商:替换CLI命令和JSON字段名,比如:
    • 腾讯云CCR:用tccli ccr DescribeImageTags --repo-namespace xxx --repo-name xxx --output json,标签字段为ImageTags数组的TagName
    • Harbor:用curl -u ${HARBOR_USER}:${HARBOR_PWD} https://harbor.example.com/v2/${REPO_NAME}/tags/list | jq '.tags',直接取tags数组
  • 凭证安全:所有敏感信息(AK/SK、仓库账号密码)必须存在Jenkins凭证中,禁止硬编码
  • 输出清理:如果你的CLI输出没有冗余内容,可去掉sed和grep步骤

内容的提问来源于stack exchange,提问作者shank46

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:18:12