@@ -17,16 +17,19 @@ limitations under the License.
1717package plank
1818
1919import (
20+ "encoding/json"
2021 "fmt"
2122 "sort"
2223 "strings"
2324 "sync"
2425 "time"
2526
27+ jsonpatch "github.com/evanphx/json-patch"
2628 "github.com/sirupsen/logrus"
2729 coreapi "k8s.io/api/core/v1"
2830 v1 "k8s.io/api/core/v1"
2931 kerrors "k8s.io/apimachinery/pkg/api/errors"
32+ ktypes "k8s.io/apimachinery/pkg/types"
3033
3134 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3235 corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -51,6 +54,7 @@ type prowJobClient interface {
5154 Update (* prowapi.ProwJob ) (* prowapi.ProwJob , error )
5255 Get (name string , options metav1.GetOptions ) (* prowapi.ProwJob , error )
5356 List (opts metav1.ListOptions ) (* prowapi.ProwJobList , error )
57+ Patch (name string , pt ktypes.PatchType , data []byte , subresources ... string ) (result * prowapi.ProwJob , err error )
5458}
5559
5660// GitHubClient contains the methods used by plank on k8s.io/test-infra/prow/github.Client
@@ -349,6 +353,7 @@ func syncProwJobs(
349353func (c * Controller ) syncPendingJob (pj prowapi.ProwJob , pm map [string ]coreapi.Pod , reports chan <- prowapi.ProwJob ) error {
350354 // Record last known state so we can log state transitions.
351355 prevState := pj .Status .State
356+ prevPJ := pj
352357
353358 pod , podExists := pm [pj .ObjectMeta .Name ]
354359 if ! podExists {
@@ -474,14 +479,14 @@ func (c *Controller) syncPendingJob(pj prowapi.ProwJob, pm map[string]coreapi.Po
474479 WithField ("from" , prevState ).
475480 WithField ("to" , pj .Status .State ).Info ("Transitioning states." )
476481 }
477- _ , err := c .prowJobClient .Update (& pj )
478- c .log .WithFields (pjutil .ProwJobFields (& pj )).Debug ("Update ProwJob." )
479- return err
482+
483+ return c .patchProwjob (prevPJ , pj )
480484}
481485
482486func (c * Controller ) syncTriggeredJob (pj prowapi.ProwJob , pm map [string ]coreapi.Pod , reports chan <- prowapi.ProwJob ) error {
483487 // Record last known state so we can log state transitions.
484488 prevState := pj .Status .State
489+ prevPJ := pj
485490
486491 var id , pn string
487492 pod , podExists := pm [pj .ObjectMeta .Name ]
@@ -525,9 +530,7 @@ func (c *Controller) syncTriggeredJob(pj prowapi.ProwJob, pm map[string]coreapi.
525530 WithField ("from" , prevState ).
526531 WithField ("to" , pj .Status .State ).Info ("Transitioning states." )
527532 }
528- _ , err := c .prowJobClient .Update (& pj )
529- c .log .WithFields (pjutil .ProwJobFields (& pj )).Debug ("Update ProwJob." )
530- return err
533+ return c .patchProwjob (prevPJ , pj )
531534}
532535
533536// TODO: No need to return the pod name since we already have the
@@ -568,3 +571,24 @@ func getPodBuildID(pod *coreapi.Pod) string {
568571 logrus .Warningf ("BUILD_ID was not found in pod %q: streaming logs from deck will not work" , pod .ObjectMeta .Name )
569572 return ""
570573}
574+
575+ func (c * Controller ) patchProwjob (srcPJ prowapi.ProwJob , destPJ prowapi.ProwJob ) error {
576+ srcPJData , err := json .Marshal (srcPJ )
577+ if err != nil {
578+ return fmt .Errorf ("marshal source prow job: %v" , err )
579+ }
580+
581+ destPJData , err := json .Marshal (destPJ )
582+ if err != nil {
583+ return fmt .Errorf ("marshal dest prow job: %v" , err )
584+ }
585+
586+ patch , err := jsonpatch .CreateMergePatch (srcPJData , destPJData )
587+ if err != nil {
588+ return fmt .Errorf ("cannot create JSON patch: %v" , err )
589+ }
590+
591+ _ , err = c .prowJobClient .Patch (srcPJ .Name , ktypes .MergePatchType , patch )
592+ c .log .WithFields (pjutil .ProwJobFields (& destPJ )).Debug ("Patched ProwJob." )
593+ return err
594+ }
0 commit comments