From 939e6cf13199b2c0cc125b50f1e050d3507f032c Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Wed, 29 Aug 2018 13:36:31 -0700 Subject: [PATCH] Delete and redeploy object upon error 'field is immutable' As discussed in #891, when running skaffold dev certain immutable Kubernetes objects (like Jobs) can't be redeployed. A 'field is immutable' error is returned when this happens. To fix this issue, we can check the error from kubectl apply for 'field is immutable'. If we find it, we can delete the object and try to deploy it again. --- pkg/skaffold/deploy/kubectl/cli.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/pkg/skaffold/deploy/kubectl/cli.go b/pkg/skaffold/deploy/kubectl/cli.go index 87ad6a92be6..28f94bcf53e 100644 --- a/pkg/skaffold/deploy/kubectl/cli.go +++ b/pkg/skaffold/deploy/kubectl/cli.go @@ -17,9 +17,12 @@ limitations under the License. package kubectl import ( + "bufio" + "bytes" "context" "io" "os/exec" + "strings" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" @@ -56,8 +59,25 @@ func (c *CLI) Apply(ctx context.Context, out io.Writer, manifests ManifestList) return nil, nil } - if err := c.Run(ctx, manifests.Reader(), out, "apply", c.Flags.Apply, "-f", "-"); err != nil { - return nil, errors.Wrap(err, "kubectl apply") + buf := bytes.NewBuffer([]byte{}) + writer := bufio.NewWriter(buf) + if err := c.Run(ctx, manifests.Reader(), writer, "apply", c.Flags.Apply, "-f", "-"); err != nil { + if !strings.Contains(buf.String(), "field is immutable") { + return nil, err + } + // If the output contains the string 'field is immutable', we want to delete the object and recreate it + // See Issue #891 for more information + if err := c.Detete(ctx, out, manifests); err != nil { + return nil, errors.Wrap(err, "deleting manifest") + } + if err := c.Run(ctx, manifests.Reader(), out, "apply", c.Flags.Apply, "-f", "-"); err != nil { + return nil, errors.Wrap(err, "kubectl apply after deletion") + } + } else { + // Write output to out + if _, err := out.Write(buf.Bytes()); err != nil { + return nil, errors.Wrap(err, "writing to out") + } } return updated, nil