From 7f6db2181cba09225e26886d1ddc3e509957e86b Mon Sep 17 00:00:00 2001 From: Balazs Nadasdi Date: Wed, 3 Nov 2021 12:18:08 +0100 Subject: [PATCH] Ability to query older versions of a vmspec (#184) I tried to come up with a proper solution to this, but all of them had flaws. == Options I found and explored their possibilities 1. Add a new version argument to the Get function. That's just ugly as hell. I like the Options pattern. Much easier to update without breaking 300 calls in the codebase. 2. Add a new function on the Repo. It seems odd and I think it's unnecessary because Get can handle it. 3. Create a function only on the Containerd repo implementation. That would require checks and casting everywhere we want to use it. == Conclusion I picked options 1, because it causes less pain not and long term. It does not matter what content store we are using, it HAS to be able to manage versions somehow, even if it's an external service, the Repository implementation has to handle versions, without versions we are are playing with a bag of venomous snakes without any kind of antidote, maybe fun, but not safe. Related to #66 --- core/application/app_test.go | 59 ++++++++++------ core/application/commands.go | 19 +++++- core/application/query.go | 3 +- core/application/reconcile.go | 6 +- core/errors/errors.go | 10 ++- core/ports/repositories.go | 8 ++- go.mod | 4 ++ go.sum | 3 + infrastructure/containerd/repo.go | 93 +++++++++++++++++--------- infrastructure/containerd/repo_test.go | 26 +++++-- infrastructure/mock/mock.go | 8 +-- 11 files changed, 165 insertions(+), 74 deletions(-) diff --git a/core/application/app_test.go b/core/application/app_test.go index f8f7caf4..e3875846 100644 --- a/core/application/app_test.go +++ b/core/application/app_test.go @@ -42,12 +42,11 @@ func TestApp_CreateMicroVM(t *testing.T) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq(defaults.MicroVMNamespace), - ).Return( - nil, - nil, - ) + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: defaults.MicroVMNamespace, + }), + ).Return(nil, nil) expectedCreatedSpec := createTestSpec("id1234", defaults.MicroVMNamespace) expectedCreatedSpec.Spec.CreatedAt = frozenTime().Unix() @@ -78,8 +77,10 @@ func TestApp_CreateMicroVM(t *testing.T) { expect: func(rm *mock.MockMicroVMRepositoryMockRecorder, em *mock.MockEventServiceMockRecorder, im *mock.MockIDServiceMockRecorder, pm *mock.MockMicroVMServiceMockRecorder) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq("default"), + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: "default", + }), ).Return( nil, nil, @@ -114,8 +115,10 @@ func TestApp_CreateMicroVM(t *testing.T) { expect: func(rm *mock.MockMicroVMRepositoryMockRecorder, em *mock.MockEventServiceMockRecorder, im *mock.MockIDServiceMockRecorder, pm *mock.MockMicroVMServiceMockRecorder) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq("default"), + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: "default", + }), ).Return( createTestSpec("id1234", "default"), nil, @@ -193,8 +196,10 @@ func TestApp_UpdateMicroVM(t *testing.T) { expect: func(rm *mock.MockMicroVMRepositoryMockRecorder, em *mock.MockEventServiceMockRecorder, im *mock.MockIDServiceMockRecorder, pm *mock.MockMicroVMServiceMockRecorder) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq("default"), + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: "default", + }), ).Return( createTestSpec("id1234", "default"), nil, @@ -289,8 +294,10 @@ func TestApp_DeleteMicroVM(t *testing.T) { expect: func(rm *mock.MockMicroVMRepositoryMockRecorder, em *mock.MockEventServiceMockRecorder, im *mock.MockIDServiceMockRecorder, pm *mock.MockMicroVMServiceMockRecorder) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq("default"), + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: "default", + }), ).Return( createTestSpec("id1234", "default"), nil, @@ -325,8 +332,10 @@ func TestApp_DeleteMicroVM(t *testing.T) { expect: func(rm *mock.MockMicroVMRepositoryMockRecorder, em *mock.MockEventServiceMockRecorder, im *mock.MockIDServiceMockRecorder, pm *mock.MockMicroVMServiceMockRecorder) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq("default"), + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: "default", + }), ).Return( nil, nil, @@ -409,8 +418,10 @@ func TestApp_GetMicroVM(t *testing.T) { expect: func(rm *mock.MockMicroVMRepositoryMockRecorder, em *mock.MockEventServiceMockRecorder, im *mock.MockIDServiceMockRecorder, pm *mock.MockMicroVMServiceMockRecorder) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq("default"), + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: defaults.MicroVMNamespace, + }), ).Return( nil, nil, @@ -425,8 +436,10 @@ func TestApp_GetMicroVM(t *testing.T) { expect: func(rm *mock.MockMicroVMRepositoryMockRecorder, em *mock.MockEventServiceMockRecorder, im *mock.MockIDServiceMockRecorder, pm *mock.MockMicroVMServiceMockRecorder) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq("default"), + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: defaults.MicroVMNamespace, + }), ).Return( nil, errors.New("an random error occurred"), @@ -441,8 +454,10 @@ func TestApp_GetMicroVM(t *testing.T) { expect: func(rm *mock.MockMicroVMRepositoryMockRecorder, em *mock.MockEventServiceMockRecorder, im *mock.MockIDServiceMockRecorder, pm *mock.MockMicroVMServiceMockRecorder) { rm.Get( gomock.AssignableToTypeOf(context.Background()), - gomock.Eq("id1234"), - gomock.Eq("default"), + gomock.Eq(ports.RepositoryGetOptions{ + Name: "id1234", + Namespace: defaults.MicroVMNamespace, + }), ).Return( createTestSpec("id1234", "default"), nil, diff --git a/core/application/commands.go b/core/application/commands.go index 723126e9..c159ba04 100644 --- a/core/application/commands.go +++ b/core/application/commands.go @@ -7,6 +7,7 @@ import ( "github.com/weaveworks/flintlock/api/events" coreerrs "github.com/weaveworks/flintlock/core/errors" "github.com/weaveworks/flintlock/core/models" + "github.com/weaveworks/flintlock/core/ports" "github.com/weaveworks/flintlock/pkg/defaults" "github.com/weaveworks/flintlock/pkg/log" ) @@ -31,12 +32,16 @@ func (a *app) CreateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.M mvm.ID = *vmid } - foundMvm, err := a.ports.Repo.Get(ctx, mvm.ID.Name(), mvm.ID.Namespace()) + foundMvm, err := a.ports.Repo.Get(ctx, ports.RepositoryGetOptions{ + Name: mvm.ID.Name(), + Namespace: mvm.ID.Namespace(), + }) if err != nil { if !coreerrs.IsSpecNotFound(err) { return nil, fmt.Errorf("checking to see if spec exists: %w", err) } } + if foundMvm != nil { return nil, specAlreadyExistsError{ name: mvm.ID.Name(), @@ -76,10 +81,14 @@ func (a *app) UpdateMicroVM(ctx context.Context, mvm *models.MicroVM) (*models.M return nil, coreerrs.ErrVMIDRequired } - foundMvm, err := a.ports.Repo.Get(ctx, mvm.ID.Name(), mvm.ID.Namespace()) + foundMvm, err := a.ports.Repo.Get(ctx, ports.RepositoryGetOptions{ + Name: mvm.ID.Name(), + Namespace: mvm.ID.Namespace(), + }) if err != nil { return nil, fmt.Errorf("checking to see if spec exists: %w", err) } + if foundMvm == nil { return nil, specNotFoundError{ name: mvm.ID.Name(), @@ -116,10 +125,14 @@ func (a *app) DeleteMicroVM(ctx context.Context, id, namespace string) error { return errIDRequired } - foundMvm, err := a.ports.Repo.Get(ctx, id, namespace) + foundMvm, err := a.ports.Repo.Get(ctx, ports.RepositoryGetOptions{ + Name: id, + Namespace: namespace, + }) if err != nil { return fmt.Errorf("checking to see if spec exists: %w", err) } + if foundMvm == nil { return specNotFoundError{ name: id, diff --git a/core/application/query.go b/core/application/query.go index 3b2712fc..ec61ccd7 100644 --- a/core/application/query.go +++ b/core/application/query.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/weaveworks/flintlock/core/models" + "github.com/weaveworks/flintlock/core/ports" "github.com/weaveworks/flintlock/pkg/log" ) @@ -20,7 +21,7 @@ func (a *app) GetMicroVM(ctx context.Context, id, namespace string) (*models.Mic return nil, errNamespaceRequired } - foundMvm, err := a.ports.Repo.Get(ctx, id, namespace) + foundMvm, err := a.ports.Repo.Get(ctx, ports.RepositoryGetOptions{Name: id, Namespace: namespace}) if err != nil { return nil, fmt.Errorf("error attempting to locate microvm with id: %s, in namespace: %s: %w", id, namespace, err) } diff --git a/core/application/reconcile.go b/core/application/reconcile.go index 51ffe823..cebf89e0 100644 --- a/core/application/reconcile.go +++ b/core/application/reconcile.go @@ -8,6 +8,7 @@ import ( "github.com/weaveworks/flintlock/core/models" "github.com/weaveworks/flintlock/core/plans" + "github.com/weaveworks/flintlock/core/ports" portsctx "github.com/weaveworks/flintlock/core/ports/context" "github.com/weaveworks/flintlock/pkg/log" "github.com/weaveworks/flintlock/pkg/planner" @@ -17,7 +18,10 @@ func (a *app) ReconcileMicroVM(ctx context.Context, id, namespace string) error logger := log.GetLogger(ctx).WithField("action", "reconcile") logger.Debugf("Getting spec for %s/%s", namespace, id) - spec, err := a.ports.Repo.Get(ctx, id, namespace) + spec, err := a.ports.Repo.Get(ctx, ports.RepositoryGetOptions{ + Name: id, + Namespace: namespace, + }) if err != nil { return fmt.Errorf("getting microvm spec for reconcile: %w", err) } diff --git a/core/errors/errors.go b/core/errors/errors.go index d68d2dfb..71a63eab 100644 --- a/core/errors/errors.go +++ b/core/errors/errors.go @@ -89,21 +89,27 @@ func (e NetworkInterfaceStatusMissingError) Error() string { return fmt.Sprintf("status for network interface %s is not found", e.guestIface) } -func NewSpecNotFound(name, namespace string) error { +func NewSpecNotFound(name, namespace, version string) error { return specNotFoundError{ name: name, namespace: namespace, + version: version, } } type specNotFoundError struct { name string namespace string + version string } // Error returns the error message. func (e specNotFoundError) Error() string { - return fmt.Sprintf("microvm spec %s/%s not found", e.namespace, e.name) + if e.version == "" { + return fmt.Sprintf("microvm spec %s/%s not found", e.namespace, e.name) + } + + return fmt.Sprintf("microvm spec %s/%s not found with version %s", e.namespace, e.name, e.version) } // IsSpecNotFound tests an error to see if its a spec not found error. diff --git a/core/ports/repositories.go b/core/ports/repositories.go index f57c1704..35f7d244 100644 --- a/core/ports/repositories.go +++ b/core/ports/repositories.go @@ -6,6 +6,12 @@ import ( "github.com/weaveworks/flintlock/core/models" ) +type RepositoryGetOptions struct { + Name string + Namespace string + Version string +} + // MicroVMRepository is the port definition for a microvm repository. type MicroVMRepository interface { // Save will save the supplied microvm spec. @@ -13,7 +19,7 @@ type MicroVMRepository interface { // Delete will delete the supplied microvm. Delete(ctx context.Context, microvm *models.MicroVM) error // Get will get the microvm spec with the given name/namespace. - Get(ctx context.Context, name, namespace string) (*models.MicroVM, error) + Get(ctx context.Context, options RepositoryGetOptions) (*models.MicroVM, error) // GetAll will get a list of microvm details. If namespace is an empty string all // details of microvms will be returned. GetAll(ctx context.Context, namespace string) ([]*models.MicroVM, error) diff --git a/go.mod b/go.mod index e96148c0..60900641 100644 --- a/go.mod +++ b/go.mod @@ -74,6 +74,7 @@ require ( github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.3 // indirect + github.com/google/subcommands v1.0.1 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-multierror v1.1.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -102,9 +103,12 @@ require ( go.mongodb.org/mongo-driver v1.3.4 // indirect go.opencensus.io v0.23.0 // indirect golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/mod v0.4.2 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect golang.org/x/text v0.3.6 // indirect + golang.org/x/tools v0.1.5 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/genproto v0.0.0-20211021150943-2b146023228c // indirect gopkg.in/ini.v1 v1.63.2 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect diff --git a/go.sum b/go.sum index cf18ac46..134f70c5 100644 --- a/go.sum +++ b/go.sum @@ -522,6 +522,7 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -1011,6 +1012,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1279,6 +1281,7 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/infrastructure/containerd/repo.go b/infrastructure/containerd/repo.go index ee105152..36dd035c 100644 --- a/infrastructure/containerd/repo.go +++ b/infrastructure/containerd/repo.go @@ -57,7 +57,10 @@ func (r *containerdRepo) Save(ctx context.Context, microvm *models.MicroVM) (*mo mu.Lock() defer mu.Unlock() - existingSpec, err := r.get(ctx, microvm.ID.Name(), microvm.ID.Namespace()) + existingSpec, err := r.get(ctx, ports.RepositoryGetOptions{ + Name: microvm.ID.Name(), + Namespace: microvm.ID.Namespace(), + }) if err != nil { return nil, fmt.Errorf("getting vm spec from store: %w", err) } @@ -106,24 +109,25 @@ func (r *containerdRepo) Save(ctx context.Context, microvm *models.MicroVM) (*mo } // Get will get the microvm spec with the given name/namespace from the containerd content store. -func (r *containerdRepo) Get(ctx context.Context, name, namespace string) (*models.MicroVM, error) { - mu := r.getMutex(name) +// If version is not empty, returns with the specified version of the spec. +func (r *containerdRepo) Get(ctx context.Context, options ports.RepositoryGetOptions) (*models.MicroVM, error) { + mu := r.getMutex(options.Name) mu.RLock() defer mu.RUnlock() - spec, err := r.get(ctx, name, namespace) + spec, err := r.get(ctx, options) if err != nil { return nil, fmt.Errorf("getting vm spec from store: %w", err) } if spec == nil { - return nil, errors.NewSpecNotFound(name, namespace) //nolint: wrapcheck + return nil, errors.NewSpecNotFound(options.Name, options.Namespace, options.Version) } return spec, nil } -// GetAll will get a list of microvm details from the containerd content store. If namespace is an empty string all -// details of microvms will be returned. +// GetAll will get a list of microvm details from the containerd content store. +// If namespace is an empty string all microvms will be returned from all namespaces. func (r *containerdRepo) GetAll(ctx context.Context, namespace string) ([]*models.MicroVM, error) { namespaceCtx := namespaces.WithNamespace(ctx, r.config.Namespace) store := r.client.ContentStore() @@ -218,10 +222,14 @@ func (r *containerdRepo) Exists(ctx context.Context, name, namespace string) (bo namespaceCtx := namespaces.WithNamespace(ctx, r.config.Namespace) - digest, err := r.findLatestDigestForSpec(namespaceCtx, name, namespace) + digest, err := r.findDigestForSpec( + namespaceCtx, + ports.RepositoryGetOptions{Name: name, Namespace: namespace}, + ) if err != nil { return false, fmt.Errorf("finding digest for %s/%s: %w", name, namespace, err) } + if digest == nil { return false, nil } @@ -229,10 +237,10 @@ func (r *containerdRepo) Exists(ctx context.Context, name, namespace string) (bo return true, nil } -func (r *containerdRepo) get(ctx context.Context, name, namespace string) (*models.MicroVM, error) { +func (r *containerdRepo) get(ctx context.Context, options ports.RepositoryGetOptions) (*models.MicroVM, error) { namespaceCtx := namespaces.WithNamespace(ctx, r.config.Namespace) - digest, err := r.findLatestDigestForSpec(namespaceCtx, name, namespace) + digest, err := r.findDigestForSpec(namespaceCtx, options) if err != nil { return nil, fmt.Errorf("finding content in store: %w", err) } @@ -260,45 +268,64 @@ func (r *containerdRepo) getWithDigest(ctx context.Context, metadigest *digest.D return microvm, nil } -func (r *containerdRepo) findLatestDigestForSpec(ctx context.Context, name, namespace string) (*digest.Digest, error) { - idLabelFilter := labelFilter(NameLabel, name) - nsFilter := labelFilter(NamespaceLabel, namespace) - allFilter := strings.Join([]string{idLabelFilter, nsFilter}, ",") +func (r *containerdRepo) findDigestForSpec(ctx context.Context, options ports.RepositoryGetOptions) (*digest.Digest, error) { + idLabelFilter := labelFilter(NameLabel, options.Name) + nsFilter := labelFilter(NamespaceLabel, options.Namespace) + versionFilter := labelFilter(VersionLabel, options.Version) + + combinedFilters := []string{idLabelFilter, nsFilter} + + if options.Version != "" { + combinedFilters = append(combinedFilters, versionFilter) + } + + allFilters := strings.Join(combinedFilters, ",") store := r.client.ContentStore() var digest *digest.Digest highestVersion := 0 - err := store.Walk(ctx, func(i content.Info) error { - version, err := strconv.Atoi(i.Labels[VersionLabel]) - if err != nil { - return fmt.Errorf("parsing version number: %w", err) - } - if version > highestVersion { - digest = &i.Digest - highestVersion = version - } - - return nil - }, allFilter) + err := store.Walk( + ctx, + func(i content.Info) error { + version, err := strconv.Atoi(i.Labels[VersionLabel]) + if err != nil { + return fmt.Errorf("parsing version number: %w", err) + } + + if version > highestVersion { + digest = &i.Digest + highestVersion = version + } + + return nil + }, + allFilters, + ) if err != nil { - return nil, fmt.Errorf("walking content store for %s: %w", name, err) + return nil, fmt.Errorf("walking content store for %s: %w", options.Name, err) } return digest, nil } func (r *containerdRepo) findAllDigestForSpec(ctx context.Context, name, namespace string) ([]*digest.Digest, error) { + store := r.client.ContentStore() idLabelFilter := labelFilter(NameLabel, name) nsLabelFilter := labelFilter(NamespaceLabel, namespace) - store := r.client.ContentStore() + combinedFilters := []string{idLabelFilter, nsLabelFilter} + allFilters := strings.Join(combinedFilters, ",") digests := []*digest.Digest{} - err := store.Walk(ctx, func(i content.Info) error { - digests = append(digests, &i.Digest) - - return nil - }, idLabelFilter, nsLabelFilter) + err := store.Walk( + ctx, + func(i content.Info) error { + digests = append(digests, &i.Digest) + + return nil + }, + allFilters, + ) if err != nil { return nil, fmt.Errorf("walking content store for %s: %w", name, err) } diff --git a/infrastructure/containerd/repo_test.go b/infrastructure/containerd/repo_test.go index 7379b340..72fae3d6 100644 --- a/infrastructure/containerd/repo_test.go +++ b/infrastructure/containerd/repo_test.go @@ -6,6 +6,7 @@ import ( . "github.com/onsi/gomega" "github.com/weaveworks/flintlock/core/models" + "github.com/weaveworks/flintlock/core/ports" "github.com/weaveworks/flintlock/infrastructure/containerd" ) @@ -43,10 +44,22 @@ func TestMicroVMRepo_Integration(t *testing.T) { Expect(err).NotTo(HaveOccurred()) Expect(exists).To(BeTrue()) - gotVM, err := repo.Get(ctx, testOwnerName, testOwnerNamespace) + gotVM, err := repo.Get(ctx, ports.RepositoryGetOptions{ + Name: testOwnerName, + Namespace: testOwnerNamespace, + }) Expect(err).NotTo(HaveOccurred()) Expect(gotVM).NotTo(BeNil()) - Expect(savedVM.Version).To(Equal(3)) + Expect(gotVM.Version).To(Equal(3)) + + olderVM, err := repo.Get(ctx, ports.RepositoryGetOptions{ + Name: testOwnerName, + Namespace: testOwnerNamespace, + Version: "2", + }) + Expect(err).NotTo(HaveOccurred()) + Expect(olderVM).NotTo(BeNil()) + Expect(olderVM.Version).To(Equal(2)) all, err := repo.GetAll(ctx, testOwnerNamespace) Expect(err).NotTo(HaveOccurred()) @@ -59,11 +72,10 @@ func TestMicroVMRepo_Integration(t *testing.T) { Expect(err).NotTo(HaveOccurred()) Expect(exists).To(BeFalse()) - exists, err = repo.Exists(ctx, testOwnerName, testOwnerNamespace) - Expect(err).NotTo(HaveOccurred()) - Expect(exists).To(BeFalse()) - - _, err = repo.Get(ctx, testOwnerName, testOwnerNamespace) + _, err = repo.Get(ctx, ports.RepositoryGetOptions{ + Name: testOwnerName, + Namespace: testOwnerNamespace, + }) Expect(err).To(HaveOccurred()) } diff --git a/infrastructure/mock/mock.go b/infrastructure/mock/mock.go index 03c2bc61..07293259 100644 --- a/infrastructure/mock/mock.go +++ b/infrastructure/mock/mock.go @@ -202,18 +202,18 @@ func (mr *MockMicroVMRepositoryMockRecorder) Exists(arg0, arg1, arg2 interface{} } // Get mocks base method. -func (m *MockMicroVMRepository) Get(arg0 context.Context, arg1, arg2 string) (*models.MicroVM, error) { +func (m *MockMicroVMRepository) Get(arg0 context.Context, arg1 ports.RepositoryGetOptions) (*models.MicroVM, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "Get", arg0, arg1) ret0, _ := ret[0].(*models.MicroVM) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockMicroVMRepositoryMockRecorder) Get(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockMicroVMRepositoryMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMicroVMRepository)(nil).Get), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMicroVMRepository)(nil).Get), arg0, arg1) } // GetAll mocks base method.