/
builds.go
120 lines (111 loc) · 3.41 KB
/
builds.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
package imagereferencemutators
import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/validation/field"
buildv1 "github.com/openshift/api/build/v1"
)
type buildSpecMutator struct {
spec *buildv1.CommonSpec
oldSpec *buildv1.CommonSpec
path *field.Path
output bool
}
// NewBuildMutator returns an ImageReferenceMutator that includes the output field.
func NewBuildMutator(build *buildv1.Build) ImageReferenceMutator {
return &buildSpecMutator{
spec: &build.Spec.CommonSpec,
path: field.NewPath("spec"),
output: true,
}
}
func hasIdenticalImageSourceObjectReference(spec *buildv1.CommonSpec, ref corev1.ObjectReference) bool {
if spec == nil {
return false
}
for i := range spec.Source.Images {
if spec.Source.Images[i].From == ref {
return true
}
}
return false
}
func hasIdenticalStrategyFrom(spec, oldSpec *buildv1.CommonSpec) bool {
if oldSpec == nil {
return false
}
switch {
case spec.Strategy.CustomStrategy != nil:
if oldSpec.Strategy.CustomStrategy != nil {
return spec.Strategy.CustomStrategy.From == oldSpec.Strategy.CustomStrategy.From
}
case spec.Strategy.DockerStrategy != nil:
if oldSpec.Strategy.DockerStrategy != nil {
return hasIdenticalObjectReference(spec.Strategy.DockerStrategy.From, oldSpec.Strategy.DockerStrategy.From)
}
case spec.Strategy.SourceStrategy != nil:
if oldSpec.Strategy.SourceStrategy != nil {
return spec.Strategy.SourceStrategy.From == oldSpec.Strategy.SourceStrategy.From
}
}
return false
}
func hasIdenticalObjectReference(ref, oldRef *corev1.ObjectReference) bool {
if ref == nil || oldRef == nil {
return false
}
return *ref == *oldRef
}
func (m *buildSpecMutator) Mutate(fn ImageReferenceMutateFunc) field.ErrorList {
var errs field.ErrorList
for i := range m.spec.Source.Images {
if hasIdenticalImageSourceObjectReference(m.oldSpec, m.spec.Source.Images[i].From) {
continue
}
if err := fn(&m.spec.Source.Images[i].From); err != nil {
errs = append(errs, fieldErrorOrInternal(err, m.path.Child("source", "images").Index(i).Child("from", "name")))
continue
}
}
if !hasIdenticalStrategyFrom(m.spec, m.oldSpec) {
if s := m.spec.Strategy.CustomStrategy; s != nil {
if err := fn(&s.From); err != nil {
errs = append(errs, fieldErrorOrInternal(err, m.path.Child("strategy", "customStrategy", "from", "name")))
}
}
if s := m.spec.Strategy.DockerStrategy; s != nil {
if s.From != nil {
if err := fn(s.From); err != nil {
errs = append(errs, fieldErrorOrInternal(err, m.path.Child("strategy", "dockerStrategy", "from", "name")))
}
}
}
if s := m.spec.Strategy.SourceStrategy; s != nil {
if err := fn(&s.From); err != nil {
errs = append(errs, fieldErrorOrInternal(err, m.path.Child("strategy", "sourceStrategy", "from", "name")))
}
}
}
if m.output {
if s := m.spec.Output.To; s != nil {
if m.oldSpec == nil || m.oldSpec.Output.To == nil || !hasIdenticalObjectReference(s, m.oldSpec.Output.To) {
if err := fn(s); err != nil {
errs = append(errs, fieldErrorOrInternal(err, m.path.Child("output", "to")))
}
}
}
}
return errs
}
func fieldErrorOrInternal(err error, path *field.Path) *field.Error {
if ferr, ok := err.(*field.Error); ok {
if len(ferr.Field) == 0 {
ferr.Field = path.String()
}
return ferr
}
if errors.IsNotFound(err) {
return field.NotFound(path, err)
}
return field.InternalError(path, err)
}