@@ -7,8 +7,12 @@ import (
7
7
"path/filepath"
8
8
"strings"
9
9
10
+ "github.com/golang/glog"
11
+
10
12
kapi "k8s.io/kubernetes/pkg/api"
11
13
"k8s.io/kubernetes/pkg/api/validation"
14
+ "k8s.io/kubernetes/pkg/runtime"
15
+ "k8s.io/kubernetes/pkg/util/strategicpatch"
12
16
kvalidation "k8s.io/kubernetes/pkg/util/validation"
13
17
"k8s.io/kubernetes/pkg/util/validation/field"
14
18
@@ -36,12 +40,43 @@ func ValidateBuildUpdate(build *buildapi.Build, older *buildapi.Build) field.Err
36
40
allErrs = append (allErrs , field .Invalid (field .NewPath ("status" , "phase" ), build .Status .Phase , "phase cannot be updated from a terminal state" ))
37
41
}
38
42
if ! kapi .Semantic .DeepEqual (build .Spec , older .Spec ) {
39
- allErrs = append (allErrs , field .Invalid (field .NewPath ("spec" ), "content of spec is not printed out, please refer to the \" details\" " , "spec is immutable" ))
43
+ diff , err := diffBuildSpec (build .Spec , older .Spec )
44
+ if err != nil {
45
+ glog .V (2 ).Infof ("Error calculating build spec patch: %v" , err )
46
+ diff = "[unknown]"
47
+ }
48
+ detail := fmt .Sprintf ("spec is immutable, diff: %s" , diff )
49
+ allErrs = append (allErrs , field .Invalid (field .NewPath ("spec" ), "content of spec is not printed out, please refer to the details" , detail ))
40
50
}
41
51
42
52
return allErrs
43
53
}
44
54
55
+ func diffBuildSpec (newer buildapi.BuildSpec , older buildapi.BuildSpec ) (string , error ) {
56
+ version := buildapi .SchemeGroupVersion
57
+ codec := kapi .Codecs .LegacyCodec (version )
58
+ newerObj := & buildapi.Build {Spec : newer }
59
+ olderObj := & buildapi.Build {Spec : older }
60
+
61
+ newerJSON , err := runtime .Encode (codec , newerObj )
62
+ if err != nil {
63
+ return "" , fmt .Errorf ("error encoding newer: %v" , err )
64
+ }
65
+ olderJSON , err := runtime .Encode (codec , olderObj )
66
+ if err != nil {
67
+ return "" , fmt .Errorf ("error encoding older: %v" , err )
68
+ }
69
+ versioned , err := kapi .Scheme .ConvertToVersion (newerObj , version .String ())
70
+ if err != nil {
71
+ return "" , fmt .Errorf ("error converting newer to versioned: %v" , err )
72
+ }
73
+ patch , err := strategicpatch .CreateTwoWayMergePatch (olderJSON , newerJSON , versioned )
74
+ if err != nil {
75
+ return "" , fmt .Errorf ("error creating a strategic patch: %v" , err )
76
+ }
77
+ return string (patch ), nil
78
+ }
79
+
45
80
// refKey returns a key for the given ObjectReference. If the ObjectReference
46
81
// doesn't include a namespace, the passed in namespace is used for the reference
47
82
func refKey (namespace string , ref * kapi.ObjectReference ) string {
0 commit comments