+
This commit is contained in:
118
SCM/部署镜像/1.groovy
Normal file
118
SCM/部署镜像/1.groovy
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
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()
|
||||
Reference in New Issue
Block a user