Skip to content

Client-side apply has a pathological case with deeply nested identical objects #698

@DirectXMan12

Description

@DirectXMan12

Test case

  1. Strip the description fields from https://raw.githubusercontent.com/kubernetes-sigs/kubebuilder/master/docs/book/src/multiversion-tutorial/testdata/project/config/crd/bases/batch.tutorial.kubebuilder.io_cronjobs.yaml (to make it fit in an annotation)
  2. kubectl apply -f the above
  3. kubectl apply -f the above again

Underlying issue

Deeply nested (e.g. validation for podspec) identical issues hit a pathological case in the json-patch library's merge patch generator, which recursively traverses every sub-tree to check if two json trees are identical

Evidence

You can attach an execution trace and use go tool trace to see this for yourself

y41oDeo5pLi

(that's me stopping the attempt after 30s, not it taking 30s total)

runtime trace call patch
diff --git a/cmd/kubectl/kubectl.go b/cmd/kubectl/kubectl.go
index 53934ac2b0..fab992ad95 100644
--- a/cmd/kubectl/kubectl.go
+++ b/cmd/kubectl/kubectl.go
@@ -21,6 +21,9 @@ import (
 	"math/rand"
 	"os"
 	"time"
+	"runtime/trace"
+	"os/signal"
+	"syscall"
 
 	"github.com/spf13/pflag"
 
@@ -33,6 +36,16 @@ import (
 )
 
 func main() {
+	traceOut, err := os.Create("/tmp/kubectl.trace")
+	if err != nil {
+		panic(err)
+	}
+	defer traceOut.Close()
+	if err := trace.Start(traceOut); err != nil {
+		panic(err)
+	}
+	defer trace.Stop()
+		
 	rand.Seed(time.Now().UnixNano())
 
 	command := cmd.NewDefaultKubectlCommand()
@@ -46,7 +59,17 @@ func main() {
 	logs.InitLogs()
 	defer logs.FlushLogs()
 
+	sigCh := make(chan os.Signal)
+	go func() {
+		<-sigCh
+		trace.Stop()
+		traceOut.Close()
+		panic("at the disco!")
+	}()
+	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
+
 	if err := command.Execute(); err != nil {
-		os.Exit(1)
+		//os.Exit(1)
+		return
 	}
 }

Potential fixes

EDIT: See below -- moving around some conditions in the jsonpatch library seems to fix things.

Also, this may be kind-of moot, since we'll be getting server-side apply, which doesn't suffer from this particular issue.

Metadata

Metadata

Assignees

Labels

area/kubectlkind/bugCategorizes issue or PR as related to a bug.lifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale.priority/P2sig/cliCategorizes an issue or PR as relevant to SIG CLI.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions