mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-22 07:10:41 -08:00
feat!: add clean subcommand (#6993)
Signed-off-by: knqyf263 <knqyf263@gmail.com> Co-authored-by: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Co-authored-by: DmitriyLewen <dmitriy.lewen@smartforce.io>
This commit is contained in:
2
.github/DISCUSSION_TEMPLATE/bugs.yml
vendored
2
.github/DISCUSSION_TEMPLATE/bugs.yml
vendored
@@ -116,7 +116,7 @@ body:
|
|||||||
label: Checklist
|
label: Checklist
|
||||||
description: Have you tried the following?
|
description: Have you tried the following?
|
||||||
options:
|
options:
|
||||||
- label: Run `trivy image --reset`
|
- label: Run `trivy clean --all`
|
||||||
- label: Read [the troubleshooting](https://aquasecurity.github.io/trivy/latest/docs/references/troubleshooting/)
|
- label: Read [the troubleshooting](https://aquasecurity.github.io/trivy/latest/docs/references/troubleshooting/)
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
@@ -9,24 +9,25 @@ The cache directory includes
|
|||||||
The cache option is common to all scanners.
|
The cache option is common to all scanners.
|
||||||
|
|
||||||
## Clear Caches
|
## Clear Caches
|
||||||
The `--clear-cache` option removes caches.
|
`trivy clean` subcommand removes caches.
|
||||||
|
|
||||||
**The scan is not performed.**
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ trivy image --clear-cache
|
$ trivy clean --scan-cache
|
||||||
```
|
```
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Result</summary>
|
<summary>Result</summary>
|
||||||
|
|
||||||
```
|
```
|
||||||
2019-11-15T15:13:26.209+0200 INFO Reopening vulnerability DB
|
2024-06-21T21:58:21+04:00 INFO Removing scan cache...
|
||||||
2019-11-15T15:13:26.209+0200 INFO Removing image caches...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
If you want to delete cached vulnerability databases, use `--vuln-db`.
|
||||||
|
You can also delete all caches with `--all`.
|
||||||
|
See `trivy clean --help` for details.
|
||||||
|
|
||||||
## Cache Directory
|
## Cache Directory
|
||||||
Specify where the cache is stored with `--cache-dir`.
|
Specify where the cache is stored with `--cache-dir`.
|
||||||
|
|
||||||
|
|||||||
@@ -78,8 +78,10 @@ $ trivy image --java-db-repository registry.gitlab.com/gitlab-org/security-produ
|
|||||||
`java-db-registry:latest` => `java-db-registry:latest`, but `java-db-registry` => `java-db-registry:1`.
|
`java-db-registry:latest` => `java-db-registry:latest`, but `java-db-registry` => `java-db-registry:1`.
|
||||||
|
|
||||||
## Remove DBs
|
## Remove DBs
|
||||||
The `--reset` flag removes all caches and databases.
|
"trivy clean" command removes caches and databases.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ trivy image --reset
|
$ trivy clean --vuln-db --java-db
|
||||||
|
2024-06-24T11:42:31+06:00 INFO Removing vulnerability database...
|
||||||
|
2024-06-24T11:42:31+06:00 INFO Removing Java database...
|
||||||
```
|
```
|
||||||
@@ -43,6 +43,7 @@ trivy [global flags] command [flags] target
|
|||||||
|
|
||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [trivy clean](trivy_clean.md) - Remove cached files
|
||||||
* [trivy config](trivy_config.md) - Scan config files for misconfigurations
|
* [trivy config](trivy_config.md) - Scan config files for misconfigurations
|
||||||
* [trivy convert](trivy_convert.md) - Convert Trivy JSON report into a different format
|
* [trivy convert](trivy_convert.md) - Convert Trivy JSON report into a different format
|
||||||
* [trivy filesystem](trivy_filesystem.md) - Scan local filesystem
|
* [trivy filesystem](trivy_filesystem.md) - Scan local filesystem
|
||||||
|
|||||||
50
docs/docs/references/configuration/cli/trivy_clean.md
Normal file
50
docs/docs/references/configuration/cli/trivy_clean.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
## trivy clean
|
||||||
|
|
||||||
|
Remove cached files
|
||||||
|
|
||||||
|
```
|
||||||
|
trivy clean [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```
|
||||||
|
# Remove all caches
|
||||||
|
$ trivy clean --all
|
||||||
|
|
||||||
|
# Remove scan cache
|
||||||
|
$ trivy clean --scan-cache
|
||||||
|
|
||||||
|
# Remove vulnerability database
|
||||||
|
$ trivy clean --vuln-db
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-a, --all remove all caches
|
||||||
|
--checks-bundle remove checks bundle
|
||||||
|
-h, --help help for clean
|
||||||
|
--java-db remove Java database
|
||||||
|
--scan-cache remove scan cache (container and VM image analysis results)
|
||||||
|
--vuln-db remove vulnerability database
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options inherited from parent commands
|
||||||
|
|
||||||
|
```
|
||||||
|
--cache-dir string cache directory (default "/path/to/cache")
|
||||||
|
-c, --config string config path (default "trivy.yaml")
|
||||||
|
-d, --debug debug mode
|
||||||
|
--generate-default-config write the default config to trivy-default.yaml
|
||||||
|
--insecure allow insecure server connections
|
||||||
|
-q, --quiet suppress progress bar and log output
|
||||||
|
--timeout duration timeout (default 5m0s)
|
||||||
|
-v, --version show version
|
||||||
|
```
|
||||||
|
|
||||||
|
### SEE ALSO
|
||||||
|
|
||||||
|
* [trivy](trivy.md) - Unified security scanner
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@ trivy config [flags] DIR
|
|||||||
--cf-params strings specify paths to override the CloudFormation parameters files
|
--cf-params strings specify paths to override the CloudFormation parameters files
|
||||||
--check-namespaces strings Rego namespaces
|
--check-namespaces strings Rego namespaces
|
||||||
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--compliance string compliance report to generate
|
--compliance string compliance report to generate
|
||||||
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
||||||
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
||||||
@@ -45,7 +44,6 @@ trivy config [flags] DIR
|
|||||||
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
||||||
--registry-token string registry token
|
--registry-token string registry token
|
||||||
--report string specify a compliance report format for the output (all,summary) (default "all")
|
--report string specify a compliance report format for the output (all,summary) (default "all")
|
||||||
--reset-checks-bundle remove checks bundle
|
|
||||||
-s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
|
-s, --severity strings severities of security issues to be displayed (UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL) (default [UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL])
|
||||||
--skip-check-update skip fetching rego check updates
|
--skip-check-update skip fetching rego check updates
|
||||||
--skip-dirs strings specify the directories or glob patterns to skip
|
--skip-dirs strings specify the directories or glob patterns to skip
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ trivy filesystem [flags] PATH
|
|||||||
--cf-params strings specify paths to override the CloudFormation parameters files
|
--cf-params strings specify paths to override the CloudFormation parameters files
|
||||||
--check-namespaces strings Rego namespaces
|
--check-namespaces strings Rego namespaces
|
||||||
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--compliance string compliance report to generate
|
--compliance string compliance report to generate
|
||||||
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
||||||
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
||||||
@@ -71,8 +70,6 @@ trivy filesystem [flags] PATH
|
|||||||
--registry-token string registry token
|
--registry-token string registry token
|
||||||
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
||||||
--report string specify a compliance report format for the output (all,summary) (default "all")
|
--report string specify a compliance report format for the output (all,summary) (default "all")
|
||||||
--reset remove all caches and database
|
|
||||||
--reset-checks-bundle remove checks bundle
|
|
||||||
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
||||||
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
||||||
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ trivy image [flags] IMAGE_NAME
|
|||||||
--cache-ttl duration cache TTL when using redis as cache backend
|
--cache-ttl duration cache TTL when using redis as cache backend
|
||||||
--check-namespaces strings Rego namespaces
|
--check-namespaces strings Rego namespaces
|
||||||
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--compliance string compliance report to generate (docker-cis)
|
--compliance string compliance report to generate (docker-cis)
|
||||||
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
||||||
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
||||||
@@ -92,8 +91,6 @@ trivy image [flags] IMAGE_NAME
|
|||||||
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
||||||
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine)
|
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine)
|
||||||
--report string specify a format for the compliance report. (all,summary) (default "summary")
|
--report string specify a format for the compliance report. (all,summary) (default "summary")
|
||||||
--reset remove all caches and database
|
|
||||||
--reset-checks-bundle remove checks bundle
|
|
||||||
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
||||||
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
||||||
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ trivy kubernetes [flags] [CONTEXT]
|
|||||||
--cache-ttl duration cache TTL when using redis as cache backend
|
--cache-ttl duration cache TTL when using redis as cache backend
|
||||||
--check-namespaces strings Rego namespaces
|
--check-namespaces strings Rego namespaces
|
||||||
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--compliance string compliance report to generate (k8s-nsa,k8s-cis,k8s-pss-baseline,k8s-pss-restricted)
|
--compliance string compliance report to generate (k8s-nsa,k8s-cis,k8s-pss-baseline,k8s-pss-restricted)
|
||||||
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
||||||
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
||||||
@@ -87,8 +86,6 @@ trivy kubernetes [flags] [CONTEXT]
|
|||||||
--registry-token string registry token
|
--registry-token string registry token
|
||||||
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
||||||
--report string specify a report format for the output (all,summary) (default "all")
|
--report string specify a report format for the output (all,summary) (default "all")
|
||||||
--reset remove all caches and database
|
|
||||||
--reset-checks-bundle remove checks bundle
|
|
||||||
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
||||||
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,rbac) (default [vuln,misconfig,secret,rbac])
|
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,rbac) (default [vuln,misconfig,secret,rbac])
|
||||||
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
|
|||||||
--cf-params strings specify paths to override the CloudFormation parameters files
|
--cf-params strings specify paths to override the CloudFormation parameters files
|
||||||
--check-namespaces strings Rego namespaces
|
--check-namespaces strings Rego namespaces
|
||||||
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--commit string pass the commit hash to be scanned
|
--commit string pass the commit hash to be scanned
|
||||||
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
||||||
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
||||||
@@ -70,8 +69,6 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
|
|||||||
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
||||||
--registry-token string registry token
|
--registry-token string registry token
|
||||||
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
||||||
--reset remove all caches and database
|
|
||||||
--reset-checks-bundle remove checks bundle
|
|
||||||
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
||||||
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
||||||
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ trivy rootfs [flags] ROOTDIR
|
|||||||
--cf-params strings specify paths to override the CloudFormation parameters files
|
--cf-params strings specify paths to override the CloudFormation parameters files
|
||||||
--check-namespaces strings Rego namespaces
|
--check-namespaces strings Rego namespaces
|
||||||
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
--config-check strings specify the paths to the Rego check files or to the directories containing them, applying config files
|
||||||
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
--config-data strings specify paths from which data for the Rego checks will be recursively loaded
|
||||||
--custom-headers strings custom headers in client mode
|
--custom-headers strings custom headers in client mode
|
||||||
@@ -72,8 +71,6 @@ trivy rootfs [flags] ROOTDIR
|
|||||||
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
||||||
--registry-token string registry token
|
--registry-token string registry token
|
||||||
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
||||||
--reset remove all caches and database
|
|
||||||
--reset-checks-bundle remove checks bundle
|
|
||||||
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
||||||
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
||||||
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ trivy sbom [flags] SBOM_PATH
|
|||||||
```
|
```
|
||||||
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
|
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
|
||||||
--cache-ttl duration cache TTL when using redis as cache backend
|
--cache-ttl duration cache TTL when using redis as cache backend
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--compliance string compliance report to generate
|
--compliance string compliance report to generate
|
||||||
--custom-headers strings custom headers in client mode
|
--custom-headers strings custom headers in client mode
|
||||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2")
|
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2")
|
||||||
@@ -49,7 +48,6 @@ trivy sbom [flags] SBOM_PATH
|
|||||||
--redis-key string redis key file location, if using redis as cache backend
|
--redis-key string redis key file location, if using redis as cache backend
|
||||||
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
||||||
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
||||||
--reset remove all caches and database
|
|
||||||
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
||||||
--scanners strings comma-separated list of what security issues to detect (vuln,license) (default [vuln])
|
--scanners strings comma-separated list of what security issues to detect (vuln,license) (default [vuln])
|
||||||
--server string server address in client mode
|
--server string server address in client mode
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ trivy server [flags]
|
|||||||
```
|
```
|
||||||
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
|
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
|
||||||
--cache-ttl duration cache TTL when using redis as cache backend
|
--cache-ttl duration cache TTL when using redis as cache backend
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2")
|
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2")
|
||||||
--download-db-only download/update vulnerability database but don't run a scan
|
--download-db-only download/update vulnerability database but don't run a scan
|
||||||
--enable-modules strings [EXPERIMENTAL] module names to enable
|
--enable-modules strings [EXPERIMENTAL] module names to enable
|
||||||
@@ -36,7 +35,6 @@ trivy server [flags]
|
|||||||
--redis-key string redis key file location, if using redis as cache backend
|
--redis-key string redis key file location, if using redis as cache backend
|
||||||
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
||||||
--registry-token string registry token
|
--registry-token string registry token
|
||||||
--reset remove all caches and database
|
|
||||||
--skip-db-update skip updating vulnerability database
|
--skip-db-update skip updating vulnerability database
|
||||||
--token string for authentication in client/server mode
|
--token string for authentication in client/server mode
|
||||||
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
|
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ trivy vm [flags] VM_IMAGE
|
|||||||
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
|
--cache-backend string cache backend (e.g. redis://localhost:6379) (default "fs")
|
||||||
--cache-ttl duration cache TTL when using redis as cache backend
|
--cache-ttl duration cache TTL when using redis as cache backend
|
||||||
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
--checks-bundle-repository string OCI registry URL to retrieve checks bundle from (default "ghcr.io/aquasecurity/trivy-checks:0")
|
||||||
--clear-cache clear image caches without scanning
|
|
||||||
--compliance string compliance report to generate
|
--compliance string compliance report to generate
|
||||||
--custom-headers strings custom headers in client mode
|
--custom-headers strings custom headers in client mode
|
||||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2")
|
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db:2")
|
||||||
@@ -62,8 +61,6 @@ trivy vm [flags] VM_IMAGE
|
|||||||
--redis-key string redis key file location, if using redis as cache backend
|
--redis-key string redis key file location, if using redis as cache backend
|
||||||
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
--redis-tls enable redis TLS with public certificates, if using redis as cache backend
|
||||||
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
--rekor-url string [EXPERIMENTAL] address of rekor STL server (default "https://rekor.sigstore.dev")
|
||||||
--reset remove all caches and database
|
|
||||||
--reset-checks-bundle remove checks bundle
|
|
||||||
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
--sbom-sources strings [EXPERIMENTAL] try to retrieve SBOM from the specified sources (oci,rekor)
|
||||||
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
--scanners strings comma-separated list of what security issues to detect (vuln,misconfig,secret,license) (default [vuln,secret])
|
||||||
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
--secret-config string specify a path to config file for secret scanning (default "trivy-secret.yaml")
|
||||||
|
|||||||
@@ -264,10 +264,10 @@ $ brew install aquasecurity/trivy/trivy
|
|||||||
## Others
|
## Others
|
||||||
### Unknown error
|
### Unknown error
|
||||||
|
|
||||||
Try again with `--reset` option:
|
Try again after running `trivy clean --all`:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ trivy image --reset
|
$ trivy clean --all
|
||||||
```
|
```
|
||||||
|
|
||||||
[air-gapped]: ../advanced/air-gap.md
|
[air-gapped]: ../advanced/air-gap.md
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ container_scanning:
|
|||||||
FULL_IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
|
FULL_IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
|
||||||
script:
|
script:
|
||||||
- trivy --version
|
- trivy --version
|
||||||
# cache cleanup is needed when scanning images with the same tags, it does not remove the database
|
|
||||||
- time trivy image --clear-cache
|
|
||||||
# update vulnerabilities db
|
# update vulnerabilities db
|
||||||
- time trivy image --download-db-only
|
- time trivy image --download-db-only
|
||||||
# Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there
|
# Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ nav:
|
|||||||
- Configuration:
|
- Configuration:
|
||||||
- CLI:
|
- CLI:
|
||||||
- Overview: docs/references/configuration/cli/trivy.md
|
- Overview: docs/references/configuration/cli/trivy.md
|
||||||
|
- Clean: docs/references/configuration/cli/trivy_clean.md
|
||||||
- Config: docs/references/configuration/cli/trivy_config.md
|
- Config: docs/references/configuration/cli/trivy_config.md
|
||||||
- Convert: docs/references/configuration/cli/trivy_convert.md
|
- Convert: docs/references/configuration/cli/trivy_convert.md
|
||||||
- Filesystem: docs/references/configuration/cli/trivy_filesystem.md
|
- Filesystem: docs/references/configuration/cli/trivy_filesystem.md
|
||||||
|
|||||||
39
pkg/cache/client.go
vendored
39
pkg/cache/client.go
vendored
@@ -20,11 +20,6 @@ const (
|
|||||||
TypeRedis Type = "redis"
|
TypeRedis Type = "redis"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
|
||||||
dir string
|
|
||||||
Cache
|
|
||||||
}
|
|
||||||
|
|
||||||
type Type string
|
type Type string
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
@@ -115,9 +110,8 @@ func NewType(backend string) (Type, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient returns a new cache client
|
// New returns a new cache client
|
||||||
func NewClient(dir string, opts Options) (*Client, error) {
|
func New(dir string, opts Options) (Cache, error) {
|
||||||
client := &Client{dir: dir}
|
|
||||||
if opts.Type == TypeRedis {
|
if opts.Type == TypeRedis {
|
||||||
log.Info("Redis cache", log.String("url", opts.Redis.BackendMasked()))
|
log.Info("Redis cache", log.String("url", opts.Redis.BackendMasked()))
|
||||||
options, err := redis.ParseURL(opts.Redis.Backend)
|
options, err := redis.ParseURL(opts.Redis.Backend)
|
||||||
@@ -142,38 +136,15 @@ func NewClient(dir string, opts Options) (*Client, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client.Cache = NewRedisCache(options, opts.TTL)
|
return NewRedisCache(options, opts.TTL), nil
|
||||||
return client, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// standalone mode
|
// standalone mode
|
||||||
var err error
|
fsCache, err := NewFSCache(dir)
|
||||||
client.Cache, err = NewFSCache(dir)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("unable to initialize fs cache: %w", err)
|
return nil, xerrors.Errorf("unable to initialize fs cache: %w", err)
|
||||||
}
|
}
|
||||||
return client, nil
|
return fsCache, nil
|
||||||
}
|
|
||||||
|
|
||||||
// Reset resets the cache
|
|
||||||
func (c *Client) Reset() error {
|
|
||||||
log.Info("Removing all caches...")
|
|
||||||
if err := c.Clear(); err != nil {
|
|
||||||
return xerrors.Errorf("failed to remove the cache: %w", err)
|
|
||||||
}
|
|
||||||
if err := os.RemoveAll(c.dir); err != nil {
|
|
||||||
return xerrors.Errorf("failed to remove the directory (%s) : %w", c.dir, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearArtifacts clears the artifact cache
|
|
||||||
func (c *Client) ClearArtifacts() error {
|
|
||||||
log.Info("Removing artifact caches...")
|
|
||||||
if err := c.Clear(); err != nil {
|
|
||||||
return xerrors.Errorf("failed to remove the cache: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTLSConfig gets tls config from CA, Cert and Key file
|
// GetTLSConfig gets tls config from CA, Cert and Key file
|
||||||
|
|||||||
50
pkg/cache/client_test.go
vendored
50
pkg/cache/client_test.go
vendored
@@ -1,8 +1,6 @@
|
|||||||
package cache_test
|
package cache_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -129,51 +127,3 @@ func TestRedisOptions_BackendMasked(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_Reset(t *testing.T) {
|
|
||||||
// Create a temporary directory for testing
|
|
||||||
tempDir := t.TempDir()
|
|
||||||
|
|
||||||
// Create test files and subdirectories
|
|
||||||
subDir := filepath.Join(tempDir, "subdir")
|
|
||||||
err := os.MkdirAll(subDir, 0755)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
testFile := filepath.Join(tempDir, "testfile.txt")
|
|
||||||
err = os.WriteFile(testFile, []byte("test content"), 0644)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Create a cache client
|
|
||||||
client, err := cache.NewClient(tempDir, cache.Options{Type: cache.TypeFS})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Call Reset method
|
|
||||||
err = client.Reset()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Verify that the subdirectory no longer exists
|
|
||||||
require.NoDirExists(t, subDir, "Subdirectory should not exist after Reset")
|
|
||||||
|
|
||||||
// Verify that the test file no longer exists
|
|
||||||
require.NoFileExists(t, testFile, "Test file should not exist after Reset")
|
|
||||||
|
|
||||||
// Verify that the cache directory no longer exists
|
|
||||||
require.NoDirExists(t, tempDir, "Cache directory should not exist after Reset")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestClient_ClearArtifacts(t *testing.T) {
|
|
||||||
// Create a temporary directory for testing
|
|
||||||
tempDir := t.TempDir()
|
|
||||||
|
|
||||||
// Create a client
|
|
||||||
client, err := cache.NewClient(tempDir, cache.Options{Type: cache.TypeFS})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.FileExists(t, filepath.Join(tempDir, "fanal", "fanal.db"), "Database file should exist")
|
|
||||||
|
|
||||||
// Call ClearArtifacts method
|
|
||||||
err = client.ClearArtifacts()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.NoDirExists(t, filepath.Join(tempDir, "fanal"), "Artifact cache should not exist after ClearArtifacts")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy/pkg/commands/artifact"
|
"github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/commands/clean"
|
||||||
"github.com/aquasecurity/trivy/pkg/commands/convert"
|
"github.com/aquasecurity/trivy/pkg/commands/convert"
|
||||||
"github.com/aquasecurity/trivy/pkg/commands/server"
|
"github.com/aquasecurity/trivy/pkg/commands/server"
|
||||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
||||||
@@ -94,6 +95,7 @@ func NewApp() *cobra.Command {
|
|||||||
NewSBOMCommand(globalFlags),
|
NewSBOMCommand(globalFlags),
|
||||||
NewVersionCommand(globalFlags),
|
NewVersionCommand(globalFlags),
|
||||||
NewVMCommand(globalFlags),
|
NewVMCommand(globalFlags),
|
||||||
|
NewCleanCommand(globalFlags),
|
||||||
)
|
)
|
||||||
|
|
||||||
if plugins := loadPluginCommands(); len(plugins) > 0 {
|
if plugins := loadPluginCommands(); len(plugins) > 0 {
|
||||||
@@ -1160,6 +1162,47 @@ func NewSBOMCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewCleanCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||||
|
cleanFlags := &flag.Flags{
|
||||||
|
GlobalFlagGroup: globalFlags,
|
||||||
|
CleanFlagGroup: flag.NewCleanFlagGroup(),
|
||||||
|
}
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "clean [flags]",
|
||||||
|
GroupID: groupUtility,
|
||||||
|
Short: "Remove cached files",
|
||||||
|
Example: ` # Remove all caches
|
||||||
|
$ trivy clean --all
|
||||||
|
|
||||||
|
# Remove scan cache
|
||||||
|
$ trivy clean --scan-cache
|
||||||
|
|
||||||
|
# Remove vulnerability database
|
||||||
|
$ trivy clean --vuln-db
|
||||||
|
`,
|
||||||
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if err := cleanFlags.Bind(cmd); err != nil {
|
||||||
|
return xerrors.Errorf("flag bind error: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
opts, err := cleanFlags.ToOptions(args)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("flag error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return clean.Run(cmd.Context(), opts)
|
||||||
|
},
|
||||||
|
SilenceErrors: true,
|
||||||
|
SilenceUsage: true,
|
||||||
|
}
|
||||||
|
cmd.SetFlagErrorFunc(flagErrorFunc)
|
||||||
|
cleanFlags.AddFlags(cmd)
|
||||||
|
cmd.SetUsageTemplate(fmt.Sprintf(usageTemplate, cleanFlags.Usages(cmd)))
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
func NewVersionCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
func NewVersionCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
||||||
var versionFormat string
|
var versionFormat string
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@@ -1199,7 +1242,8 @@ func showVersion(cacheDir, outputFormat string, w io.Writer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validateArgs(cmd *cobra.Command, args []string) error {
|
func validateArgs(cmd *cobra.Command, args []string) error {
|
||||||
// '--clear-cache', '--download-db-only', '--download-java-db-only', '--reset', '--reset-checks-bundle' and '--generate-default-config' don't conduct the subsequent scanning
|
// '--clear-cache' (removed), '--download-db-only', '--download-java-db-only', '--reset' (removed),
|
||||||
|
// '--reset-checks-bundle' (removed) and '--generate-default-config' don't conduct the subsequent scanning
|
||||||
if viper.GetBool(flag.ClearCacheFlag.ConfigName) || viper.GetBool(flag.DownloadDBOnlyFlag.ConfigName) ||
|
if viper.GetBool(flag.ClearCacheFlag.ConfigName) || viper.GetBool(flag.DownloadDBOnlyFlag.ConfigName) ||
|
||||||
viper.GetBool(flag.ResetFlag.ConfigName) || viper.GetBool(flag.GenerateDefaultConfigFlag.ConfigName) ||
|
viper.GetBool(flag.ResetFlag.ConfigName) || viper.GetBool(flag.GenerateDefaultConfigFlag.ConfigName) ||
|
||||||
viper.GetBool(flag.DownloadJavaDBOnlyFlag.ConfigName) || viper.GetBool(flag.ResetChecksBundleFlag.ConfigName) {
|
viper.GetBool(flag.DownloadJavaDBOnlyFlag.ConfigName) || viper.GetBool(flag.ResetChecksBundleFlag.ConfigName) {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/aquasecurity/trivy/pkg/log"
|
"github.com/aquasecurity/trivy/pkg/log"
|
||||||
"github.com/aquasecurity/trivy/pkg/misconf"
|
"github.com/aquasecurity/trivy/pkg/misconf"
|
||||||
"github.com/aquasecurity/trivy/pkg/module"
|
"github.com/aquasecurity/trivy/pkg/module"
|
||||||
"github.com/aquasecurity/trivy/pkg/policy"
|
|
||||||
pkgReport "github.com/aquasecurity/trivy/pkg/report"
|
pkgReport "github.com/aquasecurity/trivy/pkg/report"
|
||||||
"github.com/aquasecurity/trivy/pkg/result"
|
"github.com/aquasecurity/trivy/pkg/result"
|
||||||
"github.com/aquasecurity/trivy/pkg/rpc/client"
|
"github.com/aquasecurity/trivy/pkg/rpc/client"
|
||||||
@@ -350,41 +349,14 @@ func (r *runner) initCache(opts flag.Options) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// standalone mode
|
// standalone mode
|
||||||
cacheClient, err := cache.NewClient(opts.CacheDir, opts.CacheOptions.CacheBackendOptions)
|
cacheClient, err := cache.New(opts.CacheDir, opts.CacheOptions.CacheBackendOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("unable to initialize the cache: %w", err)
|
return xerrors.Errorf("unable to initialize the cache: %w", err)
|
||||||
}
|
}
|
||||||
log.Debug("Cache dir", log.String("dir", opts.CacheDir))
|
log.Debug("Cache dir", log.String("dir", opts.CacheDir))
|
||||||
|
|
||||||
if opts.Reset {
|
r.cache = cacheClient
|
||||||
defer cacheClient.Close()
|
r.localCache = cacheClient
|
||||||
if err = cacheClient.Reset(); err != nil {
|
|
||||||
return xerrors.Errorf("cache reset error: %w", err)
|
|
||||||
}
|
|
||||||
return SkipScan
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.ResetChecksBundle {
|
|
||||||
c, err := policy.NewClient(opts.CacheDir, true, opts.MisconfOptions.ChecksBundleRepository)
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("failed to instantiate check client: %w", err)
|
|
||||||
}
|
|
||||||
if err := c.Clear(); err != nil {
|
|
||||||
return xerrors.Errorf("failed to remove the cache: %w", err)
|
|
||||||
}
|
|
||||||
return SkipScan
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.ClearCache {
|
|
||||||
defer cacheClient.Close()
|
|
||||||
if err = cacheClient.ClearArtifacts(); err != nil {
|
|
||||||
return xerrors.Errorf("cache clear error: %w", err)
|
|
||||||
}
|
|
||||||
return SkipScan
|
|
||||||
}
|
|
||||||
|
|
||||||
r.cache = cacheClient.Cache
|
|
||||||
r.localCache = cacheClient.Cache
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
102
pkg/commands/clean/run.go
Normal file
102
pkg/commands/clean/run.go
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package clean
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/aquasecurity/trivy/pkg/cache"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/db"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/flag"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/javadb"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/log"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/policy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Run(ctx context.Context, opts flag.Options) error {
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, opts.Timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if !opts.CleanAll && !opts.CleanScanCache && !opts.CleanVulnerabilityDB && !opts.CleanJavaDB && !opts.CleanChecksBundle {
|
||||||
|
return xerrors.New("no clean option is specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CleanAll {
|
||||||
|
return cleanAll(ctx, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CleanScanCache {
|
||||||
|
if err := cleanScanCache(ctx, opts); err != nil {
|
||||||
|
return xerrors.Errorf("failed to remove scan cache : %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CleanVulnerabilityDB {
|
||||||
|
if err := cleanVulnerabilityDB(ctx, opts); err != nil {
|
||||||
|
return xerrors.Errorf("vuln db clean error: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CleanJavaDB {
|
||||||
|
if err := cleanJavaDB(ctx, opts); err != nil {
|
||||||
|
return xerrors.Errorf("java db clean error: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.CleanChecksBundle {
|
||||||
|
if err := cleanCheckBundle(opts); err != nil {
|
||||||
|
return xerrors.Errorf("check bundle clean error: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanAll(ctx context.Context, opts flag.Options) error {
|
||||||
|
log.InfoContext(ctx, "Removing all caches...")
|
||||||
|
if err := os.RemoveAll(opts.CacheDir); err != nil {
|
||||||
|
return xerrors.Errorf("failed to remove the directory (%s) : %w", opts.CacheDir, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanScanCache(ctx context.Context, opts flag.Options) error {
|
||||||
|
log.InfoContext(ctx, "Removing scan cache...")
|
||||||
|
c, err := cache.New(opts.CacheDir, opts.CacheBackendOptions)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to instantiate cache client: %w", err)
|
||||||
|
}
|
||||||
|
if err = c.Clear(); err != nil {
|
||||||
|
return xerrors.Errorf("clear scan cache: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanVulnerabilityDB(ctx context.Context, opts flag.Options) error {
|
||||||
|
log.InfoContext(ctx, "Removing vulnerability database...")
|
||||||
|
if err := db.NewClient(opts.CacheDir, true).Clear(ctx); err != nil {
|
||||||
|
return xerrors.Errorf("clear vulnerability database: %w", err)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanJavaDB(ctx context.Context, opts flag.Options) error {
|
||||||
|
log.InfoContext(ctx, "Removing Java database...")
|
||||||
|
if err := javadb.Clear(ctx, opts.CacheDir); err != nil {
|
||||||
|
return xerrors.Errorf("clear Java database: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanCheckBundle(opts flag.Options) error {
|
||||||
|
log.Info("Removing check bundle...")
|
||||||
|
c, err := policy.NewClient(opts.CacheDir, true, opts.MisconfOptions.ChecksBundleRepository)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to instantiate check client: %w", err)
|
||||||
|
}
|
||||||
|
if err := c.Clear(); err != nil {
|
||||||
|
return xerrors.Errorf("clear check bundle: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
135
pkg/commands/clean/run_test.go
Normal file
135
pkg/commands/clean/run_test.go
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package clean_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/aquasecurity/trivy/pkg/commands/clean"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/flag"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRun(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
cleanOpts flag.CleanOptions
|
||||||
|
wantErr bool
|
||||||
|
checkFunc func(*testing.T, string)
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "clean all",
|
||||||
|
cleanOpts: flag.CleanOptions{
|
||||||
|
CleanAll: true,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
checkFunc: func(t *testing.T, dir string) {
|
||||||
|
assert.NoDirExists(t, dir)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "clean scan cache",
|
||||||
|
cleanOpts: flag.CleanOptions{
|
||||||
|
CleanScanCache: true,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
checkFunc: func(t *testing.T, dir string) {
|
||||||
|
assert.NoDirExists(t, filepath.Join(dir, "fanal"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "db"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "java-db"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "policy"))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "clean vulnerability DB",
|
||||||
|
cleanOpts: flag.CleanOptions{
|
||||||
|
CleanVulnerabilityDB: true,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
checkFunc: func(t *testing.T, dir string) {
|
||||||
|
assert.NoDirExists(t, filepath.Join(dir, "db"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "fanal"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "java-db"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "policy"))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "clean Java DB",
|
||||||
|
cleanOpts: flag.CleanOptions{
|
||||||
|
CleanJavaDB: true,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
checkFunc: func(t *testing.T, dir string) {
|
||||||
|
assert.NoDirExists(t, filepath.Join(dir, "java-db"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "fanal"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "db"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "policy"))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "clean check bundle",
|
||||||
|
cleanOpts: flag.CleanOptions{
|
||||||
|
CleanChecksBundle: true,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
checkFunc: func(t *testing.T, dir string) {
|
||||||
|
assert.NoDirExists(t, filepath.Join(dir, "policy"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "fanal"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "db"))
|
||||||
|
assert.DirExists(t, filepath.Join(dir, "java-db"))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no clean option specified",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
// Create a temporary directory for testing
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
// Create test directories and files
|
||||||
|
createTestFiles(t, tempDir)
|
||||||
|
|
||||||
|
opts := flag.Options{
|
||||||
|
GlobalOptions: flag.GlobalOptions{
|
||||||
|
CacheDir: tempDir,
|
||||||
|
},
|
||||||
|
CleanOptions: tt.cleanOpts,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := clean.Run(context.Background(), opts)
|
||||||
|
|
||||||
|
if tt.wantErr {
|
||||||
|
assert.Error(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
if tt.checkFunc != nil {
|
||||||
|
tt.checkFunc(t, tempDir)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createTestFiles(t *testing.T, dir string) {
|
||||||
|
subdirs := []string{
|
||||||
|
"fanal",
|
||||||
|
"db",
|
||||||
|
"java-db",
|
||||||
|
"policy",
|
||||||
|
}
|
||||||
|
for _, subdir := range subdirs {
|
||||||
|
err := os.MkdirAll(filepath.Join(dir, subdir), 0755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
testFile := filepath.Join(dir, subdir, "testfile.txt")
|
||||||
|
err = os.WriteFile(testFile, []byte("test content"), 0644)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,13 @@ func Run(ctx context.Context, opts flag.Options) (err error) {
|
|||||||
log.InitLogger(opts.Debug, opts.Quiet)
|
log.InitLogger(opts.Debug, opts.Quiet)
|
||||||
|
|
||||||
// configure cache dir
|
// configure cache dir
|
||||||
cacheClient, err := cache.NewClient(opts.CacheDir, opts.CacheOptions.CacheBackendOptions)
|
cacheClient, err := cache.New(opts.CacheDir, opts.CacheOptions.CacheBackendOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("server cache error: %w", err)
|
return xerrors.Errorf("server cache error: %w", err)
|
||||||
}
|
}
|
||||||
defer cacheClient.Close()
|
defer cacheClient.Close()
|
||||||
log.Debug("Cache", log.String("dir", opts.CacheDir))
|
log.Debug("Cache", log.String("dir", opts.CacheDir))
|
||||||
|
|
||||||
if opts.Reset {
|
|
||||||
return cacheClient.Reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
// download the database file
|
// download the database file
|
||||||
if err = operation.DownloadDB(ctx, opts.AppVersion, opts.CacheDir, opts.DBRepository,
|
if err = operation.DownloadDB(ctx, opts.AppVersion, opts.CacheDir, opts.DBRepository,
|
||||||
true, opts.SkipDBUpdate, opts.RegistryOpts()); err != nil {
|
true, opts.SkipDBUpdate, opts.RegistryOpts()); err != nil {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
@@ -158,6 +159,13 @@ func (c *Client) Download(ctx context.Context, dst string, opt types.RegistryOpt
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) Clear(ctx context.Context) error {
|
||||||
|
if err := os.RemoveAll(db.Dir(c.cacheDir)); err != nil {
|
||||||
|
return xerrors.Errorf("failed to remove vulnerability database: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) updateDownloadedAt(ctx context.Context, dst string) error {
|
func (c *Client) updateDownloadedAt(ctx context.Context, dst string) error {
|
||||||
log.Debug("Updating database metadata...")
|
log.Debug("Updating database metadata...")
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,12 @@ import (
|
|||||||
// cert: cert.pem
|
// cert: cert.pem
|
||||||
// key: key.pem
|
// key: key.pem
|
||||||
var (
|
var (
|
||||||
|
// Deprecated
|
||||||
ClearCacheFlag = Flag[bool]{
|
ClearCacheFlag = Flag[bool]{
|
||||||
Name: "clear-cache",
|
Name: "clear-cache",
|
||||||
ConfigName: "cache.clear",
|
ConfigName: "cache.clear",
|
||||||
Usage: "clear image caches without scanning",
|
Usage: "clear image caches without scanning",
|
||||||
|
Removed: `Use "trivy clean --scan-cache" instead`,
|
||||||
}
|
}
|
||||||
CacheBackendFlag = Flag[string]{
|
CacheBackendFlag = Flag[string]{
|
||||||
Name: "cache-backend",
|
Name: "cache-backend",
|
||||||
|
|||||||
84
pkg/flag/clean_flags.go
Normal file
84
pkg/flag/clean_flags.go
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package flag
|
||||||
|
|
||||||
|
var (
|
||||||
|
CleanAll = Flag[bool]{
|
||||||
|
Name: "all",
|
||||||
|
Shorthand: "a",
|
||||||
|
ConfigName: "clean.all",
|
||||||
|
Usage: "remove all caches",
|
||||||
|
}
|
||||||
|
CleanScanCache = Flag[bool]{
|
||||||
|
Name: "scan-cache",
|
||||||
|
ConfigName: "clean.scan-cache",
|
||||||
|
Usage: "remove scan cache (container and VM image analysis results)",
|
||||||
|
}
|
||||||
|
CleanVulnerabilityDB = Flag[bool]{
|
||||||
|
Name: "vuln-db",
|
||||||
|
ConfigName: "clean.vuln-db",
|
||||||
|
Usage: "remove vulnerability database",
|
||||||
|
}
|
||||||
|
CleanJavaDB = Flag[bool]{
|
||||||
|
Name: "java-db",
|
||||||
|
ConfigName: "clean.java-db",
|
||||||
|
Usage: "remove Java database",
|
||||||
|
}
|
||||||
|
CleanChecksBundle = Flag[bool]{
|
||||||
|
Name: "checks-bundle",
|
||||||
|
ConfigName: "clean.checks-bundle",
|
||||||
|
Usage: "remove checks bundle",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type CleanFlagGroup struct {
|
||||||
|
CleanAll *Flag[bool]
|
||||||
|
CleanVulnerabilityDB *Flag[bool]
|
||||||
|
CleanJavaDB *Flag[bool]
|
||||||
|
CleanChecksBundle *Flag[bool]
|
||||||
|
CleanScanCache *Flag[bool]
|
||||||
|
}
|
||||||
|
|
||||||
|
type CleanOptions struct {
|
||||||
|
CleanAll bool
|
||||||
|
CleanVulnerabilityDB bool
|
||||||
|
CleanJavaDB bool
|
||||||
|
CleanChecksBundle bool
|
||||||
|
CleanScanCache bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCleanFlagGroup() *CleanFlagGroup {
|
||||||
|
return &CleanFlagGroup{
|
||||||
|
CleanAll: CleanAll.Clone(),
|
||||||
|
CleanVulnerabilityDB: CleanVulnerabilityDB.Clone(),
|
||||||
|
CleanJavaDB: CleanJavaDB.Clone(),
|
||||||
|
CleanChecksBundle: CleanChecksBundle.Clone(),
|
||||||
|
CleanScanCache: CleanScanCache.Clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fg *CleanFlagGroup) Name() string {
|
||||||
|
return "Clean"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fg *CleanFlagGroup) Flags() []Flagger {
|
||||||
|
return []Flagger{
|
||||||
|
fg.CleanAll,
|
||||||
|
fg.CleanVulnerabilityDB,
|
||||||
|
fg.CleanJavaDB,
|
||||||
|
fg.CleanChecksBundle,
|
||||||
|
fg.CleanScanCache,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fg *CleanFlagGroup) ToOptions() (CleanOptions, error) {
|
||||||
|
if err := parseFlags(fg); err != nil {
|
||||||
|
return CleanOptions{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return CleanOptions{
|
||||||
|
CleanAll: fg.CleanAll.Value(),
|
||||||
|
CleanVulnerabilityDB: fg.CleanVulnerabilityDB.Value(),
|
||||||
|
CleanJavaDB: fg.CleanJavaDB.Value(),
|
||||||
|
CleanChecksBundle: fg.CleanChecksBundle.Value(),
|
||||||
|
CleanScanCache: fg.CleanScanCache.Value(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -12,10 +12,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// Deprecated
|
||||||
ResetFlag = Flag[bool]{
|
ResetFlag = Flag[bool]{
|
||||||
Name: "reset",
|
Name: "reset",
|
||||||
ConfigName: "reset",
|
ConfigName: "reset",
|
||||||
Usage: "remove all caches and database",
|
Usage: "remove all caches and database",
|
||||||
|
Removed: `Use "trivy clean --all" instead.`,
|
||||||
}
|
}
|
||||||
DownloadDBOnlyFlag = Flag[bool]{
|
DownloadDBOnlyFlag = Flag[bool]{
|
||||||
Name: "download-db-only",
|
Name: "download-db-only",
|
||||||
@@ -64,7 +66,7 @@ var (
|
|||||||
Name: "light",
|
Name: "light",
|
||||||
ConfigName: "db.light",
|
ConfigName: "db.light",
|
||||||
Usage: "deprecated",
|
Usage: "deprecated",
|
||||||
Deprecated: true,
|
Deprecated: `This flag is ignored.`,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -90,7 +92,6 @@ type DBOptions struct {
|
|||||||
NoProgress bool
|
NoProgress bool
|
||||||
DBRepository name.Reference
|
DBRepository name.Reference
|
||||||
JavaDBRepository name.Reference
|
JavaDBRepository name.Reference
|
||||||
Light bool // deprecated
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDBFlagGroup returns a default DBFlagGroup
|
// NewDBFlagGroup returns a default DBFlagGroup
|
||||||
@@ -135,7 +136,6 @@ func (f *DBFlagGroup) ToOptions() (DBOptions, error) {
|
|||||||
skipJavaDBUpdate := f.SkipJavaDBUpdate.Value()
|
skipJavaDBUpdate := f.SkipJavaDBUpdate.Value()
|
||||||
downloadDBOnly := f.DownloadDBOnly.Value()
|
downloadDBOnly := f.DownloadDBOnly.Value()
|
||||||
downloadJavaDBOnly := f.DownloadJavaDBOnly.Value()
|
downloadJavaDBOnly := f.DownloadJavaDBOnly.Value()
|
||||||
light := f.Light.Value()
|
|
||||||
|
|
||||||
if downloadDBOnly && skipDBUpdate {
|
if downloadDBOnly && skipDBUpdate {
|
||||||
return DBOptions{}, xerrors.New("--skip-db-update and --download-db-only options can not be specified both")
|
return DBOptions{}, xerrors.New("--skip-db-update and --download-db-only options can not be specified both")
|
||||||
@@ -143,9 +143,6 @@ func (f *DBFlagGroup) ToOptions() (DBOptions, error) {
|
|||||||
if downloadJavaDBOnly && skipJavaDBUpdate {
|
if downloadJavaDBOnly && skipJavaDBUpdate {
|
||||||
return DBOptions{}, xerrors.New("--skip-java-db-update and --download-java-db-only options can not be specified both")
|
return DBOptions{}, xerrors.New("--skip-java-db-update and --download-java-db-only options can not be specified both")
|
||||||
}
|
}
|
||||||
if light {
|
|
||||||
log.Warn("'--light' option is deprecated and will be removed. See also: https://github.com/aquasecurity/trivy/discussions/1649")
|
|
||||||
}
|
|
||||||
|
|
||||||
var dbRepository, javaDBRepository name.Reference
|
var dbRepository, javaDBRepository name.Reference
|
||||||
var err error
|
var err error
|
||||||
@@ -179,7 +176,6 @@ func (f *DBFlagGroup) ToOptions() (DBOptions, error) {
|
|||||||
SkipDBUpdate: skipDBUpdate,
|
SkipDBUpdate: skipDBUpdate,
|
||||||
DownloadJavaDBOnly: downloadJavaDBOnly,
|
DownloadJavaDBOnly: downloadJavaDBOnly,
|
||||||
SkipJavaDBUpdate: skipJavaDBUpdate,
|
SkipJavaDBUpdate: skipJavaDBUpdate,
|
||||||
Light: light,
|
|
||||||
NoProgress: f.NoProgress.Value(),
|
NoProgress: f.NoProgress.Value(),
|
||||||
DBRepository: dbRepository,
|
DBRepository: dbRepository,
|
||||||
JavaDBRepository: javaDBRepository,
|
JavaDBRepository: javaDBRepository,
|
||||||
|
|||||||
@@ -43,23 +43,6 @@ func TestDBFlagGroup_ToOptions(t *testing.T) {
|
|||||||
},
|
},
|
||||||
assertion: require.NoError,
|
assertion: require.NoError,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "light",
|
|
||||||
fields: fields{
|
|
||||||
Light: true,
|
|
||||||
DBRepository: "ghcr.io/aquasecurity/trivy-db",
|
|
||||||
JavaDBRepository: "ghcr.io/aquasecurity/trivy-java-db",
|
|
||||||
},
|
|
||||||
want: flag.DBOptions{
|
|
||||||
Light: true,
|
|
||||||
DBRepository: name.Tag{}, // All fields are unexported
|
|
||||||
JavaDBRepository: name.Tag{}, // All fields are unexported
|
|
||||||
},
|
|
||||||
wantLogs: []string{
|
|
||||||
"'--light' option is deprecated and will be removed. See also: https://github.com/aquasecurity/trivy/discussions/1649",
|
|
||||||
},
|
|
||||||
assertion: require.NoError,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "sad",
|
name: "sad",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -88,7 +71,6 @@ func TestDBFlagGroup_ToOptions(t *testing.T) {
|
|||||||
|
|
||||||
viper.Set(flag.SkipDBUpdateFlag.ConfigName, tt.fields.SkipDBUpdate)
|
viper.Set(flag.SkipDBUpdateFlag.ConfigName, tt.fields.SkipDBUpdate)
|
||||||
viper.Set(flag.DownloadDBOnlyFlag.ConfigName, tt.fields.DownloadDBOnly)
|
viper.Set(flag.DownloadDBOnlyFlag.ConfigName, tt.fields.DownloadDBOnly)
|
||||||
viper.Set(flag.LightFlag.ConfigName, tt.fields.Light)
|
|
||||||
viper.Set(flag.DBRepositoryFlag.ConfigName, tt.fields.DBRepository)
|
viper.Set(flag.DBRepositoryFlag.ConfigName, tt.fields.DBRepository)
|
||||||
viper.Set(flag.JavaDBRepositoryFlag.ConfigName, tt.fields.JavaDBRepository)
|
viper.Set(flag.JavaDBRepositoryFlag.ConfigName, tt.fields.JavaDBRepository)
|
||||||
|
|
||||||
@@ -96,7 +78,6 @@ func TestDBFlagGroup_ToOptions(t *testing.T) {
|
|||||||
f := &flag.DBFlagGroup{
|
f := &flag.DBFlagGroup{
|
||||||
DownloadDBOnly: flag.DownloadDBOnlyFlag.Clone(),
|
DownloadDBOnly: flag.DownloadDBOnlyFlag.Clone(),
|
||||||
SkipDBUpdate: flag.SkipDBUpdateFlag.Clone(),
|
SkipDBUpdate: flag.SkipDBUpdateFlag.Clone(),
|
||||||
Light: flag.LightFlag.Clone(),
|
|
||||||
DBRepository: flag.DBRepositoryFlag.Clone(),
|
DBRepository: flag.DBRepositoryFlag.Clone(),
|
||||||
JavaDBRepository: flag.JavaDBRepositoryFlag.Clone(),
|
JavaDBRepository: flag.JavaDBRepositoryFlag.Clone(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ import (
|
|||||||
// config-policy: "custom-policy/policy"
|
// config-policy: "custom-policy/policy"
|
||||||
// policy-namespaces: "user"
|
// policy-namespaces: "user"
|
||||||
var (
|
var (
|
||||||
|
// Deprecated
|
||||||
ResetChecksBundleFlag = Flag[bool]{
|
ResetChecksBundleFlag = Flag[bool]{
|
||||||
Name: "reset-checks-bundle",
|
Name: "reset-checks-bundle",
|
||||||
ConfigName: "misconfiguration.reset-checks-bundle",
|
ConfigName: "misconfiguration.reset-checks-bundle",
|
||||||
Usage: "remove checks bundle",
|
Usage: "remove checks bundle",
|
||||||
|
Removed: `Use "trivy clean --checks-bundle" instead`,
|
||||||
Aliases: []Alias{
|
Aliases: []Alias{
|
||||||
{
|
{
|
||||||
Name: "reset-policy-bundle",
|
Name: "reset-policy-bundle",
|
||||||
|
|||||||
@@ -59,7 +59,10 @@ type Flag[T FlagType] struct {
|
|||||||
Persistent bool
|
Persistent bool
|
||||||
|
|
||||||
// Deprecated represents if the flag is deprecated
|
// Deprecated represents if the flag is deprecated
|
||||||
Deprecated bool
|
Deprecated string
|
||||||
|
|
||||||
|
// Removed represents if the flag is removed and no longer works
|
||||||
|
Removed string
|
||||||
|
|
||||||
// Aliases represents aliases
|
// Aliases represents aliases
|
||||||
Aliases []Alias
|
Aliases []Alias
|
||||||
@@ -107,6 +110,14 @@ func (f *Flag[T]) Parse() error {
|
|||||||
return xerrors.Errorf(`invalid argument "%s" for "--%s" flag: must be one of %q`, value, f.Name, f.Values)
|
return xerrors.Errorf(`invalid argument "%s" for "--%s" flag: must be one of %q`, value, f.Name, f.Values)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.Deprecated != "" && f.isSet() {
|
||||||
|
log.Warnf(`"--%s" is deprecated. %s`, f.Name, f.Deprecated)
|
||||||
|
}
|
||||||
|
if f.Removed != "" && f.isSet() {
|
||||||
|
log.Errorf(`"--%s" was removed. %s`, f.Name, f.Removed)
|
||||||
|
return xerrors.Errorf(`removed flag ("--%s")`, f.Name)
|
||||||
|
}
|
||||||
|
|
||||||
f.value = value
|
f.value = value
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -229,8 +240,8 @@ func (f *Flag[T]) Add(cmd *cobra.Command) {
|
|||||||
flags.Float64P(f.Name, f.Shorthand, v, f.Usage)
|
flags.Float64P(f.Name, f.Shorthand, v, f.Usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Deprecated {
|
if f.Deprecated != "" || f.Removed != "" {
|
||||||
flags.MarkHidden(f.Name) // nolint: gosec
|
_ = flags.MarkHidden(f.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,6 +312,7 @@ type Flags struct {
|
|||||||
GlobalFlagGroup *GlobalFlagGroup
|
GlobalFlagGroup *GlobalFlagGroup
|
||||||
AWSFlagGroup *AWSFlagGroup
|
AWSFlagGroup *AWSFlagGroup
|
||||||
CacheFlagGroup *CacheFlagGroup
|
CacheFlagGroup *CacheFlagGroup
|
||||||
|
CleanFlagGroup *CleanFlagGroup
|
||||||
DBFlagGroup *DBFlagGroup
|
DBFlagGroup *DBFlagGroup
|
||||||
ImageFlagGroup *ImageFlagGroup
|
ImageFlagGroup *ImageFlagGroup
|
||||||
K8sFlagGroup *K8sFlagGroup
|
K8sFlagGroup *K8sFlagGroup
|
||||||
@@ -323,6 +335,7 @@ type Options struct {
|
|||||||
GlobalOptions
|
GlobalOptions
|
||||||
AWSOptions
|
AWSOptions
|
||||||
CacheOptions
|
CacheOptions
|
||||||
|
CleanOptions
|
||||||
DBOptions
|
DBOptions
|
||||||
ImageOptions
|
ImageOptions
|
||||||
K8sOptions
|
K8sOptions
|
||||||
@@ -495,6 +508,9 @@ func (f *Flags) groups() []FlagGroup {
|
|||||||
if f.CacheFlagGroup != nil {
|
if f.CacheFlagGroup != nil {
|
||||||
groups = append(groups, f.CacheFlagGroup)
|
groups = append(groups, f.CacheFlagGroup)
|
||||||
}
|
}
|
||||||
|
if f.CleanFlagGroup != nil {
|
||||||
|
groups = append(groups, f.CleanFlagGroup)
|
||||||
|
}
|
||||||
if f.DBFlagGroup != nil {
|
if f.DBFlagGroup != nil {
|
||||||
groups = append(groups, f.DBFlagGroup)
|
groups = append(groups, f.DBFlagGroup)
|
||||||
}
|
}
|
||||||
@@ -621,6 +637,13 @@ func (f *Flags) ToOptions(args []string) (Options, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.CleanFlagGroup != nil {
|
||||||
|
opts.CleanOptions, err = f.CleanFlagGroup.ToOptions()
|
||||||
|
if err != nil {
|
||||||
|
return Options{}, xerrors.Errorf("clean flag error: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if f.DBFlagGroup != nil {
|
if f.DBFlagGroup != nil {
|
||||||
opts.DBOptions, err = f.DBFlagGroup.ToOptions()
|
opts.DBOptions, err = f.DBFlagGroup.ToOptions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,23 +1,17 @@
|
|||||||
package flag
|
package flag
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy/pkg/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ArtifactTypeFlag = Flag[string]{
|
ArtifactTypeFlag = Flag[string]{
|
||||||
Name: "artifact-type",
|
Name: "artifact-type",
|
||||||
ConfigName: "sbom.artifact-type",
|
ConfigName: "sbom.artifact-type",
|
||||||
Usage: "deprecated",
|
Usage: "deprecated",
|
||||||
Deprecated: true,
|
Removed: `Use 'trivy image' or other subcommands. See also https://github.com/aquasecurity/trivy/discussions/2407`,
|
||||||
}
|
}
|
||||||
SBOMFormatFlag = Flag[string]{
|
SBOMFormatFlag = Flag[string]{
|
||||||
Name: "sbom-format",
|
Name: "sbom-format",
|
||||||
ConfigName: "sbom.format",
|
ConfigName: "sbom.format",
|
||||||
Usage: "deprecated",
|
Usage: "deprecated",
|
||||||
Deprecated: true,
|
Removed: `Use 'trivy image' or other subcommands. See also https://github.com/aquasecurity/trivy/discussions/2407`,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,8 +20,7 @@ type SBOMFlagGroup struct {
|
|||||||
SBOMFormat *Flag[string] // deprecated
|
SBOMFormat *Flag[string] // deprecated
|
||||||
}
|
}
|
||||||
|
|
||||||
type SBOMOptions struct {
|
type SBOMOptions struct{}
|
||||||
}
|
|
||||||
|
|
||||||
func NewSBOMFlagGroup() *SBOMFlagGroup {
|
func NewSBOMFlagGroup() *SBOMFlagGroup {
|
||||||
return &SBOMFlagGroup{
|
return &SBOMFlagGroup{
|
||||||
@@ -52,14 +45,5 @@ func (f *SBOMFlagGroup) ToOptions() (SBOMOptions, error) {
|
|||||||
return SBOMOptions{}, err
|
return SBOMOptions{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
artifactType := f.ArtifactType.Value()
|
|
||||||
sbomFormat := f.SBOMFormat.Value()
|
|
||||||
|
|
||||||
if artifactType != "" || sbomFormat != "" {
|
|
||||||
log.Error("'trivy sbom' is now for scanning SBOM. " +
|
|
||||||
"See https://github.com/aquasecurity/trivy/discussions/2407 for the detail")
|
|
||||||
return SBOMOptions{}, xerrors.New("'--artifact-type' and '--sbom-format' are no longer available")
|
|
||||||
}
|
|
||||||
|
|
||||||
return SBOMOptions{}, nil
|
return SBOMOptions{}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ var (
|
|||||||
ConfigName: "scan.slow",
|
ConfigName: "scan.slow",
|
||||||
Default: false,
|
Default: false,
|
||||||
Usage: "scan over time with lower CPU and memory utilization",
|
Usage: "scan over time with lower CPU and memory utilization",
|
||||||
Deprecated: true,
|
Deprecated: `Use "--parallel 1" instead.`,
|
||||||
}
|
}
|
||||||
ParallelFlag = Flag[int]{
|
ParallelFlag = Flag[int]{
|
||||||
Name: "parallel",
|
Name: "parallel",
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func (u *Updater) Update() error {
|
|||||||
return xerrors.Errorf("Java DB metadata update error: %w", err)
|
return xerrors.Errorf("Java DB metadata update error: %w", err)
|
||||||
}
|
}
|
||||||
log.Info("The Java DB is cached for 3 days. If you want to update the database more frequently, " +
|
log.Info("The Java DB is cached for 3 days. If you want to update the database more frequently, " +
|
||||||
"the '--reset' flag clears the DB cache.")
|
`"trivy clean --java-db" command clears the DB cache.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -88,7 +88,7 @@ func (u *Updater) Update() error {
|
|||||||
func Init(cacheDir string, javaDBRepository name.Reference, skip, quiet bool, registryOption ftypes.RegistryOptions) {
|
func Init(cacheDir string, javaDBRepository name.Reference, skip, quiet bool, registryOption ftypes.RegistryOptions) {
|
||||||
updater = &Updater{
|
updater = &Updater{
|
||||||
repo: javaDBRepository,
|
repo: javaDBRepository,
|
||||||
dbDir: filepath.Join(cacheDir, "java-db"),
|
dbDir: dbDir(cacheDir),
|
||||||
skip: skip,
|
skip: skip,
|
||||||
quiet: quiet,
|
quiet: quiet,
|
||||||
registryOption: registryOption,
|
registryOption: registryOption,
|
||||||
@@ -107,6 +107,14 @@ func Update() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Clear(ctx context.Context, cacheDir string) error {
|
||||||
|
return os.RemoveAll(dbDir(cacheDir))
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbDir(cacheDir string) string {
|
||||||
|
return filepath.Join(cacheDir, "java-db")
|
||||||
|
}
|
||||||
|
|
||||||
type DB struct {
|
type DB struct {
|
||||||
driver db.DB
|
driver db.DB
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,7 +237,6 @@ func (c *Client) GetMetadata() (*Metadata, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Clear() error {
|
func (c *Client) Clear() error {
|
||||||
log.Info("Removing check bundle...")
|
|
||||||
if err := os.RemoveAll(c.policyDir); err != nil {
|
if err := os.RemoveAll(c.policyDir); err != nil {
|
||||||
return xerrors.Errorf("failed to remove check bundle: %w", err)
|
return xerrors.Errorf("failed to remove check bundle: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user