Files
play-with-docker/storage/file.go
Jonathan Leibiusky @xetorthio 0e08107738 Tests are working again
2017-07-28 20:42:05 -03:00

179 lines
3.0 KiB
Go

package storage
import (
"encoding/json"
"fmt"
"os"
"strings"
"sync"
"github.com/play-with-docker/play-with-docker/pwd/types"
)
type storage struct {
rw sync.Mutex
path string
db map[string]*types.Session
}
func (store *storage) SessionGet(sessionId string) (*types.Session, error) {
store.rw.Lock()
defer store.rw.Unlock()
s, found := store.db[sessionId]
if !found {
return nil, fmt.Errorf("%s", notFound)
}
return s, nil
}
func (store *storage) SessionGetAll() (map[string]*types.Session, error) {
store.rw.Lock()
defer store.rw.Unlock()
return store.db, nil
}
func (store *storage) SessionPut(s *types.Session) error {
store.rw.Lock()
defer store.rw.Unlock()
// Initialize instances map if nil
if s.Instances == nil {
s.Instances = map[string]*types.Instance{}
}
store.db[s.Id] = s
return store.save()
}
func (store *storage) InstanceFind(sessionId, ip string) (*types.Instance, error) {
store.rw.Lock()
defer store.rw.Unlock()
for id, s := range store.db {
if strings.HasPrefix(id, sessionId[:8]) {
for _, i := range s.Instances {
if i.IP == ip {
return i, nil
}
}
}
}
return nil, fmt.Errorf("%s", notFound)
}
func (store *storage) InstanceCreate(sessionId string, instance *types.Instance) error {
store.rw.Lock()
defer store.rw.Unlock()
s, found := store.db[sessionId]
if !found {
return fmt.Errorf("Session %s", notFound)
}
s.Instances[instance.Name] = instance
return store.save()
}
func (store *storage) InstanceDelete(sessionId, name string) error {
store.rw.Lock()
defer store.rw.Unlock()
s, found := store.db[sessionId]
if !found {
return fmt.Errorf("Session %s", notFound)
}
if _, found := s.Instances[name]; !found {
return nil
}
delete(s.Instances, name)
return store.save()
}
func (store *storage) SessionCount() (int, error) {
store.rw.Lock()
defer store.rw.Unlock()
return len(store.db), nil
}
func (store *storage) InstanceCount() (int, error) {
store.rw.Lock()
defer store.rw.Unlock()
var ins int
for _, s := range store.db {
ins += len(s.Instances)
}
return ins, nil
}
func (store *storage) ClientCount() (int, error) {
store.rw.Lock()
defer store.rw.Unlock()
var cli int
for _, s := range store.db {
cli += len(s.Clients)
}
return cli, nil
}
func (store *storage) SessionDelete(sessionId string) error {
store.rw.Lock()
defer store.rw.Unlock()
delete(store.db, sessionId)
return store.save()
}
func (store *storage) load() error {
file, err := os.Open(store.path)
if err == nil {
decoder := json.NewDecoder(file)
err = decoder.Decode(&store.db)
if err != nil {
return err
}
} else {
store.db = map[string]*types.Session{}
}
file.Close()
return nil
}
func (store *storage) save() error {
file, err := os.Create(store.path)
if err != nil {
return err
}
defer file.Close()
encoder := json.NewEncoder(file)
err = encoder.Encode(&store.db)
return err
}
func NewFileStorage(path string) (StorageApi, error) {
s := &storage{path: path}
err := s.load()
if err != nil {
return nil, err
}
return s, nil
}