Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

TKR Source Controller: Install TKR package contents directly #2524

Merged
merged 2 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/v1/tkr/controllers/source/tkr_source_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/go-logr/logr"
ctlimg "github.com/k14s/imgpkg/pkg/imgpkg/registry"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -33,6 +32,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
"sigs.k8s.io/yaml"

runv1 "github.com/vmware-tanzu/tanzu-framework/apis/run/v1alpha1"
"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkr/pkg/constants"
Expand Down
4 changes: 2 additions & 2 deletions pkg/v1/tkr/pkg/types/bommetadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ package types

// ManagementClusterVersion contains kubernetes versions that are supported by the management cluster with a certain TKG version.
type ManagementClusterVersion struct {
TKGVersion string `yaml:"version"`
SupportedKubernetesVersions []string `yaml:"supportedKubernetesVersions"`
TKGVersion string `json:"version"`
SupportedKubernetesVersions []string `json:"supportedKubernetesVersions"`
}

// CompatibilityMetadata contains tanzu release support matrix
Expand Down
49 changes: 40 additions & 9 deletions pkg/v1/util/patchset/patchset.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ package patchset

import (
"context"
"reflect"
"sync"

apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
kerrors "k8s.io/apimachinery/pkg/util/errors"
"sigs.k8s.io/cluster-api/util/patch"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand All @@ -35,40 +36,70 @@ func New(c client.Client) PatchSet {
}

type patchSet struct {
sync.RWMutex
client client.Client
patchers map[types.UID]*patcher
}

type patcher struct {
obj client.Object
helper *patch.Helper
obj client.Object
beforeObj client.Object
}

func (h *patcher) patch(ctx context.Context, c client.Client, obj client.Object) error {
for _, f := range []func() error{
func() error {
return c.Patch(ctx, obj, client.MergeFromWithOptions(h.beforeObj, client.MergeFromWithOptimisticLock{}))
},
func() error {
err := c.Status().Patch(ctx, obj, client.MergeFromWithOptions(h.beforeObj, client.MergeFromWithOptimisticLock{}))
return kerrors.FilterOut(err, apierrors.IsNotFound) // status resource may not exist
},
} {
if err := f(); err != nil {
return err
}
h.beforeObj.SetResourceVersion(obj.GetResourceVersion()) // get the new resourceVersion after a successful patch
}
return nil
}

func (ps *patchSet) Add(obj client.Object) {
ps.Lock()
defer ps.Unlock()

uid := obj.GetUID()
if _, exists := ps.patchers[uid]; exists {
return
}

helper, _ := patch.NewHelper(obj, ps.client)
ps.patchers[uid] = &patcher{
obj: obj,
helper: helper,
obj: obj,
beforeObj: obj.DeepCopyObject().(client.Object),
}
}

func (ps patchSet) Objects() map[types.UID]client.Object {
func (ps *patchSet) Objects() map[types.UID]client.Object {
ps.RLock()
defer ps.RUnlock()

result := make(map[types.UID]client.Object, len(ps.patchers))
for k, v := range ps.patchers {
result[k] = v.obj
}
return result
}

func (ps patchSet) Apply(ctx context.Context) error {
func (ps *patchSet) Apply(ctx context.Context) error {
ps.Lock()
defer ps.Unlock()

errs := make([]error, 0, len(ps.patchers))
for _, patcher := range ps.patchers {
if err := patcher.helper.Patch(ctx, patcher.obj); err != nil {
if reflect.DeepEqual(patcher.obj, patcher.beforeObj) {
continue
}
if err := patcher.patch(ctx, ps.client, patcher.obj); err != nil {
if !patcher.obj.GetDeletionTimestamp().IsZero() && isNotFound(err) {
continue
}
Expand Down
35 changes: 34 additions & 1 deletion pkg/v1/util/patchset/patchset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ import (

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
kerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/uuid"
"sigs.k8s.io/cluster-api/util/conditions"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -35,7 +39,7 @@ func TestPatchsetUnit(t *testing.T) {
RunSpecs(t, "vlabel Package Unit Tests")
}

var _ = Describe("Patchset", func() {
var _ = Describe("PatchSet", func() {
var (
tkr1156 *runv1.TanzuKubernetesRelease
tkr116 *runv1.TanzuKubernetesRelease
Expand Down Expand Up @@ -103,6 +107,22 @@ var _ = Describe("Patchset", func() {
})
})

When("there's a conflict applying the patchset", func() {
BeforeEach(func() {
ps = New(&conflictedPatcher{})
})

It("return a Conflict error", func() {
changedTKRs := []*runv1.TanzuKubernetesRelease{tkr116, tkr117}
for _, tkr := range changedTKRs {
tkr.Labels = labels.Set{"newLabel" + tkr.Name: ""}
}
err := ps.Apply(context.Background())
Expect(err).To(HaveOccurred())
Expect(kerrors.FilterOut(err, apierrors.IsConflict)).To(BeNil())
})
})

When("a patched object is slated for deletion", func() {
BeforeEach(func() {
tkr117.DeletionTimestamp = &metav1.Time{Time: time.Now()}
Expand Down Expand Up @@ -140,6 +160,19 @@ func (p *countingPatcher) Patch(ctx context.Context, obj client.Object, patch cl
return p.Client.Patch(ctx, obj, patch, opts...)
}

type conflictedPatcher struct {
client.Client
}

func (*conflictedPatcher) Patch(_ context.Context, obj client.Object, _ client.Patch, _ ...client.PatchOption) error {
gvk := obj.GetObjectKind().GroupVersionKind()
groupResource := schema.GroupResource{
Group: gvk.Group,
Resource: gvk.Kind,
}
return apierrors.NewConflict(groupResource, obj.GetName(), errors.New("re-read the resource before patching"))
}

func newScheme() *runtime.Scheme {
s := runtime.NewScheme()
_ = runv1.AddToScheme(s)
Expand Down
42 changes: 21 additions & 21 deletions pkg/v2/tkr/controller/tkr-source/compatibility/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/go-logr/logr"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
Expand All @@ -22,18 +21,27 @@ import (
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/source"
"sigs.k8s.io/yaml"

runv1 "github.com/vmware-tanzu/tanzu-framework/apis/run/v1alpha3"
"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkr/pkg/constants"
"github.com/vmware-tanzu/tanzu-framework/pkg/v1/tkr/pkg/types"
"github.com/vmware-tanzu/tanzu-framework/pkg/v1/util/patchset"
"github.com/vmware-tanzu/tanzu-framework/pkg/v2/tkr/util/sets"
"github.com/vmware-tanzu/tanzu-framework/pkg/v2/tkr/util/version"
)

type Reconciler struct {
version.Compatibility

Ctx context.Context
Log logr.Logger
Client client.Client
Config Config
}

type Compatibility struct {
Client client.Client
Config Config
}

Expand Down Expand Up @@ -112,51 +120,43 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ct
}

func (r *Reconciler) updateTKRCompatibleCondition(ctx context.Context, tkr *runv1.TanzuKubernetesRelease) error {
compatibleSet, err := r.getCompatibleSet(ctx)
compatibleSet, err := r.CompatibleVersions(ctx)
if err != nil {
return err
}

if _, isCompatible := compatibleSet[tkr.Spec.Version]; isCompatible {
if compatibleSet.Has(tkr.Spec.Version) {
conditions.MarkTrue(tkr, runv1.ConditionCompatible)
return nil
}
conditions.MarkFalse(tkr, runv1.ConditionCompatible, "", clusterv1.ConditionSeverityWarning, "")
return nil
}

func (r *Reconciler) getCompatibleSet(ctx context.Context) (map[string]struct{}, error) {
mgmtClusterVersion, err := r.getManagementClusterVersion(ctx)
func (c *Compatibility) CompatibleVersions(ctx context.Context) (sets.StringSet, error) {
mgmtClusterVersion, err := c.getManagementClusterVersion(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get the management cluster info")
}

metadata, err := r.compatibilityMetadata(ctx)
metadata, err := c.compatibilityMetadata(ctx)
if err != nil {
return nil, errors.Wrapf(err, "failed to get BOM compatibility metadata")
}

for _, mgmtVersion := range metadata.ManagementClusterVersions {
if mgmtClusterVersion == mgmtVersion.TKGVersion {
return stringSet(mgmtVersion.SupportedKubernetesVersions), nil
return sets.Strings(mgmtVersion.SupportedKubernetesVersions...), nil
}
}

return stringSet(nil), nil
}

func stringSet(ss []string) map[string]struct{} {
result := make(map[string]struct{}, len(ss))
for _, s := range ss {
result[s] = struct{}{}
}
return result
return sets.Strings(), nil
}

// getManagementClusterVersion get the version of the management cluster
func (r *Reconciler) getManagementClusterVersion(ctx context.Context) (string, error) {
func (c *Compatibility) getManagementClusterVersion(ctx context.Context) (string, error) {
clusterList := &clusterv1.ClusterList{}
if err := r.Client.List(ctx, clusterList, client.HasLabels{constants.ManagementClusterRoleLabel}); err != nil {
if err := c.Client.List(ctx, clusterList, client.HasLabels{constants.ManagementClusterRoleLabel}); err != nil {
return "", errors.Wrap(err, "failed to list clusters")
}

Expand All @@ -169,10 +169,10 @@ func (r *Reconciler) getManagementClusterVersion(ctx context.Context) (string, e
return "", errors.New("failed to get management cluster info")
}

func (r *Reconciler) compatibilityMetadata(ctx context.Context) (*types.CompatibilityMetadata, error) {
func (c *Compatibility) compatibilityMetadata(ctx context.Context) (*types.CompatibilityMetadata, error) {
cm := &corev1.ConfigMap{}
cmObjectKey := client.ObjectKey{Namespace: r.Config.TKRNamespace, Name: constants.BOMMetadataConfigMapName}
if err := r.Client.Get(ctx, cmObjectKey, cm); err != nil {
cmObjectKey := client.ObjectKey{Namespace: c.Config.TKRNamespace, Name: constants.BOMMetadataConfigMapName}
if err := c.Client.Get(ctx, cmObjectKey, cm); err != nil {
return nil, err
}

Expand Down
76 changes: 0 additions & 76 deletions pkg/v2/tkr/controller/tkr-source/fetcher/configurer.go

This file was deleted.

Loading