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  }