Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added CI-PRE-CHECKER for VENDOR_PRODUCT #3840

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a1e428d
Merge pull request #1 from intel/main
joydeep049 Nov 1, 2023
f0bd35d
Merge pull request #4 from intel/main
joydeep049 Nov 3, 2023
97ec9a5
Merge pull request #5 from intel/main
joydeep049 Nov 9, 2023
829036e
Merge pull request #6 from intel/main
joydeep049 Jan 4, 2024
1d8812e
Merge pull request #11 from intel/main
joydeep049 Feb 18, 2024
50b4fc1
feat: pre_checker initial commit
joydeep049 Feb 19, 2024
81af301
fix: minor filepath change
joydeep049 Feb 19, 2024
6884f0f
fix: Pyupgrade Linter issues
joydeep049 Feb 19, 2024
22910c4
feat: modified yml file and added docs
joydeep049 Mar 3, 2024
91479a6
feat: added docs
joydeep049 Mar 3, 2024
4e5d72f
fix: checkers-action error
joydeep049 Mar 3, 2024
fc83aa6
fix: checker fix
joydeep049 Mar 4, 2024
c9cbe6e
fix: checker fix
joydeep049 Mar 4, 2024
5867336
fix: checker fix
joydeep049 Mar 4, 2024
8dcb522
feat: added test for checker
joydeep049 Mar 4, 2024
1f122bf
fix: docs
joydeep049 Mar 4, 2024
d974753
fix: checker
joydeep049 Mar 4, 2024
02add8a
fix: checker fix
joydeep049 Mar 11, 2024
63f09d6
fix: checkers action
joydeep049 Mar 11, 2024
4eb7629
feat: minor changes
joydeep049 Mar 11, 2024
20bbea3
fix: failing tests
joydeep049 Mar 11, 2024
706196e
fix: failing tests
joydeep049 Mar 11, 2024
5fe48ab
fix: minor changes
joydeep049 Mar 11, 2024
b02df40
fix: added statements to investigate error
joydeep049 Mar 11, 2024
3e286ec
fix: minor changes to investigate errors 2
joydeep049 Mar 11, 2024
7ec0cc3
fix: checker action
joydeep049 Mar 11, 2024
9bf7a8e
feat: minor changes
joydeep049 Mar 11, 2024
426bfe3
fix: action
joydeep049 Mar 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/workflows/checkers-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Checkers-Action

on:
push:
branches: [ main ]
paths:
- 'cve_bin_tool/checkers/**/*.py'
pull_request:
branches: [ main ]
paths:
- 'cve_bin_tool/checkers/**/*.py'

jobs:
run-script:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Get date
id: get-date
run: |
echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT
echo "yesterday=$(/bin/date -d "-1 day" -u "+%Y%m%d")" >> $GITHUB_OUTPUT

- name: Print Cache Keys
run: |
echo "Today's Cache Key: Linux-cve-bin-tool-${{ steps.get-date.outputs.date }}"
echo "Yesterday's Cache Key: Linux-cve-bin-tool-${{ steps.get-date.outputs.yesterday }}"

- name: Get today's cached database
uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
id: todays-cache
with:
path: cache
key: Linux-cve-bin-tool-${{ steps.get-date.outputs.date }}

- name: Get yesterday's cached database if today's is not available
uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
if: steps.todays-cache.outputs.cache-hit != 'true'
with:
path: cache
key: Linux-cve-bin-tool-${{ steps.get-date.outputs.yesterday }}

- name: Install cve-bin-tool
if: env.sbom != 'true'
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools
python -m pip install --upgrade wheel
python -m pip install --upgrade -r dev-requirements.txt
python -m pip install --upgrade .

Comment on lines +45 to +53
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you were given some bad advice above: since your script doesn't actually call anything out of cve-bin-tool you shouldn't need to install it or run it, merely copy the database to the expected location. If you had any dependencies in your script that weren't python packages you could install them here (example below), but probably you just want to remove this section.

Suggested change
- name: Install cve-bin-tool
if: env.sbom != 'true'
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools
python -m pip install --upgrade wheel
python -m pip install --upgrade -r dev-requirements.txt
python -m pip install --upgrade .
- name: Install requirements for vendor product pre-check
run: |
python -m pip install YOUR_LIST_OF_REQUIREMENTS

- name: Try single CLI run of tool
if: env.sbom != 'true'
run: |
[[ -e cache ]] && mkdir -p .cache && mv cache ~/.cache/cve-bin-tool
NO_EXIT_CVE_NUM=1 python -m cve_bin_tool.cli test/assets/test-kerberos-5-1.15.1.out
cp -r ~/.cache/cve-bin-tool cache

Comment on lines +54 to +60
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- name: Try single CLI run of tool
if: env.sbom != 'true'
run: |
[[ -e cache ]] && mkdir -p .cache && mv cache ~/.cache/cve-bin-tool
NO_EXIT_CVE_NUM=1 python -m cve_bin_tool.cli test/assets/test-kerberos-5-1.15.1.out
cp -r ~/.cache/cve-bin-tool cache
- name: Copy cache to expected location
run: |
[[ -e cache ]] && mkdir -p .cache && mv cache ~/.cache/cve-bin-tool

We only need to keep the cache copy line here.

- name: Get changed files in checkers directory
id: changed-files
run: |
files=$(git diff --name-only ${{ github.sha }} ${{ github.event.before }} | grep '^cve_bin_tool/checkers/' | xargs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is generating an error when run and I don't know offhand what to do with it, so you're on your own for fixing it:

Run files=$(git diff --name-only 6abca452cae5546029a21f9b8db03a2a6ee5c822 9bf7a8e572bc4ab05248b861c5d271b48792631a | grep '^cve_bin_tool/checkers/' | xargs)
fatal: bad object 9bf7a8e572bc4ab05248b861c5d271b48792631a

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yepp. I tried changing the depth of the checkout code to 0 and it fetched all the checker files. I'm not able to fetch only the changed .py files in checkers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using https://github.com/technote-space/get-diff-action on some of our other workflows; don't know if it'll be better but maybe worth a shot?

Copy link
Member

@mastersans mastersans Mar 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joydeep049 I am not sure how comparing commits is better then just comparing branches, i think you can give it a try, not sure of the top its best way to do it but it should work, alternatively you can try get-diff-action as @terriko mentioned but on my first glance i think it only check changes between commits so you have to read a little, hope it helps:

  - name: Fetch Main Branch
    run: git fetch origin main
    
  - name: Get changed files in checkers directory
    id: changed-files
    run: |
      files=$(git diff --name-only origin/main | grep '^cve_bin_tool/checkers/' | xargs)
      echo "::set-output name=files::$files"
 
    
  - name: Print changed files in checkers directory
    run: |
      echo "Changed files in checkers directory:"
      echo "${{ steps.changed-files.outputs.files }}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mastersans Thanx! I'll try this!
Actually that is basically the problem I'm facing. I just want to read the difference between the last commit and this one!
But it actually gives me the difference between current and some very old commit!

If it doesn't work then @terriko anyways said in the meet she would give it a look next week.
Thanx!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but one branch can have multiple commit so why not just check branches for the difference.

echo "::set-output name=files::$files"
shell: bash

- name: Run Python script
run: |
IFS=' ' read -r -a files <<< "${{ steps.changed-files.outputs.files }}"
for file in "${files[@]}"; do
python cve_bin_tool/ci_pre_checker.py "$file"
done
shell: bash

5 changes: 5 additions & 0 deletions cve_bin_tool/checkers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [Running tests](#running-tests)
- [How it works](#how-it-works)
- [Updating checker table](#updating-checker-table)
- [Help, my checker PR fails `checkers-action`](#help-my-checker-pr-fails-the-checkers-action-in-github-ci)
- [Pull Request Template](#pull-request-template)

## Requirements
Expand Down Expand Up @@ -534,6 +535,10 @@ the product. We have done this in the checkers of `python` and`sqlite`.
You do not need to run format_checkers.py to update the checker table in documentation.
A pull request with updated checker table is created automatically when a new checker is merged.

## Help, my checker PR fails the `checkers-action` in github CI.

CVE Binary Tool has a action named `checkers-action` in CI. If it fails, that means every {vendor,product} pair in the VENDOR_PRODUCT of the checker does not have a reported or associated CVE. This action triggers if any changes like addition/modification is done to the `checkers` directory.

## Pull Request Template

When you are ready to share your code, you can go to [our pull request page](https://github.com/intel/cve-bin-tool/pulls) to make a new pull request from the web interface and to use the guided template for new checker, click on the `Compare & pull request` button and add `?template=new_checker.md` at the end of the url.
23 changes: 23 additions & 0 deletions cve_bin_tool/checkers/test_pre_checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: GPL-3.0-or-later

"""

Test for checker-action github action.
Below code is meant to mimic a checker, except it contains bogus VENDOR_PRODUCT.
The test in the CI should fail.


-- Joydeep Tripathy (joydeep049)
"""

from __future__ import annotations

from cve_bin_tool.checkers import Checker


class TestPreCheckerChecker(Checker):
CONTAINS_PATTERNS: list[str] = []
FILENAME_PATTERNS: list[str] = []
VERSION_PATTERNS = []
VENDOR_PRODUCT = [("apc", "something")]
54 changes: 54 additions & 0 deletions cve_bin_tool/ci_pre_checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright (C) 2021 Intel Corporation
# SPDX-License-Identifier: GPL-3.0-or-later
"""Testing script for checkers-action.yml"""
import ast
import sqlite3
import sys
from pathlib import Path

OLD_CACHE_DIR = Path("~").expanduser() / ".cache" / "cve-bin-tool" / "cve.db"


def extract_vendor_product(file_path):
"""Extract {vendor,product} pairs from given checker file"""
vendor_product = None
print(file_path)
with open(file_path) as file:
inside_vendor_product = False
vendor_product_str = ""
for line in file:
if "VENDOR_PRODUCT" in line:
inside_vendor_product = True
if inside_vendor_product:
print("inside_vendor_product")
vendor_product_str += line.strip()
if line.strip().endswith("]"):
break
if vendor_product_str:
print(vendor_product_str)
vendor_product = ast.literal_eval(vendor_product_str.split("=")[1].strip())
return vendor_product


def query_database(file_path):
"""Query the database and check whether all the {vendor,product} pairs have associated CVEs"""
vendor_product = extract_vendor_product(file_path)
dbcon = sqlite3.connect(OLD_CACHE_DIR)
cursor = dbcon.cursor()
for vendor, product in vendor_product:
cursor.execute(
"SELECT count(*) FROM cve_range WHERE vendor = ? AND product = ?",
(vendor, product),
)
result = cursor.fetchall()
# Failing Workflow
if result[0] == 0:
sys.exit(1)
# Indicate Success
sys.exit(0)


# Caller Code
file_path = sys.argv[1]
print(OLD_CACHE_DIR)
query_database(file_path)
Loading