1
0
mirror of https://github.com/ko-build/ko.git synced 2025-07-06 23:36:54 +02:00

Deterministically fail ko {apply, create} (#133)

When resolving files, we would just log.Fatal if we encountered an
error. This seems to be racy and causes ko to exit with a 0 error code
when it shouldn't. To fix this, we synchronize the builder goroutines
with the kubectl go routine and exit with an error if either of them
failed.

This fix also happened to fix a goroutine leak. If the kubectl goroutine
failed, we never properly cancelled the builds, which would happily
conitnue compiling packages and consuming resources.
This commit is contained in:
jonjohnsonjr
2020-02-11 10:44:25 -08:00
committed by GitHub
parent c3a657a04b
commit cfd680de28
4 changed files with 71 additions and 29 deletions

View File

@ -15,6 +15,7 @@
package commands
import (
"fmt"
"log"
"os"
"os/exec"
@ -22,6 +23,7 @@ import (
"github.com/google/ko/pkg/commands/options"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/sync/errgroup"
"k8s.io/cli-runtime/pkg/genericclioptions"
)
@ -110,7 +112,12 @@ func addApply(topLevel *cobra.Command) {
log.Fatalf("error piping to 'kubectl apply': %v", err)
}
go func() {
// Cancel on signals.
ctx := createCancellableContext()
// Make sure builds are cancelled if kubectl apply fails.
g, ctx := errgroup.WithContext(ctx)
g.Go(func() error {
// kubectl buffers data before starting to apply it, which
// can lead to resources being created more slowly than desired.
// In the case of --watch, it can lead to resources not being
@ -122,13 +129,19 @@ func addApply(topLevel *cobra.Command) {
stdin.Write([]byte("---\n"))
}
// Once primed kick things off.
ctx := createCancellableContext()
resolveFilesToWriter(ctx, builder, publisher, fo, so, sto, stdin)
}()
return resolveFilesToWriter(ctx, builder, publisher, fo, so, sto, stdin)
})
// Run it.
if err := kubectlCmd.Run(); err != nil {
log.Fatalf("error executing 'kubectl apply': %v", err)
g.Go(func() error {
// Run it.
if err := kubectlCmd.Run(); err != nil {
return fmt.Errorf("error executing 'kubectl apply': %v", err)
}
return nil
})
if err := g.Wait(); err != nil {
log.Fatal(err)
}
},
}