sbom-ci: meaningful stage timings, dynamic severity cols, doc update
- scan-sbom: 요약에 단계별 소요(SBOM 생성 vs 취약점 스캔) 표시, 오해 주던 "총 소요"· 항상 0인 per-SBOM Sec·min/max 라인 제거. 스캔한 SEVERITY 만 동적 컬럼. - generate-sbom: 생성 소요시간을 .sbom-gen-seconds 로 기록(요약 단계별 시간용). - doc/sbom-pipeline.md: 실행 이미지(Dockerfile)·빌드/푸시·GitHub 설정·결과 확인/대응 보강. - .gitignore: .sbom-gen-seconds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+15
-11
@@ -134,11 +134,15 @@ xargs -P "$PARALLEL" -I{} bash -c '
|
||||
>> "$RESULTS"
|
||||
echo ">> [$(ts)] 스캔 완료 ($(fmt_elapsed $(( $(date +%s) - P1 ))))" | tee -a "$LOG" >&2
|
||||
|
||||
TOTAL=$(( $(date +%s) - RUN_START ))
|
||||
python3 - "$RESULTS" "$CHARTMAP" "$SEVERITY" "$TOTAL" "$(ts)" "$SUMMARY_TSV" <<'PY' | tee "$SUMMARY_MD" >&2
|
||||
TOTAL=$(( $(date +%s) - RUN_START )) # 취약점 스캔 단계(오프라인) 소요
|
||||
GEN_SECS=$(cat "$OUT_DIR/.sbom-gen-seconds" 2>/dev/null || echo "") # SBOM 생성 단계(이미지 pull) 소요
|
||||
python3 - "$RESULTS" "$CHARTMAP" "$SEVERITY" "$TOTAL" "$(ts)" "$SUMMARY_TSV" "${GEN_SECS:-}" <<'PY' | tee "$SUMMARY_MD" >&2
|
||||
import sys
|
||||
results, chartmap, sev, total, tstamp, tsv_out = sys.argv[1:7]
|
||||
total=int(total)
|
||||
gen = sys.argv[7] if len(sys.argv)>7 and sys.argv[7].strip().isdigit() else None
|
||||
gen = int(gen) if gen is not None else None
|
||||
def dur(s): return f"{s//60}분 {s%60}초"
|
||||
# 표시 심각도 = 실제 스캔한 SEVERITY 만 (순위 내림차순). MED/LOW 는 스캔 안 하면 항상 0이므로 제외.
|
||||
RANK=["CRITICAL","HIGH","MEDIUM","LOW"]; IDX={"CRITICAL":1,"HIGH":2,"MEDIUM":3,"LOW":4}
|
||||
scanned=[s.strip().upper() for s in sev.split(",") if s.strip()]
|
||||
@@ -162,25 +166,25 @@ def cnt(r,s):
|
||||
rows.sort(key=lambda r: tuple(-cnt(r,s) for s in shown))
|
||||
ok=[r for r in rows if r[5]=="OK"]; err=[r for r in rows if r[5]!="OK"]
|
||||
totals={s:sum(cnt(r,s) for r in ok) for s in shown}
|
||||
secs=[int(r[6]) for r in rows if len(r)>=7 and r[6].isdigit()]
|
||||
# TSV: chart, image, <shown counts...>, status, sec (CRITICAL 은 첫 카운트 열 = col3)
|
||||
# TSV: chart, image, <shown counts...>, status (CRITICAL 은 첫 카운트 열 = col3)
|
||||
with open(tsv_out,"w") as f:
|
||||
for r in rows:
|
||||
cols=[cm.get(r[0],""), r[0]] + [str(cnt(r,s)) for s in shown] + [r[5], r[6] if len(r)>=7 else ""]
|
||||
cols=[cm.get(r[0],""), r[0]] + [str(cnt(r,s)) for s in shown] + [r[5]]
|
||||
f.write("\t".join(cols)+"\n")
|
||||
print("# Trivy SBOM 취약점 요약\n")
|
||||
print(f"- 생성: {tstamp}")
|
||||
print(f"- 총 소요: **{total//60}분 {total%60}초** (SBOM {len(rows)}개)")
|
||||
print(f"- 성공/실패: **{len(ok)} / {len(err)}**")
|
||||
print(f"- 대상 SBOM: **{len(rows)}개** (성공 {len(ok)} / 실패 {len(err)})")
|
||||
if gen is not None:
|
||||
print(f"- SBOM 생성 소요: **{dur(gen)}** (이미지 pull 포함, 파이프라인 주 비용)")
|
||||
print(f"- 취약점 스캔 소요: **{dur(total)}** (오프라인, SBOM 입력)")
|
||||
print(f"- 집계 심각도: `{sev}`")
|
||||
print("- 취약점 합계: " + ", ".join(f"**{s} {totals[s]}**" for s in shown))
|
||||
if secs: print(f"- SBOM당 스캔시간: 최소 {min(secs)}s / 최대 {max(secs)}s / 평균 {sum(secs)//len(secs)}s")
|
||||
print()
|
||||
print("| Chart | Image | " + " | ".join(shown) + " | Status | Sec |")
|
||||
print("|---|---|" + "---:|"*len(shown) + "---|---:|")
|
||||
print("| Chart | Image | " + " | ".join(shown) + " | Status |")
|
||||
print("|---|---|" + "---:|"*len(shown) + "---|")
|
||||
for r in rows:
|
||||
cells=" | ".join(str(cnt(r,s)) for s in shown)
|
||||
print(f"| {cm.get(r[0],'')} | `{r[0]}` | {cells} | {r[5]} | {r[6] if len(r)>=7 else '-'} |")
|
||||
print(f"| {cm.get(r[0],'')} | `{r[0]}` | {cells} | {r[5]} |")
|
||||
PY
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user