-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathdistributionscanner.go
110 lines (96 loc) · 2.79 KB
/
distributionscanner.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
package debian
import (
"bytes"
"context"
"regexp"
"runtime/trace"
"github.com/quay/zlog"
"github.com/quay/claircore"
"github.com/quay/claircore/internal/indexer"
)
const (
scannerName = "debian"
scannerVersion = "v0.0.2"
scannerKind = "distribution"
)
type debianRegex struct {
release Release
regexp *regexp.Regexp
}
var debianRegexes = []debianRegex{
{
release: Bullseye,
regexp: regexp.MustCompile(`(?is)debian gnu/linux 11`),
},
{
release: Buster,
regexp: regexp.MustCompile(`(?is)debian gnu/linux 10`),
},
{
release: Jessie,
regexp: regexp.MustCompile(`(?is)debian gnu/linux 8`),
},
{
release: Stretch,
regexp: regexp.MustCompile(`(?is)debian gnu/linux 9`),
},
{
release: Wheezy,
regexp: regexp.MustCompile(`(?is)debian gnu/linux 7`),
},
}
const (
osReleasePath = `etc/os-release`
issuePath = `etc/issue`
)
var (
_ indexer.DistributionScanner = (*DistributionScanner)(nil)
_ indexer.VersionedScanner = (*DistributionScanner)(nil)
)
// DistributionScanner attempts to discover if a layer
// displays characteristics of a Debian distribution
type DistributionScanner struct{}
// Name implements scanner.VersionedScanner.
func (*DistributionScanner) Name() string { return scannerName }
// Version implements scanner.VersionedScanner.
func (*DistributionScanner) Version() string { return scannerVersion }
// Kind implements scanner.VersionedScanner.
func (*DistributionScanner) Kind() string { return scannerKind }
// Scan will inspect the layer for an os-release or lsb-release file
// and perform a regex match for keywords indicating the associated Debian release
//
// If neither file is found a (nil,nil) is returned.
// If the files are found but all regexp fail to match an empty slice is returned.
func (ds *DistributionScanner) Scan(ctx context.Context, l *claircore.Layer) ([]*claircore.Distribution, error) {
defer trace.StartRegion(ctx, "Scanner.Scan").End()
ctx = zlog.ContextWithValues(ctx,
"component", "debian/DistributionScanner.Scan",
"version", ds.Version(),
"layer", l.Hash.String())
zlog.Debug(ctx).Msg("start")
defer zlog.Debug(ctx).Msg("done")
files, err := l.Files(osReleasePath, issuePath)
if err != nil {
zlog.Debug(ctx).Msg("didn't find an os-release or issue file")
return nil, nil
}
for _, buff := range files {
dist := ds.parse(buff)
if dist != nil {
return []*claircore.Distribution{dist}, nil
}
}
return []*claircore.Distribution{}, nil
}
// parse attempts to match all Debian release regexp and returns the associated
// distribution if it exists.
//
// separated into its own method to aid testing.
func (ds *DistributionScanner) parse(buff *bytes.Buffer) *claircore.Distribution {
for _, ur := range debianRegexes {
if ur.regexp.Match(buff.Bytes()) {
return releaseToDist(ur.release)
}
}
return nil
}