Move etcd storage to pkg/storage/etcd

This commit is contained in:
Wojciech Tyczynski
2015-07-30 13:27:18 +02:00
parent 99d6b0e9f4
commit 3cbbe72f9f
43 changed files with 289 additions and 202 deletions

View File

@@ -37,7 +37,7 @@ import (
kclientcmd "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd" kclientcmd "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd"
kframework "github.com/GoogleCloudPlatform/kubernetes/pkg/controller/framework" kframework "github.com/GoogleCloudPlatform/kubernetes/pkg/controller/framework"
kSelector "github.com/GoogleCloudPlatform/kubernetes/pkg/fields" kSelector "github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
tools "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
etcd "github.com/coreos/go-etcd/etcd" etcd "github.com/coreos/go-etcd/etcd"
@@ -354,7 +354,7 @@ func newEtcdClient(etcdServer string) (*etcd.Client, error) {
err error err error
) )
for attempt := 1; attempt <= maxConnectAttempts; attempt++ { for attempt := 1; attempt <= maxConnectAttempts; attempt++ {
if _, err = tools.GetEtcdVersion(etcdServer); err == nil { if _, err = etcdstorage.GetEtcdVersion(etcdServer); err == nil {
break break
} }
if attempt == maxConnectAttempts { if attempt == maxConnectAttempts {

View File

@@ -41,6 +41,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/service" "github.com/GoogleCloudPlatform/kubernetes/pkg/service"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
@@ -167,7 +168,7 @@ func main() {
defer util.FlushLogs() defer util.FlushLogs()
glog.Infof("Creating etcd client pointing to %v", *etcdServer) glog.Infof("Creating etcd client pointing to %v", *etcdServer)
etcdClient, err := tools.NewEtcdClientStartServerIfNecessary(*etcdServer) etcdClient, err := etcdstorage.NewEtcdClientStartServerIfNecessary(*etcdServer)
if err != nil { if err != nil {
glog.Fatalf("Failed to connect to etcd: %v", err) glog.Fatalf("Failed to connect to etcd: %v", err)
} }

View File

@@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"time" "time"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@@ -90,10 +91,10 @@ func (e *etcdMasterElector) extendMaster(path, id string, ttl uint64, res *etcd.
// We don't handle the TTL delete w/o a write case here, it's handled in the next loop // We don't handle the TTL delete w/o a write case here, it's handled in the next loop
// iteration. // iteration.
_, err := e.etcd.CompareAndSwap(path, id, ttl, "", res.Node.ModifiedIndex) _, err := e.etcd.CompareAndSwap(path, id, ttl, "", res.Node.ModifiedIndex)
if err != nil && !tools.IsEtcdTestFailed(err) { if err != nil && !etcdstorage.IsEtcdTestFailed(err) {
return "", err return "", err
} }
if err != nil && tools.IsEtcdTestFailed(err) { if err != nil && etcdstorage.IsEtcdTestFailed(err) {
return "", nil return "", nil
} }
return id, nil return id, nil
@@ -105,11 +106,11 @@ func (e *etcdMasterElector) extendMaster(path, id string, ttl uint64, res *etcd.
// returns "", err if an error occurred // returns "", err if an error occurred
func (e *etcdMasterElector) becomeMaster(path, id string, ttl uint64) (string, error) { func (e *etcdMasterElector) becomeMaster(path, id string, ttl uint64) (string, error) {
_, err := e.etcd.Create(path, id, ttl) _, err := e.etcd.Create(path, id, ttl)
if err != nil && !tools.IsEtcdNodeExist(err) { if err != nil && !etcdstorage.IsEtcdNodeExist(err) {
// unexpected error // unexpected error
return "", err return "", err
} }
if err != nil && tools.IsEtcdNodeExist(err) { if err != nil && etcdstorage.IsEtcdNodeExist(err) {
return "", nil return "", nil
} }
return id, nil return id, nil
@@ -124,12 +125,12 @@ func (e *etcdMasterElector) handleMaster(path, id string, ttl uint64) (string, e
res, err := e.etcd.Get(path, false, false) res, err := e.etcd.Get(path, false, false)
// Unexpected error, bail out // Unexpected error, bail out
if err != nil && !tools.IsEtcdNotFound(err) { if err != nil && !etcdstorage.IsEtcdNotFound(err) {
return "", err return "", err
} }
// There is no master, try to become the master. // There is no master, try to become the master.
if err != nil && tools.IsEtcdNotFound(err) { if err != nil && etcdstorage.IsEtcdNotFound(err) {
return e.becomeMaster(path, id, ttl) return e.becomeMaster(path, id, ttl)
} }

View File

@@ -47,6 +47,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth" "github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports" "github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
@@ -740,7 +741,7 @@ func (s *SchedulerServer) buildFrameworkInfo() (info *mesos.FrameworkInfo, cred
func (s *SchedulerServer) fetchFrameworkID(client tools.EtcdClient) (*mesos.FrameworkID, error) { func (s *SchedulerServer) fetchFrameworkID(client tools.EtcdClient) (*mesos.FrameworkID, error) {
if s.FailoverTimeout > 0 { if s.FailoverTimeout > 0 {
if response, err := client.Get(meta.FrameworkIDKey, false, false); err != nil { if response, err := client.Get(meta.FrameworkIDKey, false, false); err != nil {
if !tools.IsEtcdNotFound(err) { if !etcdstorage.IsEtcdNotFound(err) {
return nil, fmt.Errorf("unexpected failure attempting to load framework ID from etcd: %v", err) return nil, fmt.Errorf("unexpected failure attempting to load framework ID from etcd: %v", err)
} }
log.V(1).Infof("did not find framework ID in etcd") log.V(1).Infof("did not find framework ID in etcd")
@@ -751,7 +752,7 @@ func (s *SchedulerServer) fetchFrameworkID(client tools.EtcdClient) (*mesos.Fram
} else { } else {
//TODO(jdef) this seems like a totally hackish way to clean up the framework ID //TODO(jdef) this seems like a totally hackish way to clean up the framework ID
if _, err := client.Delete(meta.FrameworkIDKey, true); err != nil { if _, err := client.Delete(meta.FrameworkIDKey, true); err != nil {
if !tools.IsEtcdNotFound(err) { if !etcdstorage.IsEtcdNotFound(err) {
return nil, fmt.Errorf("failed to delete framework ID from etcd: %v", err) return nil, fmt.Errorf("failed to delete framework ID from etcd: %v", err)
} }
log.V(1).Infof("nothing to delete: did not find framework ID in etcd") log.V(1).Infof("nothing to delete: did not find framework ID in etcd")

View File

@@ -27,7 +27,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
"github.com/golang/glog" "github.com/golang/glog"
@@ -72,7 +72,7 @@ func (c *Config) leaseAndUpdateLoop(etcdClient *etcd.Client) {
func (c *Config) acquireOrRenewLease(etcdClient *etcd.Client) (bool, error) { func (c *Config) acquireOrRenewLease(etcdClient *etcd.Client) (bool, error) {
result, err := etcdClient.Get(c.key, false, false) result, err := etcdClient.Get(c.key, false, false)
if err != nil { if err != nil {
if tools.IsEtcdNotFound(err) { if etcdstorage.IsEtcdNotFound(err) {
// there is no current master, try to become master, create will fail if the key already exists // there is no current master, try to become master, create will fail if the key already exists
_, err := etcdClient.Create(c.key, c.whoami, c.ttl) _, err := etcdClient.Create(c.key, c.whoami, c.ttl)
if err != nil { if err != nil {

View File

@@ -163,7 +163,7 @@ resource type. However, this watch can potentially expire at any time and
reconnecting can return "too old resource version". In that case relisting is reconnecting can return "too old resource version". In that case relisting is
necessary. In such case, to avoid LIST requests coming from all watchers at necessary. In such case, to avoid LIST requests coming from all watchers at
the same time, we can introduce an additional etcd event type: the same time, we can introduce an additional etcd event type:
[EtcdResync](../../pkg/tools/etcd_watcher.go#L36) [EtcdResync](../../pkg/storage/etcd/etcd_watcher.go#L36)
Whenever reslisting will be done to refresh the internal watch to etcd, Whenever reslisting will be done to refresh the internal watch to etcd,
EtcdResync event will be send to all the watchers. It will contain the EtcdResync event will be send to all the watchers. It will contain the

View File

@@ -18,14 +18,14 @@ package etcd
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
) )
// InterpretGetError converts a generic etcd error on a retrieval // InterpretGetError converts a generic etcd error on a retrieval
// operation into the appropriate API error. // operation into the appropriate API error.
func InterpretGetError(err error, kind, name string) error { func InterpretGetError(err error, kind, name string) error {
switch { switch {
case tools.IsEtcdNotFound(err): case etcdstorage.IsEtcdNotFound(err):
return errors.NewNotFound(kind, name) return errors.NewNotFound(kind, name)
default: default:
return err return err
@@ -36,7 +36,7 @@ func InterpretGetError(err error, kind, name string) error {
// operation into the appropriate API error. // operation into the appropriate API error.
func InterpretCreateError(err error, kind, name string) error { func InterpretCreateError(err error, kind, name string) error {
switch { switch {
case tools.IsEtcdNodeExist(err): case etcdstorage.IsEtcdNodeExist(err):
return errors.NewAlreadyExists(kind, name) return errors.NewAlreadyExists(kind, name)
default: default:
return err return err
@@ -47,7 +47,7 @@ func InterpretCreateError(err error, kind, name string) error {
// operation into the appropriate API error. // operation into the appropriate API error.
func InterpretUpdateError(err error, kind, name string) error { func InterpretUpdateError(err error, kind, name string) error {
switch { switch {
case tools.IsEtcdTestFailed(err), tools.IsEtcdNodeExist(err): case etcdstorage.IsEtcdTestFailed(err), etcdstorage.IsEtcdNodeExist(err):
return errors.NewConflict(kind, name, err) return errors.NewConflict(kind, name, err)
default: default:
return err return err
@@ -58,7 +58,7 @@ func InterpretUpdateError(err error, kind, name string) error {
// operation into the appropriate API error. // operation into the appropriate API error.
func InterpretDeleteError(err error, kind, name string) error { func InterpretDeleteError(err error, kind, name string) error {
switch { switch {
case tools.IsEtcdNotFound(err): case etcdstorage.IsEtcdNotFound(err):
return errors.NewNotFound(kind, name) return errors.NewNotFound(kind, name)
default: default:
return err return err

View File

@@ -21,7 +21,7 @@ import (
"net/http" "net/http"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
) )
@@ -52,7 +52,7 @@ func errToAPIStatus(err error) *api.Status {
status := http.StatusInternalServerError status := http.StatusInternalServerError
switch { switch {
//TODO: replace me with NewConflictErr //TODO: replace me with NewConflictErr
case tools.IsEtcdTestFailed(err): case etcdstorage.IsEtcdTestFailed(err):
status = http.StatusConflict status = http.StatusConflict
} }
// Log errors that were not converted to an error status // Log errors that were not converted to an error status

View File

@@ -70,6 +70,7 @@ import (
ipallocator "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/ipallocator" ipallocator "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/ipallocator"
serviceaccountetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount/etcd" serviceaccountetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/serviceaccount/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/ui" "github.com/GoogleCloudPlatform/kubernetes/pkg/ui"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -234,7 +235,7 @@ func NewEtcdStorage(client tools.EtcdClient, version string, prefix string) (etc
if err != nil { if err != nil {
return etcdStorage, err return etcdStorage, err
} }
return tools.NewEtcdStorage(client, versionInterfaces.Codec, prefix), nil return etcdstorage.NewEtcdStorage(client, versionInterfaces.Codec, prefix), nil
} }
// setDefaults fills in any fields not set that are required to have valid data. // setDefaults fills in any fields not set that are required to have valid data.
@@ -722,7 +723,7 @@ func (m *Master) getServersToValidate(c *Config) map[string]apiserver.Server {
addr = etcdUrl.Host addr = etcdUrl.Host
port = 4001 port = 4001
} }
serversToValidate[fmt.Sprintf("etcd-%d", ix)] = apiserver.Server{Addr: addr, Port: port, Path: "/health", Validate: tools.EtcdHealthCheck} serversToValidate[fmt.Sprintf("etcd-%d", ix)] = apiserver.Server{Addr: addr, Port: port, Path: "/health", Validate: etcdstorage.EtcdHealthCheck}
} }
return serversToValidate return serversToValidate
} }

View File

@@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
@@ -31,7 +32,7 @@ func TestGetServersToValidate(t *testing.T) {
config := Config{} config := Config{}
fakeClient := tools.NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"} fakeClient.Machines = []string{"http://machine1:4001", "http://machine2", "http://machine3:4003"}
config.DatabaseStorage = tools.NewEtcdStorage(fakeClient, latest.Codec, etcdtest.PathPrefix()) config.DatabaseStorage = etcdstorage.NewEtcdStorage(fakeClient, latest.Codec, etcdtest.PathPrefix())
master.nodeRegistry = registrytest.NewMinionRegistry([]string{"node1", "node2"}, api.NodeResources{}) master.nodeRegistry = registrytest.NewMinionRegistry([]string{"node1", "node2"}, api.NodeResources{})

View File

@@ -31,6 +31,7 @@ import (
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
@@ -44,7 +45,7 @@ const (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }
@@ -625,10 +626,10 @@ func TestEtcdWatchControllersFields(t *testing.T) {
}, },
} }
testEtcdActions := []string{ testEtcdActions := []string{
tools.EtcdCreate, etcdstorage.EtcdCreate,
tools.EtcdSet, etcdstorage.EtcdSet,
tools.EtcdCAS, etcdstorage.EtcdCAS,
tools.EtcdDelete} etcdstorage.EtcdDelete}
controller := &api.ReplicationController{ controller := &api.ReplicationController{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
@@ -654,7 +655,7 @@ func TestEtcdWatchControllersFields(t *testing.T) {
node := &etcd.Node{ node := &etcd.Node{
Value: string(controllerBytes), Value: string(controllerBytes),
} }
if action == tools.EtcdDelete { if action == etcdstorage.EtcdDelete {
prevNode = node prevNode = node
} }
fakeClient.WaitForWatchCompletion() fakeClient.WaitForWatchCompletion()

View File

@@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -36,7 +37,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -27,7 +27,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@@ -159,7 +158,7 @@ func (r *Registry) UpdateService(ctx api.Context, svc *api.Service) (*api.Servic
// WatchServices begins watching for new, changed, or deleted service configurations. // WatchServices begins watching for new, changed, or deleted service configurations.
func (r *Registry) WatchServices(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) { func (r *Registry) WatchServices(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
version, err := tools.ParseWatchResourceVersion(resourceVersion, "service") version, err := storage.ParseWatchResourceVersion(resourceVersion, "service")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -31,6 +31,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
podetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/etcd" podetcd "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
@@ -38,13 +39,13 @@ import (
) )
func NewTestEtcdRegistry(client tools.EtcdClient) *Registry { func NewTestEtcdRegistry(client tools.EtcdClient) *Registry {
storage := tools.NewEtcdStorage(client, latest.Codec, etcdtest.PathPrefix()) storage := etcdstorage.NewEtcdStorage(client, latest.Codec, etcdtest.PathPrefix())
registry := NewRegistry(storage, nil, nil) registry := NewRegistry(storage, nil, nil)
return registry return registry
} }
func NewTestEtcdRegistryWithPods(client tools.EtcdClient) *Registry { func NewTestEtcdRegistryWithPods(client tools.EtcdClient) *Registry {
etcdStorage := tools.NewEtcdStorage(client, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(client, latest.Codec, etcdtest.PathPrefix())
podStorage := podetcd.NewStorage(etcdStorage, nil) podStorage := podetcd.NewStorage(etcdStorage, nil)
endpointStorage := endpointetcd.NewStorage(etcdStorage) endpointStorage := endpointetcd.NewStorage(etcdStorage)
registry := NewRegistry(etcdStorage, pod.NewRegistry(podStorage.Pod), endpoint.NewRegistry(endpointStorage)) registry := NewRegistry(etcdStorage, pod.NewRegistry(podStorage.Pod), endpoint.NewRegistry(endpointStorage))

View File

@@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -39,7 +40,7 @@ func NewTestEventEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Regi
f := tools.NewFakeEtcdClient(t) f := tools.NewFakeEtcdClient(t)
f.TestIndex = true f.TestIndex = true
s := tools.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix()) s := etcdstorage.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(s, testTTL) return f, NewEtcdRegistry(s, testTTL)
} }

View File

@@ -30,7 +30,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@@ -456,7 +455,7 @@ func (e *Etcd) Watch(ctx api.Context, label labels.Selector, field fields.Select
// WatchPredicate starts a watch for the items that m matches. // WatchPredicate starts a watch for the items that m matches.
func (e *Etcd) WatchPredicate(ctx api.Context, m generic.Matcher, resourceVersion string) (watch.Interface, error) { func (e *Etcd) WatchPredicate(ctx api.Context, m generic.Matcher, resourceVersion string) (watch.Interface, error) {
version, err := tools.ParseWatchResourceVersion(resourceVersion, e.EndpointName) version, err := storage.ParseWatchResourceVersion(resourceVersion, e.EndpointName)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -69,7 +70,7 @@ func hasCreated(t *testing.T, pod *api.Pod) func(runtime.Object) bool {
func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) { func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) {
f := tools.NewFakeEtcdClient(t) f := tools.NewFakeEtcdClient(t)
f.TestIndex = true f.TestIndex = true
s := tools.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix()) s := etcdstorage.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix())
strategy := &testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false, true} strategy := &testRESTStrategy{api.Scheme, api.SimpleNameGenerator, true, false, true}
podPrefix := "/pods" podPrefix := "/pods"
return f, &Etcd{ return f, &Etcd{

View File

@@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -37,7 +38,7 @@ import (
func NewTestLimitRangeEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { func NewTestLimitRangeEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) {
f := tools.NewFakeEtcdClient(t) f := tools.NewFakeEtcdClient(t)
f.TestIndex = true f.TestIndex = true
s := tools.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix()) s := etcdstorage.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewEtcdRegistry(s) return f, NewEtcdRegistry(s)
} }

View File

@@ -30,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
@@ -51,7 +52,7 @@ func (fakeConnectionInfoGetter) GetConnectionInfo(host string) (string, uint, ht
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/namespace"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -37,7 +38,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -42,7 +43,7 @@ type testRegistry struct {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
storage, statusStorage := NewStorage(etcdStorage) storage, statusStorage := NewStorage(etcdStorage)
return storage, statusStorage, fakeEtcdClient, etcdStorage return storage, statusStorage, fakeEtcdClient, etcdStorage
} }

View File

@@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -42,7 +43,7 @@ type testRegistry struct {
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
storage, statusStorage := NewStorage(etcdStorage) storage, statusStorage := NewStorage(etcdStorage)
return storage, statusStorage, fakeEtcdClient, etcdStorage return storage, statusStorage, fakeEtcdClient, etcdStorage
} }

View File

@@ -36,7 +36,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
) )
@@ -144,7 +143,7 @@ func (r *BindingREST) setPodHostAndAnnotations(ctx api.Context, podID, oldMachin
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = r.store.Storage.GuaranteedUpdate(podKey, &api.Pod{}, false, tools.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) { err = r.store.Storage.GuaranteedUpdate(podKey, &api.Pod{}, false, storage.SimpleUpdate(func(obj runtime.Object) (runtime.Object, error) {
pod, ok := obj.(*api.Pod) pod, ok := obj.(*api.Pod)
if !ok { if !ok {
return nil, fmt.Errorf("unexpected object: %#v", obj) return nil, fmt.Errorf("unexpected object: %#v", obj)

View File

@@ -34,6 +34,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/securitycontext" "github.com/GoogleCloudPlatform/kubernetes/pkg/securitycontext"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -44,7 +45,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -23,6 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
@@ -30,7 +31,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -32,6 +32,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@@ -42,7 +43,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -23,6 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
@@ -30,7 +31,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -28,7 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
) )
var ( var (
@@ -142,7 +142,7 @@ func (e *Etcd) Release(item int) error {
// tryUpdate performs a read-update to persist the latest snapshot state of allocation. // tryUpdate performs a read-update to persist the latest snapshot state of allocation.
func (e *Etcd) tryUpdate(fn func() error) error { func (e *Etcd) tryUpdate(fn func() error) error {
err := e.storage.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true, err := e.storage.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true,
tools.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) { storage.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) {
existing := input.(*api.RangeAllocation) existing := input.(*api.RangeAllocation)
if len(existing.ResourceVersion) == 0 { if len(existing.ResourceVersion) == 0 {
return nil, fmt.Errorf("cannot allocate resources of type %s at this time", e.kind) return nil, fmt.Errorf("cannot allocate resources of type %s at this time", e.kind)
@@ -172,7 +172,7 @@ func (e *Etcd) Refresh() (*api.RangeAllocation, error) {
existing := &api.RangeAllocation{} existing := &api.RangeAllocation{}
if err := e.storage.Get(e.baseKey, existing, false); err != nil { if err := e.storage.Get(e.baseKey, existing, false); err != nil {
if tools.IsEtcdNotFound(err) { if etcdstorage.IsEtcdNotFound(err) {
return nil, nil return nil, nil
} }
return nil, etcderr.InterpretGetError(err, e.kind, "") return nil, etcderr.InterpretGetError(err, e.kind, "")
@@ -199,7 +199,7 @@ func (e *Etcd) CreateOrUpdate(snapshot *api.RangeAllocation) error {
last := "" last := ""
err := e.storage.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true, err := e.storage.GuaranteedUpdate(e.baseKey, &api.RangeAllocation{}, true,
tools.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) { storage.SimpleUpdate(func(input runtime.Object) (output runtime.Object, err error) {
existing := input.(*api.RangeAllocation) existing := input.(*api.RangeAllocation)
switch { switch {
case len(snapshot.ResourceVersion) != 0 && len(existing.ResourceVersion) != 0: case len(snapshot.ResourceVersion) != 0 && len(existing.ResourceVersion) != 0:

View File

@@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/allocator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
@@ -34,7 +35,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -30,6 +30,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/ipallocator" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/ipallocator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
@@ -37,7 +38,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -23,6 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
etcdstorage "github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
) )
@@ -30,7 +31,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := tools.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tools package etcd
import ( import (
"strconv" "strconv"

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tools package etcd
import ( import (
"testing" "testing"

17
pkg/storage/etcd/doc.go Normal file
View File

@@ -0,0 +1,17 @@
/*
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 etcd

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tools package etcd
import ( import (
"errors" "errors"
@@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion" "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/metrics" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/metrics"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@@ -36,7 +37,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
func NewEtcdStorage(client EtcdClient, codec runtime.Codec, prefix string) storage.Interface { func NewEtcdStorage(client tools.EtcdClient, codec runtime.Codec, prefix string) storage.Interface {
return &etcdHelper{ return &etcdHelper{
client: client, client: client,
codec: codec, codec: codec,
@@ -49,7 +50,7 @@ func NewEtcdStorage(client EtcdClient, codec runtime.Codec, prefix string) stora
// etcdHelper is the reference implementation of storage.Interface. // etcdHelper is the reference implementation of storage.Interface.
type etcdHelper struct { type etcdHelper struct {
client EtcdClient client tools.EtcdClient
codec runtime.Codec codec runtime.Codec
copier runtime.ObjectCopier copier runtime.ObjectCopier
// optional, has to be set to perform any atomic operations // optional, has to be set to perform any atomic operations
@@ -365,16 +366,6 @@ func (h *etcdHelper) listEtcdNode(key string) ([]*etcd.Node, uint64, error) {
return result.Node.Nodes, result.EtcdIndex, nil return result.Node.Nodes, result.EtcdIndex, nil
} }
type SimpleUpdateFunc func(runtime.Object) (runtime.Object, error)
// SimpleUpdateFunc converts SimpleUpdateFunc into UpdateFunc
func SimpleUpdate(fn SimpleUpdateFunc) storage.UpdateFunc {
return func(input runtime.Object, _ storage.ResponseMeta) (runtime.Object, *uint64, error) {
out, err := fn(input)
return out, nil, err
}
}
// Implements storage.Interface. // Implements storage.Interface.
func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate storage.UpdateFunc) error { func (h *etcdHelper) GuaranteedUpdate(key string, ptrToType runtime.Object, ignoreNotFound bool, tryUpdate storage.UpdateFunc) error {
v, err := conversion.EnforcePtr(ptrToType) v, err := conversion.EnforcePtr(ptrToType)

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tools package etcd
import ( import (
"errors" "errors"
@@ -35,6 +35,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion" "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -66,7 +67,7 @@ func init() {
) )
} }
func newEtcdHelper(client EtcdClient, codec runtime.Codec, prefix string) etcdHelper { func newEtcdHelper(client tools.EtcdClient, codec runtime.Codec, prefix string) etcdHelper {
return *NewEtcdStorage(client, codec, prefix).(*etcdHelper) return *NewEtcdStorage(client, codec, prefix).(*etcdHelper)
} }
@@ -76,7 +77,7 @@ func TestIsEtcdNotFound(t *testing.T) {
t.Errorf("Expected %#v to return %v, but it did not", err, isNotFound) t.Errorf("Expected %#v to return %v, but it did not", err, isNotFound)
} }
} }
try(EtcdErrorNotFound, true) try(tools.EtcdErrorNotFound, true)
try(&etcd.EtcdError{ErrorCode: 101}, false) try(&etcd.EtcdError{ErrorCode: 101}, false)
try(nil, false) try(nil, false)
try(fmt.Errorf("some other kind of error"), false) try(fmt.Errorf("some other kind of error"), false)
@@ -91,10 +92,10 @@ func getEncodedPod(name string) string {
} }
func TestList(t *testing.T) { func TestList(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
EtcdIndex: 10, EtcdIndex: 10,
Node: &etcd.Node{ Node: &etcd.Node{
@@ -161,10 +162,10 @@ func TestList(t *testing.T) {
// TestListAcrossDirectories ensures that the client excludes directories and flattens tree-response - simulates cross-namespace query // TestListAcrossDirectories ensures that the client excludes directories and flattens tree-response - simulates cross-namespace query
func TestListAcrossDirectories(t *testing.T) { func TestListAcrossDirectories(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
EtcdIndex: 10, EtcdIndex: 10,
Node: &etcd.Node{ Node: &etcd.Node{
@@ -244,10 +245,10 @@ func TestListAcrossDirectories(t *testing.T) {
} }
func TestListExcludesDirectories(t *testing.T) { func TestListExcludesDirectories(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
EtcdIndex: 10, EtcdIndex: 10,
Node: &etcd.Node{ Node: &etcd.Node{
@@ -315,7 +316,7 @@ func TestListExcludesDirectories(t *testing.T) {
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
expect := api.Pod{ expect := api.Pod{
@@ -337,10 +338,10 @@ func TestGet(t *testing.T) {
} }
func TestGetNotFoundErr(t *testing.T) { func TestGetNotFoundErr(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key1 := etcdtest.AddPrefix("/some/key") key1 := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key1] = EtcdResponseWithError{ fakeClient.Data[key1] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
}, },
@@ -349,13 +350,13 @@ func TestGetNotFoundErr(t *testing.T) {
}, },
} }
key2 := etcdtest.AddPrefix("/some/key2") key2 := etcdtest.AddPrefix("/some/key2")
fakeClient.Data[key2] = EtcdResponseWithError{ fakeClient.Data[key2] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
}, },
} }
key3 := etcdtest.AddPrefix("/some/key3") key3 := etcdtest.AddPrefix("/some/key3")
fakeClient.Data[key3] = EtcdResponseWithError{ fakeClient.Data[key3] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: "", Value: "",
@@ -381,7 +382,7 @@ func TestGetNotFoundErr(t *testing.T) {
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
returnedObj := &api.Pod{} returnedObj := &api.Pod{}
err := helper.Create("/some/key", obj, returnedObj, 5) err := helper.Create("/some/key", obj, returnedObj, 5)
@@ -407,7 +408,7 @@ func TestCreate(t *testing.T) {
func TestCreateNilOutParam(t *testing.T) { func TestCreateNilOutParam(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
err := helper.Create("/some/key", obj, nil, 5) err := helper.Create("/some/key", obj, nil, 5)
if err != nil { if err != nil {
@@ -417,7 +418,7 @@ func TestCreateNilOutParam(t *testing.T) {
func TestSet(t *testing.T) { func TestSet(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
returnedObj := &api.Pod{} returnedObj := &api.Pod{}
err := helper.Set("/some/key", obj, returnedObj, 5) err := helper.Set("/some/key", obj, returnedObj, 5)
@@ -444,7 +445,7 @@ func TestSet(t *testing.T) {
func TestSetFailCAS(t *testing.T) { func TestSetFailCAS(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.CasErr = fakeClient.NewError(123) fakeClient.CasErr = fakeClient.NewError(123)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
err := helper.Set("/some/key", obj, nil, 5) err := helper.Set("/some/key", obj, nil, 5)
@@ -455,11 +456,11 @@ func TestSetFailCAS(t *testing.T) {
func TestSetWithVersion(t *testing.T) { func TestSetWithVersion(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
fakeClient.Data[key] = EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), obj), Value: runtime.EncodeOrDie(testapi.Codec(), obj),
@@ -492,7 +493,7 @@ func TestSetWithVersion(t *testing.T) {
func TestSetWithoutResourceVersioner(t *testing.T) { func TestSetWithoutResourceVersioner(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
helper.versioner = nil helper.versioner = nil
returnedObj := &api.Pod{} returnedObj := &api.Pod{}
@@ -520,7 +521,7 @@ func TestSetWithoutResourceVersioner(t *testing.T) {
func TestSetNilOutParam(t *testing.T) { func TestSetNilOutParam(t *testing.T) {
obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} obj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
helper.versioner = nil helper.versioner = nil
err := helper.Set("/some/key", obj, nil, 3) err := helper.Set("/some/key", obj, nil, 3)
@@ -530,7 +531,7 @@ func TestSetNilOutParam(t *testing.T) {
} }
func TestGuaranteedUpdate(t *testing.T) { func TestGuaranteedUpdate(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
@@ -538,7 +539,7 @@ func TestGuaranteedUpdate(t *testing.T) {
// Create a new node. // Create a new node.
fakeClient.ExpectNotFoundGet(key) fakeClient.ExpectNotFoundGet(key)
obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1}
err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) {
return obj, nil return obj, nil
})) }))
if err != nil { if err != nil {
@@ -557,7 +558,7 @@ func TestGuaranteedUpdate(t *testing.T) {
// Update an existing node. // Update an existing node.
callbackCalled := false callbackCalled := false
objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 2} objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 2}
err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) {
callbackCalled = true callbackCalled = true
if in.(*TestResource).Value != 1 { if in.(*TestResource).Value != 1 {
@@ -585,7 +586,7 @@ func TestGuaranteedUpdate(t *testing.T) {
} }
func TestGuaranteedUpdateTTL(t *testing.T) { func TestGuaranteedUpdateTTL(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
@@ -686,7 +687,7 @@ func TestGuaranteedUpdateTTL(t *testing.T) {
} }
func TestGuaranteedUpdateNoChange(t *testing.T) { func TestGuaranteedUpdateNoChange(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
@@ -694,7 +695,7 @@ func TestGuaranteedUpdateNoChange(t *testing.T) {
// Create a new node. // Create a new node.
fakeClient.ExpectNotFoundGet(key) fakeClient.ExpectNotFoundGet(key)
obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1}
err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) {
return obj, nil return obj, nil
})) }))
if err != nil { if err != nil {
@@ -704,7 +705,7 @@ func TestGuaranteedUpdateNoChange(t *testing.T) {
// Update an existing node with the same data // Update an existing node with the same data
callbackCalled := false callbackCalled := false
objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} objUpdate := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1}
err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { err = helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) {
fakeClient.Err = errors.New("should not be called") fakeClient.Err = errors.New("should not be called")
callbackCalled = true callbackCalled = true
return objUpdate, nil return objUpdate, nil
@@ -718,7 +719,7 @@ func TestGuaranteedUpdateNoChange(t *testing.T) {
} }
func TestGuaranteedUpdateKeyNotFound(t *testing.T) { func TestGuaranteedUpdateKeyNotFound(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
@@ -727,7 +728,7 @@ func TestGuaranteedUpdateKeyNotFound(t *testing.T) {
fakeClient.ExpectNotFoundGet(key) fakeClient.ExpectNotFoundGet(key)
obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1} obj := &TestResource{ObjectMeta: api.ObjectMeta{Name: "foo"}, Value: 1}
f := SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { f := storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) {
return obj, nil return obj, nil
}) })
@@ -745,7 +746,7 @@ func TestGuaranteedUpdateKeyNotFound(t *testing.T) {
} }
func TestGuaranteedUpdate_CreateCollision(t *testing.T) { func TestGuaranteedUpdate_CreateCollision(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) helper := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := etcdtest.AddPrefix("/some/key") key := etcdtest.AddPrefix("/some/key")
@@ -764,7 +765,7 @@ func TestGuaranteedUpdate_CreateCollision(t *testing.T) {
defer wgDone.Done() defer wgDone.Done()
firstCall := true firstCall := true
err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, SimpleUpdate(func(in runtime.Object) (runtime.Object, error) { err := helper.GuaranteedUpdate("/some/key", &TestResource{}, true, storage.SimpleUpdate(func(in runtime.Object) (runtime.Object, error) {
defer func() { firstCall = false }() defer func() { firstCall = false }()
if firstCall { if firstCall {
@@ -843,7 +844,7 @@ func TestGetEtcdVersion_NotListening(t *testing.T) {
} }
func TestPrefixEtcdKey(t *testing.T) { func TestPrefixEtcdKey(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
prefix := path.Join("/", etcdtest.PathPrefix()) prefix := path.Join("/", etcdtest.PathPrefix())
helper := newEtcdHelper(fakeClient, testapi.Codec(), prefix) helper := newEtcdHelper(fakeClient, testapi.Codec(), prefix)

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tools package etcd
import ( import (
"encoding/json" "encoding/json"
@@ -23,41 +23,42 @@ import (
"net/http" "net/http"
"os/exec" "os/exec"
"github.com/coreos/go-etcd/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
goetcd "github.com/coreos/go-etcd/etcd"
"github.com/golang/glog" "github.com/golang/glog"
) )
// IsEtcdNotFound returns true iff err is an etcd not found error. // IsEtcdNotFound returns true iff err is an etcd not found error.
func IsEtcdNotFound(err error) bool { func IsEtcdNotFound(err error) bool {
return isEtcdErrorNum(err, EtcdErrorCodeNotFound) return isEtcdErrorNum(err, tools.EtcdErrorCodeNotFound)
} }
// IsEtcdNodeExist returns true iff err is an etcd node aleady exist error. // IsEtcdNodeExist returns true iff err is an etcd node aleady exist error.
func IsEtcdNodeExist(err error) bool { func IsEtcdNodeExist(err error) bool {
return isEtcdErrorNum(err, EtcdErrorCodeNodeExist) return isEtcdErrorNum(err, tools.EtcdErrorCodeNodeExist)
} }
// IsEtcdTestFailed returns true iff err is an etcd write conflict. // IsEtcdTestFailed returns true iff err is an etcd write conflict.
func IsEtcdTestFailed(err error) bool { func IsEtcdTestFailed(err error) bool {
return isEtcdErrorNum(err, EtcdErrorCodeTestFailed) return isEtcdErrorNum(err, tools.EtcdErrorCodeTestFailed)
} }
// IsEtcdWatchStoppedByUser returns true iff err is a client triggered stop. // IsEtcdWatchStoppedByUser returns true iff err is a client triggered stop.
func IsEtcdWatchStoppedByUser(err error) bool { func IsEtcdWatchStoppedByUser(err error) bool {
return etcd.ErrWatchStoppedByUser == err return goetcd.ErrWatchStoppedByUser == err
} }
// isEtcdErrorNum returns true iff err is an etcd error, whose errorCode matches errorCode // isEtcdErrorNum returns true iff err is an etcd error, whose errorCode matches errorCode
func isEtcdErrorNum(err error, errorCode int) bool { func isEtcdErrorNum(err error, errorCode int) bool {
etcdError, ok := err.(*etcd.EtcdError) etcdError, ok := err.(*goetcd.EtcdError)
return ok && etcdError != nil && etcdError.ErrorCode == errorCode return ok && etcdError != nil && etcdError.ErrorCode == errorCode
} }
// etcdErrorIndex returns the index associated with the error message and whether the // etcdErrorIndex returns the index associated with the error message and whether the
// index was available. // index was available.
func etcdErrorIndex(err error) (uint64, bool) { func etcdErrorIndex(err error) (uint64, bool) {
if etcdError, ok := err.(*etcd.EtcdError); ok { if etcdError, ok := err.(*goetcd.EtcdError); ok {
return etcdError.Index, true return etcdError.Index, true
} }
return 0, false return 0, false
@@ -90,7 +91,7 @@ func startEtcd() (*exec.Cmd, error) {
return cmd, nil return cmd, nil
} }
func NewEtcdClientStartServerIfNecessary(server string) (EtcdClient, error) { func NewEtcdClientStartServerIfNecessary(server string) (tools.EtcdClient, error) {
_, err := GetEtcdVersion(server) _, err := GetEtcdVersion(server)
if err != nil { if err != nil {
glog.Infof("Failed to find etcd, attempting to start.") glog.Infof("Failed to find etcd, attempting to start.")
@@ -101,7 +102,7 @@ func NewEtcdClientStartServerIfNecessary(server string) (EtcdClient, error) {
} }
servers := []string{server} servers := []string{server}
return etcd.NewClient(servers), nil return goetcd.NewClient(servers), nil
} }
type etcdHealth struct { type etcdHealth struct {

View File

@@ -14,19 +14,17 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tools package etcd
import ( import (
"strconv"
"sync" "sync"
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
@@ -42,22 +40,6 @@ const (
EtcdDelete = "delete" EtcdDelete = "delete"
) )
// 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
// the next value (if you pass "1", you will see updates from "2" onwards).
func ParseWatchResourceVersion(resourceVersion, kind string) (uint64, error) {
if resourceVersion == "" || resourceVersion == "0" {
return 0, nil
}
version, err := strconv.ParseUint(resourceVersion, 10, 64)
if err != nil {
// TODO: Does this need to be a ValidationErrorList? I can't convince myself it does.
return 0, errors.NewInvalid(kind, "", fielderrors.ValidationErrorList{fielderrors.NewFieldInvalid("resourceVersion", resourceVersion, err.Error())})
}
return version + 1, nil
}
// TransformFunc attempts to convert an object to another object for use with a watcher. // TransformFunc attempts to convert an object to another object for use with a watcher.
type TransformFunc func(runtime.Object) (runtime.Object, error) type TransformFunc func(runtime.Object) (runtime.Object, error)
@@ -134,7 +116,7 @@ func newEtcdWatcher(list bool, include includeFunc, filter storage.FilterFunc, e
// etcdWatch calls etcd's Watch function, and handles any errors. Meant to be called // etcdWatch calls etcd's Watch function, and handles any errors. Meant to be called
// as a goroutine. // as a goroutine.
func (w *etcdWatcher) etcdWatch(client EtcdClient, key string, resourceVersion uint64) { func (w *etcdWatcher) etcdWatch(client tools.EtcdClient, key string, resourceVersion uint64) {
defer util.HandleCrash() defer util.HandleCrash()
defer close(w.etcdError) defer close(w.etcdError)
if resourceVersion == 0 { if resourceVersion == 0 {
@@ -152,7 +134,7 @@ func (w *etcdWatcher) etcdWatch(client EtcdClient, key string, resourceVersion u
} }
// etcdGetInitialWatchState turns an etcd Get request into a watch equivalent // etcdGetInitialWatchState turns an etcd Get request into a watch equivalent
func etcdGetInitialWatchState(client EtcdClient, key string, recursive bool, incoming chan<- *etcd.Response) (resourceVersion uint64, err error) { func etcdGetInitialWatchState(client tools.EtcdClient, key string, recursive bool, incoming chan<- *etcd.Response) (resourceVersion uint64, err error) {
resp, err := client.Get(key, false, recursive) resp, err := client.Get(key, false, recursive)
if err != nil { if err != nil {
if !IsEtcdNotFound(err) { if !IsEtcdNotFound(err) {

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package tools package etcd
import ( import (
"fmt" "fmt"
@@ -22,10 +22,10 @@ import (
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
@@ -216,8 +216,8 @@ func TestWatchInterpretation_ResponseBadData(t *testing.T) {
func TestWatchEtcdError(t *testing.T) { func TestWatchEtcdError(t *testing.T) {
codec := latest.Codec codec := latest.Codec
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.expectNotFoundGetSet["/some/key"] = struct{}{} fakeClient.ExpectNotFoundGet("/some/key")
fakeClient.WatchImmediateError = fmt.Errorf("immediate error") fakeClient.WatchImmediateError = fmt.Errorf("immediate error")
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
@@ -245,10 +245,10 @@ func TestWatchEtcdError(t *testing.T) {
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
codec := latest.Codec codec := latest.Codec
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{} fakeClient.ExpectNotFoundGet(prefixedKey)
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.Watch(key, 0, storage.Everything) watching, err := h.Watch(key, 0, storage.Everything)
@@ -323,13 +323,13 @@ func TestWatchEtcdState(t *testing.T) {
Endpoints []api.EndpointSubset Endpoints []api.EndpointSubset
} }
testCases := map[string]struct { testCases := map[string]struct {
Initial map[string]EtcdResponseWithError Initial map[string]tools.EtcdResponseWithError
Responses []*etcd.Response Responses []*etcd.Response
From uint64 From uint64
Expected []*T Expected []*T
}{ }{
"from not found": { "from not found": {
Initial: map[string]EtcdResponseWithError{}, Initial: map[string]tools.EtcdResponseWithError{},
Responses: []*etcd.Response{ Responses: []*etcd.Response{
{ {
Action: "create", Action: "create",
@@ -374,7 +374,7 @@ func TestWatchEtcdState(t *testing.T) {
}, },
}, },
"from initial state": { "from initial state": {
Initial: map[string]EtcdResponseWithError{ Initial: map[string]tools.EtcdResponseWithError{
prefixedKey: { prefixedKey: {
R: &etcd.Response{ R: &etcd.Response{
Action: "get", Action: "get",
@@ -420,7 +420,7 @@ func TestWatchEtcdState(t *testing.T) {
} }
for k, testCase := range testCases { for k, testCase := range testCases {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
for key, value := range testCase.Initial { for key, value := range testCase.Initial {
fakeClient.Data[key] = value fakeClient.Data[key] = value
} }
@@ -457,12 +457,12 @@ func TestWatchFromZeroIndex(t *testing.T) {
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
testCases := map[string]struct { testCases := map[string]struct {
Response EtcdResponseWithError Response tools.EtcdResponseWithError
ExpectedVersion string ExpectedVersion string
ExpectedType watch.EventType ExpectedType watch.EventType
}{ }{
"get value created": { "get value created": {
EtcdResponseWithError{ tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(codec, pod), Value: runtime.EncodeOrDie(codec, pod),
@@ -477,7 +477,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
watch.Added, watch.Added,
}, },
"get value modified": { "get value modified": {
EtcdResponseWithError{ tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(codec, pod), Value: runtime.EncodeOrDie(codec, pod),
@@ -494,7 +494,7 @@ func TestWatchFromZeroIndex(t *testing.T) {
} }
for k, testCase := range testCases { for k, testCase := range testCases {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = testCase.Response fakeClient.Data[prefixedKey] = testCase.Response
@@ -535,8 +535,8 @@ func TestWatchListFromZeroIndex(t *testing.T) {
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.Data[prefixedKey] = EtcdResponseWithError{ fakeClient.Data[prefixedKey] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Dir: true, Dir: true,
@@ -598,7 +598,7 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
watching, err := h.WatchList(key, 1, storage.Everything) watching, err := h.WatchList(key, 1, storage.Everything)
@@ -640,10 +640,10 @@ func TestWatchListIgnoresRootKey(t *testing.T) {
} }
func TestWatchFromNotFound(t *testing.T) { func TestWatchFromNotFound(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = EtcdResponseWithError{ fakeClient.Data[prefixedKey] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
}, },
@@ -667,10 +667,10 @@ func TestWatchFromNotFound(t *testing.T) {
} }
func TestWatchFromOtherError(t *testing.T) { func TestWatchFromOtherError(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient.Data[prefixedKey] = EtcdResponseWithError{ fakeClient.Data[prefixedKey] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
}, },
@@ -709,12 +709,12 @@ func TestWatchFromOtherError(t *testing.T) {
} }
func TestWatchPurposefulShutdown(t *testing.T) { func TestWatchPurposefulShutdown(t *testing.T) {
fakeClient := NewFakeEtcdClient(t) fakeClient := tools.NewFakeEtcdClient(t)
h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix()) h := newEtcdHelper(fakeClient, codec, etcdtest.PathPrefix())
key := "/some/key" key := "/some/key"
prefixedKey := etcdtest.AddPrefix(key) prefixedKey := etcdtest.AddPrefix(key)
fakeClient.expectNotFoundGetSet[prefixedKey] = struct{}{} fakeClient.ExpectNotFoundGet(prefixedKey)
// Test purposeful shutdown // Test purposeful shutdown
watching, err := h.Watch(key, 0, storage.Everything) watching, err := h.Watch(key, 0, storage.Everything)
@@ -733,38 +733,3 @@ func TestWatchPurposefulShutdown(t *testing.T) {
t.Errorf("An injected error did not cause a graceful shutdown") t.Errorf("An injected error did not cause a graceful shutdown")
} }
} }
func TestEtcdParseWatchResourceVersion(t *testing.T) {
testCases := []struct {
Version string
Kind string
ExpectVersion uint64
Err bool
}{
{Version: "", ExpectVersion: 0},
{Version: "a", Err: true},
{Version: " ", Err: true},
{Version: "1", ExpectVersion: 2},
{Version: "10", ExpectVersion: 11},
}
for _, testCase := range testCases {
version, err := ParseWatchResourceVersion(testCase.Version, testCase.Kind)
switch {
case testCase.Err:
if err == nil {
t.Errorf("%s: unexpected non-error", testCase.Version)
continue
}
if !errors.IsInvalid(err) {
t.Errorf("%s: unexpected error: %v", testCase.Version, err)
continue
}
case !testCase.Err && err != nil:
t.Errorf("%s: unexpected error: %v", testCase.Version, err)
continue
}
if version != testCase.ExpectVersion {
t.Errorf("%s: expected version %d but was %d", testCase.Version, testCase.ExpectVersion, version)
}
}
}

51
pkg/storage/util.go Normal file
View File

@@ -0,0 +1,51 @@
/*
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 (
"strconv"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
)
type SimpleUpdateFunc func(runtime.Object) (runtime.Object, error)
// SimpleUpdateFunc converts SimpleUpdateFunc into UpdateFunc
func SimpleUpdate(fn SimpleUpdateFunc) UpdateFunc {
return func(input runtime.Object, _ ResponseMeta) (runtime.Object, *uint64, error) {
out, err := fn(input)
return out, nil, err
}
}
// 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
// the next value (if you pass "1", you will see updates from "2" onwards).
func ParseWatchResourceVersion(resourceVersion, kind string) (uint64, error) {
if resourceVersion == "" || resourceVersion == "0" {
return 0, nil
}
version, err := strconv.ParseUint(resourceVersion, 10, 64)
if err != nil {
// TODO: Does this need to be a ValidationErrorList? I can't convince myself it does.
return 0, errors.NewInvalid(kind, "", fielderrors.ValidationErrorList{fielderrors.NewFieldInvalid("resourceVersion", resourceVersion, err.Error())})
}
return version + 1, nil
}

58
pkg/storage/util_test.go Normal file
View File

@@ -0,0 +1,58 @@
/*
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 (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
)
func TestEtcdParseWatchResourceVersion(t *testing.T) {
testCases := []struct {
Version string
Kind string
ExpectVersion uint64
Err bool
}{
{Version: "", ExpectVersion: 0},
{Version: "a", Err: true},
{Version: " ", Err: true},
{Version: "1", ExpectVersion: 2},
{Version: "10", ExpectVersion: 11},
}
for _, testCase := range testCases {
version, err := ParseWatchResourceVersion(testCase.Version, testCase.Kind)
switch {
case testCase.Err:
if err == nil {
t.Errorf("%s: unexpected non-error", testCase.Version)
continue
}
if !errors.IsInvalid(err) {
t.Errorf("%s: unexpected error: %v", testCase.Version, err)
continue
}
case !testCase.Err && err != nil:
t.Errorf("%s: unexpected error: %v", testCase.Version, err)
continue
}
if version != testCase.ExpectVersion {
t.Errorf("%s: expected version %d but was %d", testCase.Version, testCase.ExpectVersion, version)
}
}
}

View File

@@ -281,7 +281,8 @@ func (f *FakeEtcdClient) Delete(key string, recursive bool) (*etcd.Response, err
Index: f.ChangeIndex, Index: f.ChangeIndex,
} }
} }
if IsEtcdNotFound(existing.E) { etcdError, ok := existing.E.(*etcd.EtcdError)
if ok && etcdError != nil && etcdError.ErrorCode == EtcdErrorCodeNotFound {
f.DeletedKeys = append(f.DeletedKeys, key) f.DeletedKeys = append(f.DeletedKeys, key)
return existing.R, existing.E return existing.R, existing.E
} }

View File

@@ -25,7 +25,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/storage"
"github.com/GoogleCloudPlatform/kubernetes/pkg/storage/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcdtest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/GoogleCloudPlatform/kubernetes/test/integration/framework" "github.com/GoogleCloudPlatform/kubernetes/test/integration/framework"
@@ -33,7 +34,7 @@ import (
func TestSet(t *testing.T) { func TestSet(t *testing.T) {
client := framework.NewEtcdClient() client := framework.NewEtcdClient()
etcdStorage := tools.NewEtcdStorage(client, testapi.Codec(), "") etcdStorage := etcd.NewEtcdStorage(client, testapi.Codec(), "")
framework.WithEtcdKey(func(key string) { framework.WithEtcdKey(func(key string) {
testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}} testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}}
if err := etcdStorage.Set(key, &testObject, nil, 0); err != nil { if err := etcdStorage.Set(key, &testObject, nil, 0); err != nil {
@@ -56,7 +57,7 @@ func TestSet(t *testing.T) {
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
client := framework.NewEtcdClient() client := framework.NewEtcdClient()
etcdStorage := tools.NewEtcdStorage(client, testapi.Codec(), "") etcdStorage := etcd.NewEtcdStorage(client, testapi.Codec(), "")
framework.WithEtcdKey(func(key string) { framework.WithEtcdKey(func(key string) {
testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}} testObject := api.ServiceAccount{ObjectMeta: api.ObjectMeta{Name: "foo"}}
coded, err := testapi.Codec().Encode(&testObject) coded, err := testapi.Codec().Encode(&testObject)
@@ -81,7 +82,7 @@ func TestGet(t *testing.T) {
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
client := framework.NewEtcdClient() client := framework.NewEtcdClient()
etcdStorage := tools.NewEtcdStorage(client, testapi.Codec(), etcdtest.PathPrefix()) etcdStorage := etcd.NewEtcdStorage(client, testapi.Codec(), etcdtest.PathPrefix())
framework.WithEtcdKey(func(key string) { framework.WithEtcdKey(func(key string) {
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
resp, err := client.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0) resp, err := client.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
@@ -91,7 +92,7 @@ func TestWatch(t *testing.T) {
expectedVersion := resp.Node.ModifiedIndex expectedVersion := resp.Node.ModifiedIndex
// watch should load the object at the current index // watch should load the object at the current index
w, err := etcdStorage.Watch(key, 0, tools.Everything) w, err := etcdStorage.Watch(key, 0, storage.Everything)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }