mirror of
https://github.com/anchore/syft.git
synced 2026-02-13 11:06:43 +01:00
Initial README (#120)
* initial readme + logging and output fixes to support descriptions * minor tweaks to README descriptions * simplify phrasing Co-authored-by: Alfredo Deza <adeza@anchore.com> * add comment for example gif Co-authored-by: Alfredo Deza <adeza@anchore.com> * spelling fix Co-authored-by: Alfredo Deza <adeza@anchore.com> * update phrasing Co-authored-by: Alfredo Deza <adeza@anchore.com> * simplify TODO note Co-authored-by: Alfredo Deza <adeza@anchore.com> * grammar fix Co-authored-by: Alfredo Deza <adeza@anchore.com> * phrase fix Co-authored-by: Alfredo Deza <adeza@anchore.com> * rm readme bash block indicators * clarify config examples are default values * rm value Co-authored-by: Alfredo Deza <adeza@anchore.com> Co-authored-by: Alfredo Deza <adeza@anchore.com>
This commit is contained in:
parent
8fe59c6f1a
commit
2560266e38
92
README.md
92
README.md
@ -1,3 +1,93 @@
|
|||||||
# syft
|
# syft
|
||||||
|
|
||||||
A CLI tool and go library for generating a Software Bill of Materials from container images and filesystems.
|
A CLI tool and go library for generating a Software Bill of Materials (SBOM) from container images and filesystems.
|
||||||
|
|
||||||
|
[//]: # (TODO: add example gif here)
|
||||||
|
|
||||||
|
**Features**
|
||||||
|
- Catalog container images and filesystems to discover packages and libraries.
|
||||||
|
- Supports packages and libraries from various ecosystems (APK, DEB, RPM, Ruby Bundles, Python Wheel/Egg/requirements.txt, JavaScript NPM/Yarn, Java JAR/EAR/WAR, Jenkins plugins JPI/HPI, Go modules)
|
||||||
|
- OS distribution detection (supports alpine, busybox, centos/redhat, debian/ubuntu flavored distributions)
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
To generate an SBOM for an image:
|
||||||
|
```
|
||||||
|
syft <image>
|
||||||
|
```
|
||||||
|
|
||||||
|
The above output includes only software that is visible in the container (i.e., the squashed representation of the image).
|
||||||
|
To include software from all image layers in the SBOM, regardless of its presence in the final image, provide `--scope all-layers`:
|
||||||
|
|
||||||
|
```
|
||||||
|
syft <image> --scope all-layers
|
||||||
|
```
|
||||||
|
|
||||||
|
Syft can generate a SBOM from a variety of sources:
|
||||||
|
```
|
||||||
|
# catalog a docker image tar (from the result of "docker image save ... -o image.tar" command)
|
||||||
|
syft docker-archive://path/to/image.tar
|
||||||
|
|
||||||
|
# catalog a directory
|
||||||
|
syft dir://path/to/dir
|
||||||
|
```
|
||||||
|
|
||||||
|
By default Syft shows a summary table, however, more detailed `text` and `json` formats are also available.
|
||||||
|
```
|
||||||
|
syft <image> -o json
|
||||||
|
syft <image> -o text
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
*NOTE: This tool hasn't been released yet, so these installation methods work right now*
|
||||||
|
|
||||||
|
**Recommended**
|
||||||
|
```bash
|
||||||
|
# install the latest version to /usr/local/bin
|
||||||
|
curl -sSfL https://raw.githubusercontent.com/anchore/syft/master/install.sh | sh -s -- -b /usr/local/bin
|
||||||
|
|
||||||
|
# install a specific version into a specific dir
|
||||||
|
curl -sSfL https://raw.githubusercontent.com/anchore/syft/master/install.sh | sh -s <RELEASE_VERSION> -b <SOME_BIN_PATH>
|
||||||
|
```
|
||||||
|
|
||||||
|
**macOS**
|
||||||
|
```bash
|
||||||
|
brew tap anchore/syft
|
||||||
|
brew install syft
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Configuration search paths:
|
||||||
|
|
||||||
|
- `.syft.yaml`
|
||||||
|
- `.syft/config.yaml`
|
||||||
|
- `~/.syft.yaml`
|
||||||
|
- `<XDG_CONFIG_HOME>/syft/config.yaml`
|
||||||
|
|
||||||
|
Configuration options (example values are the default):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# same as -o ; the output format of the SBOM report (options: table, text, json)
|
||||||
|
output: "table"
|
||||||
|
|
||||||
|
# same as -s ; the search space to look for packages (options: all-layers, squashed)
|
||||||
|
scope: "squashed"
|
||||||
|
|
||||||
|
# same as -q ; suppress all output (except for the SBOM report)
|
||||||
|
quiet: false
|
||||||
|
|
||||||
|
log:
|
||||||
|
# use structured logging
|
||||||
|
structured: false
|
||||||
|
|
||||||
|
# the log level; note: detailed logging suppress the ETUI
|
||||||
|
level: "error"
|
||||||
|
|
||||||
|
# location to write the log file (default is not to have a log file)
|
||||||
|
file: ""
|
||||||
|
|
||||||
|
# enable/disable checking for application updates on startup
|
||||||
|
check-for-app-update: true
|
||||||
|
```
|
||||||
|
|||||||
@ -49,7 +49,7 @@ func setGlobalCliOptions() {
|
|||||||
// scan options
|
// scan options
|
||||||
flag := "scope"
|
flag := "scope"
|
||||||
rootCmd.Flags().StringP(
|
rootCmd.Flags().StringP(
|
||||||
"scope", "s", scope.AllLayersScope.String(),
|
"scope", "s", scope.SquashedScope.String(),
|
||||||
fmt.Sprintf("selection of layers to catalog, options=%v", scope.Options))
|
fmt.Sprintf("selection of layers to catalog, options=%v", scope.Options))
|
||||||
if err := viper.BindPFlag(flag, rootCmd.Flags().Lookup(flag)); err != nil {
|
if err := viper.BindPFlag(flag, rootCmd.Flags().Lookup(flag)); err != nil {
|
||||||
fmt.Printf("unable to bind flag '%s': %+v", flag, err)
|
fmt.Printf("unable to bind flag '%s': %+v", flag, err)
|
||||||
|
|||||||
@ -21,6 +21,7 @@ type LogrusConfig struct {
|
|||||||
type LogrusLogger struct {
|
type LogrusLogger struct {
|
||||||
Config LogrusConfig
|
Config LogrusConfig
|
||||||
Logger *logrus.Logger
|
Logger *logrus.Logger
|
||||||
|
Output io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogrusNestedLogger struct {
|
type LogrusNestedLogger struct {
|
||||||
@ -71,6 +72,7 @@ func NewLogrusLogger(cfg LogrusConfig) *LogrusLogger {
|
|||||||
return &LogrusLogger{
|
return &LogrusLogger{
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
Logger: appLogger,
|
Logger: appLogger,
|
||||||
|
Output: output,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,12 @@ func OutputToEphemeralTUI(workerErrs <-chan error, subscription *partybus.Subscr
|
|||||||
fr.Close()
|
fr.Close()
|
||||||
frame.Close()
|
frame.Close()
|
||||||
// flush any errors to the screen before the report
|
// flush any errors to the screen before the report
|
||||||
fmt.Fprint(output, logBuffer.String())
|
logWrapper, ok := log.Log.(*logger.LogrusLogger)
|
||||||
|
if ok {
|
||||||
|
fmt.Fprint(logWrapper.Output, logBuffer.String())
|
||||||
|
} else {
|
||||||
|
fmt.Fprint(output, logBuffer.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
logWrapper, ok := log.Log.(*logger.LogrusLogger)
|
logWrapper, ok := log.Log.(*logger.LogrusLogger)
|
||||||
if ok {
|
if ok {
|
||||||
@ -107,7 +112,12 @@ eventLoop:
|
|||||||
isClosed = true
|
isClosed = true
|
||||||
|
|
||||||
// flush any errors to the screen before the report
|
// flush any errors to the screen before the report
|
||||||
fmt.Fprint(output, logBuffer.String())
|
logWrapper, ok := log.Log.(*logger.LogrusLogger)
|
||||||
|
if ok {
|
||||||
|
fmt.Fprint(logWrapper.Output, logBuffer.String())
|
||||||
|
} else {
|
||||||
|
fmt.Fprint(output, logBuffer.String())
|
||||||
|
}
|
||||||
|
|
||||||
if err := common.CatalogerFinishedHandler(e); err != nil {
|
if err := common.CatalogerFinishedHandler(e); err != nil {
|
||||||
log.Errorf("unable to show %s event: %+v", e.Type, err)
|
log.Errorf("unable to show %s event: %+v", e.Type, err)
|
||||||
|
|||||||
@ -7,9 +7,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/mapstructure"
|
|
||||||
|
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseApkDB(_ string, reader io.Reader) ([]pkg.Package, error) {
|
func parseApkDB(_ string, reader io.Reader) ([]pkg.Package, error) {
|
||||||
|
|||||||
@ -25,7 +25,7 @@ func ParseOption(userStr string) Option {
|
|||||||
switch strings.ToLower(userStr) {
|
switch strings.ToLower(userStr) {
|
||||||
case strings.ToLower(SquashedScope.String()):
|
case strings.ToLower(SquashedScope.String()):
|
||||||
return SquashedScope
|
return SquashedScope
|
||||||
case strings.ToLower(AllLayersScope.String()):
|
case "all-layers", strings.ToLower(AllLayersScope.String()):
|
||||||
return AllLayersScope
|
return AllLayersScope
|
||||||
}
|
}
|
||||||
return UnknownScope
|
return UnknownScope
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user