Skip to content

Commit

Permalink
Images in state of OBSOLETE or DELETED still exist, use new typed err…
Browse files Browse the repository at this point in the history
…or (#288)

Images in state of OBSOLETE or DELETED still exist and should be added to the registry
This allows DeleteResources to delete images in this state
  • Loading branch information
adjackura committed Jan 19, 2018
1 parent f0e53e3 commit 0a75bca
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 25 deletions.
5 changes: 5 additions & 0 deletions daisy/disk_test.go
Expand Up @@ -369,6 +369,11 @@ func TestDiskValidate(t *testing.T) {
&Disk{Disk: compute.Disk{Name: "d4", SizeGb: 1, Type: ty}},
false,
},
{
"image OBSOLETE case",
&Disk{Disk: compute.Disk{Name: "d1", SourceImage: fmt.Sprintf("projects/foo/global/images/%s", testImage), Type: ty}},
true,
},
{
"source image dne case",
&Disk{Disk: compute.Disk{Name: "d5", SourceImage: "dne", Type: ty}},
Expand Down
9 changes: 5 additions & 4 deletions daisy/error.go
Expand Up @@ -20,10 +20,11 @@ import (
)

const (
untypedError = ""
multiError = "MultiError"
fileIOError = "FileIOError"
resourceDNEError = "ResourceDoesNotExist"
untypedError = ""
multiError = "MultiError"
fileIOError = "FileIOError"
resourceDNEError = "ResourceDoesNotExist"
imageObsoleteDeletedError = "ImageObsoleteOrDeleted"

apiError = "APIError"
apiError404 = "APIError404"
Expand Down
25 changes: 13 additions & 12 deletions daisy/image.go
Expand Up @@ -29,7 +29,7 @@ import (

var (
imageCache struct {
exists map[string][]string
exists map[string][]*compute.Image
mu sync.Mutex
}
imageFamilyCache struct {
Expand Down Expand Up @@ -64,7 +64,7 @@ func imageExists(client daisyCompute.Client, project, family, name string) (bool
}
if img.Deprecated != nil {
if img.Deprecated.State == "OBSOLETE" || img.Deprecated.State == "DELETED" {
return false, nil
return true, typedErrf(imageObsoleteDeletedError, "image %q in state %q", img.Name, img.Deprecated.State)
}
}
imageFamilyCache.exists[project] = append(imageFamilyCache.exists[project], name)
Expand All @@ -77,25 +77,26 @@ func imageExists(client daisyCompute.Client, project, family, name string) (bool
imageCache.mu.Lock()
defer imageCache.mu.Unlock()
if imageCache.exists == nil {
imageCache.exists = map[string][]string{}
imageCache.exists = map[string][]*compute.Image{}
}
if _, ok := imageCache.exists[project]; !ok {
il, err := client.ListImages(project)
if err != nil {
return false, errf("error listing images for project %q: %v", project, err)
}
var images []string
for _, i := range il {
if i.Deprecated != nil {
if i.Deprecated.State == "OBSOLETE" || i.Deprecated.State == "DELETED" {
continue
}
imageCache.exists[project] = il
}

for _, i := range imageCache.exists[project] {
if name == i.Name {
if i.Deprecated != nil && (i.Deprecated.State == "OBSOLETE" || i.Deprecated.State == "DELETED") {
return true, typedErrf(imageObsoleteDeletedError, "image %q in state %q", name, i.Deprecated.State)
}
images = append(images, i.Name)
return true, nil
}
imageCache.exists[project] = images
}
return strIn(name, imageCache.exists[project]), nil

return false, nil
}

// Image is used to create a GCE image.
Expand Down
10 changes: 6 additions & 4 deletions daisy/resource_registry.go
Expand Up @@ -148,16 +148,18 @@ func (r *baseResourceRegistry) registerExisting(url string) (*Resource, dErr) {
if r, ok := r.m[url]; ok {
return r, nil
}
if exists, err := resourceExists(r.w.ComputeClient, url); err != nil {
return nil, err
} else if !exists {
exists, err := resourceExists(r.w.ComputeClient, url)
if !exists {
if err != nil {
return nil, err
}
return nil, typedErrf(resourceDNEError, "%s does not exist", url)
}

parts := strings.Split(url, "/")
res := &Resource{RealName: parts[len(parts)-1], link: url, NoCleanup: true}
r.m[url] = res
return res, nil
return res, err
}

func (r *baseResourceRegistry) registerUsage(name string, s *Step) (*Resource, dErr) {
Expand Down
5 changes: 3 additions & 2 deletions daisy/step_delete_resources.go
Expand Up @@ -16,9 +16,8 @@ package daisy

import (
"context"
"sync"

"log"
"sync"

compute "google.golang.org/api/compute/v1"
)
Expand Down Expand Up @@ -78,6 +77,8 @@ func (d *DeleteResources) checkError(err dErr, logger *log.Logger) dErr {
if err != nil && err.Type() == resourceDNEError {
logger.Printf("DeleteResources WARNING: Error validating deletion: %v", err)
return nil
} else if err != nil && err.Type() == imageObsoleteDeletedError {
return nil
}
return err
}
Expand Down
2 changes: 1 addition & 1 deletion daisy/step_delete_resources_test.go
Expand Up @@ -120,7 +120,7 @@ func TestDeleteResourcesValidate(t *testing.T) {
}

// Good case.
dr := DeleteResources{Disks: []string{"d0"}, Images: []string{"im0"}, Instances: []string{"in0"}}
dr := DeleteResources{Disks: []string{"d0"}, Images: []string{"im0", "projects/foo/global/images/" + testImage, "projects/foo/global/images/family/foo"}, Instances: []string{"in0"}}
if err := dr.validate(ctx, s); err != nil {
t.Errorf("validation should not have failed: %v", err)
}
Expand Down
13 changes: 11 additions & 2 deletions daisy/test_common_test.go
Expand Up @@ -161,8 +161,11 @@ func newTestGCEClient() (*daisyCompute.TestClient, error) {
c.ListZonesFn = func(_ string, _ ...daisyCompute.ListCallOption) ([]*compute.Zone, error) {
return []*compute.Zone{{Name: testZone}}, nil
}
c.ListImagesFn = func(_ string, _ ...daisyCompute.ListCallOption) ([]*compute.Image, error) {
return []*compute.Image{{Name: testImage}}, nil
c.ListImagesFn = func(p string, _ ...daisyCompute.ListCallOption) ([]*compute.Image, error) {
if p == testProject {
return []*compute.Image{{Name: testImage}}, nil
}
return []*compute.Image{{Name: testImage, Deprecated: &compute.DeprecationStatus{State: "OBSOLETE"}}}, nil
}
c.ListDisksFn = func(p, z string, _ ...daisyCompute.ListCallOption) ([]*compute.Disk, error) {
if p != testProject {
Expand Down Expand Up @@ -200,6 +203,12 @@ func newTestGCEClient() (*daisyCompute.TestClient, error) {
}
return nil
}
c.GetImageFromFamilyFn = func(_, f string) (*compute.Image, error) {
if f == testFamily {
return &compute.Image{Name: testImage}, nil
}
return &compute.Image{Name: testImage, Deprecated: &compute.DeprecationStatus{State: "OBSOLETE"}}, nil
}

return c, err
}
Expand Down

0 comments on commit 0a75bca

Please sign in to comment.