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"