github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/environs/configstore/mem.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package configstore 5 6 import ( 7 "fmt" 8 "sync" 9 10 "github.com/juju/errors" 11 ) 12 13 type memStore struct { 14 mu sync.Mutex 15 envs map[string]*memInfo 16 } 17 18 type memInfo struct { 19 store *memStore 20 name string 21 environInfo 22 } 23 24 // clone returns a copy of the given environment info, isolated 25 // from the store itself. 26 func (info *memInfo) clone() *memInfo { 27 // Note that none of the Set* methods ever set fields inside 28 // references, which makes this OK to do. 29 info1 := *info 30 newAttrs := make(map[string]interface{}) 31 for name, attr := range info.bootstrapConfig { 32 newAttrs[name] = attr 33 } 34 info1.bootstrapConfig = newAttrs 35 info1.created = false 36 return &info1 37 } 38 39 // NewMem returns a ConfigStorage implementation that 40 // stores configuration in memory. 41 func NewMem() Storage { 42 return &memStore{ 43 envs: make(map[string]*memInfo), 44 } 45 } 46 47 // CreateInfo implements Storage.CreateInfo. 48 func (m *memStore) CreateInfo(envName string) EnvironInfo { 49 m.mu.Lock() 50 defer m.mu.Unlock() 51 info := &memInfo{ 52 store: m, 53 name: envName, 54 } 55 info.created = true 56 return info 57 } 58 59 // List implements Storage.List 60 func (m *memStore) List() ([]string, error) { 61 var envs []string 62 m.mu.Lock() 63 defer m.mu.Unlock() 64 for name := range m.envs { 65 envs = append(envs, name) 66 } 67 return envs, nil 68 } 69 70 // ReadInfo implements Storage.ReadInfo. 71 func (m *memStore) ReadInfo(envName string) (EnvironInfo, error) { 72 m.mu.Lock() 73 defer m.mu.Unlock() 74 info := m.envs[envName] 75 if info != nil { 76 return info.clone(), nil 77 } 78 return nil, errors.NotFoundf("environment %q", envName) 79 } 80 81 // Location implements EnvironInfo.Location. 82 func (info *memInfo) Location() string { 83 return "memory" 84 } 85 86 // Write implements EnvironInfo.Write. 87 func (info *memInfo) Write() error { 88 m := info.store 89 m.mu.Lock() 90 defer m.mu.Unlock() 91 92 if info.created && m.envs[info.name] != nil { 93 return ErrEnvironInfoAlreadyExists 94 } 95 96 info.initialized = true 97 m.envs[info.name] = info.clone() 98 return nil 99 } 100 101 // Destroy implements EnvironInfo.Destroy. 102 func (info *memInfo) Destroy() error { 103 m := info.store 104 m.mu.Lock() 105 defer m.mu.Unlock() 106 if info.initialized { 107 if m.envs[info.name] == nil { 108 return fmt.Errorf("environment info has already been removed") 109 } 110 delete(m.envs, info.name) 111 } 112 return nil 113 }