Skip to content

Commit

Permalink
refactor: use object cache instead of event info
Browse files Browse the repository at this point in the history
  • Loading branch information
FabianKramm committed Nov 1, 2024
1 parent c907b9b commit 9e1cdd9
Show file tree
Hide file tree
Showing 55 changed files with 2,446 additions and 1,755 deletions.
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/denisbrodbeck/machineid v1.0.1
github.com/docker/cli v25.0.0+incompatible
github.com/docker/docker v25.0.6+incompatible
github.com/evanphx/json-patch/v5 v5.9.0
github.com/ghodss/yaml v1.0.0
github.com/go-logr/logr v1.4.2
github.com/go-openapi/loads v0.21.2
Expand All @@ -16,7 +17,6 @@ require (
github.com/hashicorp/go-hclog v0.14.1
github.com/hashicorp/go-plugin v1.6.0
github.com/hashicorp/golang-lru/v2 v2.0.2
github.com/hashicorp/yamux v0.1.1
github.com/invopop/jsonschema v0.12.0
github.com/kubernetes-csi/external-snapshotter/client/v4 v4.2.0
github.com/loft-sh/admin-apis v0.0.0-20240203010124-3600c1c582a8
Expand All @@ -26,9 +26,7 @@ require (
github.com/loft-sh/utils v0.0.29
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/go-testing-interface v1.0.0
github.com/moby/term v0.5.0
github.com/oklog/run v1.0.0
github.com/olekukonko/tablewriter v0.0.5
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.33.1
Expand Down Expand Up @@ -83,7 +81,6 @@ require (
github.com/docker/docker-credential-helpers v0.8.1 // indirect
github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960 // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/frankban/quicktest v1.14.5 // indirect
Expand All @@ -93,11 +90,14 @@ require (
github.com/google/cel-go v0.21.0 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect
github.com/klauspost/compress v1.17.10 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/loft-sh/apiserver v0.0.0-20240607231110-634aeeab2b36 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/otiai10/copy v1.11.0 // indirect
Expand Down Expand Up @@ -141,7 +141,7 @@ require (
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-github/v30 v30.1.0 // indirect
Expand Down
7 changes: 4 additions & 3 deletions pkg/controllers/generic/export_syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/loft-sh/vcluster/pkg/mappings/generic"
"github.com/loft-sh/vcluster/pkg/patcher"
"github.com/loft-sh/vcluster/pkg/syncer"
"github.com/loft-sh/vcluster/pkg/syncer/synccontext"
"github.com/loft-sh/vcluster/pkg/syncer/translator"
Expand Down Expand Up @@ -143,8 +144,8 @@ func (f *exporter) SyncToHost(ctx *synccontext.SyncContext, event *synccontext.S
}

// delete object if host was deleted
if event.IsDelete() {
return syncer.DeleteVirtualObject(ctx, event.Virtual, "host object was deleted")
if event.Virtual.GetDeletionTimestamp() != nil {
return patcher.DeleteVirtualObject(ctx, event.Virtual, event.HostOld, "host object was deleted")
}

// apply object to physical cluster
Expand Down Expand Up @@ -279,7 +280,7 @@ func (f *exporter) SyncToVirtual(ctx *synccontext.SyncContext, event *synccontex
}

// delete physical object because virtual one is missing
return syncer.DeleteHostObject(ctx, event.Host, fmt.Sprintf("delete physical %s because virtual is missing", event.Host.GetName()))
return patcher.DeleteHostObject(ctx, event.Host, event.VirtualOld, fmt.Sprintf("delete physical %s because virtual is missing", event.Host.GetName()))
}

func (f *exporter) Name() string {
Expand Down
44 changes: 27 additions & 17 deletions pkg/controllers/resources/configmaps/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ type configMapSyncer struct {
syncertypes.Importer
}

var _ syncertypes.OptionsProvider = &configMapSyncer{}

func (s *configMapSyncer) Options() *syncertypes.Options {
return &syncertypes.Options{
ObjectCaching: true,
}
}

var _ syncertypes.Syncer = &configMapSyncer{}

func (s *configMapSyncer) Syncer() syncertypes.Sync[client.Object] {
Expand All @@ -65,8 +73,8 @@ func (s *configMapSyncer) SyncToHost(ctx *synccontext.SyncContext, event *syncco
return ctrl.Result{}, nil
}

if event.IsDelete() || event.Virtual.DeletionTimestamp != nil {
return syncer.DeleteVirtualObject(ctx, event.Virtual, "host object was deleted")
if event.HostOld != nil || event.Virtual.DeletionTimestamp != nil {
return patcher.DeleteVirtualObject(ctx, event.Virtual, event.HostOld, "host object was deleted")
}

pObj := translate.HostMetadata(event.Virtual, s.VirtualToHost(ctx, types.NamespacedName{Name: event.Virtual.Name, Namespace: event.Virtual.Namespace}, event.Virtual))
Expand All @@ -75,13 +83,13 @@ func (s *configMapSyncer) SyncToHost(ctx *synccontext.SyncContext, event *syncco
return ctrl.Result{}, err
}

return syncer.CreateHostObject(ctx, event.Virtual, pObj, s.EventRecorder())
return patcher.CreateHostObject(ctx, event.Virtual, pObj, s.EventRecorder(), false)
}

func (s *configMapSyncer) SyncToVirtual(ctx *synccontext.SyncContext, event *synccontext.SyncToVirtualEvent[*corev1.ConfigMap]) (_ ctrl.Result, retErr error) {
if event.IsDelete() || event.Host.DeletionTimestamp != nil {
if event.VirtualOld != nil || event.Host.DeletionTimestamp != nil {
// virtual object is not here anymore, so we delete
return syncer.DeleteHostObject(ctx, event.Host, "virtual object was deleted")
return patcher.DeleteHostObject(ctx, event.Host, event.VirtualOld, "virtual object was deleted")
}

vObj := translate.VirtualMetadata(event.Host, s.HostToVirtual(ctx, types.NamespacedName{Name: event.Host.Name, Namespace: event.Host.Namespace}, event.Host))
Expand All @@ -95,7 +103,7 @@ func (s *configMapSyncer) SyncToVirtual(ctx *synccontext.SyncContext, event *syn
return ctrl.Result{}, err
}

return syncer.CreateVirtualObject(ctx, event.Host, vObj, s.EventRecorder())
return patcher.CreateVirtualObject(ctx, event.Host, vObj, s.EventRecorder(), false)
}

func (s *configMapSyncer) Sync(ctx *synccontext.SyncContext, event *synccontext.SyncEvent[*corev1.ConfigMap]) (_ ctrl.Result, retErr error) {
Expand All @@ -111,13 +119,13 @@ func (s *configMapSyncer) Sync(ctx *synccontext.SyncContext, event *synccontext.
return ctrl.Result{}, nil
}

patch, err := patcher.NewSyncerPatcher(ctx, event.Host, event.Virtual, patcher.TranslatePatches(ctx.Config.Sync.ToHost.ConfigMaps.Patches, false))
patchHelper, err := patcher.NewSyncerPatcher(ctx, event.Host, event.Virtual, patcher.TranslatePatches(ctx.Config.Sync.ToHost.ConfigMaps.Patches, false))
if err != nil {
return ctrl.Result{}, fmt.Errorf("new syncer patcher: %w", err)
}

defer func() {
if err := patch.Patch(ctx, event.Host, event.Virtual); err != nil {
if err := patchHelper.Patch(ctx, event.Host, event.Virtual); err != nil {
retErr = utilerrors.NewAggregate([]error{retErr, err})
}
if retErr != nil {
Expand All @@ -126,17 +134,19 @@ func (s *configMapSyncer) Sync(ctx *synccontext.SyncContext, event *synccontext.
}()

// bi-directional sync of annotations and labels
if event.Source == synccontext.SyncEventSourceHost {
event.Virtual.Annotations = translate.VirtualAnnotations(event.Host, event.Virtual)
event.Virtual.Labels = translate.VirtualLabels(event.Host, event.Virtual)
} else {
event.Host.Annotations = translate.HostAnnotations(event.Virtual, event.Host)
event.Host.Labels = translate.HostLabels(event.Virtual, event.Host)
}
event.Virtual.Annotations, event.Host.Annotations = translate.AnnotationsBidirectionalUpdate(event)
event.Virtual.Labels, event.Host.Labels = translate.LabelsBidirectionalUpdate(event)

// bidirectional sync
event.TargetObject().Data = event.SourceObject().Data
event.TargetObject().BinaryData = event.SourceObject().BinaryData
event.Virtual.Data, event.Host.Data, err = patcher.MergeBidirectional(event.VirtualOld.Data, event.Virtual.Data, event.HostOld.Data, event.Host.Data)
if err != nil {
return ctrl.Result{}, err
}
event.Virtual.BinaryData, event.Host.BinaryData, err = patcher.MergeBidirectional(event.VirtualOld.BinaryData, event.Virtual.BinaryData, event.HostOld.BinaryData, event.Host.BinaryData)
if err != nil {
return ctrl.Result{}, err
}

return ctrl.Result{}, nil
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/controllers/resources/configmaps/syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func TestSync(t *testing.T) {
},
Sync: func(ctx *synccontext.RegisterContext) {
syncCtx, syncer := syncertesting.FakeStartSyncer(t, ctx, New)
_, err := syncer.(*configMapSyncer).Sync(syncCtx, synccontext.NewSyncEvent(syncedConfigMap, updatedConfigMap))
_, err := syncer.(*configMapSyncer).Sync(syncCtx, synccontext.NewSyncEventWithOld(syncedConfigMap, syncedConfigMap, baseConfigMap, updatedConfigMap))
assert.NilError(t, err)
},
},
Expand All @@ -133,7 +133,7 @@ func TestSync(t *testing.T) {
},
Sync: func(ctx *synccontext.RegisterContext) {
syncCtx, syncer := syncertesting.FakeStartSyncer(t, ctx, New)
_, err := syncer.(*configMapSyncer).Sync(syncCtx, synccontext.NewSyncEvent(syncedConfigMap, updatedConfigMap))
_, err := syncer.(*configMapSyncer).Sync(syncCtx, synccontext.NewSyncEventWithOld(syncedConfigMap, syncedConfigMap, updatedConfigMap, updatedConfigMap))
assert.NilError(t, err)
},
},
Expand Down
26 changes: 15 additions & 11 deletions pkg/controllers/resources/endpoints/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,23 @@ type endpointsSyncer struct {
excludedAnnotations []string
}

var _ syncertypes.OptionsProvider = &endpointsSyncer{}

func (s *endpointsSyncer) Options() *syncertypes.Options {
return &syncertypes.Options{
ObjectCaching: true,
}
}

var _ syncertypes.Syncer = &endpointsSyncer{}

func (s *endpointsSyncer) Syncer() syncertypes.Sync[client.Object] {
return syncer.ToGenericSyncer(s)
}

func (s *endpointsSyncer) SyncToHost(ctx *synccontext.SyncContext, event *synccontext.SyncToHostEvent[*corev1.Endpoints]) (ctrl.Result, error) {
if event.IsDelete() {
return syncer.DeleteVirtualObject(ctx, event.Virtual, "host object was deleted")
if event.HostOld != nil {
return patcher.DeleteVirtualObject(ctx, event.Virtual, event.HostOld, "host object was deleted")
}

pObj := s.translate(ctx, event.Virtual)
Expand All @@ -59,7 +67,7 @@ func (s *endpointsSyncer) SyncToHost(ctx *synccontext.SyncContext, event *syncco
return ctrl.Result{}, err
}

return syncer.CreateHostObject(ctx, event.Virtual, pObj, s.EventRecorder())
return patcher.CreateHostObject(ctx, event.Virtual, pObj, s.EventRecorder(), false)
}

func (s *endpointsSyncer) Sync(ctx *synccontext.SyncContext, event *synccontext.SyncEvent[*corev1.Endpoints]) (_ ctrl.Result, retErr error) {
Expand All @@ -82,20 +90,16 @@ func (s *endpointsSyncer) Sync(ctx *synccontext.SyncContext, event *synccontext.
return ctrl.Result{}, err
}

if event.Source == synccontext.SyncEventSourceHost {
event.Virtual.Annotations = translate.VirtualAnnotations(event.Host, event.Virtual, s.excludedAnnotations...)
event.Virtual.Labels = translate.VirtualLabels(event.Host, event.Virtual)
} else {
event.Host.Annotations = translate.HostAnnotations(event.Virtual, event.Host, s.excludedAnnotations...)
event.Host.Labels = translate.HostLabels(event.Virtual, event.Host)
}
// bi-directional sync of annotations and labels
event.Virtual.Annotations, event.Host.Annotations = translate.AnnotationsBidirectionalUpdate(event, s.excludedAnnotations...)
event.Virtual.Labels, event.Host.Labels = translate.LabelsBidirectionalUpdate(event)

return ctrl.Result{}, nil
}

func (s *endpointsSyncer) SyncToVirtual(ctx *synccontext.SyncContext, event *synccontext.SyncToVirtualEvent[*corev1.Endpoints]) (_ ctrl.Result, retErr error) {
// virtual object is not here anymore, so we delete
return syncer.DeleteHostObject(ctx, event.Host, "virtual object was deleted")
return patcher.DeleteHostObject(ctx, event.Host, event.VirtualOld, "virtual object was deleted")
}

var _ syncertypes.Starter = &endpointsSyncer{}
Expand Down
7 changes: 1 addition & 6 deletions pkg/controllers/resources/events/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,7 @@ func (s *eventSyncer) Options() *syncertypes.Options {
}
}

func (s *eventSyncer) SyncToHost(ctx *synccontext.SyncContext, event *synccontext.SyncToHostEvent[*corev1.Event]) (ctrl.Result, error) {
// check if delete event
if event.IsDelete() {
return syncer.DeleteVirtualObject(ctx, event.Virtual, "host event was deleted")
}

func (s *eventSyncer) SyncToHost(_ *synccontext.SyncContext, _ *synccontext.SyncToHostEvent[*corev1.Event]) (ctrl.Result, error) {
// just ignore, Kubernetes will clean them up
return ctrl.Result{}, nil
}
Expand Down
29 changes: 21 additions & 8 deletions pkg/controllers/resources/ingresses/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,23 @@ type ingressSyncer struct {
syncertypes.Importer
}

var _ syncertypes.OptionsProvider = &ingressSyncer{}

func (s *ingressSyncer) Options() *syncertypes.Options {
return &syncertypes.Options{
ObjectCaching: true,
}
}

var _ syncertypes.Syncer = &ingressSyncer{}

func (s *ingressSyncer) Syncer() syncertypes.Sync[client.Object] {
return syncer.ToGenericSyncer(s)
}

func (s *ingressSyncer) SyncToHost(ctx *synccontext.SyncContext, event *synccontext.SyncToHostEvent[*networkingv1.Ingress]) (ctrl.Result, error) {
if event.IsDelete() {
return syncer.DeleteVirtualObject(ctx, event.Virtual, "host object was deleted")
if event.HostOld != nil || event.Virtual.DeletionTimestamp != nil {
return patcher.DeleteVirtualObject(ctx, event.Virtual, event.HostOld, "host object was deleted")
}

pObj, err := s.translate(ctx, event.Virtual)
Expand All @@ -60,7 +68,7 @@ func (s *ingressSyncer) SyncToHost(ctx *synccontext.SyncContext, event *synccont
return ctrl.Result{}, err
}

return syncer.CreateHostObject(ctx, event.Virtual, pObj, s.EventRecorder())
return patcher.CreateHostObject(ctx, event.Virtual, pObj, s.EventRecorder(), true)
}

func (s *ingressSyncer) Sync(ctx *synccontext.SyncContext, event *synccontext.SyncEvent[*networkingv1.Ingress]) (_ ctrl.Result, retErr error) {
Expand All @@ -78,16 +86,21 @@ func (s *ingressSyncer) Sync(ctx *synccontext.SyncContext, event *synccontext.Sy
}
}()

event.TargetObject().Spec.IngressClassName = event.SourceObject().Spec.IngressClassName
event.Virtual.Spec.IngressClassName, event.Host.Spec.IngressClassName = patcher.CopyBidirectional(
event.VirtualOld.Spec.IngressClassName,
event.Virtual.Spec.IngressClassName,
event.HostOld.Spec.IngressClassName,
event.Host.Spec.IngressClassName,
)
event.Virtual.Status = event.Host.Status
s.translateUpdate(ctx, event.Source, event.Host, event.Virtual)
s.translateUpdate(ctx, event)
return ctrl.Result{}, nil
}

func (s *ingressSyncer) SyncToVirtual(ctx *synccontext.SyncContext, event *synccontext.SyncToVirtualEvent[*networkingv1.Ingress]) (_ ctrl.Result, retErr error) {
// virtual object is not here anymore, so we delete
if event.IsDelete() || event.Host.DeletionTimestamp != nil {
return syncer.DeleteHostObject(ctx, event.Host, "virtual object was deleted")
if event.VirtualOld != nil || event.Host.DeletionTimestamp != nil {
return patcher.DeleteHostObject(ctx, event.Host, event.VirtualOld, "virtual object was deleted")
}

vIngress := translate.VirtualMetadata(event.Host, s.HostToVirtual(ctx, types.NamespacedName{Name: event.Host.Name, Namespace: event.Host.Namespace}, event.Host))
Expand All @@ -96,5 +109,5 @@ func (s *ingressSyncer) SyncToVirtual(ctx *synccontext.SyncContext, event *syncc
return ctrl.Result{}, err
}

return syncer.CreateVirtualObject(ctx, event.Host, vIngress, s.EventRecorder())
return patcher.CreateVirtualObject(ctx, event.Host, vIngress, s.EventRecorder(), true)
}
Loading

0 comments on commit 9e1cdd9

Please sign in to comment.