@@ -246,7 +246,14 @@ func buildRenderStatus(hctx *hydrationContext, hydErr error) *kptfilev1.RenderSt
246246 }
247247 if hydErr != nil {
248248 var errLines []string
249- for _ , s := range append (hctx .mutationSteps , hctx .validationSteps ... ) {
249+ for _ , s := range hctx .mutationSteps {
250+ if s .ExecutionError != "" {
251+ errLines = append (errLines , fmt .Sprintf ("%s: %s" , stepName (s ), s .ExecutionError ))
252+ } else if s .ExitCode != 0 {
253+ errLines = append (errLines , fmt .Sprintf ("%s: exit code %d" , stepName (s ), s .ExitCode ))
254+ }
255+ }
256+ for _ , s := range hctx .validationSteps {
250257 if s .ExecutionError != "" {
251258 errLines = append (errLines , fmt .Sprintf ("%s: %s" , stepName (s ), s .ExecutionError ))
252259 } else if s .ExitCode != 0 {
@@ -286,7 +293,7 @@ func setRenderStatus(fs filesys.FileSystem, pkgPath string, condition kptfilev1.
286293 kf .Status .Conditions = append (kf .Status .Conditions , condition )
287294 kf .Status .RenderStatus = renderStatus
288295 if err := kptfileutil .WriteKptfileToFS (fs , pkgPath , kf ); err != nil {
289- klog .V (3 ).Infof ("failed to write render status condition to Kptfile at %s: %v" , pkgPath , err )
296+ klog .V (3 ).Infof ("failed to write render status to Kptfile at %s: %v" , pkgPath , err )
290297 }
291298}
292299
@@ -743,10 +750,10 @@ func (pn *pkgNode) runMutators(ctx context.Context, hctx *hydrationContext, inpu
743750 return input , nil
744751 }
745752
746- mutators , err := fnChain (ctx , hctx , pn .pkg .UniquePath , pl .Mutators )
753+ mutators , failIdx , err := fnChain (ctx , hctx , pn .pkg .UniquePath , pl .Mutators )
747754 if err != nil {
748755 // Capture execution error (e.g. missing exec, image resolution failure)
749- hctx .mutationSteps = append (hctx .mutationSteps , executionErrorStep (pl .Mutators , err ))
756+ hctx .mutationSteps = append (hctx .mutationSteps , preExecFailureStep (pl .Mutators [ failIdx ] , err ))
750757 return nil , err
751758 }
752759
@@ -802,11 +809,11 @@ func (pn *pkgNode) runMutators(ctx context.Context, hctx *hydrationContext, inpu
802809 err = mutation .Execute ()
803810 if err != nil {
804811 clearAnnotationsOnMutFailure (input )
805- hctx .mutationSteps = append (hctx .mutationSteps , captureStepResult (pl .Mutators [i ], hctx .fnResults , prevLen ))
812+ hctx .mutationSteps = append (hctx .mutationSteps , captureStepResult (pl .Mutators [i ], hctx .fnResults , prevLen , err ))
806813 return input , err
807814 }
808815 hctx .executedFunctionCnt ++
809- hctx .mutationSteps = append (hctx .mutationSteps , captureStepResult (pl .Mutators [i ], hctx .fnResults , prevLen ))
816+ hctx .mutationSteps = append (hctx .mutationSteps , captureStepResult (pl .Mutators [i ], hctx .fnResults , prevLen , nil ))
810817
811818 if len (selectors ) > 0 || len (exclusions ) > 0 {
812819 // merge the output resources with input resources
@@ -852,23 +859,23 @@ func (pn *pkgNode) runValidators(ctx context.Context, hctx *hydrationContext, in
852859 displayResourceCount = true
853860 }
854861 if function .Exec != "" && ! hctx .runnerOptions .AllowExec {
855- hctx .validationSteps = append (hctx .validationSteps , executionErrorStep ([]kptfilev1. Function { function } , errAllowedExecNotSpecified ))
862+ hctx .validationSteps = append (hctx .validationSteps , preExecFailureStep ( function , errAllowedExecNotSpecified ))
856863 return errAllowedExecNotSpecified
857864 }
858865 opts := hctx .runnerOptions
859866 opts .SetPkgPathAnnotation = true
860867 opts .DisplayResourceCount = displayResourceCount
861868 validator , err = fnruntime .NewRunner (ctx , hctx .fileSystem , & function , pn .pkg .UniquePath , hctx .fnResults , opts , hctx .runtime )
862869 if err != nil {
863- hctx .validationSteps = append (hctx .validationSteps , executionErrorStep ([]kptfilev1. Function { function } , err ))
870+ hctx .validationSteps = append (hctx .validationSteps , preExecFailureStep ( function , err ))
864871 return err
865872 }
866873 if _ , err = validator .Filter (cloneResources (selectedResources )); err != nil {
867- hctx .validationSteps = append (hctx .validationSteps , captureStepResult (function , hctx .fnResults , prevLen ))
874+ hctx .validationSteps = append (hctx .validationSteps , captureStepResult (function , hctx .fnResults , prevLen , err ))
868875 return err
869876 }
870877 hctx .executedFunctionCnt ++
871- hctx .validationSteps = append (hctx .validationSteps , captureStepResult (function , hctx .fnResults , prevLen ))
878+ hctx .validationSteps = append (hctx .validationSteps , captureStepResult (function , hctx .fnResults , prevLen , nil ))
872879 }
873880 return nil
874881}
@@ -970,7 +977,7 @@ func pathRelToRoot(rootPkgPath, subPkgPath, resourcePath string) (relativePath s
970977}
971978
972979// fnChain returns a slice of function runners given a list of functions defined in pipeline.
973- func fnChain (ctx context.Context , hctx * hydrationContext , pkgPath types.UniquePath , fns []kptfilev1.Function ) ([]* fnruntime.FunctionRunner , error ) {
980+ func fnChain (ctx context.Context , hctx * hydrationContext , pkgPath types.UniquePath , fns []kptfilev1.Function ) ([]* fnruntime.FunctionRunner , int , error ) {
974981 var runners []* fnruntime.FunctionRunner
975982 for i := range fns {
976983 var err error
@@ -981,18 +988,18 @@ func fnChain(ctx context.Context, hctx *hydrationContext, pkgPath types.UniquePa
981988 displayResourceCount = true
982989 }
983990 if function .Exec != "" && ! hctx .runnerOptions .AllowExec {
984- return nil , errAllowedExecNotSpecified
991+ return nil , i , errAllowedExecNotSpecified
985992 }
986993 opts := hctx .runnerOptions
987994 opts .SetPkgPathAnnotation = true
988995 opts .DisplayResourceCount = displayResourceCount
989996 runner , err = fnruntime .NewRunner (ctx , hctx .fileSystem , & function , pkgPath , hctx .fnResults , opts , hctx .runtime )
990997 if err != nil {
991- return nil , err
998+ return nil , i , err
992999 }
9931000 runners = append (runners , runner )
9941001 }
995- return runners , nil
1002+ return runners , - 1 , nil
9961003}
9971004
9981005// trackInputFiles records file paths of input resources in the hydration context.
@@ -1041,7 +1048,7 @@ func pruneResources(fsys filesys.FileSystem, hctx *hydrationContext) error {
10411048
10421049// captureStepResult builds a PipelineStepResult from the fnresult.Result items
10431050// appended since prevLen.
1044- func captureStepResult (fn kptfilev1.Function , fnResults * fnresult.ResultList , prevLen int ) kptfilev1.PipelineStepResult {
1051+ func captureStepResult (fn kptfilev1.Function , fnResults * fnresult.ResultList , prevLen int , execErr error ) kptfilev1.PipelineStepResult {
10451052 step := kptfilev1.PipelineStepResult {
10461053 Name : fn .Name ,
10471054 Image : fn .Image ,
@@ -1057,22 +1064,23 @@ func captureStepResult(fn kptfilev1.Function, fnResults *fnresult.ResultList, pr
10571064 step .ErrorResults = append (step .ErrorResults , ri )
10581065 }
10591066 }
1067+ } else if execErr != nil {
1068+ step .ExitCode = 1
1069+ step .ExecutionError = execErr .Error ()
10601070 }
10611071 return step
10621072}
10631073
1064- // executionErrorStep creates a PipelineStepResult for errors that occur before
1065- // function execution (e.g. image pull failure, missing exec).
1066- func executionErrorStep (fns []kptfilev1.Function , err error ) kptfilev1.PipelineStepResult {
1067- if len (fns ) == 0 {
1068- return kptfilev1.PipelineStepResult {ExecutionError : err .Error ()}
1069- }
1070- // Use the first function in the list that failed to resolve
1071- fn := fns [0 ]
1074+ // preExecFailureStep creates a PipelineStepResult for errors that occur before
1075+ // the function is executed (e.g. image pull failure, missing exec permission).
1076+ // ExitCode is set to 1 to indicate failure; the executionError field provides
1077+ // the specific reason the function could not be started.
1078+ func preExecFailureStep (fn kptfilev1.Function , err error ) kptfilev1.PipelineStepResult {
10721079 return kptfilev1.PipelineStepResult {
10731080 Name : fn .Name ,
10741081 Image : fn .Image ,
10751082 ExecPath : fn .Exec ,
1083+ ExitCode : 1 ,
10761084 ExecutionError : err .Error (),
10771085 }
10781086}
0 commit comments