-
Notifications
You must be signed in to change notification settings - Fork 147
/
sbom.go
112 lines (95 loc) · 2.82 KB
/
sbom.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2021-Present The Zarf Authors
// Package layout contains functions for interacting with Zarf's package layout on disk.
package layout
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"github.com/defenseunicorns/pkg/helpers"
"github.com/mholt/archiver/v3"
)
// ComponentSBOM contains paths for a component's SBOM.
type ComponentSBOM struct {
Files []string
Component *ComponentPaths
}
// SBOMs contains paths for SBOMs.
type SBOMs struct {
Path string
}
// Unarchive unarchives the package's SBOMs.
func (s *SBOMs) Unarchive() (err error) {
if s.Path == "" || helpers.InvalidPath(s.Path) {
return &fs.PathError{
Op: "stat",
Path: s.Path,
Err: fs.ErrNotExist,
}
}
if helpers.IsDir(s.Path) {
return nil
}
tb := s.Path
dir := filepath.Join(filepath.Dir(tb), SBOMDir)
if err := archiver.Unarchive(tb, dir); err != nil {
return err
}
s.Path = dir
return os.Remove(tb)
}
// Archive archives the package's SBOMs.
func (s *SBOMs) Archive() (err error) {
if s.Path == "" || helpers.InvalidPath(s.Path) {
return &fs.PathError{
Op: "stat",
Path: s.Path,
Err: fs.ErrNotExist,
}
}
if !helpers.IsDir(s.Path) {
return nil
}
dir := s.Path
tb := filepath.Join(filepath.Dir(dir), SBOMTar)
if err := helpers.CreateReproducibleTarballFromDir(dir, "", tb); err != nil {
return err
}
s.Path = tb
return os.RemoveAll(dir)
}
// StageSBOMViewFiles copies SBOM viewer HTML files to the Zarf SBOM directory.
func (s *SBOMs) StageSBOMViewFiles() (sbomViewFiles, warnings []string, err error) {
if s.IsTarball() {
return nil, nil, fmt.Errorf("unable to process the SBOM files for this package: %s is a tarball", s.Path)
}
// If SBOMs were loaded, temporarily place them in the deploy directory
if !helpers.InvalidPath(s.Path) {
sbomViewFiles, err = filepath.Glob(filepath.Join(s.Path, "sbom-viewer-*"))
if err != nil {
return nil, nil, err
}
if _, err := s.OutputSBOMFiles(SBOMDir, ""); err != nil {
// Don't stop the deployment, let the user decide if they want to continue the deployment
warning := fmt.Sprintf("Unable to process the SBOM files for this package: %s", err.Error())
warnings = append(warnings, warning)
}
}
return sbomViewFiles, warnings, nil
}
// OutputSBOMFiles outputs SBOM files into outputDir.
func (s *SBOMs) OutputSBOMFiles(outputDir, packageName string) (string, error) {
packagePath := filepath.Join(outputDir, packageName)
if err := os.RemoveAll(packagePath); err != nil {
return "", err
}
if err := helpers.CreateDirectory(packagePath, 0700); err != nil {
return "", err
}
return packagePath, helpers.CreatePathAndCopy(s.Path, packagePath)
}
// IsTarball returns true if the SBOMs are a tarball.
func (s SBOMs) IsTarball() bool {
return !helpers.IsDir(s.Path) && filepath.Ext(s.Path) == ".tar"
}