github.com/anchore/syft@v1.38.2/task.d/generate/cpe-index.yaml (about) 1 version: "3" 2 3 vars: 4 CPE_CACHE_DIR: "syft/pkg/cataloger/internal/cpegenerate/dictionary/index-generator/.cpe-cache" 5 CPE_CACHE_REGISTRY: "ghcr.io/anchore/syft/cpe-cache:latest" 6 CPE_INDEX_OUTPUT: "syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json" 7 CPE_GENERATOR_DIR: "syft/pkg/cataloger/internal/cpegenerate/dictionary/index-generator" 8 9 tasks: 10 cache:pull: 11 desc: Pull CPE cache from ORAS registry (ghcr.io/anchore/syft/cpe-cache:latest) 12 # deps: [tools] 13 cmds: 14 - cmd: | 15 set -eu 16 echo "Pulling CPE cache from ORAS registry..." 17 mkdir -p {{ .CPE_CACHE_DIR }} 18 19 # pull compressed files from ORAS 20 {{ .ORAS }} pull {{ .CPE_CACHE_REGISTRY }} --output {{ .CPE_CACHE_DIR }} || { 21 exit_code=$? 22 if [ $exit_code -eq 1 ]; then 23 echo "No existing cache found in registry (this is normal for first run)" 24 exit 0 25 else 26 exit $exit_code 27 fi 28 } 29 30 # handle nested directory structure from old pushes (if exists) 31 # files might be at .cpe-cache/syft/pkg/.../cpe-cache/*.json.zst 32 nested_cache=$(find {{ .CPE_CACHE_DIR }} -type d -name ".cpe-cache" ! -path {{ .CPE_CACHE_DIR }} | head -1) 33 if [ -n "$nested_cache" ]; then 34 echo "Found nested cache structure, moving files to correct location..." 35 mv "$nested_cache"/*.json.zst {{ .CPE_CACHE_DIR }}/ 2>/dev/null || true 36 # clean up nested directories 37 rm -rf {{ .CPE_CACHE_DIR }}/syft 2>/dev/null || true 38 fi 39 40 # decompress all .json.zst files to .json 41 echo "Decompressing cache files..." 42 decompressed_count=0 43 for zst_file in {{ .CPE_CACHE_DIR }}/*.json.zst; do 44 # skip if no .zst files found (glob didn't match) 45 if [ ! -f "$zst_file" ]; then 46 echo "No compressed files to decompress" 47 break 48 fi 49 50 # decompress to .json (removing .zst extension) 51 json_file="${zst_file%.zst}" 52 echo " Decompressing $(basename "$zst_file")..." 53 zstd -d -q -f "$zst_file" -o "$json_file" 54 55 # remove compressed file 56 rm "$zst_file" 57 decompressed_count=$((decompressed_count + 1)) 58 done 59 60 if [ $decompressed_count -gt 0 ]; then 61 echo "Decompressed $decompressed_count file(s) successfully" 62 fi 63 silent: false 64 65 cache:update: 66 desc: Fetch incremental CPE updates from NVD API and update local cache 67 # deps: [tools] 68 dir: "{{ .CPE_GENERATOR_DIR }}" 69 cmds: 70 - cmd: | 71 echo "Updating CPE cache from NVD Products API..." 72 go run . -cache-only 73 silent: false 74 sources: 75 - "{{ .CPE_GENERATOR_DIR }}/*.go" 76 generates: 77 - "{{ .CPE_CACHE_DIR }}/metadata.json" 78 - "{{ .CPE_CACHE_DIR }}/products/*.json" 79 80 cache:push: 81 desc: Push updated CPE cache to ORAS registry 82 # deps: [tools] 83 cmds: 84 - cmd: | 85 set -eu 86 echo "Pushing CPE cache to ORAS registry..." 87 88 if [ ! -d "{{ .CPE_CACHE_DIR }}" ]; then 89 echo "No cache directory found" 90 exit 1 91 fi 92 93 # store absolute path to ORAS before changing directory 94 oras_bin="$(pwd)/{{ .ORAS }}" 95 96 # change to cache directory to avoid including full paths in ORAS push 97 cd {{ .CPE_CACHE_DIR }} 98 99 # find all JSON files (basenames only) 100 json_files=$(find . -maxdepth 1 -type f -name "*.json" -exec basename {} \;) 101 if [ -z "$json_files" ]; then 102 echo "No cache files to push" 103 exit 1 104 fi 105 106 # compress each JSON file to .json.zst 107 echo "Compressing cache files..." 108 compressed_files="" 109 for json_file in $json_files; do 110 zst_file="${json_file}.zst" 111 echo " Compressing $(basename "$json_file")..." 112 zstd -q -f "$json_file" -o "$zst_file" 113 compressed_files="$compressed_files $zst_file" 114 done 115 116 # push compressed files to ORAS (from cache directory, so only basenames are used) 117 echo "Pushing compressed files to registry..." 118 "$oras_bin" push {{ .CPE_CACHE_REGISTRY }} $compressed_files \ 119 --annotation org.opencontainers.image.source=https://github.com/{{ .OWNER }}/{{ .PROJECT }} \ 120 --annotation org.opencontainers.image.created=$(date -u +"%Y-%m-%dT%H:%M:%SZ") 121 122 # clean up compressed files 123 echo "Cleaning up compressed files..." 124 for zst_file in $compressed_files; do 125 rm "$zst_file" 126 done 127 128 echo "Cache pushed successfully" 129 silent: false 130 131 build: 132 desc: Generate cpe-index.json from existing local cache (does not pull/push/update) 133 dir: "{{ .CPE_GENERATOR_DIR }}" 134 cmds: 135 - cmd: | 136 echo "Generating CPE index from local cache..." 137 go run . -o ../data/cpe-index.json 138 echo "CPE index generated successfully" 139 silent: false 140 sources: 141 - "{{ .CPE_GENERATOR_DIR }}/*.go" 142 - "{{ .CPE_CACHE_DIR }}/metadata.json" 143 - "{{ .CPE_CACHE_DIR }}/products/*.json" 144 generates: 145 - "{{ .CPE_INDEX_OUTPUT }}" 146 147 cache:clean: 148 desc: Remove local CPE cache directory 149 dir: "{{ .CPE_GENERATOR_DIR }}" 150 cmds: 151 - rm -rf .cpe-cache 152 - echo "CPE cache cleaned"