Files
dxin 32eb516a2d +
2025-11-29 19:11:23 +08:00

118 lines
4.5 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 groovy.json.JsonSlurper
def resultHtml = '' // 初始化一个变量来存储最终的 HTML
try {
// --- 1. 参数处理 ---
def rawInput = IMAGE_NAME ?: ''
def pureTag = rawInput.split(/\s*\|\s*/)[0].trim()
if (!pureTag) {
resultHtml = '<div style="color: gray; font-style: italic;">(请选择镜像 tag)</div>'
return resultHtml // 立即返回
}
// --- 2. 硬编码凭据 ---
def user = '100038894437' // 你的 TCR 用户名 (UIN)
def pass = 'h8H1o6Fd!HLXn' // 你的 TCR 登录密码
if (!user || !pass) {
resultHtml = '<div style="color: red;">❌ 凭据为空</div>'
return resultHtml // 立即返回
}
// --- 3. API 查询 ---
final String REG = "https://uswccr.ccs.tencentyun.com"
final String REPO = "lessiesit/flymoon-email"
// 3.1. Token
def auth = "Basic " + "${user}:${pass}".bytes.encodeBase64().toString()
def tokenUrl = new URL("${REG}/service/token?service=uswccr&scope=repository:${REPO}:pull")
def tokenConn = tokenUrl.openConnection()
tokenConn.setRequestProperty("Authorization", auth)
tokenConn.connect()
if (tokenConn.responseCode != 200) {
def errorBody = tokenConn.errorStream?.text ?: "No error body"
resultHtml = "<div style='color: red;'>❌ Token 请求失败 (${tokenConn.responseCode}): ${errorBody.take(200)}</div>"
return resultHtml // 立即返回
}
def tokenJson = new JsonSlurper().parse(tokenConn.inputStream)
def token = tokenJson?.token
if (!token) {
resultHtml = '<div style="color: red;">❌ 无法从响应中获取 Token</div>'
return resultHtml // 立即返回
}
// 3.2. Manifest
def manifestUrl = new URL("${REG}/v2/${REPO}/manifests/${pureTag}")
def manifestConn = manifestUrl.openConnection()
manifestConn.setRequestProperty("Authorization", "Bearer ${token}")
manifestConn.setRequestProperty("Accept", "application/vnd.docker.distribution.manifest.v2+json")
manifestConn.connect()
if (manifestConn.responseCode != 200) {
if (manifestConn.responseCode == 404) {
resultHtml = "<div style='color: orange;'>⚠️ Tag '${pureTag}' 不存在</div>"
return resultHtml // 立即返回
}
def errorBody = manifestConn.errorStream?.text ?: "No error body"
resultHtml = "<div style='color: red;'>❌ Manifest 请求失败 (${manifestConn.responseCode}): ${errorBody.take(200)}</div>"
return resultHtml // 立即返回
}
def manifestJson = new JsonSlurper().parse(manifestConn.inputStream)
def configDigest = manifestJson?.config?.digest
if (!configDigest) {
resultHtml = '<div style="color: red;">❌ Manifest 中无 config.digest</div>'
return resultHtml // 立即返回
}
// 3.3. Config Blob (Labels)
def blobUrl = new URL("${REG}/v2/${REPO}/blobs/${configDigest}")
def blobConn = blobUrl.openConnection()
blobConn.setRequestProperty("Authorization", "Bearer ${token}")
blobConn.connect()
if (blobConn.responseCode != 200) {
def errorBody = blobConn.errorStream?.text ?: "No error body"
resultHtml = "<div style='color: red;'>❌ Config Blob 请求失败 (${blobConn.responseCode}): ${errorBody.take(200)}</div>"
return resultHtml // 立即返回
}
def configJson = new JsonSlurper().parse(blobConn.inputStream)
def labels = configJson?.config?.Labels ?: [:]
// --- 4. 格式化输出 ---
// 再次确保 labels 是 Map
if (!(labels instanceof Map)) {
labels = [:]
}
resultHtml = "<div style='font-family: monospace; font-size: 12px; padding: 5px; border: 1px solid #ccc; background-color: #f9f9f9;'><strong>🏷️ Labels for ${pureTag}:</strong><br/>"
if (labels.isEmpty()) {
resultHtml += "<em>(无 Labels</em><br/>"
} else {
labels.each { k, v ->
def key = (k != null) ? k.toString() : 'null_key'
def value = (v != null) ? v.toString().replaceAll(/^'|'$/, '') : 'null_value'
resultHtml += "<strong>${key}:</strong> ${value}<br/>"
}
}
resultHtml += "</div>"
// ✅ 修复:在 try 块结束前,确保 resultHtml 是字符串
resultHtml = resultHtml.toString()
} catch (Exception e) {
def errorMsg = e.message?.toString() ?: '未知错误'
def errorClass = e.class.simpleName
resultHtml = "<div style='color: red;'>🚨 脚本异常: ${errorClass} - ${errorMsg}</div>"
}
// ✅ 修复:确保在所有路径下,最终返回的都是字符串
return resultHtml.toString()