我们使用的是 Jenkins 版本 2.60。
我想使用指纹验证部署复制过程。我正在使用 Jenkins API 来获取构建工件的指纹。我发现,当存在具有相同校验和的文件时,只有其中一个文件出现在指纹数组中。我需要一种方法来验证具有相同内容的其他文件的校验和。
示例:FileA 和 FileB 具有相同的内容和相同的校验和。 FileA 在 API 指纹数组中列出,但 FileB 未出现。我使用的网址是: https://jenkinshost/job/webapps/view/myview/job/myjob/1/api/json?tree=fingerprint[fileName,hash]
当我直接使用https://jenkinshost/fingerprint/49a681ceb33c90077fd3f49912c933ca/api/json检查指纹时,它返回文件名:FileA。
有什么方法可以验证 Jenkins 为 FileB 记录了相同的指纹吗?或者只是验证校验和对于作业是否有效而不担心文件名差异?
看起来指纹识别不仅存在缺陷,而且显然不适合用于检查完整性或本地文件。 除了文件名由于相同的哈希值而丢失之外,文件夹详细信息也被省略,因此即使没有不明确的文件名,您也可能会得到完全误导的结果。
采用以下管道片段创建一些具有固定内容/哈希的文件并将它们存储为工件:
sh("rm -rf ${WORKSPACE}/build") // cleanup
dir("${WORKSPACE}/build") {
sh("""
mkdir folder1
mkdir folder2
echo one > file_a
echo two > file_b
echo two > file_c # same content, different name
echo three > folder1/file_d
echo one > folder1/file_e # same content, different folder
echo four > folder1/file_a # different content, different folder, but same name
echo one > folder2/file_a
echo four > folder2/file_b
echo three > folder2/file_d
""")
}
archiveArtifacts(artifacts: "build/**", fingerprint: true)
比较实际的工件名称和指纹数据,您会得到如下结果:
索引 | 神器名称 | 内容 | 指纹 |
---|---|---|---|
0 |
|
|
:
|
1 |
|
|
:
|
2 |
|
|
:
|
3 |
|
|
:
|
4 |
|
|
:
|
5 |
|
|
:
|
6 |
|
|
:
|
7 |
|
|
:
|
8 |
|
|
:
|
如您所见,指纹列表中的
fileName
条目完全损坏且具有误导性。
但是,看起来(未排序的)工件列表和(未排序的)指纹列表仍然对齐,因此您可以一一获取工件名称和指纹哈希。
这就是我创建从(完整)工件名称到哈希值的映射的方法:
# first: create a name: value tuple rather than a dict for filename->hash in order
# to keep duplicates. Do not sort to keep the order
raw_fingerprints = [
(fingerprint["fileName"], fingerprint["hash"])
for fingerprint in client._session.get(
f"{build.url}api/json?tree=fingerprint[fileName,hash]"
).json()["fingerprint"]
]
# second: check consistency: names must match or fingerprint hash must be ambiguous
duplicate_hashes = set(fp[1] for fp, count in Counter(raw_fingerprints).items() if count > 1)
assert all(
fp_hash in duplicate_hashes or artifact.split("/")[-1] == fp_name
for artifact, (fp_name, fp_hash) in zip(build.artifacts, raw_fingerprints)
)
# third: create new fingerprints from artifact names an fingerprint hashes, keeping their order
artifact_hashes = {
artifact: fp_hash for artifact, (_, fp_hash) in zip(build.artifacts, raw_fingerprints)
}