From 0b113999aaf838bb9546186d67259f4b2d4bfa6c Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Wed, 20 Nov 2024 08:40:15 +1100 Subject: [PATCH] fix: OCI client is slow fixes: #3400 --- backend/controller/artefacts/oci_registry.go | 18 ++++++++++++++---- backend/controller/controller.go | 6 +++++- backend/runner/runner.go | 6 +++++- frontend/cli/cmd_release.go | 7 +++++-- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/backend/controller/artefacts/oci_registry.go b/backend/controller/artefacts/oci_registry.go index befd26f945..ecfb2dcfe9 100644 --- a/backend/controller/artefacts/oci_registry.go +++ b/backend/controller/artefacts/oci_registry.go @@ -39,6 +39,7 @@ type OCIArtefactService struct { repoFactory func() (*remote.Repository, error) auth authn.AuthConfig allowInsecure bool + puller *googleremote.Puller } type ArtefactRepository struct { @@ -56,11 +57,19 @@ type ArtefactBlobs struct { } func NewForTesting() *OCIArtefactService { - return NewOCIRegistryStorage(RegistryConfig{Registry: "127.0.0.1:15000/ftl-tests", AllowInsecure: true}) + storage, err := NewOCIRegistryStorage(RegistryConfig{Registry: "127.0.0.1:15000/ftl-tests", AllowInsecure: true}) + if err != nil { + panic(err) + } + return storage } -func NewOCIRegistryStorage(c RegistryConfig) *OCIArtefactService { +func NewOCIRegistryStorage(c RegistryConfig) (*OCIArtefactService, error) { // Connect the registry targeting the specified container + puller, err := googleremote.NewPuller() + if err != nil { + return nil, fmt.Errorf("unable to create puller for registry '%s': %w", c.Registry, err) + } repoFactory := func() (*remote.Repository, error) { reg, err := remote.NewRepository(c.Registry) if err != nil { @@ -85,7 +94,8 @@ func NewOCIRegistryStorage(c RegistryConfig) *OCIArtefactService { repoFactory: repoFactory, auth: authn.AuthConfig{Username: c.Username, Password: c.Password}, allowInsecure: c.AllowInsecure, - } + puller: puller, + }, nil } func (s *OCIArtefactService) GetDigestsKeys(ctx context.Context, digests []sha256.SHA256) (keys []ArtefactKey, missing []sha256.SHA256, err error) { @@ -180,7 +190,7 @@ func (s *OCIArtefactService) Download(ctx context.Context, dg sha256.SHA256) (io if err != nil { return nil, fmt.Errorf("unable to create digest '%s': %w", dg, err) } - layer, err := googleremote.Layer(newDigest, googleremote.WithAuthFromKeychain(authn.DefaultKeychain)) + layer, err := googleremote.Layer(newDigest, googleremote.WithAuthFromKeychain(authn.DefaultKeychain), googleremote.Reuse(s.puller)) if err != nil { return nil, fmt.Errorf("unable to read layer '%s': %w", newDigest, err) } diff --git a/backend/controller/controller.go b/backend/controller/controller.go index 9b8d121492..1655c17e08 100644 --- a/backend/controller/controller.go +++ b/backend/controller/controller.go @@ -296,7 +296,11 @@ func New( } svc.schemaState.Store(schemaState{routes: map[string]Route{}, schema: &schema.Schema{}}) - svc.registry = artefacts.NewOCIRegistryStorage(config.Registry) + storage, err := artefacts.NewOCIRegistryStorage(config.Registry) + if err != nil { + return nil, fmt.Errorf("failed to create OCI registry storage: %w", err) + } + svc.registry = storage timelineSvc := timeline.New(ctx, conn, encryption) svc.timeline = timelineSvc diff --git a/backend/runner/runner.go b/backend/runner/runner.go index 5bec578f3a..4c8454120a 100644 --- a/backend/runner/runner.go +++ b/backend/runner/runner.go @@ -339,7 +339,11 @@ func (s *Service) deploy(ctx context.Context) error { return fmt.Errorf("failed to create deployment directory: %w", err) } } - err = download.ArtefactsFromOCI(ctx, s.controllerClient, key, deploymentDir, artefacts.NewOCIRegistryStorage(s.config.Registry)) + storage, err := artefacts.NewOCIRegistryStorage(s.config.Registry) + if err != nil { + return fmt.Errorf("failed to create OCI registry storage: %w", err) + } + err = download.ArtefactsFromOCI(ctx, s.controllerClient, key, deploymentDir, storage) if err != nil { observability.Deployment.Failure(ctx, optional.Some(key.String())) return fmt.Errorf("failed to download artefacts: %w", err) diff --git a/frontend/cli/cmd_release.go b/frontend/cli/cmd_release.go index 20028e9ce4..53e1a29ebd 100644 --- a/frontend/cli/cmd_release.go +++ b/frontend/cli/cmd_release.go @@ -81,6 +81,9 @@ func createContainerService(release *releaseCmd) (*artefacts.OCIArtefactService, } conn.SetMaxIdleConns(release.MaxIdleDBConnections) conn.SetMaxOpenConns(release.MaxOpenDBConnections) - - return artefacts.NewOCIRegistryStorage(release.Registry), nil + storage, err := artefacts.NewOCIRegistryStorage(release.Registry) + if err != nil { + return nil, fmt.Errorf("failed to create OCI registry storage: %w", err) + } + return storage, nil }