From 0c79d6d627566e7a81f8b6b8f3b3811431c1de7d Mon Sep 17 00:00:00 2001 From: Hari Date: Mon, 25 Mar 2024 14:54:09 +0530 Subject: [PATCH] fix: K8s version change transformer was not being run sometimes because Parameterizer was running first (#1165) feat: Added a new feature to sort transformers based on a label "move2kube.konveyor.io/sort-order" specified in the transformer.yaml. This is only the initial sorted order in which transformers are run and does not affect dependency related stuff like MandatoryPassThrough. Signed-off-by: Harikrishnan Balagopal --- .../kubernetesversionchanger/transformer.yaml | 1 + .../kubernetes/parameterizer/transformer.yaml | 1 + common/utils.go | 28 +++++++++++++++++++ transformer/transformer.go | 27 +++++++++++++++++- 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/assets/built-in/transformers/kubernetes/kubernetesversionchanger/transformer.yaml b/assets/built-in/transformers/kubernetes/kubernetesversionchanger/transformer.yaml index e8e5a7153..bdb597f78 100644 --- a/assets/built-in/transformers/kubernetes/kubernetesversionchanger/transformer.yaml +++ b/assets/built-in/transformers/kubernetes/kubernetesversionchanger/transformer.yaml @@ -4,6 +4,7 @@ metadata: name: KubernetesVersionChanger labels: move2kube.konveyor.io/built-in: true + move2kube.konveyor.io/sort-order: 9999 spec: class: "KubernetesVersionChanger" directoryDetect: diff --git a/assets/built-in/transformers/kubernetes/parameterizer/transformer.yaml b/assets/built-in/transformers/kubernetes/parameterizer/transformer.yaml index c45f8858b..43aecad85 100644 --- a/assets/built-in/transformers/kubernetes/parameterizer/transformer.yaml +++ b/assets/built-in/transformers/kubernetes/parameterizer/transformer.yaml @@ -4,6 +4,7 @@ metadata: name: Parameterizer labels: move2kube.konveyor.io/built-in: true + move2kube.konveyor.io/sort-order: 10000 spec: class: "Parameterizer" directoryDetect: diff --git a/common/utils.go b/common/utils.go index 5a7edd52a..cd13fba7b 100644 --- a/common/utils.go +++ b/common/utils.go @@ -59,6 +59,34 @@ import ( core "k8s.io/kubernetes/pkg/apis/core" ) +// sorting + +// Sortable is an implementation of the sort.Interface interface. +// This is useful when you want to sort one slice using another slice. +type Sortable[T any] struct { + Xs []T + Ys []int +} + +// Len is the number of elements in the collection. +func (s *Sortable[T]) Len() int { + return len(s.Xs) +} + +// Less reports whether the element with index i +// must sort before the element with index j. +func (s *Sortable[T]) Less(i, j int) bool { + return s.Ys[i] < s.Ys[j] +} + +// Swap swaps the elements with indexes i and j. +func (s *Sortable[T]) Swap(i, j int) { + s.Xs[i], s.Xs[j] = s.Xs[j], s.Xs[i] + s.Ys[i], s.Ys[j] = s.Ys[j], s.Ys[i] +} + +// sorting + // LookupEnv looks for a environment variable in a list of environment variables func LookupEnv(envNameToLookup string, envList []core.EnvVar) (core.EnvVar, bool) { for _, env := range envList { diff --git a/transformer/transformer.go b/transformer/transformer.go index 87b7aa1d6..dd103f926 100644 --- a/transformer/transformer.go +++ b/transformer/transformer.go @@ -76,6 +76,8 @@ const ( DEFAULT_SELECTED_LABEL = types.GroupName + "/default-selected" // CONTAINER_BASED_LABEL is a label that indicates that the transformer needs to spawn containers to run. CONTAINER_BASED_LABEL = types.GroupName + "/container-based" + // SORT_ORDER_LABEL is a label that is used while sorting the list of all transformers. + SORT_ORDER_LABEL = types.GroupName + "/sort-order" ) var ( @@ -232,7 +234,8 @@ func InitTransformers(transformerYamlPaths map[string]string, selector labels.Se deselectedTransformers[transformerName] = transformerYamlPaths[transformerName] } } - for _, selectedTransformerName := range selectedTransformerNames { + transformerSortOrders := []int{} + for currSortOrder, selectedTransformerName := range selectedTransformerNames { transformerConfig, ok := transformerConfigs[selectedTransformerName] if !ok { logrus.Errorf("failed to find the transformer with the name: '%s'", selectedTransformerName) @@ -284,12 +287,34 @@ func InitTransformers(transformerYamlPaths map[string]string, selector labels.Se continue } transformers = append(transformers, transformer) + // for sorting later on + newSortOrder := currSortOrder + if s, ok := transformerConfig.ObjectMeta.Labels[SORT_ORDER_LABEL]; ok { + if x, err := cast.ToIntE(s); err != nil { + logrus.Errorf( + "Using %d as the sort order since the one specified in the transformer.yaml is not a valid integer. Actual: '%s' Error: %q", + currSortOrder, s, err, + ) + } else { + logrus.Debugf("using new sort order: %d", x) + newSortOrder = x + } + } + transformerSortOrders = append(transformerSortOrders, newSortOrder) + // for sorting later on transformerMap[selectedTransformerName] = transformer if transformerConfig.Spec.InvokedByDefault.Enabled { invokedByDefaultTransformers = append(invokedByDefaultTransformers, transformer) } } initialized = true + if len(transformerSortOrders) != len(transformers) { + panic("expected transformers and transformerSortOrders to have the same length") + } + logrus.Debugf("before sorting the transformers list, transformerSortOrders: %+v transformers: %+v", transformerSortOrders, transformers) + sortable := &common.Sortable[Transformer]{Xs: transformers, Ys: transformerSortOrders} + sort.Stable(sortable) + logrus.Debugf("after sorting the transformers list, transformerSortOrders: %+v transformers: %+v", transformerSortOrders, transformers) return deselectedTransformers, nil }