Move StorageInterface to pkg/storage.

This commit is contained in:
Wojciech Tyczynski 2015-07-30 09:27:38 +02:00
parent 769230e735
commit d17985f1ad
43 changed files with 284 additions and 223 deletions

View File

@ -38,6 +38,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
forked "github.com/GoogleCloudPlatform/kubernetes/third_party/forked/coreos/go-etcd/etcd"
@ -216,7 +217,7 @@ func (s *APIServer) verifyClusterIPFlags() {
}
}
func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string, pathPrefix string) (etcdStorage tools.StorageInterface, err error) {
func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string, pathPrefix string) (etcdStorage storage.StorageInterface, err error) {
var client tools.EtcdClient
if etcdConfigFile != "" {
client, err = etcd.NewClientFromFile(etcdConfigFile)

View File

@ -22,7 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator/bearertoken"
"github.com/GoogleCloudPlatform/kubernetes/pkg/serviceaccount"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/request/basicauth"
@ -32,7 +32,7 @@ import (
)
// NewAuthenticator returns an authenticator.Request or an error
func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyFile string, serviceAccountLookup bool, storage tools.StorageInterface) (authenticator.Request, error) {
func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyFile string, serviceAccountLookup bool, storage storage.StorageInterface) (authenticator.Request, error) {
var authenticators []authenticator.Request
if len(basicAuthFile) > 0 {
@ -104,7 +104,7 @@ func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Request,
}
// newServiceAccountAuthenticator returns an authenticator.Request or an error
func newServiceAccountAuthenticator(keyfile string, lookup bool, storage tools.StorageInterface) (authenticator.Request, error) {
func newServiceAccountAuthenticator(keyfile string, lookup bool, storage storage.StorageInterface) (authenticator.Request, error) {
publicKey, err := serviceaccount.ReadPublicKey(keyfile)
if err != nil {
return nil, err

View File

@ -69,6 +69,7 @@ import (
etcdallocator "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator/etcd"
ipallocator "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/ipallocator"
serviceaccountetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/ui"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -87,7 +88,7 @@ const (
// Config is a structure used to configure a Master.
type Config struct {
DatabaseStorage tools.StorageInterface
DatabaseStorage storage.StorageInterface
EventTTL time.Duration
MinionRegexp string
KubeletClient client.KubeletClient
@ -225,7 +226,7 @@ type Master struct {
// NewEtcdStorage returns a StorageInterface for the provided arguments or an error if the version
// is incorrect.
func NewEtcdStorage(client tools.EtcdClient, version string, prefix string) (etcdStorage tools.StorageInterface, err error) {
func NewEtcdStorage(client tools.EtcdClient, version string, prefix string) (etcdStorage storage.StorageInterface, err error) {
if version == "" {
version = latest.Version
}

View File

@ -24,7 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// rest implements a RESTStorage for replication controllers against etcd
@ -37,7 +37,7 @@ type REST struct {
var controllerPrefix = "/controllers"
// NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(s tools.StorageInterface) *REST {
func NewREST(s storage.StorageInterface) *REST {
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ReplicationController{} },

View File

@ -30,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
@ -40,7 +41,7 @@ const (
FAIL
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())

View File

@ -24,7 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// rest implements a RESTStorage for endpoints against etcd
@ -33,7 +33,7 @@ type REST struct {
}
// NewStorage returns a RESTStorage object that will work against endpoints.
func NewStorage(s tools.StorageInterface) *REST {
func NewStorage(s storage.StorageInterface) *REST {
prefix := "/services/endpoints"
return &REST{
&etcdgeneric.Etcd{

View File

@ -25,6 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -32,7 +33,7 @@ import (
"github.com/coreos/go-etcd/etcd"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())

View File

@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
@ -44,13 +45,13 @@ const (
// Registry implements BindingRegistry, ControllerRegistry, EndpointRegistry,
// MinionRegistry, PodRegistry and ServiceRegistry, backed by etcd.
type Registry struct {
tools.StorageInterface
storage.StorageInterface
pods pod.Registry
endpoints endpoint.Registry
}
// NewRegistry creates an etcd registry.
func NewRegistry(storage tools.StorageInterface, pods pod.Registry, endpoints endpoint.Registry) *Registry {
func NewRegistry(storage storage.StorageInterface, pods pod.Registry, endpoints endpoint.Registry) *Registry {
registry := &Registry{
StorageInterface: storage,
pods: pods,
@ -171,10 +172,10 @@ func (r *Registry) WatchServices(ctx api.Context, label labels.Selector, field f
return nil, err
}
// TODO: use generic.SelectionPredicate
return r.Watch(key, version, tools.Everything)
return r.Watch(key, version, storage.Everything)
}
if field.Empty() {
return r.WatchList(makeServiceListKey(ctx), version, tools.Everything)
return r.WatchList(makeServiceListKey(ctx), version, storage.Everything)
}
return nil, fmt.Errorf("only the 'name' and default (everything) field selectors are supported")
}

View File

@ -21,7 +21,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// registry implements custom changes to generic.Etcd.
@ -31,7 +31,7 @@ type registry struct {
// NewEtcdRegistry returns a registry which will store Events in the given
// EtcdStorage. ttl is the time that Events will be retained by the system.
func NewEtcdRegistry(s tools.StorageInterface, ttl uint64) generic.Registry {
func NewEtcdRegistry(s storage.StorageInterface, ttl uint64) generic.Registry {
prefix := "/events"
return registry{
Etcd: &etcdgeneric.Etcd{

View File

@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -103,7 +104,7 @@ type Etcd struct {
ReturnDeletedObject bool
// Used for all etcd access functions
Storage tools.StorageInterface
Storage storage.StorageInterface
}
// NamespaceKeyRootFunc is the default function for constructing etcd paths to resource directories enforcing namespace rules.
@ -282,7 +283,7 @@ func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool
// TODO: expose TTL
creating := false
out := e.NewFunc()
err = e.Storage.GuaranteedUpdate(key, out, true, func(existing runtime.Object, res tools.ResponseMeta) (runtime.Object, *uint64, error) {
err = e.Storage.GuaranteedUpdate(key, out, true, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
version, err := e.Storage.Versioner().ObjectResourceVersion(existing)
if err != nil {
return nil, nil, err

View File

@ -21,7 +21,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// registry implements custom changes to generic.Etcd.
@ -30,7 +30,7 @@ type registry struct {
}
// NewEtcdRegistry returns a registry which will store LimitRange in the given storage
func NewEtcdRegistry(s tools.StorageInterface) generic.Registry {
func NewEtcdRegistry(s storage.StorageInterface) generic.Registry {
prefix := "/limitranges"
return registry{
Etcd: &etcdgeneric.Etcd{

View File

@ -26,7 +26,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
type REST struct {
@ -49,7 +49,7 @@ func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object
}
// NewStorage returns a RESTStorage object that will work against nodes.
func NewStorage(s tools.StorageInterface, connection client.ConnectionInfoGetter) (*REST, *StatusREST) {
func NewStorage(s storage.StorageInterface, connection client.ConnectionInfoGetter) (*REST, *StatusREST) {
prefix := "/minions"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Node{} },

View File

@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
@ -47,7 +48,7 @@ func (fakeConnectionInfoGetter) GetConnectionInfo(host string) (string, uint, ht
return "http", 12345, nil, nil
}
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())

View File

@ -28,7 +28,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
@ -49,7 +49,7 @@ type FinalizeREST struct {
}
// NewStorage returns a RESTStorage object that will work against namespaces
func NewStorage(s tools.StorageInterface) (*REST, *StatusREST, *FinalizeREST) {
func NewStorage(s storage.StorageInterface) (*REST, *StatusREST, *FinalizeREST) {
prefix := "/namespaces"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Namespace{} },

View File

@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -33,14 +34,14 @@ import (
"github.com/coreos/go-etcd/etcd"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient, tools.StorageInterface) {
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient, s := newEtcdStorage(t)
storage, _, _ := NewStorage(s)
return storage, fakeEtcdClient, s

View File

@ -26,7 +26,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/persistentvolume"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// rest implements a RESTStorage for persistentvolumes against etcd
@ -35,7 +35,7 @@ type REST struct {
}
// NewREST returns a RESTStorage object that will work against PersistentVolume objects.
func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) {
func NewStorage(s storage.StorageInterface) (*REST, *StatusREST) {
prefix := "/persistentvolumes"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolume{} },

View File

@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -38,7 +39,7 @@ type testRegistry struct {
*registrytest.GenericRegistry
}
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())

View File

@ -24,7 +24,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/persistentvolumeclaim"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// rest implements a RESTStorage for persistentvolumeclaims against etcd
@ -33,7 +33,7 @@ type REST struct {
}
// NewREST returns a RESTStorage object that will work against PersistentVolumeClaim objects.
func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) {
func NewStorage(s storage.StorageInterface) (*REST, *StatusREST) {
prefix := "/persistentvolumeclaims"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} },

View File

@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -38,7 +39,7 @@ type testRegistry struct {
*registrytest.GenericRegistry
}
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())

View File

@ -35,6 +35,7 @@ import (
genericrest "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
)
@ -56,7 +57,7 @@ type REST struct {
}
// NewStorage returns a RESTStorage object that will work against pods.
func NewStorage(s tools.StorageInterface, k client.ConnectionInfoGetter) PodStorage {
func NewStorage(s storage.StorageInterface, k client.ConnectionInfoGetter) PodStorage {
prefix := "/pods"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Pod{} },

View File

@ -33,6 +33,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/securitycontext"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -40,14 +41,14 @@ import (
"github.com/coreos/go-etcd/etcd"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) {
func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(etcdStorage, nil)
return storage.Pod, storage.Binding, storage.Status, fakeEtcdClient, etcdStorage

View File

@ -24,7 +24,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/podtemplate"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// rest implements a RESTStorage for pod templates against etcd
@ -33,7 +33,7 @@ type REST struct {
}
// NewREST returns a RESTStorage object that will work against pod templates.
func NewREST(s tools.StorageInterface) *REST {
func NewREST(s storage.StorageInterface) *REST {
prefix := "/podtemplates"
store := etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PodTemplate{} },

View File

@ -22,11 +22,12 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())

View File

@ -24,7 +24,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// rest implements a RESTStorage for resourcequotas against etcd
@ -33,7 +33,7 @@ type REST struct {
}
// NewStorage returns a RESTStorage object that will work against ResourceQuota objects.
func NewStorage(s tools.StorageInterface) (*REST, *StatusREST) {
func NewStorage(s storage.StorageInterface) (*REST, *StatusREST) {
prefix := "/resourcequotas"
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ResourceQuota{} },

View File

@ -31,6 +31,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -38,14 +39,14 @@ import (
"github.com/coreos/go-etcd/etcd"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, tools.StorageInterface) {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient, h := newEtcdStorage(t)
storage, statusStorage := NewStorage(h)
return storage, statusStorage, fakeEtcdClient, h

View File

@ -24,7 +24,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// REST implements a RESTStorage for secrets against etcd
@ -33,7 +33,7 @@ type REST struct {
}
// NewStorage returns a registry which will store Secret in the given etcdStorage
func NewStorage(s tools.StorageInterface) *REST {
func NewStorage(s storage.StorageInterface) *REST {
prefix := "/secrets"
store := &etcdgeneric.Etcd{

View File

@ -22,11 +22,12 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())

View File

@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
)
@ -42,7 +43,7 @@ type Etcd struct {
lock sync.Mutex
alloc allocator.Snapshottable
storage tools.StorageInterface
storage storage.StorageInterface
last string
baseKey string
@ -55,7 +56,7 @@ var _ service.RangeRegistry = &Etcd{}
// NewEtcd returns an allocator that is backed by Etcd and can manage
// persisting the snapshot state of allocation after each allocation is made.
func NewEtcd(alloc allocator.Snapshottable, baseKey string, kind string, storage tools.StorageInterface) *Etcd {
func NewEtcd(alloc allocator.Snapshottable, baseKey string, kind string, storage storage.StorageInterface) *Etcd {
return &Etcd{
alloc: alloc,
storage: storage,

View File

@ -26,11 +26,12 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())

View File

@ -29,11 +29,12 @@ import (
allocator_etcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/ipallocator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())

View File

@ -24,7 +24,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// REST implements a RESTStorage for service accounts against etcd
@ -35,7 +35,7 @@ type REST struct {
const Prefix = "/serviceaccounts"
// NewStorage returns a RESTStorage object that will work against service accounts objects.
func NewStorage(s tools.StorageInterface) *REST {
func NewStorage(s storage.StorageInterface) *REST {
store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ServiceAccount{} },
NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} },

View File

@ -22,11 +22,12 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, tools.StorageInterface) {
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.StorageInterface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())

View File

@ -23,7 +23,7 @@ import (
secretetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount"
serviceaccountetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
)
// ServiceAccountTokenGetter defines functions to retrieve a named service account and secret
@ -73,7 +73,7 @@ func (r *registryGetter) GetSecret(namespace, name string) (*api.Secret, error)
// NewGetterFromStorageInterface returns a ServiceAccountTokenGetter that
// uses the specified storage to retrieve service accounts and secrets.
func NewGetterFromStorageInterface(storage tools.StorageInterface) ServiceAccountTokenGetter {
func NewGetterFromStorageInterface(storage storage.StorageInterface) ServiceAccountTokenGetter {
return NewGetterFromRegistries(
serviceaccount.NewRegistry(serviceaccountetcd.NewStorage(storage)),
secret.NewRegistry(secretetcd.NewStorage(storage)),

18
pkg/storage/doc.go Normal file
View File

@ -0,0 +1,18 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Interfaces for database-related operations.
package storage

149
pkg/storage/interfaces.go Normal file
View File

@ -0,0 +1,149 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package storage
import (
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// StorageVersioner abstracts setting and retrieving metadata fields from database response
// onto the object ot list.
type StorageVersioner interface {
// UpdateObject sets storage metadata into an API object. Returns an error if the object
// cannot be updated correctly. May return nil if the requested object does not need metadata
// from database.
UpdateObject(obj runtime.Object, expiration *time.Time, resourceVersion uint64) error
// UpdateList sets the resource version into an API list object. Returns an error if the object
// cannot be updated correctly. May return nil if the requested object does not need metadata
// from database.
UpdateList(obj runtime.Object, resourceVersion uint64) error
// ObjectResourceVersion returns the resource version (for persistence) of the specified object.
// Should return an error if the specified object does not have a persistable version.
ObjectResourceVersion(obj runtime.Object) (uint64, error)
}
// ResponseMeta contains information about the database metadata that is associated with
// an object. It abstracts the actual underlying objects to prevent coupling with concrete
// database and to improve testability.
type ResponseMeta struct {
// TTL is the time to live of the node that contained the returned object. It may be
// zero or negative in some cases (objects may be expired after the requested
// expiration time due to server lag).
TTL int64
// Expiration is the time at which the node that contained the returned object will expire and be deleted.
// This can be nil if there is no expiration time set for the node.
Expiration *time.Time
// The resource version of the node that contained the returned object.
ResourceVersion uint64
}
// FilterFunc is a predicate which takes an API object and returns true
// iff the object should remain in the set.
type FilterFunc func(obj runtime.Object) bool
// Everything is a FilterFunc which accepts all objects.
func Everything(runtime.Object) bool {
return true
}
// Pass an StorageUpdateFunc to StorageInterface.GuaranteedUpdate to make an update
// that is guaranteed to succeed.
// See the comment for GuaranteedUpdate for more details.
type StorageUpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error)
// StorageInterface offers a common interface for object marshaling/unmarshling operations and
// hids all the storage-related operations behind it.
type StorageInterface interface {
// Returns list of servers addresses of the underyling database.
// TODO: This method is used only in a single place. Consider refactoring and getting rid
// of this method from the interface.
Backends() []string
// Returns StorageVersioner associated with this interface.
Versioner() StorageVersioner
// Create adds a new object at a key unless it already exists. 'ttl' is time-to-live
// in seconds (0 means forever). If no error is returned and out is not nil, out will be
// set to the read value from database.
Create(key string, obj, out runtime.Object, ttl uint64) error
// Set marshals obj via json and stores in database under key. Will do an atomic update
// if obj's ResourceVersion field is set. 'ttl' is time-to-live in seconds (0 means forever).
// If no error is returned and out is not nil, out will be set to the read value from database.
Set(key string, obj, out runtime.Object, ttl uint64) error
// Delete removes the specified key and returns the value that existed at that spot.
Delete(key string, out runtime.Object) error
// RecursiveDelete removes the specified key.
// TODO: Get rid of this method and use Delete() instead.
RecursiveDelete(key string, recursive bool) error
// Watch begins watching the specified key. Events are decoded into API objects,
// and any items passing 'filter' are sent down to returned watch.Interface.
// resourceVersion may be used to specify what version to begin watching
// (e.g. reconnecting without missing any updates).
Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error)
// WatchList begins watching the specified key's items. Items are decoded into API
// objects and any item passing 'filter' are sent down to returned watch.Interface.
// resourceVersion may be used to specify what version to begin watching
// (e.g. reconnecting without missing any updates).
WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error)
// Get unmarshals json found at key into objPtr. On a not found error, will either
// return a zero object of the requested type, or an error, depending on ignoreNotFound.
// Treats empty responses and nil response nodes exactly like a not found error.
Get(key string, objPtr runtime.Object, ignoreNotFound bool) error
// GetToList unmarshals json found at key and opaque it into *List api object
// (an object that satisfies the runtime.IsList definition).
GetToList(key string, listObj runtime.Object) error
// List unmarshalls jsons found at directory defined by key and opaque them
// into *List api object (an object that satisfies runtime.IsList definition).
List(key string, listObj runtime.Object) error
// GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'ptrToType')
// retrying the update until success if there is index conflict.
// Note that object passed to tryUpdate may change acress incovations of tryUpdate() if
// other writers are simultanously updateing it, to tryUpdate() needs to take into account
// the current contents of the object when deciding how the update object should look.
//
// Exmaple:
//
// s := /* implementation of StorageInterface */
// err := s.GuaranteedUpdate(
// "myKey", &MyType{}, true,
// func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) {
// // Before each incovation of the user defined function, "input" is reset to
// // current contents for "myKey" in database.
// curr := input.(*MyType) // Guaranteed to succeed.
//
// // Make the modification
// curr.Counter++
//
// // Return the modified object - return an error to stop iterating. Return
// // a uint64 to alter the TTL on the object, or nil to keep it the same value.
// return cur, nil, nil
// }
// })
GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate StorageUpdateFunc) error
}

View File

@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/metrics"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -35,7 +36,7 @@ import (
"github.com/golang/glog"
)
func NewEtcdStorage(client EtcdClient, codec runtime.Codec, prefix string) StorageInterface {
func NewEtcdStorage(client EtcdClient, codec runtime.Codec, prefix string) storage.StorageInterface {
return &etcdHelper{
client: client,
codec: codec,
@ -52,7 +53,7 @@ type etcdHelper struct {
codec runtime.Codec
copier runtime.ObjectCopier
// optional, has to be set to perform any atomic operations
versioner StorageVersioner
versioner storage.StorageVersioner
// prefix for all etcd keys
pathPrefix string
@ -76,7 +77,7 @@ func (h *etcdHelper) Backends() []string {
}
// Implements StorageInterface.
func (h *etcdHelper) Versioner() StorageVersioner {
func (h *etcdHelper) Versioner() storage.StorageVersioner {
return h.versioner
}
@ -178,7 +179,7 @@ func (h *etcdHelper) RecursiveDelete(key string, recursive bool) error {
}
// Implements StorageInterface.
func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) {
func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter storage.FilterFunc) (watch.Interface, error) {
key = h.prefixEtcdKey(key)
w := newEtcdWatcher(false, nil, filter, h.codec, h.versioner, nil, h)
go w.etcdWatch(h.client, key, resourceVersion)
@ -186,7 +187,7 @@ func (h *etcdHelper) Watch(key string, resourceVersion uint64, filter FilterFunc
}
// Implements StorageInterface.
func (h *etcdHelper) WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) {
func (h *etcdHelper) WatchList(key string, resourceVersion uint64, filter storage.FilterFunc) (watch.Interface, error) {
key = h.prefixEtcdKey(key)
w := newEtcdWatcher(true, exceptKey(key), filter, h.codec, h.versioner, nil, h)
go w.etcdWatch(h.client, key, resourceVersion)
@ -364,18 +365,18 @@ func (h *etcdHelper) listEtcdNode(key string) ([]*etcd.Node, uint64, error) {
return result.Node.Nodes, result.EtcdIndex, nil
}
type SimpleEtcdUpdateFunc func(runtime.Object) (runtime.Object, error)
type SimpleUpdateFunc func(runtime.Object) (runtime.Object, error)
// SimpleUpdateFunc converts SimpleEtcdUpdateFunc into EtcdUpdateFunc
func SimpleUpdate(fn SimpleEtcdUpdateFunc) StorageUpdateFunc {
return func(input runtime.Object, _ ResponseMeta) (runtime.Object, *uint64, error) {
// SimpleUpdateFunc converts SimpleUpdateFunc into StorageUpdateFunc
func SimpleUpdate(fn SimpleUpdateFunc) storage.StorageUpdateFunc {
return func(input runtime.Object, _ storage.ResponseMeta) (runtime.Object, *uint64, error) {
out, err := fn(input)
return out, nil, err
}
}
// Implements StorageInterface.
func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate StorageUpdateFunc) error {
func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate storage.StorageUpdateFunc) error {
v, err := conversion.EnforcePtr(ptrToType)
if err != nil {
// Panic is appropriate, because this is a programming error.
@ -388,7 +389,7 @@ func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, igno
if err != nil {
return err
}
meta := ResponseMeta{}
meta := storage.ResponseMeta{}
if node != nil {
meta.TTL = node.TTL
if node.Expiration != nil {

View File

@ -34,6 +34,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
"github.com/stretchr/testify/assert"
@ -592,7 +593,7 @@ func TestGuaranteedUpdateTTL(t *testing.T) {
// Create a new node.
fakeClient.ExpectNotFoundGet(key)
obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1}
err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) {
err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
if res.TTL != 0 {
t.Fatalf("unexpected response meta: %#v", res)
}
@ -618,7 +619,7 @@ func TestGuaranteedUpdateTTL(t *testing.T) {
// Update an existing node.
callbackCalled := false
objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 2}
err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) {
err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
if res.TTL != 10 {
t.Fatalf("unexpected response meta: %#v", res)
}
@ -650,7 +651,7 @@ func TestGuaranteedUpdateTTL(t *testing.T) {
// Update an existing node and change ttl
callbackCalled = false
objUpdate = &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 3}
err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) {
err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, func(in runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
if res.TTL != 10 {
t.Fatalf("unexpected response meta: %#v", res)
}

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
@ -74,4 +75,4 @@ func (a APIObjectVersioner) ObjectResourceVersion(obj runtime.Object) (uint64, e
}
// APIObjectVersioner implements StorageVersioner
var _ StorageVersioner = APIObjectVersioner{}
var _ storage.StorageVersioner = APIObjectVersioner{}

View File

@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -41,15 +42,6 @@ const (
EtcdDelete = "delete"
)
// FilterFunc is a predicate which takes an API object and returns true
// iff the object should remain in the set.
type FilterFunc func(obj runtime.Object) bool
// Everything is a FilterFunc which accepts all objects.
func Everything(runtime.Object) bool {
return true
}
// ParseWatchResourceVersion takes a resource version argument and converts it to
// the etcd version we should pass to helper.Watch(). Because resourceVersion is
// an opaque value, the default watch behavior for non-zero watch is to watch
@ -82,12 +74,12 @@ func exceptKey(except string) includeFunc {
// etcdWatcher converts a native etcd watch to a watch.Interface.
type etcdWatcher struct {
encoding runtime.Codec
versioner StorageVersioner
versioner storage.StorageVersioner
transform TransformFunc
list bool // If we're doing a recursive watch, should be true.
include includeFunc
filter FilterFunc
filter storage.FilterFunc
etcdIncoming chan *etcd.Response
etcdError chan error
@ -110,7 +102,7 @@ const watchWaitDuration = 100 * time.Millisecond
// newEtcdWatcher returns a new etcdWatcher; if list is true, watch sub-nodes. If you provide a transform
// and a versioner, the versioner must be able to handle the objects that transform creates.
func newEtcdWatcher(list bool, include includeFunc, filter FilterFunc, encoding runtime.Codec, versioner StorageVersioner, transform TransformFunc, cache etcdCache) *etcdWatcher {
func newEtcdWatcher(list bool, include includeFunc, filter storage.FilterFunc, encoding runtime.Codec, versioner storage.StorageVersioner, transform TransformFunc, cache etcdCache) *etcdWatcher {
w := &etcdWatcher{
encoding: encoding,
versioner: versioner,

View File

@ -25,6 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/coreos/go-etcd/etcd"
@ -165,7 +166,7 @@ func TestWatchInterpretations(t *testing.T) {
}
func TestWatchInterpretation_ResponseNotSet(t *testing.T) {
w := newEtcdWatcher(false, nil, Everything, codec, versioner, nil, &fakeEtcdCache{})
w := newEtcdWatcher(false, nil, storage.Everything, codec, versioner, nil, &fakeEtcdCache{})
w.emit = func(e watch.Event) {
t.Errorf("Unexpected emit: %v", e)
}
@ -179,7 +180,7 @@ func TestWatchInterpretation_ResponseNotSet(t *testing.T) {
func TestWatchInterpretation_ResponseNoNode(t *testing.T) {
actions := []string{"create", "set", "compareAndSwap", "delete"}
for _, action := range actions {
w := newEtcdWatcher(false, nil, Everything, codec, versioner, nil, &fakeEtcdCache{})
w := newEtcdWatcher(false, nil, storage.Everything, codec, versioner, nil, &fakeEtcdCache{})
w.emit = func(e watch.Event) {
t.Errorf("Unexpected emit: %v", e)
}
@ -193,7 +194,7 @@ func TestWatchInterpretation_ResponseNoNode(t *testing.T) {
func TestWatchInterpretation_ResponseBadData(t *testing.T) {
actions := []string{"create", "set", "compareAndSwap", "delete"}
for _, action := range actions {
w := newEtcdWatcher(false, nil, Everything, codec, versioner, nil, &fakeEtcdCache{})
w := newEtcdWatcher(false, nil, storage.Everything, codec, versioner, nil, &fakeEtcdCache{})
w.emit = func(e watch.Event) {
t.Errorf("Unexpected emit: %v", e)
}
@ -220,7 +221,7 @@ func TestWatchEtcdError(t *testing.T) {
fakeClient.WatchImmediateError = fmt.Errorf("immediate error")
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch("/some/key", 4, Everything)
watching, err := h.Watch("/some/key", 4, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -250,7 +251,7 @@ func TestWatch(t *testing.T) {
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{}
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, Everything)
watching, err := h.Watch(key, 0, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -425,7 +426,7 @@ func TestWatchEtcdState(t *testing.T) {
}
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(baseKey, testCase.From, Everything)
watching, err := h.Watch(baseKey, testCase.From, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -499,7 +500,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
fakeClient.Data[prefixedKey] = testCase.Response
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, Everything)
watching, err := h.Watch(key, 0, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -560,7 +561,7 @@ func TestWatchListFromZeroIndex(t *testing.T) {
}
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.WatchList(key, 0, Everything)
watching, err := h.WatchList(key, 0, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -600,7 +601,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
fakeClient := NewFakeEtcdClient(t)
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.WatchList(key, 1, Everything)
watching, err := h.WatchList(key, 1, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -653,7 +654,7 @@ func TestWatchFromNotFound(t *testing.T) {
}
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, Everything)
watching, err := h.Watch(key, 0, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -680,7 +681,7 @@ func TestWatchFromOtherError(t *testing.T) {
}
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, Everything)
watching, err := h.Watch(key, 0, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -716,7 +717,7 @@ func TestWatchPurposefulShutdown(t *testing.T) {
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{}
// Test purposeful shutdown
watching, err := h.Watch(key, 0, Everything)
watching, err := h.Watch(key, 0, storage.Everything)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

View File

@ -17,11 +17,6 @@ limitations under the License.
package tools
import (
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/coreos/go-etcd/etcd"
)
@ -51,119 +46,3 @@ type EtcdClient interface {
// the etcd client interface which doesn't, and it doesn't seem worth it to wrap the api.
Watch(prefix string, waitIndex uint64, recursive bool, receiver chan *etcd.Response, stop chan bool) (*etcd.Response, error)
}
// StorageVersioner abstracts setting and retrieving metadata fields from the etcd response onto the object
// or list.
type StorageVersioner interface {
// UpdateObject sets etcd storage metadata into an API object. Returns an error if the object
// cannot be updated correctly. May return nil if the requested object does not need metadata
// from etcd.
UpdateObject(obj runtime.Object, expiration *time.Time, resourceVersion uint64) error
// UpdateList sets the resource version into an API list object. Returns an error if the object
// cannot be updated correctly. May return nil if the requested object does not need metadata
// from etcd.
UpdateList(obj runtime.Object, resourceVersion uint64) error
// ObjectResourceVersion returns the resource version (for persistence) of the specified object.
// Should return an error if the specified object does not have a persistable version.
ObjectResourceVersion(obj runtime.Object) (uint64, error)
}
// ResponseMeta contains information about the etcd metadata that is associated with
// an object. It abstracts the actual underlying objects to prevent coupling with etcd
// and to improve testability.
type ResponseMeta struct {
// TTL is the time to live of the node that contained the returned object. It may be
// zero or negative in some cases (objects may be expired after the requested
// expiration time due to server lag).
TTL int64
// Expiration is the time at which the node that contained the returned object will expire and be deleted.
// This can be nil if there is no expiration time set for the node.
Expiration *time.Time
// The resource version of the node that contained the returned object.
ResourceVersion uint64
}
// Pass an StorageUpdateFunc to StorageInterface.GuaranteedUpdate to make an update
// that is guaranteed to succeed.
// See the comment for GuaranteedUpdate for more details.
type StorageUpdateFunc func(input runtime.Object, res ResponseMeta) (output runtime.Object, ttl *uint64, err error)
// StorageInterface offers a common interface for object marshaling/unmarshling operations and
// hids all the storage-related operations behind it.
type StorageInterface interface {
// Returns list of servers addresses of the underyling database.
// TODO: This method is used only in a single place. Consider refactoring and getting rid
// of this method from the interface.
Backends() []string
// Returns StorageVersioner associated with this interface.
Versioner() StorageVersioner
// Create adds a new object at a key unless it already exists. 'ttl' is time-to-live
// in seconds (0 means forever). If no error is returned and out is not nil, out will be
// set to the read value from etcd.
Create(key string, obj, out runtime.Object, ttl uint64) error
// Set marshals obj via json and stores in etcd under key. Will do an atomic update
// if obj's ResourceVersion field is set. 'ttl' is time-to-live in seconds (0 means forever).
// If no error is returned and out is not nil, out will be set to the read value from etcd.
Set(key string, obj, out runtime.Object, ttl uint64) error
// Delete removes the specified key and returns the value that existed at that spot.
Delete(key string, out runtime.Object) error
// RecursiveDelete removes the specified key.
// TODO: Get rid of this method and use Delete() instead.
RecursiveDelete(key string, recursive bool) error
// Watch begins watching the specified key. Events are decoded into API objects,
// and any items passing 'filter' are sent down to returned watch.Interface.
// resourceVersion may be used to specify what version to begin watching
// (e.g. reconnecting without missing any updates).
Watch(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error)
// WatchList begins watching the specified key's items. Items are decoded into API
// objects and any item passing 'filter' are sent down to returned watch.Interface.
// resourceVersion may be used to specify what version to begin watching
// (e.g. reconnecting without missing any updates).
WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error)
// Get unmarshals json found at key into objPtr. On a not found error, will either
// return a zero object of the requested type, or an error, depending on ignoreNotFound.
// Treats empty responses and nil response nodes exactly like a not found error.
Get(key string, objPtr runtime.Object, ignoreNotFound bool) error
// GetToList unmarshals json found at key and opaque it into *List api object
// (an object that satisfies the runtime.IsList definition).
GetToList(key string, listObj runtime.Object) error
// List unmarshalls jsons found at directory defined by key and opaque them
// into *List api object (an object that satisfies runtime.IsList definition).
List(key string, listObj runtime.Object) error
// GuaranteedUpdate keeps calling 'tryUpdate()' to update key 'key' (of type 'ptrToType')
// retrying the update until success if there is etcd index conflict.
// Note that object passed to tryUpdate may change acress incovations of tryUpdate() if
// other writers are simultanously updateing it, to tryUpdate() needs to take into account
// the current contents of the object when deciding how the update object should look.
//
// Exmaple:
//
// s := /* implementation of StorageInterface */
// err := s.GuaranteedUpdate(
// "myKey", &MyType{}, true,
// func(input runtime.Object, res ResponseMeta) (runtime.Object, *uint64, error) {
// // Before each incovation of the user defined function, "input" is reset to
// // etcd's current contents for "myKey".
// curr := input.(*MyType) // Guaranteed to succeed.
//
// // Make the modification
// curr.Counter++
//
// // Return the modified object - return an error to stop iterating. Return
// // a uint64 to alter the TTL on the object, or nil to keep it the same value.
// return cur, nil, nil
// }
// })
GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate StorageUpdateFunc) error
}

View File

@ -24,7 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
"github.com/golang/glog"
@ -41,7 +41,7 @@ func NewEtcdClient() *etcd.Client {
return etcd.NewClient([]string{})
}
func NewEtcdStorage() (tools.StorageInterface, error) {
func NewEtcdStorage() (storage.StorageInterface, error) {
return master.NewEtcdStorage(NewEtcdClient(), testapi.Version(), etcdtest.PathPrefix())
}

View File

@ -35,7 +35,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/golang/glog"
@ -72,7 +72,7 @@ type MasterComponents struct {
// Used to stop master components individually, and via MasterComponents.Stop
once sync.Once
// Kubernetes etcd storage, has embedded etcd client
EtcdStorage tools.StorageInterface
EtcdStorage storage.StorageInterface
}
// Config is a struct of configuration directives for NewMasterComponents.
@ -119,13 +119,13 @@ func NewMasterComponents(c *Config) *MasterComponents {
}
// startMasterOrDie starts a kubernetes master and an httpserver to handle api requests
func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Server, tools.StorageInterface) {
func startMasterOrDie(masterConfig *master.Config) (*master.Master, *httptest.Server, storage.StorageInterface) {
var m *master.Master
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
m.Handler.ServeHTTP(w, req)
}))
var etcdStorage tools.StorageInterface
var etcdStorage storage.StorageInterface
var err error
if masterConfig == nil {
etcdStorage, err = master.NewEtcdStorage(NewEtcdClient(), "", etcdtest.PathPrefix())