1// Copyright 2017-2018 VMware, Inc. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package mock 16 17import ( 18 "fmt" 19 "io" 20 "net/url" 21 "os" 22 23 "github.com/vmware/govmomi/object" 24 "github.com/vmware/govmomi/vim25/mo" 25 "github.com/vmware/vic/lib/portlayer/storage/image" 26 "github.com/vmware/vic/lib/portlayer/util" 27 "github.com/vmware/vic/pkg/trace" 28 "github.com/vmware/vic/pkg/vsphere/vm" 29) 30 31type MockDataStore struct { 32 object.DatastorePath 33 34 // id -> image 35 db map[url.URL]map[string]*image.Image 36 37 createImageStoreError error 38 writeImageError error 39} 40 41func NewMockDataStore(images map[url.URL]map[string]*image.Image) *MockDataStore { 42 m := &MockDataStore{ 43 db: images, 44 } 45 46 if m.db == nil { 47 m.db = make(map[url.URL]map[string]*image.Image) 48 } 49 50 return m 51} 52 53// SetWriteImageError injects an error to be returned on next call to WriteImage 54func (c *MockDataStore) SetWriteImageError(err error) { 55 c.writeImageError = err 56} 57 58// SetCreateImageStoreError injects an error to be returned on next call to CreateImageStore 59func (c *MockDataStore) SetCreateImageStoreError(err error) { 60 c.createImageStoreError = err 61} 62 63// GetImageStore checks to see if a named image store exists and returls the 64// URL to it if so or error. 65func (c *MockDataStore) GetImageStore(op trace.Operation, storeName string) (*url.URL, error) { 66 u, err := util.ImageStoreNameToURL(storeName) 67 if err != nil { 68 return nil, err 69 } 70 71 if _, ok := c.db[*u]; !ok { 72 return nil, os.ErrNotExist 73 } 74 75 return u, nil 76} 77 78func (c *MockDataStore) CreateImageStore(op trace.Operation, storeName string) (*url.URL, error) { 79 if c.createImageStoreError != nil { 80 return nil, c.createImageStoreError 81 } 82 83 u, err := util.ImageStoreNameToURL(storeName) 84 if err != nil { 85 return nil, err 86 } 87 88 c.db[*u] = make(map[string]*image.Image) 89 return u, nil 90} 91 92func (c *MockDataStore) DeleteImageStore(op trace.Operation, storeName string) error { 93 u, err := util.ImageStoreNameToURL(storeName) 94 if err != nil { 95 return err 96 } 97 98 c.db[*u] = nil 99 return nil 100} 101 102func (c *MockDataStore) ListImageStores(op trace.Operation) ([]*url.URL, error) { 103 stores := make([]*url.URL, len(c.db)) 104 i := 0 105 for k := range c.db { 106 stores[i] = &k 107 i++ 108 } 109 110 return stores, nil 111} 112 113func (c *MockDataStore) URL(op trace.Operation, id string) (*url.URL, error) { 114 return nil, nil 115} 116 117func (c *MockDataStore) Owners(op trace.Operation, url *url.URL, filter func(vm *mo.VirtualMachine) bool) ([]*vm.VirtualMachine, error) { 118 return nil, nil 119} 120 121func (c *MockDataStore) WriteImage(op trace.Operation, parent *image.Image, ID string, meta map[string][]byte, sum string, r io.Reader) (*image.Image, error) { 122 if c.writeImageError != nil { 123 op.Infof("WriteImage: returning error") 124 return nil, c.writeImageError 125 } 126 127 storeName, err := util.ImageStoreName(parent.Store) 128 if err != nil { 129 return nil, err 130 } 131 132 selflink, err := util.ImageURL(storeName, ID) 133 if err != nil { 134 return nil, err 135 } 136 137 var parentLink *url.URL 138 if parent.ID != "" { 139 parentLink, err = util.ImageURL(storeName, parent.ID) 140 if err != nil { 141 return nil, err 142 } 143 } 144 145 i := &image.Image{ 146 ID: ID, 147 Store: parent.Store, 148 ParentLink: parentLink, 149 SelfLink: selflink, 150 Metadata: meta, 151 DatastorePath: &object.DatastorePath{ 152 Datastore: c.Datastore, 153 Path: c.Path, 154 }, 155 } 156 157 c.db[*parent.Store][ID] = i 158 159 return i, nil 160} 161 162func (c *MockDataStore) WriteMetadata(op trace.Operation, storeName string, ID string, meta map[string][]byte) error { 163 return nil 164} 165 166// GetImage gets the specified image from the given store by retreiving it from the cache. 167func (c *MockDataStore) GetImage(op trace.Operation, store *url.URL, ID string) (*image.Image, error) { 168 i, ok := c.db[*store][ID] 169 if !ok { 170 return nil, fmt.Errorf("not found") 171 } 172 return i, nil 173} 174 175// ListImages resturns a list of Images for a list of IDs, or all if no IDs are passed 176func (c *MockDataStore) ListImages(op trace.Operation, store *url.URL, IDs []string) ([]*image.Image, error) { 177 var imageList []*image.Image 178 for _, i := range c.db[*store] { 179 imageList = append(imageList, i) 180 } 181 return imageList, nil 182} 183 184// DeleteImage removes an image from the image store 185func (c *MockDataStore) DeleteImage(op trace.Operation, image *image.Image) (*image.Image, error) { 186 delete(c.db[*image.Store], image.ID) 187 return image, nil 188} 189 190func (c *MockDataStore) GetImageStorageUsage(op trace.Operation, storeName string) (int64, error) { 191 return 0, nil 192} 193 194func (c *MockDataStore) GetImageLayerStorageUsage(op trace.Operation, storeName, ID string) (int64, error) { 195 return 0, nil 196} 197