mirror of
https://github.com/containers/podman.git
synced 2025-06-23 02:18:13 +08:00
Merge pull request #10014 from mheon/in_memory_state_gone
Remove in-memory state implementation
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -282,11 +282,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
|
|||||||
// package.
|
// package.
|
||||||
switch runtime.config.Engine.StateType {
|
switch runtime.config.Engine.StateType {
|
||||||
case config.InMemoryStateStore:
|
case config.InMemoryStateStore:
|
||||||
state, err := NewInMemoryState()
|
return errors.Wrapf(define.ErrInvalidArg, "in-memory state is currently disabled")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
runtime.state = state
|
|
||||||
case config.SQLiteStateStore:
|
case config.SQLiteStateStore:
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "SQLite state is currently disabled")
|
return errors.Wrapf(define.ErrInvalidArg, "SQLite state is currently disabled")
|
||||||
case config.BoltDBStateStore:
|
case config.BoltDBStateStore:
|
||||||
|
@ -28,8 +28,7 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
testedStates = map[string]emptyStateFunc{
|
testedStates = map[string]emptyStateFunc{
|
||||||
"in-memory": getEmptyInMemoryState,
|
"boltdb": getEmptyBoltState,
|
||||||
"boltdb": getEmptyBoltState,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,31 +64,6 @@ func getEmptyBoltState() (_ State, _ string, _ lock.Manager, retErr error) {
|
|||||||
return state, tmpDir, lockManager, nil
|
return state, tmpDir, lockManager, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an empty in-memory state for use in tests
|
|
||||||
func getEmptyInMemoryState() (_ State, _ string, _ lock.Manager, retErr error) {
|
|
||||||
tmpDir, err := ioutil.TempDir("", tmpDirPrefix)
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", nil, err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if retErr != nil {
|
|
||||||
os.RemoveAll(tmpDir)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
state, err := NewInMemoryState()
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
lockManager, err := lock.NewInMemoryManager(16)
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return state, tmpDir, lockManager, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func runForAllStates(t *testing.T, testFunc func(*testing.T, State, lock.Manager)) {
|
func runForAllStates(t *testing.T, testFunc func(*testing.T, State, lock.Manager)) {
|
||||||
for stateName, stateFunc := range testedStates {
|
for stateName, stateFunc := range testedStates {
|
||||||
state, path, manager, err := stateFunc()
|
state, path, manager, err := stateFunc()
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
// Package registrar provides name registration. It reserves a name to a given key.
|
|
||||||
package registrar
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrNameReserved is an error which is returned when a name is requested to be reserved that already is reserved
|
|
||||||
ErrNameReserved = errors.New("name is reserved")
|
|
||||||
// ErrNameNotReserved is an error which is returned when trying to find a name that is not reserved
|
|
||||||
ErrNameNotReserved = errors.New("name is not reserved")
|
|
||||||
// ErrNoSuchKey is returned when trying to find the names for a key which is not known
|
|
||||||
ErrNoSuchKey = errors.New("provided key does not exist")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Registrar stores indexes a list of keys and their registered names as well as indexes names and the key that they are registered to
|
|
||||||
// Names must be unique.
|
|
||||||
// Registrar is safe for concurrent access.
|
|
||||||
type Registrar struct {
|
|
||||||
idx map[string][]string
|
|
||||||
names map[string]string
|
|
||||||
mu sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRegistrar creates a new Registrar with the an empty index
|
|
||||||
func NewRegistrar() *Registrar {
|
|
||||||
return &Registrar{
|
|
||||||
idx: make(map[string][]string),
|
|
||||||
names: make(map[string]string),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reserve registers a key to a name
|
|
||||||
// Reserve is idempotent
|
|
||||||
// Attempting to reserve a key to a name that already exists results in an `ErrNameReserved`
|
|
||||||
// A name reservation is globally unique
|
|
||||||
func (r *Registrar) Reserve(name, key string) error {
|
|
||||||
r.mu.Lock()
|
|
||||||
defer r.mu.Unlock()
|
|
||||||
|
|
||||||
if k, exists := r.names[name]; exists {
|
|
||||||
if k != key {
|
|
||||||
return ErrNameReserved
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
r.idx[key] = append(r.idx[key], name)
|
|
||||||
r.names[name] = key
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release releases the reserved name
|
|
||||||
// Once released, a name can be reserved again
|
|
||||||
func (r *Registrar) Release(name string) {
|
|
||||||
r.mu.Lock()
|
|
||||||
defer r.mu.Unlock()
|
|
||||||
|
|
||||||
key, exists := r.names[name]
|
|
||||||
if !exists {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, n := range r.idx[key] {
|
|
||||||
if n != name {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
r.idx[key] = append(r.idx[key][:i], r.idx[key][i+1:]...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(r.names, name)
|
|
||||||
|
|
||||||
if len(r.idx[key]) == 0 {
|
|
||||||
delete(r.idx, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete removes all reservations for the passed in key.
|
|
||||||
// All names reserved to this key are released.
|
|
||||||
func (r *Registrar) Delete(key string) {
|
|
||||||
r.mu.Lock()
|
|
||||||
for _, name := range r.idx[key] {
|
|
||||||
delete(r.names, name)
|
|
||||||
}
|
|
||||||
delete(r.idx, key)
|
|
||||||
r.mu.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNames lists all the reserved names for the given key
|
|
||||||
func (r *Registrar) GetNames(key string) ([]string, error) {
|
|
||||||
r.mu.Lock()
|
|
||||||
defer r.mu.Unlock()
|
|
||||||
|
|
||||||
names, exists := r.idx[key]
|
|
||||||
if !exists {
|
|
||||||
return nil, ErrNoSuchKey
|
|
||||||
}
|
|
||||||
return names, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the key that the passed in name is reserved to
|
|
||||||
func (r *Registrar) Get(name string) (string, error) {
|
|
||||||
r.mu.Lock()
|
|
||||||
key, exists := r.names[name]
|
|
||||||
r.mu.Unlock()
|
|
||||||
|
|
||||||
if !exists {
|
|
||||||
return "", ErrNameNotReserved
|
|
||||||
}
|
|
||||||
return key, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAll returns all registered names
|
|
||||||
func (r *Registrar) GetAll() map[string][]string {
|
|
||||||
out := make(map[string][]string)
|
|
||||||
|
|
||||||
r.mu.Lock()
|
|
||||||
// copy index into out
|
|
||||||
for id, names := range r.idx {
|
|
||||||
out[id] = names
|
|
||||||
}
|
|
||||||
r.mu.Unlock()
|
|
||||||
return out
|
|
||||||
}
|
|
@ -1,213 +0,0 @@
|
|||||||
package registrar_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/containers/podman/v3/pkg/registrar"
|
|
||||||
. "github.com/containers/podman/v3/test/framework"
|
|
||||||
. "github.com/onsi/ginkgo"
|
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestRegistrar runs the created specs
|
|
||||||
func TestRegistrar(t *testing.T) {
|
|
||||||
RegisterFailHandler(Fail)
|
|
||||||
RunSpecs(t, "Registrar")
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint: gochecknoglobals
|
|
||||||
var t *TestFramework
|
|
||||||
|
|
||||||
var _ = BeforeSuite(func() {
|
|
||||||
t = NewTestFramework(NilFunc, NilFunc)
|
|
||||||
t.Setup()
|
|
||||||
})
|
|
||||||
|
|
||||||
var _ = AfterSuite(func() {
|
|
||||||
t.Teardown()
|
|
||||||
})
|
|
||||||
|
|
||||||
// The actual test suite
|
|
||||||
var _ = t.Describe("Registrar", func() {
|
|
||||||
// Constant test data needed by some tests
|
|
||||||
const (
|
|
||||||
testKey = "testKey"
|
|
||||||
testName = "testName"
|
|
||||||
anotherKey = "anotherKey"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The system under test
|
|
||||||
var sut *registrar.Registrar
|
|
||||||
|
|
||||||
// Prepare the system under test and register a test name and key before
|
|
||||||
// each test
|
|
||||||
BeforeEach(func() {
|
|
||||||
sut = registrar.NewRegistrar()
|
|
||||||
Expect(sut.Reserve(testName, testKey)).To(BeNil())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Describe("Reserve", func() {
|
|
||||||
It("should succeed to reserve a new registrar", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
err := sut.Reserve("name", "key")
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should succeed to reserve a registrar twice", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
err := sut.Reserve(testName, testKey)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should fail to reserve an already reserved registrar", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
err := sut.Reserve(testName, anotherKey)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).NotTo(BeNil())
|
|
||||||
Expect(err).To(Equal(registrar.ErrNameReserved))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Describe("Release", func() {
|
|
||||||
It("should succeed to release a registered registrar multiple times", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
// Then
|
|
||||||
sut.Release(testName)
|
|
||||||
sut.Release(testName)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should succeed to release a unknown registrar multiple times", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
// Then
|
|
||||||
sut.Release(anotherKey)
|
|
||||||
sut.Release(anotherKey)
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should succeed to release and re-register a registrar", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
sut.Release(testName)
|
|
||||||
err := sut.Reserve(testName, testKey)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Describe("GetNames", func() {
|
|
||||||
It("should succeed to retrieve a single name for a registrar", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
names, err := sut.GetNames(testKey)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
Expect(len(names)).To(Equal(1))
|
|
||||||
Expect(names[0]).To(Equal(testName))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should succeed to retrieve all names for a registrar", func() {
|
|
||||||
// Given
|
|
||||||
testNames := []string{"test1", "test2"}
|
|
||||||
for _, name := range testNames {
|
|
||||||
Expect(sut.Reserve(name, anotherKey)).To(BeNil())
|
|
||||||
}
|
|
||||||
|
|
||||||
// When
|
|
||||||
names, err := sut.GetNames(anotherKey)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
Expect(len(names)).To(Equal(2))
|
|
||||||
Expect(names).To(Equal(testNames))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Describe("GetNames", func() {
|
|
||||||
It("should succeed to retrieve a single name for a registrar", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
names, err := sut.GetNames(testKey)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
Expect(len(names)).To(Equal(1))
|
|
||||||
Expect(names[0]).To(Equal(testName))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should succeed to retrieve all names for a registrar", func() {
|
|
||||||
// Given
|
|
||||||
anotherKey := "anotherKey"
|
|
||||||
testNames := []string{"test1", "test2"}
|
|
||||||
for _, name := range testNames {
|
|
||||||
Expect(sut.Reserve(name, anotherKey)).To(BeNil())
|
|
||||||
}
|
|
||||||
|
|
||||||
// When
|
|
||||||
names, err := sut.GetNames(anotherKey)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
Expect(len(names)).To(Equal(2))
|
|
||||||
Expect(names).To(Equal(testNames))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Describe("Delete", func() {
|
|
||||||
It("should succeed to delete a registrar", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
sut.Delete(testKey)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
names, err := sut.GetNames(testKey)
|
|
||||||
Expect(len(names)).To(BeZero())
|
|
||||||
Expect(err).To(Equal(registrar.ErrNoSuchKey))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Describe("Get", func() {
|
|
||||||
It("should succeed to get a key for a registrar", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
key, err := sut.Get(testName)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
Expect(key).To(Equal(testKey))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("should fail to get a key for a not existing registrar", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
key, err := sut.Get("notExistingName")
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(key).To(BeEmpty())
|
|
||||||
Expect(err).To(Equal(registrar.ErrNameNotReserved))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Describe("GetAll", func() {
|
|
||||||
It("should succeed to get all names", func() {
|
|
||||||
// Given
|
|
||||||
// When
|
|
||||||
names := sut.GetAll()
|
|
||||||
|
|
||||||
// Then
|
|
||||||
Expect(len(names)).To(Equal(1))
|
|
||||||
Expect(len(names[testKey])).To(Equal(1))
|
|
||||||
Expect(names[testKey][0]).To(Equal(testName))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
Reference in New Issue
Block a user