From a6869ab7464a065cda65feb884cad87c285faf2a Mon Sep 17 00:00:00 2001 From: yang qf Date: Sun, 12 Mar 2017 15:04:56 -0500 Subject: [PATCH] Fix function delete with uid (#142) If no uid is provided, all versions of function files and function metadata will be deleted. If a uid is provided, only that specific version is deleted, and the "latest" version of the function moves back to the previous one. Fixes #152 --- controller/api_test.go | 55 +++++++++++++++++++++++++++++++++++++ controller/functionStore.go | 21 +++++++++++++- controller/resourceStore.go | 2 +- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/controller/api_test.go b/controller/api_test.go index 535936a0..94779edf 100644 --- a/controller/api_test.go +++ b/controller/api_test.go @@ -126,6 +126,61 @@ func TestFunctionApi(t *testing.T) { panicIf(err) } +func TestFunctionVersionApi(t *testing.T) { + testFunc := &fission.Function{ + Metadata: fission.Metadata{ + Name: "foo", + Uid: "", + }, + Environment: fission.Metadata{ + Name: "nodejs", + Uid: "xxx", + }, + Code: "code1", + } + + testFunc.Code = "code1" + m, err := g.client.FunctionCreate(testFunc) + panicIf(err) + uid1 := m.Uid + + testFunc.Code = "code2" + m, err = g.client.FunctionUpdate(testFunc) + panicIf(err) + uid2 := m.Uid + + err = g.client.FunctionDelete(&fission.Metadata{Name: "foo", Uid: uid1}) + panicIf(err) + + f, err := g.client.FunctionGet(&fission.Metadata{Name: "foo"}) + panicIf(err) + assert(f.Metadata.Uid == uid2, "deleted version1, but version2 does not exist") + + testFunc.Code = "code3" + m, err = g.client.FunctionUpdate(testFunc) + panicIf(err) + uid3 := m.Uid + + err = g.client.FunctionDelete(&fission.Metadata{Name: "foo", Uid: uid3}) + panicIf(err) + + f, err = g.client.FunctionGet(&fission.Metadata{Name: "foo"}) + panicIf(err) + assert(f.Metadata.Uid == uid2, "deleted version3, but version2 does not exist") + + testFunc.Code = "code4" + m, err = g.client.FunctionUpdate(testFunc) + panicIf(err) + + err = g.client.FunctionDelete(&fission.Metadata{Name: "foo"}) + panicIf(err) + + funcs, err := g.client.FunctionList() + panicIf(err) + assert(len(funcs) == 0, + "created one function with two versions(2 and 4), delete without uid but cannot delete them all") +} + func TestHTTPTriggerApi(t *testing.T) { testTrigger := &fission.HTTPTrigger{ Metadata: fission.Metadata{ diff --git a/controller/functionStore.go b/controller/functionStore.go index a6fdfe99..da81c451 100644 --- a/controller/functionStore.go +++ b/controller/functionStore.go @@ -108,7 +108,26 @@ func (fs *FunctionStore) Delete(m fission.Metadata) error { if err != nil { return err } - return fs.ResourceStore.delete(typeName, m.Name) + + bufs, err := fs.ResourceStore.getAll("file/" + m.Name) + if err != nil { + return err + } + if len(bufs) == 0 { + return fs.ResourceStore.delete(typeName, m.Name) + } + + fnew, err := fs.Get(&fission.Metadata{Name: m.Name}) + if err != nil { + return err + } + + latestUid := bufs[len(bufs)-1] // function always tracks the latest version of code + if latestUid == fnew.Uid { + return nil + } + fnew.Uid = latestUid + return fs.ResourceStore.update(fnew) } func (fs *FunctionStore) List() ([]fission.Function, error) { diff --git a/controller/resourceStore.go b/controller/resourceStore.go index 93fc9f5d..605c0f68 100644 --- a/controller/resourceStore.go +++ b/controller/resourceStore.go @@ -139,7 +139,7 @@ func (rs *ResourceStore) delete(typename, rkey string) error { // getAll finds all entries under key. If none or found or key // doesn't exist, returns an empty slice. func (rs *ResourceStore) getAll(key string) ([]string, error) { - resp, err := rs.KeysAPI.Get(context.Background(), key, &client.GetOptions{Recursive: true}) + resp, err := rs.KeysAPI.Get(context.Background(), key, &client.GetOptions{Recursive: true, Sort: true}) if err != nil { if client.IsKeyNotFound(err) { return []string{}, nil