|
|
|
@ -18,7 +18,6 @@ package storage // import "k8s.io/helm/pkg/storage"
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
|
|
rspb "k8s.io/helm/pkg/proto/hapi/release"
|
|
|
|
|
relutil "k8s.io/helm/pkg/releaseutil"
|
|
|
|
@ -28,12 +27,6 @@ import (
|
|
|
|
|
// Storage represents a storage engine for a Release.
|
|
|
|
|
type Storage struct {
|
|
|
|
|
driver.Driver
|
|
|
|
|
|
|
|
|
|
// releaseLocks are for locking releases to make sure that only one operation at a time is executed on each release
|
|
|
|
|
releaseLocks map[string]*sync.Mutex
|
|
|
|
|
// releaseLocksLock is a mutex for accessing releaseLocks
|
|
|
|
|
releaseLocksLock *sync.Mutex
|
|
|
|
|
|
|
|
|
|
Log func(string, ...interface{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -157,53 +150,6 @@ func (s *Storage) Last(name string) (*rspb.Release, error) {
|
|
|
|
|
return h[0], nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// LockRelease gains a mutually exclusive access to a release via a mutex.
|
|
|
|
|
func (s *Storage) LockRelease(name string) error {
|
|
|
|
|
s.Log("locking release %s", name)
|
|
|
|
|
s.releaseLocksLock.Lock()
|
|
|
|
|
defer s.releaseLocksLock.Unlock()
|
|
|
|
|
|
|
|
|
|
var lock *sync.Mutex
|
|
|
|
|
lock, exists := s.releaseLocks[name]
|
|
|
|
|
|
|
|
|
|
if !exists {
|
|
|
|
|
releases, err := s.ListReleases()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
found := false
|
|
|
|
|
for _, release := range releases {
|
|
|
|
|
if release.Name == name {
|
|
|
|
|
found = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
return fmt.Errorf("Unable to lock release %q: release not found", name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lock = &sync.Mutex{}
|
|
|
|
|
s.releaseLocks[name] = lock
|
|
|
|
|
}
|
|
|
|
|
lock.Lock()
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UnlockRelease releases a mutually exclusive access to a release.
|
|
|
|
|
// If release doesn't exist or wasn't previously locked - the unlock will pass
|
|
|
|
|
func (s *Storage) UnlockRelease(name string) {
|
|
|
|
|
s.Log("unlocking release %s", name)
|
|
|
|
|
s.releaseLocksLock.Lock()
|
|
|
|
|
defer s.releaseLocksLock.Unlock()
|
|
|
|
|
|
|
|
|
|
var lock *sync.Mutex
|
|
|
|
|
lock, exists := s.releaseLocks[name]
|
|
|
|
|
if !exists {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
lock.Unlock()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// makeKey concatenates a release name and version into
|
|
|
|
|
// a string with format ```<release_name>#v<version>```.
|
|
|
|
|
// This key is used to uniquely identify storage objects.
|
|
|
|
@ -220,8 +166,6 @@ func Init(d driver.Driver) *Storage {
|
|
|
|
|
}
|
|
|
|
|
return &Storage{
|
|
|
|
|
Driver: d,
|
|
|
|
|
releaseLocks: make(map[string]*sync.Mutex),
|
|
|
|
|
releaseLocksLock: &sync.Mutex{},
|
|
|
|
|
Log: func(_ string, _ ...interface{}) {},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|