// NewREST returns a registry which will store ThirdPartyResourceData in the given helper func NewREST(s storage.Interface, group, kind string) *REST { prefix := "/ThirdPartyResourceData/" + group + "/" + strings.ToLower(kind) + "s" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &extensions.ThirdPartyResourceData{} }, NewListFunc: func() runtime.Object { return &extensions.ThirdPartyResourceDataList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, KeyFunc: func(ctx api.Context, id string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*extensions.ThirdPartyResourceData).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return thirdpartyresourcedata.Matcher(label, field) }, EndpointName: "thirdpartyresourcedata", CreateStrategy: thirdpartyresourcedata.Strategy, UpdateStrategy: thirdpartyresourcedata.Strategy, Storage: s, } return &REST{store} }
// NewREST returns a RESTStorage object that will work against horizontal pod autoscalers. func NewREST(s storage.Interface) *REST { prefix := "/limitranges" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.LimitRange{} }, NewListFunc: func() runtime.Object { return &api.LimitRangeList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, KeyFunc: func(ctx api.Context, id string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.LimitRange).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return limitrange.MatchLimitRange(label, field) }, EndpointName: "limitranges", CreateStrategy: limitrange.Strategy, UpdateStrategy: limitrange.Strategy, Storage: s, } return &REST{store} }
// NewREST returns a RESTStorage object that will work against events. func NewREST(s storage.Interface, ttl uint64) *REST { prefix := "/events" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.Event{} }, NewListFunc: func() runtime.Object { return &api.EventList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, KeyFunc: func(ctx api.Context, id string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, id) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Event).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return event.MatchEvent(label, field) }, TTLFunc: func(runtime.Object, uint64, bool) (uint64, error) { return ttl, nil }, EndpointName: "events", CreateStrategy: event.Strategy, UpdateStrategy: event.Strategy, Storage: s, } return &REST{store} }
// NewREST returns a RESTStorage object that will work against resource quotas. func NewREST(s storage.Interface) (*REST, *StatusREST) { prefix := "/resourcequotas" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.ResourceQuota{} }, NewListFunc: func() runtime.Object { return &api.ResourceQuotaList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, KeyFunc: func(ctx api.Context, name string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.ResourceQuota).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return resourcequota.MatchResourceQuota(label, field) }, EndpointName: "resourcequotas", CreateStrategy: resourcequota.Strategy, UpdateStrategy: resourcequota.Strategy, ReturnDeletedObject: true, Storage: s, } statusStore := *store statusStore.UpdateStrategy = resourcequota.StatusStrategy return &REST{store}, &StatusREST{store: &statusStore} }
// NewREST returns a RESTStorage object that will work against service accounts. func NewREST(s storage.Interface) *REST { prefix := "/serviceaccounts" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.ServiceAccount{} }, NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, KeyFunc: func(ctx api.Context, name string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.ServiceAccount).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return serviceaccount.Matcher(label, field) }, EndpointName: "serviceaccounts", CreateStrategy: serviceaccount.Strategy, UpdateStrategy: serviceaccount.Strategy, ReturnDeletedObject: true, Storage: s, } return &REST{store} }
// NewREST returns a RESTStorage object that will work against persistent volume claims. func NewREST(s storage.Interface) (*REST, *StatusREST) { prefix := "/persistentvolumeclaims" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} }, NewListFunc: func() runtime.Object { return &api.PersistentVolumeClaimList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, KeyFunc: func(ctx api.Context, name string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.PersistentVolumeClaim).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return persistentvolumeclaim.MatchPersistentVolumeClaim(label, field) }, EndpointName: "persistentvolumeclaims", CreateStrategy: persistentvolumeclaim.Strategy, UpdateStrategy: persistentvolumeclaim.Strategy, ReturnDeletedObject: true, Storage: s, } statusStore := *store statusStore.UpdateStrategy = persistentvolumeclaim.StatusStrategy return &REST{store}, &StatusREST{store: &statusStore} }
// NewStorage returns a RESTStorage object that will work against pods. func NewStorage(s storage.Interface, useCacher bool, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper) PodStorage { prefix := "/pods" storageInterface := s if useCacher { config := storage.CacherConfig{ CacheCapacity: 1000, Storage: s, Type: &api.Pod{}, ResourcePrefix: prefix, KeyFunc: func(obj runtime.Object) (string, error) { return storage.NamespaceKeyFunc(prefix, obj) }, NewListFunc: func() runtime.Object { return &api.PodList{} }, } storageInterface = storage.NewCacher(config) } store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.Pod{} }, NewListFunc: func() runtime.Object { return &api.PodList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, KeyFunc: func(ctx api.Context, name string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Pod).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return pod.MatchPod(label, field) }, EndpointName: "pods", CreateStrategy: pod.Strategy, UpdateStrategy: pod.Strategy, DeleteStrategy: pod.Strategy, ReturnDeletedObject: true, Storage: storageInterface, } statusStore := *store statusStore.UpdateStrategy = pod.StatusStrategy return PodStorage{ Pod: &REST{store, proxyTransport}, Binding: &BindingREST{store: store}, Status: &StatusREST{store: &statusStore}, Log: &LogREST{store: store, kubeletConn: k}, Proxy: &ProxyREST{store: store, proxyTransport: proxyTransport}, Exec: &ExecREST{store: store, kubeletConn: k}, Attach: &AttachREST{store: store, kubeletConn: k}, PortForward: &PortForwardREST{store: store, kubeletConn: k}, } }
// NewREST returns a RESTStorage object that will work against endpoints. func NewREST(s storage.Interface, useCacher bool) *REST { prefix := "/services/endpoints" storageInterface := s if useCacher { config := storage.CacherConfig{ CacheCapacity: 1000, Storage: s, Type: &api.Endpoints{}, ResourcePrefix: prefix, KeyFunc: func(obj runtime.Object) (string, error) { return storage.NamespaceKeyFunc(prefix, obj) }, NewListFunc: func() runtime.Object { return &api.EndpointsList{} }, } storageInterface = storage.NewCacher(config) } store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.Endpoints{} }, NewListFunc: func() runtime.Object { return &api.EndpointsList{} }, KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, KeyFunc: func(ctx api.Context, name string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name) }, ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.Endpoints).Name, nil }, PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return endpoint.MatchEndpoints(label, field) }, EndpointName: "endpoints", CreateStrategy: endpoint.Strategy, UpdateStrategy: endpoint.Strategy, Storage: storageInterface, } return &REST{store} }
// NewREST returns a RESTStorage object that will work against replication controllers. func NewREST(s storage.Interface) (*REST, *StatusREST) { prefix := "/controllers" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.ReplicationController{} }, // NewListFunc returns an object capable of storing results of an etcd list. NewListFunc: func() runtime.Object { return &api.ReplicationControllerList{} }, // Produces a path that etcd understands, to the root of the resource // by combining the namespace in the context with the given prefix KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, // Produces a path that etcd understands, to the resource by combining // the namespace in the context with the given prefix KeyFunc: func(ctx api.Context, name string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name) }, // Retrieve the name field of a replication controller ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*api.ReplicationController).Name, nil }, // Used to match objects based on labels/fields for list and watch PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return controller.MatchController(label, field) }, EndpointName: "replicationControllers", // Used to validate controller creation CreateStrategy: controller.Strategy, // Used to validate controller updates UpdateStrategy: controller.Strategy, Storage: s, } statusStore := *store statusStore.UpdateStrategy = controller.StatusStrategy return &REST{store}, &StatusREST{store: &statusStore} }
// Benchmark pod listing by waiting on `Tasks` listers to list `Pods` pods via `Workers`. func BenchmarkPodListEtcd(b *testing.B) { b.StopTimer() m := framework.NewMasterComponents(&framework.Config{nil, true, false, 250.0, 500}) defer m.Stop(true, true) numPods, numTasks, iter := getPods(b.N), getTasks(b.N), getIterations(b.N) podsPerNode := numPods / numTasks if podsPerNode < 1 { podsPerNode = 1 } startPodsOnNodes(numPods, numTasks, m.RestClient) // Stop the rc manager so it doesn't steal resources m.Stop(false, true) glog.Infof("Starting benchmark: b.N %d, pods %d, workers %d, podsPerNode %d", b.N, numPods, numTasks, podsPerNode) ctx := api.WithNamespace(api.NewContext(), framework.TestNS) key := etcdgeneric.NamespaceKeyRootFunc(ctx, fmt.Sprintf("%s/pods", etcdtest.PathPrefix())) b.StartTimer() for i := 0; i < iter; i++ { framework.RunParallel(func(id int) error { now := time.Now() defer func() { glog.V(3).Infof("Worker %d: listing pods took %v", id, time.Since(now)) }() if response, err := m.EtcdStorage.Client.Get(key, true, true); err != nil { return err } else if len(response.Node.Nodes) < podsPerNode { glog.Fatalf("List retrieved %d pods, which is less than %d", len(response.Node.Nodes), podsPerNode) } return nil }, numTasks, Workers) } b.StopTimer() }
// NewREST returns a RESTStorage object that will work against deployments. func NewREST(s storage.Interface) *REST { prefix := "/deployments" store := &etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &extensions.Deployment{} }, // NewListFunc returns an object capable of storing results of an etcd list. NewListFunc: func() runtime.Object { return &extensions.DeploymentList{} }, // Produces a path that etcd understands, to the root of the resource // by combining the namespace in the context with the given prefix. KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix) }, // Produces a path that etcd understands, to the resource by combining // the namespace in the context with the given prefix. KeyFunc: func(ctx api.Context, name string) (string, error) { return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name) }, // Retrieve the name field of a deployment. ObjectNameFunc: func(obj runtime.Object) (string, error) { return obj.(*extensions.Deployment).Name, nil }, // Used to match objects based on labels/fields for list. PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { return deployment.MatchDeployment(label, field) }, EndpointName: "deployments", // Used to validate deployment creation. CreateStrategy: deployment.Strategy, // Used to validate deployment updates. UpdateStrategy: deployment.Strategy, Storage: s, } return &REST{store} }