forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
resolvers.go
127 lines (110 loc) · 3.54 KB
/
resolvers.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package prune
import (
"sort"
"k8s.io/apimachinery/pkg/util/sets"
buildapi "github.com/openshift/origin/pkg/build/apis/build"
)
// Resolver knows how to resolve the set of candidate objects to prune
type Resolver interface {
Resolve() ([]*buildapi.Build, error)
}
// mergeResolver merges the set of results from multiple resolvers
type mergeResolver struct {
resolvers []Resolver
}
func (m *mergeResolver) Resolve() ([]*buildapi.Build, error) {
results := []*buildapi.Build{}
for _, resolver := range m.resolvers {
builds, err := resolver.Resolve()
if err != nil {
return nil, err
}
results = append(results, builds...)
}
return results, nil
}
// NewOrphanBuildResolver returns a Resolver that matches Build objects with no associated BuildConfig and has a BuildPhase in filter
func NewOrphanBuildResolver(dataSet DataSet, BuildPhaseFilter []buildapi.BuildPhase) Resolver {
filter := sets.NewString()
for _, BuildPhase := range BuildPhaseFilter {
filter.Insert(string(BuildPhase))
}
return &orphanBuildResolver{
dataSet: dataSet,
BuildPhaseFilter: filter,
}
}
// orphanBuildResolver resolves orphan builds that match the specified filter
type orphanBuildResolver struct {
dataSet DataSet
BuildPhaseFilter sets.String
}
// Resolve the matching set of Build objects
func (o *orphanBuildResolver) Resolve() ([]*buildapi.Build, error) {
builds, err := o.dataSet.ListBuilds()
if err != nil {
return nil, err
}
results := []*buildapi.Build{}
for _, build := range builds {
if !o.BuildPhaseFilter.Has(string(build.Status.Phase)) {
continue
}
isOrphan := false
if build.Status.Config == nil {
isOrphan = true
} else {
_, exists, _ := o.dataSet.GetBuildConfig(build)
isOrphan = !exists
}
if isOrphan {
results = append(results, build)
}
}
return results, nil
}
type perBuildConfigResolver struct {
dataSet DataSet
keepComplete int
keepFailed int
}
// NewPerBuildConfigResolver returns a Resolver that selects Builds to prune per BuildConfig
func NewPerBuildConfigResolver(dataSet DataSet, keepComplete int, keepFailed int) Resolver {
return &perBuildConfigResolver{
dataSet: dataSet,
keepComplete: keepComplete,
keepFailed: keepFailed,
}
}
func (o *perBuildConfigResolver) Resolve() ([]*buildapi.Build, error) {
buildConfigs, err := o.dataSet.ListBuildConfigs()
if err != nil {
return nil, err
}
completeStates := sets.NewString(string(buildapi.BuildPhaseComplete))
failedStates := sets.NewString(string(buildapi.BuildPhaseFailed), string(buildapi.BuildPhaseError), string(buildapi.BuildPhaseCancelled))
prunableBuilds := []*buildapi.Build{}
for _, buildConfig := range buildConfigs {
builds, err := o.dataSet.ListBuildsByBuildConfig(buildConfig)
if err != nil {
return nil, err
}
var completeBuilds, failedBuilds []*buildapi.Build
for _, build := range builds {
if completeStates.Has(string(build.Status.Phase)) {
completeBuilds = append(completeBuilds, build)
} else if failedStates.Has(string(build.Status.Phase)) {
failedBuilds = append(failedBuilds, build)
}
}
sort.Sort(sort.Reverse(buildapi.BuildPtrSliceByCreationTimestamp(completeBuilds)))
sort.Sort(sort.Reverse(buildapi.BuildPtrSliceByCreationTimestamp(failedBuilds)))
if o.keepComplete >= 0 && o.keepComplete < len(completeBuilds) {
prunableBuilds = append(prunableBuilds, completeBuilds[o.keepComplete:]...)
}
if o.keepFailed >= 0 && o.keepFailed < len(failedBuilds) {
prunableBuilds = append(prunableBuilds, failedBuilds[o.keepFailed:]...)
}
}
return prunableBuilds, nil
}