Merge pull request #42056 from ncdc/shared-informers-16-remove-legacy-code

Automatic merge from submit-queue (batch tested with PRs 42053, 41282, 42056, 41663, 40927)

Fully remove hand-written listers and informers

Note: the first commit is from #41927. Adding do-not-merge for now as we'll want that to go in first, and then I'll rebase this on top.

Update statefulset controller to use a lister for PVCs instead of a client request. Also replace a unit test's dependency on legacylisters with the generated ones. cc @kargakis @kow3ns @foxish @kubernetes/sig-apps-pr-reviews 

Remove all references to pkg/controller/informers and pkg/client/legacylisters, and remove those packages.

@smarterclayton @deads2k this should be it!

cc @gmarek @wojtek-t @derekwaynecarr @kubernetes/sig-scalability-pr-reviews
This commit is contained in:
Kubernetes Submit Queue 2017-02-27 12:45:31 -08:00 committed by GitHub
commit c274e9d715
35 changed files with 135 additions and 3382 deletions

View File

@ -21,7 +21,6 @@ go_library(
"//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/controller/cloud:go_default_library", "//pkg/controller/cloud:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/controller/route:go_default_library", "//pkg/controller/route:go_default_library",
"//pkg/controller/service:go_default_library", "//pkg/controller/service:go_default_library",
"//pkg/util/configz:go_default_library", "//pkg/util/configz:go_default_library",

View File

@ -36,13 +36,12 @@ import (
"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options" "k8s.io/kubernetes/cmd/cloud-controller-manager/app/options"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
newinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
"k8s.io/kubernetes/pkg/client/leaderelection" "k8s.io/kubernetes/pkg/client/leaderelection"
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
nodecontroller "k8s.io/kubernetes/pkg/controller/cloud" nodecontroller "k8s.io/kubernetes/pkg/controller/cloud"
"k8s.io/kubernetes/pkg/controller/informers"
routecontroller "k8s.io/kubernetes/pkg/controller/route" routecontroller "k8s.io/kubernetes/pkg/controller/route"
servicecontroller "k8s.io/kubernetes/pkg/controller/service" servicecontroller "k8s.io/kubernetes/pkg/controller/service"
"k8s.io/kubernetes/pkg/util/configz" "k8s.io/kubernetes/pkg/util/configz"
@ -196,9 +195,7 @@ func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restc
return rootClientBuilder.ClientOrDie(serviceAccountName) return rootClientBuilder.ClientOrDie(serviceAccountName)
} }
versionedClient := client("shared-informers") versionedClient := client("shared-informers")
// TODO replace sharedInformers with newSharedInformers sharedInformers := informers.NewSharedInformerFactory(versionedClient, resyncPeriod(s)())
sharedInformers := informers.NewSharedInformerFactory(versionedClient, nil, resyncPeriod(s)())
newSharedInformers := newinformers.NewSharedInformerFactory(versionedClient, resyncPeriod(s)())
_, clusterCIDR, err := net.ParseCIDR(s.ClusterCIDR) _, clusterCIDR, err := net.ParseCIDR(s.ClusterCIDR)
if err != nil { if err != nil {
@ -207,7 +204,7 @@ func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restc
// Start the CloudNodeController // Start the CloudNodeController
nodeController, err := nodecontroller.NewCloudNodeController( nodeController, err := nodecontroller.NewCloudNodeController(
newSharedInformers.Core().V1().Nodes(), sharedInformers.Core().V1().Nodes(),
client("cloud-node-controller"), cloud, client("cloud-node-controller"), cloud,
s.NodeMonitorPeriod.Duration) s.NodeMonitorPeriod.Duration)
if err != nil { if err != nil {
@ -220,8 +217,8 @@ func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restc
serviceController, err := servicecontroller.New( serviceController, err := servicecontroller.New(
cloud, cloud,
client("service-controller"), client("service-controller"),
newSharedInformers.Core().V1().Services(), sharedInformers.Core().V1().Services(),
newSharedInformers.Core().V1().Nodes(), sharedInformers.Core().V1().Nodes(),
s.ClusterName, s.ClusterName,
) )
if err != nil { if err != nil {
@ -236,7 +233,7 @@ func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restc
if routes, ok := cloud.Routes(); !ok { if routes, ok := cloud.Routes(); !ok {
glog.Warning("configure-cloud-routes is set, but cloud provider does not support routes. Will not configure cloud provider routes.") glog.Warning("configure-cloud-routes is set, but cloud provider does not support routes. Will not configure cloud provider routes.")
} else { } else {
routeController := routecontroller.New(routes, client("route-controller"), newSharedInformers.Core().V1().Nodes(), s.ClusterName, clusterCIDR) routeController := routecontroller.New(routes, client("route-controller"), sharedInformers.Core().V1().Nodes(), s.ClusterName, clusterCIDR)
routeController.Run(stop, s.RouteReconciliationPeriod.Duration) routeController.Run(stop, s.RouteReconciliationPeriod.Duration)
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
} }
@ -258,9 +255,7 @@ func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restc
glog.Fatalf("Failed to get api versions from server: %v", err) glog.Fatalf("Failed to get api versions from server: %v", err)
} }
// TODO replace sharedInformers with newSharedInformers
sharedInformers.Start(stop) sharedInformers.Start(stop)
newSharedInformers.Start(stop)
select {} select {}
} }

View File

@ -52,7 +52,6 @@ go_library(
"//pkg/controller/endpoint:go_default_library", "//pkg/controller/endpoint:go_default_library",
"//pkg/controller/garbagecollector:go_default_library", "//pkg/controller/garbagecollector:go_default_library",
"//pkg/controller/garbagecollector/metaonly:go_default_library", "//pkg/controller/garbagecollector/metaonly:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/controller/job:go_default_library", "//pkg/controller/job:go_default_library",
"//pkg/controller/namespace:go_default_library", "//pkg/controller/namespace:go_default_library",
"//pkg/controller/node:go_default_library", "//pkg/controller/node:go_default_library",

View File

@ -30,8 +30,9 @@ func startStatefulSetController(ctx ControllerContext) (bool, error) {
return false, nil return false, nil
} }
go statefulset.NewStatefulSetController( go statefulset.NewStatefulSetController(
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
ctx.NewInformerFactory.Apps().V1beta1().StatefulSets(), ctx.InformerFactory.Apps().V1beta1().StatefulSets(),
ctx.InformerFactory.Core().V1().PersistentVolumeClaims(),
ctx.ClientBuilder.ClientOrDie("statefulset-controller"), ctx.ClientBuilder.ClientOrDie("statefulset-controller"),
).Run(1, ctx.Stop) ).Run(1, ctx.Stop)
return true, nil return true, nil

View File

@ -44,7 +44,7 @@ func startHPAController(ctx ControllerContext) (bool, error) {
hpaClient.Extensions(), hpaClient.Extensions(),
hpaClient.Autoscaling(), hpaClient.Autoscaling(),
replicaCalc, replicaCalc,
ctx.NewInformerFactory.Autoscaling().V1().HorizontalPodAutoscalers(), ctx.InformerFactory.Autoscaling().V1().HorizontalPodAutoscalers(),
ctx.Options.HorizontalPodAutoscalerSyncPeriod.Duration, ctx.Options.HorizontalPodAutoscalerSyncPeriod.Duration,
).Run(ctx.Stop) ).Run(ctx.Stop)
return true, nil return true, nil

View File

@ -33,8 +33,8 @@ func startJobController(ctx ControllerContext) (bool, error) {
return false, nil return false, nil
} }
go job.NewJobController( go job.NewJobController(
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
ctx.NewInformerFactory.Batch().V1().Jobs(), ctx.InformerFactory.Batch().V1().Jobs(),
ctx.ClientBuilder.ClientOrDie("job-controller"), ctx.ClientBuilder.ClientOrDie("job-controller"),
).Run(int(ctx.Options.ConcurrentJobSyncs), ctx.Stop) ).Run(int(ctx.Options.ConcurrentJobSyncs), ctx.Stop)
return true, nil return true, nil

View File

@ -41,7 +41,7 @@ func startCSRController(ctx ControllerContext) (bool, error) {
certController, err := certcontroller.NewCertificateController( certController, err := certcontroller.NewCertificateController(
c, c,
ctx.NewInformerFactory.Certificates().V1beta1().CertificateSigningRequests(), ctx.InformerFactory.Certificates().V1beta1().CertificateSigningRequests(),
signer, signer,
certcontroller.NewGroupApprover(ctx.Options.ApproveAllKubeletCSRsForGroup), certcontroller.NewGroupApprover(ctx.Options.ApproveAllKubeletCSRsForGroup),
) )

View File

@ -46,12 +46,11 @@ import (
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options" "k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
newinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
"k8s.io/kubernetes/pkg/client/leaderelection" "k8s.io/kubernetes/pkg/client/leaderelection"
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/controller/informers"
nodecontroller "k8s.io/kubernetes/pkg/controller/node" nodecontroller "k8s.io/kubernetes/pkg/controller/node"
routecontroller "k8s.io/kubernetes/pkg/controller/route" routecontroller "k8s.io/kubernetes/pkg/controller/route"
servicecontroller "k8s.io/kubernetes/pkg/controller/service" servicecontroller "k8s.io/kubernetes/pkg/controller/service"
@ -216,13 +215,8 @@ type ControllerContext struct {
ClientBuilder controller.ControllerClientBuilder ClientBuilder controller.ControllerClientBuilder
// InformerFactory gives access to informers for the controller. // InformerFactory gives access to informers for the controller.
// TODO delete this instance once the conversion to generated informers is complete.
InformerFactory informers.SharedInformerFactory InformerFactory informers.SharedInformerFactory
// NewInformerFactory gives access to informers for the controller.
// TODO rename this to InformerFactory once the conversion to generated informers is complete.
NewInformerFactory newinformers.SharedInformerFactory
// Options provides access to init options for a given controller // Options provides access to init options for a given controller
Options options.CMServer Options options.CMServer
@ -343,9 +337,7 @@ func getAvailableResources(clientBuilder controller.ControllerClientBuilder) (ma
func StartControllers(controllers map[string]InitFunc, s *options.CMServer, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}) error { func StartControllers(controllers map[string]InitFunc, s *options.CMServer, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}) error {
versionedClient := rootClientBuilder.ClientOrDie("shared-informers") versionedClient := rootClientBuilder.ClientOrDie("shared-informers")
// TODO replace sharedInformers with newSharedInformers sharedInformers := informers.NewSharedInformerFactory(versionedClient, ResyncPeriod(s)())
sharedInformers := informers.NewSharedInformerFactory(versionedClient, nil, ResyncPeriod(s)())
newSharedInformers := newinformers.NewSharedInformerFactory(versionedClient, ResyncPeriod(s)())
// always start the SA token controller first using a full-power client, since it needs to mint tokens for the rest // always start the SA token controller first using a full-power client, since it needs to mint tokens for the rest
if len(s.ServiceAccountKeyFile) > 0 { if len(s.ServiceAccountKeyFile) > 0 {
@ -385,7 +377,6 @@ func StartControllers(controllers map[string]InitFunc, s *options.CMServer, root
ctx := ControllerContext{ ctx := ControllerContext{
ClientBuilder: clientBuilder, ClientBuilder: clientBuilder,
InformerFactory: sharedInformers, InformerFactory: sharedInformers,
NewInformerFactory: newSharedInformers,
Options: *s, Options: *s,
AvailableResources: availableResources, AvailableResources: availableResources,
Stop: stop, Stop: stop,
@ -426,9 +417,9 @@ func StartControllers(controllers map[string]InitFunc, s *options.CMServer, root
glog.Warningf("Unsuccessful parsing of service CIDR %v: %v", s.ServiceCIDR, err) glog.Warningf("Unsuccessful parsing of service CIDR %v: %v", s.ServiceCIDR, err)
} }
nodeController, err := nodecontroller.NewNodeController( nodeController, err := nodecontroller.NewNodeController(
newSharedInformers.Core().V1().Pods(), sharedInformers.Core().V1().Pods(),
newSharedInformers.Core().V1().Nodes(), sharedInformers.Core().V1().Nodes(),
newSharedInformers.Extensions().V1beta1().DaemonSets(), sharedInformers.Extensions().V1beta1().DaemonSets(),
cloud, cloud,
clientBuilder.ClientOrDie("node-controller"), clientBuilder.ClientOrDie("node-controller"),
s.PodEvictionTimeout.Duration, s.PodEvictionTimeout.Duration,
@ -455,8 +446,8 @@ func StartControllers(controllers map[string]InitFunc, s *options.CMServer, root
serviceController, err := servicecontroller.New( serviceController, err := servicecontroller.New(
cloud, cloud,
clientBuilder.ClientOrDie("service-controller"), clientBuilder.ClientOrDie("service-controller"),
newSharedInformers.Core().V1().Services(), sharedInformers.Core().V1().Services(),
newSharedInformers.Core().V1().Nodes(), sharedInformers.Core().V1().Nodes(),
s.ClusterName, s.ClusterName,
) )
if err != nil { if err != nil {
@ -472,7 +463,7 @@ func StartControllers(controllers map[string]InitFunc, s *options.CMServer, root
} else if routes, ok := cloud.Routes(); !ok { } else if routes, ok := cloud.Routes(); !ok {
glog.Warning("configure-cloud-routes is set, but cloud provider does not support routes. Will not configure cloud provider routes.") glog.Warning("configure-cloud-routes is set, but cloud provider does not support routes. Will not configure cloud provider routes.")
} else { } else {
routeController := routecontroller.New(routes, clientBuilder.ClientOrDie("route-controller"), newSharedInformers.Core().V1().Nodes(), s.ClusterName, clusterCIDR) routeController := routecontroller.New(routes, clientBuilder.ClientOrDie("route-controller"), sharedInformers.Core().V1().Nodes(), s.ClusterName, clusterCIDR)
go routeController.Run(stop, s.RouteReconciliationPeriod.Duration) go routeController.Run(stop, s.RouteReconciliationPeriod.Duration)
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
} }
@ -491,9 +482,9 @@ func StartControllers(controllers map[string]InitFunc, s *options.CMServer, root
VolumePlugins: ProbeControllerVolumePlugins(cloud, s.VolumeConfiguration), VolumePlugins: ProbeControllerVolumePlugins(cloud, s.VolumeConfiguration),
Cloud: cloud, Cloud: cloud,
ClusterName: s.ClusterName, ClusterName: s.ClusterName,
VolumeInformer: newSharedInformers.Core().V1().PersistentVolumes(), VolumeInformer: sharedInformers.Core().V1().PersistentVolumes(),
ClaimInformer: newSharedInformers.Core().V1().PersistentVolumeClaims(), ClaimInformer: sharedInformers.Core().V1().PersistentVolumeClaims(),
ClassInformer: newSharedInformers.Storage().V1beta1().StorageClasses(), ClassInformer: sharedInformers.Storage().V1beta1().StorageClasses(),
EnableDynamicProvisioning: s.VolumeConfiguration.EnableDynamicProvisioning, EnableDynamicProvisioning: s.VolumeConfiguration.EnableDynamicProvisioning,
} }
volumeController := persistentvolumecontroller.NewController(params) volumeController := persistentvolumecontroller.NewController(params)
@ -507,10 +498,10 @@ func StartControllers(controllers map[string]InitFunc, s *options.CMServer, root
attachDetachController, attachDetachControllerErr := attachDetachController, attachDetachControllerErr :=
attachdetach.NewAttachDetachController( attachdetach.NewAttachDetachController(
clientBuilder.ClientOrDie("attachdetach-controller"), clientBuilder.ClientOrDie("attachdetach-controller"),
newSharedInformers.Core().V1().Pods(), sharedInformers.Core().V1().Pods(),
newSharedInformers.Core().V1().Nodes(), sharedInformers.Core().V1().Nodes(),
newSharedInformers.Core().V1().PersistentVolumeClaims(), sharedInformers.Core().V1().PersistentVolumeClaims(),
newSharedInformers.Core().V1().PersistentVolumes(), sharedInformers.Core().V1().PersistentVolumes(),
cloud, cloud,
ProbeAttachableVolumePlugins(s.VolumeConfiguration), ProbeAttachableVolumePlugins(s.VolumeConfiguration),
s.DisableAttachDetachReconcilerSync, s.DisableAttachDetachReconcilerSync,
@ -522,9 +513,7 @@ func StartControllers(controllers map[string]InitFunc, s *options.CMServer, root
go attachDetachController.Run(stop) go attachDetachController.Run(stop)
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
// TODO replace sharedInformers with newSharedInformers
sharedInformers.Start(stop) sharedInformers.Start(stop)
newSharedInformers.Start(stop)
select {} select {}
} }

View File

@ -46,8 +46,8 @@ import (
func startEndpointController(ctx ControllerContext) (bool, error) { func startEndpointController(ctx ControllerContext) (bool, error) {
go endpointcontroller.NewEndpointController( go endpointcontroller.NewEndpointController(
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
ctx.NewInformerFactory.Core().V1().Services(), ctx.InformerFactory.Core().V1().Services(),
ctx.ClientBuilder.ClientOrDie("endpoint-controller"), ctx.ClientBuilder.ClientOrDie("endpoint-controller"),
).Run(int(ctx.Options.ConcurrentEndpointSyncs), ctx.Stop) ).Run(int(ctx.Options.ConcurrentEndpointSyncs), ctx.Stop)
return true, nil return true, nil
@ -55,8 +55,8 @@ func startEndpointController(ctx ControllerContext) (bool, error) {
func startReplicationController(ctx ControllerContext) (bool, error) { func startReplicationController(ctx ControllerContext) (bool, error) {
go replicationcontroller.NewReplicationManager( go replicationcontroller.NewReplicationManager(
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
ctx.NewInformerFactory.Core().V1().ReplicationControllers(), ctx.InformerFactory.Core().V1().ReplicationControllers(),
ctx.ClientBuilder.ClientOrDie("replication-controller"), ctx.ClientBuilder.ClientOrDie("replication-controller"),
replicationcontroller.BurstReplicas, replicationcontroller.BurstReplicas,
int(ctx.Options.LookupCacheSizeForRC), int(ctx.Options.LookupCacheSizeForRC),
@ -67,7 +67,7 @@ func startReplicationController(ctx ControllerContext) (bool, error) {
func startPodGCController(ctx ControllerContext) (bool, error) { func startPodGCController(ctx ControllerContext) (bool, error) {
go podgc.NewPodGC( go podgc.NewPodGC(
ctx.ClientBuilder.ClientOrDie("pod-garbage-collector"), ctx.ClientBuilder.ClientOrDie("pod-garbage-collector"),
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
int(ctx.Options.TerminatedPodGCThreshold), int(ctx.Options.TerminatedPodGCThreshold),
).Run(ctx.Stop) ).Run(ctx.Stop)
return true, nil return true, nil
@ -75,7 +75,7 @@ func startPodGCController(ctx ControllerContext) (bool, error) {
func startResourceQuotaController(ctx ControllerContext) (bool, error) { func startResourceQuotaController(ctx ControllerContext) (bool, error) {
resourceQuotaControllerClient := ctx.ClientBuilder.ClientOrDie("resourcequota-controller") resourceQuotaControllerClient := ctx.ClientBuilder.ClientOrDie("resourcequota-controller")
resourceQuotaRegistry := quotainstall.NewRegistry(resourceQuotaControllerClient, ctx.NewInformerFactory) resourceQuotaRegistry := quotainstall.NewRegistry(resourceQuotaControllerClient, ctx.InformerFactory)
groupKindsToReplenish := []schema.GroupKind{ groupKindsToReplenish := []schema.GroupKind{
api.Kind("Pod"), api.Kind("Pod"),
api.Kind("Service"), api.Kind("Service"),
@ -86,10 +86,10 @@ func startResourceQuotaController(ctx ControllerContext) (bool, error) {
} }
resourceQuotaControllerOptions := &resourcequotacontroller.ResourceQuotaControllerOptions{ resourceQuotaControllerOptions := &resourcequotacontroller.ResourceQuotaControllerOptions{
KubeClient: resourceQuotaControllerClient, KubeClient: resourceQuotaControllerClient,
ResourceQuotaInformer: ctx.NewInformerFactory.Core().V1().ResourceQuotas(), ResourceQuotaInformer: ctx.InformerFactory.Core().V1().ResourceQuotas(),
ResyncPeriod: controller.StaticResyncPeriodFunc(ctx.Options.ResourceQuotaSyncPeriod.Duration), ResyncPeriod: controller.StaticResyncPeriodFunc(ctx.Options.ResourceQuotaSyncPeriod.Duration),
Registry: resourceQuotaRegistry, Registry: resourceQuotaRegistry,
ControllerFactory: resourcequotacontroller.NewReplenishmentControllerFactory(ctx.NewInformerFactory), ControllerFactory: resourcequotacontroller.NewReplenishmentControllerFactory(ctx.InformerFactory),
ReplenishmentResyncPeriod: ResyncPeriod(&ctx.Options), ReplenishmentResyncPeriod: ResyncPeriod(&ctx.Options),
GroupKindsToReplenish: groupKindsToReplenish, GroupKindsToReplenish: groupKindsToReplenish,
} }
@ -130,7 +130,7 @@ func startNamespaceController(ctx ControllerContext) (bool, error) {
namespaceKubeClient, namespaceKubeClient,
namespaceClientPool, namespaceClientPool,
discoverResourcesFn, discoverResourcesFn,
ctx.NewInformerFactory.Core().V1().Namespaces(), ctx.InformerFactory.Core().V1().Namespaces(),
ctx.Options.NamespaceSyncPeriod.Duration, ctx.Options.NamespaceSyncPeriod.Duration,
v1.FinalizerKubernetes, v1.FinalizerKubernetes,
) )
@ -142,8 +142,8 @@ func startNamespaceController(ctx ControllerContext) (bool, error) {
func startServiceAccountController(ctx ControllerContext) (bool, error) { func startServiceAccountController(ctx ControllerContext) (bool, error) {
go serviceaccountcontroller.NewServiceAccountsController( go serviceaccountcontroller.NewServiceAccountsController(
ctx.NewInformerFactory.Core().V1().ServiceAccounts(), ctx.InformerFactory.Core().V1().ServiceAccounts(),
ctx.NewInformerFactory.Core().V1().Namespaces(), ctx.InformerFactory.Core().V1().Namespaces(),
ctx.ClientBuilder.ClientOrDie("service-account-controller"), ctx.ClientBuilder.ClientOrDie("service-account-controller"),
serviceaccountcontroller.DefaultServiceAccountsControllerOptions(), serviceaccountcontroller.DefaultServiceAccountsControllerOptions(),
).Run(1, ctx.Stop) ).Run(1, ctx.Stop)
@ -152,7 +152,7 @@ func startServiceAccountController(ctx ControllerContext) (bool, error) {
func startTTLController(ctx ControllerContext) (bool, error) { func startTTLController(ctx ControllerContext) (bool, error) {
go ttlcontroller.NewTTLController( go ttlcontroller.NewTTLController(
ctx.NewInformerFactory.Core().V1().Nodes(), ctx.InformerFactory.Core().V1().Nodes(),
ctx.ClientBuilder.ClientOrDie("ttl-controller"), ctx.ClientBuilder.ClientOrDie("ttl-controller"),
).Run(5, ctx.Stop) ).Run(5, ctx.Stop)
return true, nil return true, nil

View File

@ -32,9 +32,9 @@ func startDaemonSetController(ctx ControllerContext) (bool, error) {
return false, nil return false, nil
} }
go daemon.NewDaemonSetsController( go daemon.NewDaemonSetsController(
ctx.NewInformerFactory.Extensions().V1beta1().DaemonSets(), ctx.InformerFactory.Extensions().V1beta1().DaemonSets(),
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
ctx.NewInformerFactory.Core().V1().Nodes(), ctx.InformerFactory.Core().V1().Nodes(),
ctx.ClientBuilder.ClientOrDie("daemon-set-controller"), ctx.ClientBuilder.ClientOrDie("daemon-set-controller"),
int(ctx.Options.LookupCacheSizeForDaemonSet), int(ctx.Options.LookupCacheSizeForDaemonSet),
).Run(int(ctx.Options.ConcurrentDaemonSetSyncs), ctx.Stop) ).Run(int(ctx.Options.ConcurrentDaemonSetSyncs), ctx.Stop)
@ -46,9 +46,9 @@ func startDeploymentController(ctx ControllerContext) (bool, error) {
return false, nil return false, nil
} }
go deployment.NewDeploymentController( go deployment.NewDeploymentController(
ctx.NewInformerFactory.Extensions().V1beta1().Deployments(), ctx.InformerFactory.Extensions().V1beta1().Deployments(),
ctx.NewInformerFactory.Extensions().V1beta1().ReplicaSets(), ctx.InformerFactory.Extensions().V1beta1().ReplicaSets(),
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
ctx.ClientBuilder.ClientOrDie("deployment-controller"), ctx.ClientBuilder.ClientOrDie("deployment-controller"),
).Run(int(ctx.Options.ConcurrentDeploymentSyncs), ctx.Stop) ).Run(int(ctx.Options.ConcurrentDeploymentSyncs), ctx.Stop)
return true, nil return true, nil
@ -59,8 +59,8 @@ func startReplicaSetController(ctx ControllerContext) (bool, error) {
return false, nil return false, nil
} }
go replicaset.NewReplicaSetController( go replicaset.NewReplicaSetController(
ctx.NewInformerFactory.Extensions().V1beta1().ReplicaSets(), ctx.InformerFactory.Extensions().V1beta1().ReplicaSets(),
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
ctx.ClientBuilder.ClientOrDie("replicaset-controller"), ctx.ClientBuilder.ClientOrDie("replicaset-controller"),
replicaset.BurstReplicas, replicaset.BurstReplicas,
int(ctx.Options.LookupCacheSizeForRS), int(ctx.Options.LookupCacheSizeForRS),

View File

@ -30,12 +30,12 @@ func startDisruptionController(ctx ControllerContext) (bool, error) {
return false, nil return false, nil
} }
go disruption.NewDisruptionController( go disruption.NewDisruptionController(
ctx.NewInformerFactory.Core().V1().Pods(), ctx.InformerFactory.Core().V1().Pods(),
ctx.NewInformerFactory.Policy().V1beta1().PodDisruptionBudgets(), ctx.InformerFactory.Policy().V1beta1().PodDisruptionBudgets(),
ctx.NewInformerFactory.Core().V1().ReplicationControllers(), ctx.InformerFactory.Core().V1().ReplicationControllers(),
ctx.NewInformerFactory.Extensions().V1beta1().ReplicaSets(), ctx.InformerFactory.Extensions().V1beta1().ReplicaSets(),
ctx.NewInformerFactory.Extensions().V1beta1().Deployments(), ctx.InformerFactory.Extensions().V1beta1().Deployments(),
ctx.NewInformerFactory.Apps().V1beta1().StatefulSets(), ctx.InformerFactory.Apps().V1beta1().StatefulSets(),
ctx.ClientBuilder.ClientOrDie("disruption-controller"), ctx.ClientBuilder.ClientOrDie("disruption-controller"),
).Run(ctx.Stop) ).Run(ctx.Stop)
return true, nil return true, nil

View File

@ -575,6 +575,7 @@ function start_kubelet {
fi fi
sudo -E "${GO_OUT}/hyperkube" kubelet ${priv_arg}\ sudo -E "${GO_OUT}/hyperkube" kubelet ${priv_arg}\
--enable-cri=false \
--v=${LOG_LEVEL} \ --v=${LOG_LEVEL} \
--chaos-chance="${CHAOS_CHANCE}" \ --chaos-chance="${CHAOS_CHANCE}" \
--container-runtime="${CONTAINER_RUNTIME}" \ --container-runtime="${CONTAINER_RUNTIME}" \

View File

@ -40,7 +40,6 @@ filegroup(
"//pkg/client/informers/informers_generated/externalversions:all-srcs", "//pkg/client/informers/informers_generated/externalversions:all-srcs",
"//pkg/client/informers/informers_generated/internalversion:all-srcs", "//pkg/client/informers/informers_generated/internalversion:all-srcs",
"//pkg/client/leaderelection:all-srcs", "//pkg/client/leaderelection:all-srcs",
"//pkg/client/legacylisters:all-srcs",
"//pkg/client/listers/apps/internalversion:all-srcs", "//pkg/client/listers/apps/internalversion:all-srcs",
"//pkg/client/listers/apps/v1beta1:all-srcs", "//pkg/client/listers/apps/v1beta1:all-srcs",
"//pkg/client/listers/authentication/internalversion:all-srcs", "//pkg/client/listers/authentication/internalversion:all-srcs",

View File

@ -1,66 +0,0 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["listers_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/client-go/tools/cache",
],
)
go_library(
name = "go_default_library",
srcs = [
"listers.go",
"listers_core.go",
"listers_extensions.go",
"listers_rbac.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/apps/v1beta1:go_default_library",
"//pkg/apis/certificates/v1beta1:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//pkg/apis/policy/v1beta1:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/apis/storage/v1beta1:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/client-go/tools/cache",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -1,346 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
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 listers
import (
"fmt"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api/v1"
apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1"
certificates "k8s.io/kubernetes/pkg/apis/certificates/v1beta1"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
policy "k8s.io/kubernetes/pkg/apis/policy/v1beta1"
storageinternal "k8s.io/kubernetes/pkg/apis/storage"
storage "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
)
// TODO: generate these classes and methods for all resources of interest using
// a script. Can use "go generate" once 1.4 is supported by all users.
// NodeConditionPredicate is a function that indicates whether the given node's conditions meet
// some set of criteria defined by the function.
type NodeConditionPredicate func(node *v1.Node) bool
// StoreToNodeLister makes a Store have the List method of the client.NodeInterface
// The Store must contain (only) Nodes.
type StoreToNodeLister struct {
cache.Store
}
func (s *StoreToNodeLister) List() (machines v1.NodeList, err error) {
for _, m := range s.Store.List() {
machines.Items = append(machines.Items, *(m.(*v1.Node)))
}
return machines, nil
}
// NodeCondition returns a storeToNodeConditionLister
func (s *StoreToNodeLister) NodeCondition(predicate NodeConditionPredicate) storeToNodeConditionLister {
// TODO: Move this filtering server side. Currently our selectors don't facilitate searching through a list so we
// have the reflector filter out the Unschedulable field and sift through node conditions in the lister.
return storeToNodeConditionLister{s.Store, predicate}
}
// storeToNodeConditionLister filters and returns nodes matching the given type and status from the store.
type storeToNodeConditionLister struct {
store cache.Store
predicate NodeConditionPredicate
}
// List returns a list of nodes that match the conditions defined by the predicate functions in the storeToNodeConditionLister.
func (s storeToNodeConditionLister) List() (nodes []*v1.Node, err error) {
for _, m := range s.store.List() {
node := m.(*v1.Node)
if s.predicate(node) {
nodes = append(nodes, node)
} else {
glog.V(5).Infof("Node %s matches none of the conditions", node.Name)
}
}
return
}
// StoreToDaemonSetLister gives a store List and Exists methods. The store must contain only DaemonSets.
type StoreToDaemonSetLister struct {
cache.Store
}
// Exists checks if the given daemon set exists in the store.
func (s *StoreToDaemonSetLister) Exists(ds *extensions.DaemonSet) (bool, error) {
_, exists, err := s.Store.Get(ds)
if err != nil {
return false, err
}
return exists, nil
}
// List lists all daemon sets in the store.
// TODO: converge on the interface in pkg/client
func (s *StoreToDaemonSetLister) List() (dss extensions.DaemonSetList, err error) {
for _, c := range s.Store.List() {
dss.Items = append(dss.Items, *(c.(*extensions.DaemonSet)))
}
return dss, nil
}
// GetPodDaemonSets returns a list of daemon sets managing a pod.
// Returns an error if and only if no matching daemon sets are found.
func (s *StoreToDaemonSetLister) GetPodDaemonSets(pod *v1.Pod) (daemonSets []extensions.DaemonSet, err error) {
var selector labels.Selector
var daemonSet extensions.DaemonSet
if len(pod.Labels) == 0 {
err = fmt.Errorf("no daemon sets found for pod %v because it has no labels", pod.Name)
return
}
for _, m := range s.Store.List() {
daemonSet = *m.(*extensions.DaemonSet)
if daemonSet.Namespace != pod.Namespace {
continue
}
selector, err = metav1.LabelSelectorAsSelector(daemonSet.Spec.Selector)
if err != nil {
// this should not happen if the DaemonSet passed validation
return nil, err
}
// If a daemonSet with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
continue
}
daemonSets = append(daemonSets, daemonSet)
}
if len(daemonSets) == 0 {
err = fmt.Errorf("could not find daemon set for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
}
return
}
// StoreToEndpointsLister makes a Store that lists endpoints.
type StoreToEndpointsLister struct {
cache.Store
}
// List lists all endpoints in the store.
func (s *StoreToEndpointsLister) List() (services v1.EndpointsList, err error) {
for _, m := range s.Store.List() {
services.Items = append(services.Items, *(m.(*v1.Endpoints)))
}
return services, nil
}
// GetServiceEndpoints returns the endpoints of a service, matched on service name.
func (s *StoreToEndpointsLister) GetServiceEndpoints(svc *v1.Service) (ep v1.Endpoints, err error) {
for _, m := range s.Store.List() {
ep = *m.(*v1.Endpoints)
if svc.Name == ep.Name && svc.Namespace == ep.Namespace {
return ep, nil
}
}
err = fmt.Errorf("could not find endpoints for service: %v", svc.Name)
return
}
// Typed wrapper around a store of PersistentVolumes
type StoreToPVFetcher struct {
cache.Store
}
// GetPersistentVolumeInfo returns cached data for the PersistentVolume 'id'.
func (s *StoreToPVFetcher) GetPersistentVolumeInfo(id string) (*v1.PersistentVolume, error) {
o, exists, err := s.Get(&v1.PersistentVolume{ObjectMeta: metav1.ObjectMeta{Name: id}})
if err != nil {
return nil, fmt.Errorf("error retrieving PersistentVolume '%v' from cache: %v", id, err)
}
if !exists {
return nil, fmt.Errorf("PersistentVolume '%v' not found", id)
}
return o.(*v1.PersistentVolume), nil
}
// StoreToStatefulSetLister gives a store List and Exists methods. The store must contain only StatefulSets.
type StoreToStatefulSetLister struct {
cache.Store
}
// Exists checks if the given StatefulSet exists in the store.
func (s *StoreToStatefulSetLister) Exists(ps *apps.StatefulSet) (bool, error) {
_, exists, err := s.Store.Get(ps)
if err != nil {
return false, err
}
return exists, nil
}
// List lists all StatefulSets in the store.
func (s *StoreToStatefulSetLister) List() (psList []apps.StatefulSet, err error) {
for _, ps := range s.Store.List() {
psList = append(psList, *(ps.(*apps.StatefulSet)))
}
return psList, nil
}
type storeStatefulSetsNamespacer struct {
store cache.Store
namespace string
}
func (s *StoreToStatefulSetLister) StatefulSets(namespace string) storeStatefulSetsNamespacer {
return storeStatefulSetsNamespacer{s.Store, namespace}
}
// GetPodStatefulSets returns a list of StatefulSets managing a pod. Returns an error only if no matching StatefulSets are found.
func (s *StoreToStatefulSetLister) GetPodStatefulSets(pod *v1.Pod) (psList []apps.StatefulSet, err error) {
var selector labels.Selector
var ps apps.StatefulSet
if len(pod.Labels) == 0 {
err = fmt.Errorf("no StatefulSets found for pod %v because it has no labels", pod.Name)
return
}
for _, m := range s.Store.List() {
ps = *m.(*apps.StatefulSet)
if ps.Namespace != pod.Namespace {
continue
}
selector, err = metav1.LabelSelectorAsSelector(ps.Spec.Selector)
if err != nil {
err = fmt.Errorf("invalid selector: %v", err)
return
}
// If a StatefulSet with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
continue
}
psList = append(psList, ps)
}
if len(psList) == 0 {
err = fmt.Errorf("could not find StatefulSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
}
return
}
// StoreToCertificateRequestLister gives a store List and Exists methods. The store must contain only CertificateRequests.
type StoreToCertificateRequestLister struct {
cache.Store
}
// Exists checks if the given csr exists in the store.
func (s *StoreToCertificateRequestLister) Exists(csr *certificates.CertificateSigningRequest) (bool, error) {
_, exists, err := s.Store.Get(csr)
if err != nil {
return false, err
}
return exists, nil
}
// StoreToCertificateRequestLister lists all csrs in the store.
func (s *StoreToCertificateRequestLister) List() (csrs certificates.CertificateSigningRequestList, err error) {
for _, c := range s.Store.List() {
csrs.Items = append(csrs.Items, *(c.(*certificates.CertificateSigningRequest)))
}
return csrs, nil
}
type StoreToPodDisruptionBudgetLister struct {
cache.Store
}
// GetPodPodDisruptionBudgets returns a list of PodDisruptionBudgets matching a pod. Returns an error only if no matching PodDisruptionBudgets are found.
func (s *StoreToPodDisruptionBudgetLister) GetPodPodDisruptionBudgets(pod *v1.Pod) (pdbList []policy.PodDisruptionBudget, err error) {
var selector labels.Selector
if len(pod.Labels) == 0 {
err = fmt.Errorf("no PodDisruptionBudgets found for pod %v because it has no labels", pod.Name)
return
}
for _, m := range s.Store.List() {
pdb, ok := m.(*policy.PodDisruptionBudget)
if !ok {
glog.Errorf("Unexpected: %v is not a PodDisruptionBudget", m)
continue
}
if pdb.Namespace != pod.Namespace {
continue
}
selector, err = metav1.LabelSelectorAsSelector(pdb.Spec.Selector)
if err != nil {
glog.Warningf("invalid selector: %v", err)
// TODO(mml): add an event to the PDB
continue
}
// If a PDB with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
continue
}
pdbList = append(pdbList, *pdb)
}
if len(pdbList) == 0 {
err = fmt.Errorf("could not find PodDisruptionBudget for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
}
return
}
// StorageClassLister knows how to list storage classes
type StorageClassLister interface {
List(selector labels.Selector) (ret []*storage.StorageClass, err error)
Get(name string) (*storage.StorageClass, error)
}
// storageClassLister implements StorageClassLister
type storageClassLister struct {
indexer cache.Indexer
}
// NewStorageClassLister returns a new lister.
func NewStorageClassLister(indexer cache.Indexer) StorageClassLister {
return &storageClassLister{indexer: indexer}
}
// List returns a list of storage classes
func (s *storageClassLister) List(selector labels.Selector) (ret []*storage.StorageClass, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*storage.StorageClass))
})
return ret, err
}
// Get returns storage class with name 'name'.
func (s *storageClassLister) Get(name string) (*storage.StorageClass, error) {
key := &storage.StorageClass{ObjectMeta: metav1.ObjectMeta{Name: name}}
obj, exists, err := s.indexer.Get(key)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(storageinternal.Resource("storageclass"), name)
}
return obj.(*storage.StorageClass), nil
}

View File

@ -1,351 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 listers
import (
"fmt"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
)
// TODO: generate these classes and methods for all resources of interest using
// a script. Can use "go generate" once 1.4 is supported by all users.
// Lister makes an Index have the List method. The Stores must contain only the expected type
// Example:
// s := cache.NewStore()
// lw := cache.ListWatch{Client: c, FieldSelector: sel, Resource: "pods"}
// r := cache.NewReflector(lw, &api.Pod{}, s).Run()
// l := StoreToPodLister{s}
// l.List()
// StoreToPodLister helps list pods
type StoreToPodLister struct {
Indexer cache.Indexer
}
func (s *StoreToPodLister) List(selector labels.Selector) (ret []*v1.Pod, err error) {
err = cache.ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1.Pod))
})
return ret, err
}
func (s *StoreToPodLister) Pods(namespace string) storePodsNamespacer {
return storePodsNamespacer{Indexer: s.Indexer, namespace: namespace}
}
type storePodsNamespacer struct {
Indexer cache.Indexer
namespace string
}
func (s storePodsNamespacer) List(selector labels.Selector) (ret []*v1.Pod, err error) {
err = cache.ListAllByNamespace(s.Indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1.Pod))
})
return ret, err
}
func (s storePodsNamespacer) Get(name string) (*v1.Pod, error) {
obj, exists, err := s.Indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("pod"), name)
}
return obj.(*v1.Pod), nil
}
// StoreToServiceLister helps list services
type StoreToServiceLister struct {
Indexer cache.Indexer
}
func (s *StoreToServiceLister) List(selector labels.Selector) (ret []*v1.Service, err error) {
err = cache.ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1.Service))
})
return ret, err
}
func (s *StoreToServiceLister) Services(namespace string) storeServicesNamespacer {
return storeServicesNamespacer{s.Indexer, namespace}
}
type storeServicesNamespacer struct {
indexer cache.Indexer
namespace string
}
func (s storeServicesNamespacer) List(selector labels.Selector) (ret []*v1.Service, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1.Service))
})
return ret, err
}
func (s storeServicesNamespacer) Get(name string) (*v1.Service, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("service"), name)
}
return obj.(*v1.Service), nil
}
// TODO: Move this back to scheduler as a helper function that takes a Store,
// rather than a method of StoreToServiceLister.
func (s *StoreToServiceLister) GetPodServices(pod *v1.Pod) (services []*v1.Service, err error) {
allServices, err := s.Services(pod.Namespace).List(labels.Everything())
if err != nil {
return nil, err
}
for i := range allServices {
service := allServices[i]
if service.Spec.Selector == nil {
// services with nil selectors match nothing, not everything.
continue
}
selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated()
if selector.Matches(labels.Set(pod.Labels)) {
services = append(services, service)
}
}
return services, nil
}
// StoreToReplicationControllerLister helps list rcs
type StoreToReplicationControllerLister struct {
Indexer cache.Indexer
}
func (s *StoreToReplicationControllerLister) List(selector labels.Selector) (ret []*v1.ReplicationController, err error) {
err = cache.ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1.ReplicationController))
})
return ret, err
}
func (s *StoreToReplicationControllerLister) ReplicationControllers(namespace string) storeReplicationControllersNamespacer {
return storeReplicationControllersNamespacer{s.Indexer, namespace}
}
type storeReplicationControllersNamespacer struct {
indexer cache.Indexer
namespace string
}
func (s storeReplicationControllersNamespacer) List(selector labels.Selector) (ret []*v1.ReplicationController, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1.ReplicationController))
})
return ret, err
}
func (s storeReplicationControllersNamespacer) Get(name string) (*v1.ReplicationController, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("replicationcontroller"), name)
}
return obj.(*v1.ReplicationController), nil
}
// GetPodControllers returns a list of replication controllers managing a pod. Returns an error only if no matching controllers are found.
func (s *StoreToReplicationControllerLister) GetPodControllers(pod *v1.Pod) (controllers []*v1.ReplicationController, err error) {
if len(pod.Labels) == 0 {
err = fmt.Errorf("no controllers found for pod %v because it has no labels", pod.Name)
return
}
key := &v1.ReplicationController{ObjectMeta: metav1.ObjectMeta{Namespace: pod.Namespace}}
items, err := s.Indexer.Index(cache.NamespaceIndex, key)
if err != nil {
return
}
for _, m := range items {
rc := m.(*v1.ReplicationController)
selector := labels.Set(rc.Spec.Selector).AsSelectorPreValidated()
// If an rc with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
continue
}
controllers = append(controllers, rc)
}
if len(controllers) == 0 {
err = fmt.Errorf("could not find controller for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
}
return
}
// StoreToServiceAccountLister helps list service accounts
type StoreToServiceAccountLister struct {
Indexer cache.Indexer
}
func (s *StoreToServiceAccountLister) List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) {
err = cache.ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1.ServiceAccount))
})
return ret, err
}
func (s *StoreToServiceAccountLister) ServiceAccounts(namespace string) storeServiceAccountsNamespacer {
return storeServiceAccountsNamespacer{s.Indexer, namespace}
}
type storeServiceAccountsNamespacer struct {
indexer cache.Indexer
namespace string
}
func (s storeServiceAccountsNamespacer) List(selector labels.Selector) (ret []*v1.ServiceAccount, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1.ServiceAccount))
})
return ret, err
}
func (s storeServiceAccountsNamespacer) Get(name string) (*v1.ServiceAccount, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("serviceaccount"), name)
}
return obj.(*v1.ServiceAccount), nil
}
// StoreToLimitRangeLister helps list limit ranges
type StoreToLimitRangeLister struct {
Indexer cache.Indexer
}
func (s *StoreToLimitRangeLister) List(selector labels.Selector) (ret []*v1.LimitRange, err error) {
err = cache.ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1.LimitRange))
})
return ret, err
}
// StoreToPersistentVolumeClaimLister helps list pvcs
type StoreToPersistentVolumeClaimLister struct {
Indexer cache.Indexer
}
// List returns all persistentvolumeclaims that match the specified selector
func (s *StoreToPersistentVolumeClaimLister) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) {
err = cache.ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1.PersistentVolumeClaim))
})
return ret, err
}
func (s *StoreToLimitRangeLister) LimitRanges(namespace string) storeLimitRangesNamespacer {
return storeLimitRangesNamespacer{s.Indexer, namespace}
}
type storeLimitRangesNamespacer struct {
indexer cache.Indexer
namespace string
}
func (s storeLimitRangesNamespacer) List(selector labels.Selector) (ret []*v1.LimitRange, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1.LimitRange))
})
return ret, err
}
func (s storeLimitRangesNamespacer) Get(name string) (*v1.LimitRange, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("limitrange"), name)
}
return obj.(*v1.LimitRange), nil
}
// PersistentVolumeClaims returns all claims in a specified namespace.
func (s *StoreToPersistentVolumeClaimLister) PersistentVolumeClaims(namespace string) storePersistentVolumeClaimsNamespacer {
return storePersistentVolumeClaimsNamespacer{Indexer: s.Indexer, namespace: namespace}
}
type storePersistentVolumeClaimsNamespacer struct {
Indexer cache.Indexer
namespace string
}
func (s storePersistentVolumeClaimsNamespacer) List(selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) {
err = cache.ListAllByNamespace(s.Indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1.PersistentVolumeClaim))
})
return ret, err
}
func (s storePersistentVolumeClaimsNamespacer) Get(name string) (*v1.PersistentVolumeClaim, error) {
obj, exists, err := s.Indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("persistentvolumeclaims"), name)
}
return obj.(*v1.PersistentVolumeClaim), nil
}
// IndexerToNamespaceLister gives an Indexer List method
type IndexerToNamespaceLister struct {
cache.Indexer
}
// List returns a list of namespaces
func (i *IndexerToNamespaceLister) List(selector labels.Selector) (ret []*v1.Namespace, err error) {
err = cache.ListAll(i.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1.Namespace))
})
return ret, err
}
func (i *IndexerToNamespaceLister) Get(name string) (*v1.Namespace, error) {
obj, exists, err := i.Indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(api.Resource("namespace"), name)
}
return obj.(*v1.Namespace), nil
}

View File

@ -1,212 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 listers
import (
"fmt"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api/v1"
extensionsinternal "k8s.io/kubernetes/pkg/apis/extensions"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
)
// TODO: generate these classes and methods for all resources of interest using
// a script. Can use "go generate" once 1.4 is supported by all users.
// Lister makes an Index have the List method. The Stores must contain only the expected type
// Example:
// s := cache.NewStore()
// lw := cache.ListWatch{Client: c, FieldSelector: sel, Resource: "pods"}
// r := cache.NewReflector(lw, &extensions.Deployment{}, s).Run()
// l := StoreToDeploymentLister{s}
// l.List()
// StoreToDeploymentLister helps list deployments
type StoreToDeploymentLister struct {
Indexer cache.Indexer
}
func (s *StoreToDeploymentLister) List(selector labels.Selector) (ret []*extensions.Deployment, err error) {
err = cache.ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*extensions.Deployment))
})
return ret, err
}
func (s *StoreToDeploymentLister) Deployments(namespace string) storeDeploymentsNamespacer {
return storeDeploymentsNamespacer{Indexer: s.Indexer, namespace: namespace}
}
type storeDeploymentsNamespacer struct {
Indexer cache.Indexer
namespace string
}
func (s storeDeploymentsNamespacer) List(selector labels.Selector) (ret []*extensions.Deployment, err error) {
err = cache.ListAllByNamespace(s.Indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*extensions.Deployment))
})
return ret, err
}
func (s storeDeploymentsNamespacer) Get(name string) (*extensions.Deployment, error) {
obj, exists, err := s.Indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(extensionsinternal.Resource("deployment"), name)
}
return obj.(*extensions.Deployment), nil
}
// GetDeploymentsForReplicaSet returns a list of deployments managing a replica set. Returns an error only if no matching deployments are found.
func (s *StoreToDeploymentLister) GetDeploymentsForReplicaSet(rs *extensions.ReplicaSet) (deployments []*extensions.Deployment, err error) {
if len(rs.Labels) == 0 {
err = fmt.Errorf("no deployments found for ReplicaSet %v because it has no labels", rs.Name)
return
}
// TODO: MODIFY THIS METHOD so that it checks for the podTemplateSpecHash label
dList, err := s.Deployments(rs.Namespace).List(labels.Everything())
if err != nil {
return
}
for _, d := range dList {
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
}
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(rs.Labels)) {
continue
}
deployments = append(deployments, d)
}
if len(deployments) == 0 {
err = fmt.Errorf("could not find deployments set for ReplicaSet %s in namespace %s with labels: %v", rs.Name, rs.Namespace, rs.Labels)
}
return
}
// GetDeploymentsForDeployments returns a list of deployments managing a pod. Returns an error only if no matching deployments are found.
// TODO eliminate shallow copies
func (s *StoreToDeploymentLister) GetDeploymentsForPod(pod *v1.Pod) (deployments []*extensions.Deployment, err error) {
if len(pod.Labels) == 0 {
err = fmt.Errorf("no deployments found for Pod %v because it has no labels", pod.Name)
return
}
if len(pod.Labels[extensions.DefaultDeploymentUniqueLabelKey]) == 0 {
return
}
dList, err := s.Deployments(pod.Namespace).List(labels.Everything())
if err != nil {
return
}
for _, d := range dList {
selector, err := metav1.LabelSelectorAsSelector(d.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
}
// If a deployment with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
continue
}
deployments = append(deployments, d)
}
if len(deployments) == 0 {
err = fmt.Errorf("could not find deployments set for Pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
}
return
}
// StoreToReplicaSetLister helps list replicasets
type StoreToReplicaSetLister struct {
Indexer cache.Indexer
}
func (s *StoreToReplicaSetLister) List(selector labels.Selector) (ret []*extensions.ReplicaSet, err error) {
err = cache.ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*extensions.ReplicaSet))
})
return ret, err
}
func (s *StoreToReplicaSetLister) ReplicaSets(namespace string) storeReplicaSetsNamespacer {
return storeReplicaSetsNamespacer{Indexer: s.Indexer, namespace: namespace}
}
type storeReplicaSetsNamespacer struct {
Indexer cache.Indexer
namespace string
}
func (s storeReplicaSetsNamespacer) List(selector labels.Selector) (ret []*extensions.ReplicaSet, err error) {
err = cache.ListAllByNamespace(s.Indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*extensions.ReplicaSet))
})
return ret, err
}
func (s storeReplicaSetsNamespacer) Get(name string) (*extensions.ReplicaSet, error) {
obj, exists, err := s.Indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(extensionsinternal.Resource("replicaset"), name)
}
return obj.(*extensions.ReplicaSet), nil
}
// GetPodReplicaSets returns a list of ReplicaSets managing a pod. Returns an error only if no matching ReplicaSets are found.
func (s *StoreToReplicaSetLister) GetPodReplicaSets(pod *v1.Pod) (rss []*extensions.ReplicaSet, err error) {
if len(pod.Labels) == 0 {
err = fmt.Errorf("no ReplicaSets found for pod %v because it has no labels", pod.Name)
return
}
list, err := s.ReplicaSets(pod.Namespace).List(labels.Everything())
if err != nil {
return
}
for _, rs := range list {
if rs.Namespace != pod.Namespace {
continue
}
selector, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("invalid selector: %v", err)
}
// If a ReplicaSet with a nil or empty selector creeps in, it should match nothing, not everything.
if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) {
continue
}
rss = append(rss, rs)
}
if len(rss) == 0 {
err = fmt.Errorf("could not find ReplicaSet for pod %s in namespace %s with labels: %v", pod.Name, pod.Namespace, pod.Labels)
}
return
}

View File

@ -1,235 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 listers
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
)
// TODO: generate these classes and methods for all resources of interest using
// a script. Can use "go generate" once 1.4 is supported by all users.
// Lister makes an Index have the List method. The Stores must contain only the expected type
// Example:
// s := cache.NewStore()
// lw := cache.ListWatch{Client: c, FieldSelector: sel, Resource: "pods"}
// r := cache.NewReflector(lw, &rbac.ClusterRole{}, s).Run()
// l := clusterRoleLister{s}
// l.List()
func NewClusterRoleLister(indexer cache.Indexer) ClusterRoleLister {
return &clusterRoleLister{indexer: indexer}
}
func NewClusterRoleBindingLister(indexer cache.Indexer) ClusterRoleBindingLister {
return &clusterRoleBindingLister{indexer: indexer}
}
func NewRoleLister(indexer cache.Indexer) RoleLister {
return &roleLister{indexer: indexer}
}
func NewRoleBindingLister(indexer cache.Indexer) RoleBindingLister {
return &roleBindingLister{indexer: indexer}
}
// these interfaces are used by the rbac authorizer
type authorizerClusterRoleGetter interface {
GetClusterRole(name string) (*rbac.ClusterRole, error)
}
type authorizerClusterRoleBindingLister interface {
ListClusterRoleBindings() ([]*rbac.ClusterRoleBinding, error)
}
type authorizerRoleGetter interface {
GetRole(namespace, name string) (*rbac.Role, error)
}
type authorizerRoleBindingLister interface {
ListRoleBindings(namespace string) ([]*rbac.RoleBinding, error)
}
type ClusterRoleLister interface {
authorizerClusterRoleGetter
List(selector labels.Selector) (ret []*rbac.ClusterRole, err error)
Get(name string) (*rbac.ClusterRole, error)
}
type clusterRoleLister struct {
indexer cache.Indexer
}
func (s *clusterRoleLister) List(selector labels.Selector) (ret []*rbac.ClusterRole, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*rbac.ClusterRole))
})
return ret, err
}
func (s clusterRoleLister) Get(name string) (*rbac.ClusterRole, error) {
obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(rbac.Resource("clusterrole"), name)
}
return obj.(*rbac.ClusterRole), nil
}
func (s clusterRoleLister) GetClusterRole(name string) (*rbac.ClusterRole, error) {
return s.Get(name)
}
type ClusterRoleBindingLister interface {
authorizerClusterRoleBindingLister
List(selector labels.Selector) (ret []*rbac.ClusterRoleBinding, err error)
Get(name string) (*rbac.ClusterRoleBinding, error)
}
type clusterRoleBindingLister struct {
indexer cache.Indexer
}
func (s *clusterRoleBindingLister) List(selector labels.Selector) (ret []*rbac.ClusterRoleBinding, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*rbac.ClusterRoleBinding))
})
return ret, err
}
func (s clusterRoleBindingLister) Get(name string) (*rbac.ClusterRoleBinding, error) {
obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(rbac.Resource("clusterrolebinding"), name)
}
return obj.(*rbac.ClusterRoleBinding), nil
}
func (s clusterRoleBindingLister) ListClusterRoleBindings() ([]*rbac.ClusterRoleBinding, error) {
return s.List(labels.Everything())
}
type RoleLister interface {
authorizerRoleGetter
List(selector labels.Selector) (ret []*rbac.Role, err error)
Roles(namespace string) RoleNamespaceLister
}
type RoleNamespaceLister interface {
List(selector labels.Selector) (ret []*rbac.Role, err error)
Get(name string) (*rbac.Role, error)
}
type roleLister struct {
indexer cache.Indexer
}
func (s *roleLister) List(selector labels.Selector) (ret []*rbac.Role, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*rbac.Role))
})
return ret, err
}
func (s *roleLister) Roles(namespace string) RoleNamespaceLister {
return roleNamespaceLister{indexer: s.indexer, namespace: namespace}
}
func (s roleLister) GetRole(namespace, name string) (*rbac.Role, error) {
return s.Roles(namespace).Get(name)
}
type roleNamespaceLister struct {
indexer cache.Indexer
namespace string
}
func (s roleNamespaceLister) List(selector labels.Selector) (ret []*rbac.Role, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*rbac.Role))
})
return ret, err
}
func (s roleNamespaceLister) Get(name string) (*rbac.Role, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(rbac.Resource("role"), name)
}
return obj.(*rbac.Role), nil
}
type RoleBindingLister interface {
authorizerRoleBindingLister
List(selector labels.Selector) (ret []*rbac.RoleBinding, err error)
RoleBindings(namespace string) RoleBindingNamespaceLister
}
type RoleBindingNamespaceLister interface {
List(selector labels.Selector) (ret []*rbac.RoleBinding, err error)
Get(name string) (*rbac.RoleBinding, error)
}
type roleBindingLister struct {
indexer cache.Indexer
}
func (s *roleBindingLister) List(selector labels.Selector) (ret []*rbac.RoleBinding, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*rbac.RoleBinding))
})
return ret, err
}
func (s *roleBindingLister) RoleBindings(namespace string) RoleBindingNamespaceLister {
return roleBindingNamespaceLister{indexer: s.indexer, namespace: namespace}
}
func (s roleBindingLister) ListRoleBindings(namespace string) ([]*rbac.RoleBinding, error) {
return s.RoleBindings(namespace).List(labels.Everything())
}
type roleBindingNamespaceLister struct {
indexer cache.Indexer
namespace string
}
func (s roleBindingNamespaceLister) List(selector labels.Selector) (ret []*rbac.RoleBinding, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*rbac.RoleBinding))
})
return ret, err
}
func (s roleBindingNamespaceLister) Get(name string) (*rbac.RoleBinding, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(rbac.Resource("rolebinding"), name)
}
return obj.(*rbac.RoleBinding), nil
}

View File

@ -1,614 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
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 listers
import (
"testing"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api/v1"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
)
func TestStoreToNodeLister(t *testing.T) {
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
ids := sets.NewString("foo", "bar", "baz")
for id := range ids {
store.Add(&v1.Node{ObjectMeta: metav1.ObjectMeta{Name: id}})
}
sml := StoreToNodeLister{store}
gotNodes, err := sml.List()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
got := make([]string, len(gotNodes.Items))
for ix := range gotNodes.Items {
got[ix] = gotNodes.Items[ix].Name
}
if !ids.HasAll(got...) || len(got) != len(ids) {
t.Errorf("Expected %v, got %v", ids, got)
}
}
func TestStoreToNodeConditionLister(t *testing.T) {
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
nodes := []*v1.Node{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Status: v1.NodeStatus{
Conditions: []v1.NodeCondition{
{
Type: v1.NodeReady,
Status: v1.ConditionTrue,
},
{
Type: v1.NodeOutOfDisk,
Status: v1.ConditionFalse,
},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar"},
Status: v1.NodeStatus{
Conditions: []v1.NodeCondition{
{
Type: v1.NodeOutOfDisk,
Status: v1.ConditionTrue,
},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "baz"},
Status: v1.NodeStatus{
Conditions: []v1.NodeCondition{
{
Type: v1.NodeReady,
Status: v1.ConditionFalse,
},
{
Type: v1.NodeOutOfDisk,
Status: v1.ConditionUnknown,
},
},
},
},
}
for _, n := range nodes {
store.Add(n)
}
predicate := func(node *v1.Node) bool {
for _, cond := range node.Status.Conditions {
if cond.Type == v1.NodeOutOfDisk && cond.Status == v1.ConditionTrue {
return false
}
}
return true
}
snl := StoreToNodeLister{store}
sncl := snl.NodeCondition(predicate)
want := sets.NewString("foo", "baz")
gotNodes, err := sncl.List()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
got := make([]string, len(gotNodes))
for ix := range gotNodes {
got[ix] = gotNodes[ix].Name
}
if !want.HasAll(got...) || len(got) != len(want) {
t.Errorf("Expected %v, got %v", want, got)
}
}
func TestStoreToReplicationControllerLister(t *testing.T) {
testCases := []struct {
description string
inRCs []*v1.ReplicationController
list func(StoreToReplicationControllerLister) ([]*v1.ReplicationController, error)
outRCNames sets.String
expectErr bool
onlyIfIndexedByNamespace bool
}{
{
description: "Verify we can search all namespaces",
inRCs: []*v1.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "hmm", Namespace: "hmm"},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
return lister.ReplicationControllers(metav1.NamespaceAll).List(labels.Set{}.AsSelectorPreValidated())
},
outRCNames: sets.NewString("hmm", "foo"),
},
{
description: "Verify we can search a specific namespace",
inRCs: []*v1.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "hmm", Namespace: "hmm"},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
return lister.ReplicationControllers("hmm").List(labels.Set{}.AsSelectorPreValidated())
},
outRCNames: sets.NewString("hmm"),
},
{
description: "Basic listing with all labels and no selectors",
inRCs: []*v1.ReplicationController{
{ObjectMeta: metav1.ObjectMeta{Name: "basic"}},
},
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
return lister.List(labels.Everything())
},
outRCNames: sets.NewString("basic"),
},
{
description: "No pod labels",
inRCs: []*v1.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"},
Spec: v1.ReplicationControllerSpec{
Selector: map[string]string{"foo": "baz"},
},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "pod1", Namespace: "ns"},
}
return lister.GetPodControllers(pod)
},
outRCNames: sets.NewString(),
expectErr: true,
},
{
description: "No RC selectors",
inRCs: []*v1.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
Namespace: "ns",
Labels: map[string]string{"foo": "bar"},
},
}
return lister.GetPodControllers(pod)
},
outRCNames: sets.NewString(),
expectErr: true,
},
{
description: "Matching labels to selectors and namespace",
inRCs: []*v1.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: v1.ReplicationControllerSpec{
Selector: map[string]string{"foo": "bar"},
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "ns"},
Spec: v1.ReplicationControllerSpec{
Selector: map[string]string{"foo": "bar"},
},
},
},
list: func(lister StoreToReplicationControllerLister) ([]*v1.ReplicationController, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
Labels: map[string]string{"foo": "bar"},
Namespace: "ns",
},
}
return lister.GetPodControllers(pod)
},
outRCNames: sets.NewString("bar"),
onlyIfIndexedByNamespace: true,
},
}
for _, c := range testCases {
for _, withIndex := range []bool{true, false} {
if c.onlyIfIndexedByNamespace && !withIndex {
continue
}
var store cache.Indexer
if withIndex {
store = cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
} else {
store = cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
}
for _, r := range c.inRCs {
store.Add(r)
}
gotControllers, err := c.list(StoreToReplicationControllerLister{store})
if err != nil && c.expectErr {
continue
} else if c.expectErr {
t.Errorf("(%q, withIndex=%v) Expected error, got none", c.description, withIndex)
continue
} else if err != nil {
t.Errorf("(%q, withIndex=%v) Unexpected error %#v", c.description, withIndex, err)
continue
}
gotNames := make([]string, len(gotControllers))
for ix := range gotControllers {
gotNames[ix] = gotControllers[ix].Name
}
if !c.outRCNames.HasAll(gotNames...) || len(gotNames) != len(c.outRCNames) {
t.Errorf("(%q, withIndex=%v) Unexpected got controllers %+v expected %+v", c.description, withIndex, gotNames, c.outRCNames)
}
}
}
}
func TestStoreToReplicaSetLister(t *testing.T) {
store := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
lister := StoreToReplicaSetLister{store}
testCases := []struct {
inRSs []*extensions.ReplicaSet
list func() ([]*extensions.ReplicaSet, error)
outRSNames sets.String
expectErr bool
}{
// Basic listing with all labels and no selectors
{
inRSs: []*extensions.ReplicaSet{
{ObjectMeta: metav1.ObjectMeta{Name: "basic"}},
},
list: func() ([]*extensions.ReplicaSet, error) {
return lister.List(labels.Everything())
},
outRSNames: sets.NewString("basic"),
},
// No pod labels
{
inRSs: []*extensions.ReplicaSet{
{
ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"},
Spec: extensions.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}},
},
},
},
list: func() ([]*extensions.ReplicaSet, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "pod1", Namespace: "ns"},
}
return lister.GetPodReplicaSets(pod)
},
outRSNames: sets.NewString(),
expectErr: true,
},
// No ReplicaSet selectors
{
inRSs: []*extensions.ReplicaSet{
{
ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"},
},
},
list: func() ([]*extensions.ReplicaSet, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
Namespace: "ns",
Labels: map[string]string{"foo": "bar"},
},
}
return lister.GetPodReplicaSets(pod)
},
outRSNames: sets.NewString(),
expectErr: true,
},
// Matching labels to selectors and namespace
{
inRSs: []*extensions.ReplicaSet{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: extensions.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "ns"},
Spec: extensions.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
},
list: func() ([]*extensions.ReplicaSet, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
Labels: map[string]string{"foo": "bar"},
Namespace: "ns",
},
}
return lister.GetPodReplicaSets(pod)
},
outRSNames: sets.NewString("bar"),
},
}
for _, c := range testCases {
for _, r := range c.inRSs {
store.Add(r)
}
gotRSs, err := c.list()
if err != nil && c.expectErr {
continue
} else if c.expectErr {
t.Error("Expected error, got none")
continue
} else if err != nil {
t.Errorf("Unexpected error %#v", err)
continue
}
gotNames := make([]string, len(gotRSs))
for ix := range gotRSs {
gotNames[ix] = gotRSs[ix].Name
}
if !c.outRSNames.HasAll(gotNames...) || len(gotNames) != len(c.outRSNames) {
t.Errorf("Unexpected got ReplicaSets %+v expected %+v", gotNames, c.outRSNames)
}
}
}
func TestStoreToDaemonSetLister(t *testing.T) {
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
lister := StoreToDaemonSetLister{store}
testCases := []struct {
inDSs []*extensions.DaemonSet
list func() ([]extensions.DaemonSet, error)
outDaemonSetNames sets.String
expectErr bool
}{
// Basic listing
{
inDSs: []*extensions.DaemonSet{
{ObjectMeta: metav1.ObjectMeta{Name: "basic"}},
},
list: func() ([]extensions.DaemonSet, error) {
list, err := lister.List()
return list.Items, err
},
outDaemonSetNames: sets.NewString("basic"),
},
// Listing multiple daemon sets
{
inDSs: []*extensions.DaemonSet{
{ObjectMeta: metav1.ObjectMeta{Name: "basic"}},
{ObjectMeta: metav1.ObjectMeta{Name: "complex"}},
{ObjectMeta: metav1.ObjectMeta{Name: "complex2"}},
},
list: func() ([]extensions.DaemonSet, error) {
list, err := lister.List()
return list.Items, err
},
outDaemonSetNames: sets.NewString("basic", "complex", "complex2"),
},
// No pod labels
{
inDSs: []*extensions.DaemonSet{
{
ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"},
Spec: extensions.DaemonSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}},
},
},
},
list: func() ([]extensions.DaemonSet, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "pod1", Namespace: "ns"},
}
return lister.GetPodDaemonSets(pod)
},
outDaemonSetNames: sets.NewString(),
expectErr: true,
},
// No DS selectors
{
inDSs: []*extensions.DaemonSet{
{
ObjectMeta: metav1.ObjectMeta{Name: "basic", Namespace: "ns"},
},
},
list: func() ([]extensions.DaemonSet, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
Namespace: "ns",
Labels: map[string]string{"foo": "bar"},
},
}
return lister.GetPodDaemonSets(pod)
},
outDaemonSetNames: sets.NewString(),
expectErr: true,
},
// Matching labels to selectors and namespace
{
inDSs: []*extensions.DaemonSet{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: extensions.DaemonSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "ns"},
Spec: extensions.DaemonSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
},
list: func() ([]extensions.DaemonSet, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
Labels: map[string]string{"foo": "bar"},
Namespace: "ns",
},
}
return lister.GetPodDaemonSets(pod)
},
outDaemonSetNames: sets.NewString("bar"),
},
}
for _, c := range testCases {
for _, r := range c.inDSs {
store.Add(r)
}
daemonSets, err := c.list()
if err != nil && c.expectErr {
continue
} else if c.expectErr {
t.Error("Expected error, got none")
continue
} else if err != nil {
t.Errorf("Unexpected error %#v", err)
continue
}
daemonSetNames := make([]string, len(daemonSets))
for ix := range daemonSets {
daemonSetNames[ix] = daemonSets[ix].Name
}
if !c.outDaemonSetNames.HasAll(daemonSetNames...) || len(daemonSetNames) != len(c.outDaemonSetNames) {
t.Errorf("Unexpected got controllers %+v expected %+v", daemonSetNames, c.outDaemonSetNames)
}
}
}
func TestStoreToPodLister(t *testing.T) {
// We test with and without a namespace index, because StoreToPodLister has
// special logic to work on namespaces even when no namespace index is
// present.
stores := []cache.Indexer{
cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}),
cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}),
}
for _, store := range stores {
ids := []string{"foo", "bar", "baz"}
for _, id := range ids {
store.Add(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Namespace: "other",
Name: id,
Labels: map[string]string{"name": id},
},
})
}
store.Add(&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "quux",
Namespace: metav1.NamespaceDefault,
Labels: map[string]string{"name": "quux"},
},
})
spl := StoreToPodLister{store}
// Verify that we can always look up by Namespace.
defaultPods, err := spl.Pods(metav1.NamespaceDefault).List(labels.Set{}.AsSelectorPreValidated())
if err != nil {
t.Errorf("Unexpected error: %v", err)
} else if e, a := 1, len(defaultPods); e != a {
t.Errorf("Expected %v, got %v", e, a)
} else if e, a := "quux", defaultPods[0].Name; e != a {
t.Errorf("Expected %v, got %v", e, a)
}
for _, id := range ids {
got, err := spl.List(labels.Set{"name": id}.AsSelectorPreValidated())
if err != nil {
t.Errorf("Unexpected error: %v", err)
continue
}
if e, a := 1, len(got); e != a {
t.Errorf("Expected %v, got %v", e, a)
continue
}
if e, a := id, got[0].Name; e != a {
t.Errorf("Expected %v, got %v", e, a)
continue
}
_, err = spl.Pods("other").Get(id)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
}
if _, err := spl.Pods("").Get("qux"); !apierrors.IsNotFound(err) {
t.Error("Unexpected pod exists")
}
}
}
func TestStoreToServiceLister(t *testing.T) {
store := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
store.Add(&v1.Service{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: v1.ServiceSpec{
Selector: map[string]string{},
},
})
store.Add(&v1.Service{ObjectMeta: metav1.ObjectMeta{Name: "bar"}})
ssl := StoreToServiceLister{store}
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "foopod",
Labels: map[string]string{"role": "foo"},
},
}
services, err := ssl.GetPodServices(pod)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if len(services) != 1 {
t.Fatalf("Expected 1 service, got %v", len(services))
}
if e, a := "foo", services[0].Name; e != a {
t.Errorf("Expected service %q, got %q", e, a)
}
}

View File

@ -100,7 +100,6 @@ filegroup(
"//pkg/controller/disruption:all-srcs", "//pkg/controller/disruption:all-srcs",
"//pkg/controller/endpoint:all-srcs", "//pkg/controller/endpoint:all-srcs",
"//pkg/controller/garbagecollector:all-srcs", "//pkg/controller/garbagecollector:all-srcs",
"//pkg/controller/informers:all-srcs",
"//pkg/controller/job:all-srcs", "//pkg/controller/job:all-srcs",
"//pkg/controller/namespace:all-srcs", "//pkg/controller/namespace:all-srcs",
"//pkg/controller/node:all-srcs", "//pkg/controller/node:all-srcs",

View File

@ -1,56 +0,0 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"batch.go",
"core.go",
"extensions.go",
"factory.go",
"generic.go",
"rbac.go",
"storage.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/batch/v1:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/storage/v1beta1:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/legacylisters:go_default_library",
"//pkg/client/listers/batch/v1:go_default_library",
"//pkg/client/listers/core/internalversion:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/watch",
"//vendor:k8s.io/client-go/tools/cache",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -1,6 +0,0 @@
reviewers:
- derekwaynecarr
- caesarxuchao
- wojtek-t
- lavalamp
- deads2k

View File

@ -1,83 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 informers
import (
"reflect"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
batch "k8s.io/kubernetes/pkg/apis/batch/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
batchv1listers "k8s.io/kubernetes/pkg/client/listers/batch/v1"
)
// JobInformer is type of SharedIndexInformer which watches and lists all jobs.
// Interface provides constructor for informer and lister for jobs
type JobInformer interface {
Informer() cache.SharedIndexInformer
Lister() batchv1listers.JobLister
}
type jobInformer struct {
*sharedInformerFactory
}
// Informer checks whether jobInformer exists in sharedInformerFactory and if not, it creates new informer of type
// jobInformer and connects it to sharedInformerFactory
func (f *jobInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&batch.Job{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewJobInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// NewJobInformer returns a SharedIndexInformer that lists and watches all jobs
func NewJobInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Batch().Jobs(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Batch().Jobs(metav1.NamespaceAll).Watch(options)
},
},
&batch.Job{},
resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
return sharedIndexInformer
}
// Lister returns lister for jobInformer
func (f *jobInformer) Lister() batchv1listers.JobLister {
informer := f.Informer()
return batchv1listers.NewJobLister(informer.GetIndexer())
}

View File

@ -1,576 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 informers
import (
"reflect"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/legacylisters"
coreinternallisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
)
// PodInformer is type of SharedIndexInformer which watches and lists all pods.
// Interface provides constructor for informer and lister for pods
type PodInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToPodLister
}
type podInformer struct {
*sharedInformerFactory
}
// Informer checks whether podInformer exists in sharedInformerFactory and if not, it creates new informer of type
// podInformer and connects it to sharedInformerFactory
func (f *podInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&v1.Pod{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewPodInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for podInformer
func (f *podInformer) Lister() *listers.StoreToPodLister {
informer := f.Informer()
return &listers.StoreToPodLister{Indexer: informer.GetIndexer()}
}
//*****************************************************************************
// NamespaceInformer is type of SharedIndexInformer which watches and lists all namespaces.
// Interface provides constructor for informer and lister for namsespaces
type NamespaceInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.IndexerToNamespaceLister
}
type namespaceInformer struct {
*sharedInformerFactory
}
// Informer checks whether namespaceInformer exists in sharedInformerFactory and if not, it creates new informer of type
// namespaceInformer and connects it to sharedInformerFactory
func (f *namespaceInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&v1.Namespace{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewNamespaceInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for namespaceInformer
func (f *namespaceInformer) Lister() *listers.IndexerToNamespaceLister {
informer := f.Informer()
return &listers.IndexerToNamespaceLister{Indexer: informer.GetIndexer()}
}
//*****************************************************************************
// InternalNamespaceInformer is type of SharedIndexInformer which watches and lists all namespaces.
// Interface provides constructor for informer and lister for namsespaces
type InternalNamespaceInformer interface {
Informer() cache.SharedIndexInformer
Lister() coreinternallisters.NamespaceLister
}
type internalNamespaceInformer struct {
*sharedInformerFactory
}
// Informer checks whether internalNamespaceInformer exists in sharedInformerFactory and if not, it creates new informer of type
// internalNamespaceInformer and connects it to sharedInformerFactory
func (f *internalNamespaceInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&api.Namespace{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewInternalNamespaceInformer(f.internalclient, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for internalNamespaceInformer
func (f *internalNamespaceInformer) Lister() coreinternallisters.NamespaceLister {
informer := f.Informer()
return coreinternallisters.NewNamespaceLister(informer.GetIndexer())
}
//*****************************************************************************
// NodeInformer is type of SharedIndexInformer which watches and lists all nodes.
// Interface provides constructor for informer and lister for nodes
type NodeInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToNodeLister
}
type nodeInformer struct {
*sharedInformerFactory
}
// Informer checks whether nodeInformer exists in sharedInformerFactory and if not, it creates new informer of type
// nodeInformer and connects it to sharedInformerFactory
func (f *nodeInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&v1.Node{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewNodeInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for nodeInformer
func (f *nodeInformer) Lister() *listers.StoreToNodeLister {
informer := f.Informer()
return &listers.StoreToNodeLister{Store: informer.GetStore()}
}
//*****************************************************************************
// PVCInformer is type of SharedIndexInformer which watches and lists all persistent volume claims.
// Interface provides constructor for informer and lister for persistent volume claims
type PVCInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToPersistentVolumeClaimLister
}
type pvcInformer struct {
*sharedInformerFactory
}
// Informer checks whether pvcInformer exists in sharedInformerFactory and if not, it creates new informer of type
// pvcInformer and connects it to sharedInformerFactory
func (f *pvcInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&v1.PersistentVolumeClaim{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewPVCInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for pvcInformer
func (f *pvcInformer) Lister() *listers.StoreToPersistentVolumeClaimLister {
informer := f.Informer()
return &listers.StoreToPersistentVolumeClaimLister{Indexer: informer.GetIndexer()}
}
//*****************************************************************************
// PVInformer is type of SharedIndexInformer which watches and lists all persistent volumes.
// Interface provides constructor for informer and lister for persistent volumes
type PVInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToPVFetcher
}
type pvInformer struct {
*sharedInformerFactory
}
// Informer checks whether pvInformer exists in sharedInformerFactory and if not, it creates new informer of type
// pvInformer and connects it to sharedInformerFactory
func (f *pvInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&v1.PersistentVolume{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewPVInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for pvInformer
func (f *pvInformer) Lister() *listers.StoreToPVFetcher {
informer := f.Informer()
return &listers.StoreToPVFetcher{Store: informer.GetStore()}
}
//*****************************************************************************
// LimitRangeInformer is type of SharedIndexInformer which watches and lists all limit ranges.
// Interface provides constructor for informer and lister for limit ranges.
type LimitRangeInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToLimitRangeLister
}
type limitRangeInformer struct {
*sharedInformerFactory
}
// Informer checks whether pvcInformer exists in sharedInformerFactory and if not, it creates new informer of type
// limitRangeInformer and connects it to sharedInformerFactory
func (f *limitRangeInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&v1.LimitRange{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewLimitRangeInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for limitRangeInformer
func (f *limitRangeInformer) Lister() *listers.StoreToLimitRangeLister {
informer := f.Informer()
return &listers.StoreToLimitRangeLister{Indexer: informer.GetIndexer()}
}
//*****************************************************************************
// InternalLimitRangeInformer is type of SharedIndexInformer which watches and lists all limit ranges.
// Interface provides constructor for informer and lister for limit ranges.
type InternalLimitRangeInformer interface {
Informer() cache.SharedIndexInformer
Lister() coreinternallisters.LimitRangeLister
}
type internalLimitRangeInformer struct {
*sharedInformerFactory
}
// Informer checks whether pvcInformer exists in sharedInformerFactory and if not, it creates new informer of type
// internalLimitRangeInformer and connects it to sharedInformerFactory
func (f *internalLimitRangeInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&api.LimitRange{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewInternalLimitRangeInformer(f.internalclient, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for internalLimitRangeInformer
func (f *internalLimitRangeInformer) Lister() coreinternallisters.LimitRangeLister {
informer := f.Informer()
return coreinternallisters.NewLimitRangeLister(informer.GetIndexer())
}
//*****************************************************************************
// ReplicationControllerInformer is type of SharedIndexInformer which watches and lists all replication controllers.
// Interface provides constructor for informer and lister for replication controllers.
type ReplicationControllerInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToReplicationControllerLister
}
type replicationControllerInformer struct {
*sharedInformerFactory
}
// Informer checks whether replicationControllerInformer exists in sharedInformerFactory and if not, it creates new informer of type
// replicationControllerInformer and connects it to sharedInformerFactory
func (f *replicationControllerInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&v1.ReplicationController{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewReplicationControllerInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for replicationControllerInformer
func (f *replicationControllerInformer) Lister() *listers.StoreToReplicationControllerLister {
informer := f.Informer()
return &listers.StoreToReplicationControllerLister{Indexer: informer.GetIndexer()}
}
//*****************************************************************************
// NewPodInformer returns a SharedIndexInformer that lists and watches all pods
func NewPodInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().Pods(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().Pods(metav1.NamespaceAll).Watch(options)
},
},
&v1.Pod{},
resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
return sharedIndexInformer
}
// NewNodeInformer returns a SharedIndexInformer that lists and watches all nodes
func NewNodeInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().Nodes().List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().Nodes().Watch(options)
},
},
&v1.Node{},
resyncPeriod,
cache.Indexers{})
return sharedIndexInformer
}
// NewPVCInformer returns a SharedIndexInformer that lists and watches all PVCs
func NewPVCInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().PersistentVolumeClaims(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().PersistentVolumeClaims(metav1.NamespaceAll).Watch(options)
},
},
&v1.PersistentVolumeClaim{},
resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
return sharedIndexInformer
}
// NewPVInformer returns a SharedIndexInformer that lists and watches all PVs
func NewPVInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().PersistentVolumes().List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().PersistentVolumes().Watch(options)
},
},
&v1.PersistentVolume{},
resyncPeriod,
cache.Indexers{})
return sharedIndexInformer
}
// NewNamespaceInformer returns a SharedIndexInformer that lists and watches namespaces
func NewNamespaceInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().Namespaces().List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().Namespaces().Watch(options)
},
},
&v1.Namespace{},
resyncPeriod,
cache.Indexers{})
return sharedIndexInformer
}
// NewInternalNamespaceInformer returns a SharedIndexInformer that lists and watches namespaces
func NewInternalNamespaceInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().Namespaces().List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().Namespaces().Watch(options)
},
},
&api.Namespace{},
resyncPeriod,
cache.Indexers{})
return sharedIndexInformer
}
// NewLimitRangeInformer returns a SharedIndexInformer that lists and watches all LimitRanges
func NewLimitRangeInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().LimitRanges(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().LimitRanges(metav1.NamespaceAll).Watch(options)
},
},
&v1.LimitRange{},
resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
return sharedIndexInformer
}
// NewInternalLimitRangeInformer returns a SharedIndexInformer that lists and watches all LimitRanges
func NewInternalLimitRangeInformer(internalclient internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return internalclient.Core().LimitRanges(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return internalclient.Core().LimitRanges(metav1.NamespaceAll).Watch(options)
},
},
&api.LimitRange{},
resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
return sharedIndexInformer
}
// NewReplicationControllerInformer returns a SharedIndexInformer that lists and watches all replication controllers.
func NewReplicationControllerInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().ReplicationControllers(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().ReplicationControllers(metav1.NamespaceAll).Watch(options)
},
},
&v1.ReplicationController{},
resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
return sharedIndexInformer
}
/*****************************************************************************/
// ServiceAccountInformer is type of SharedIndexInformer which watches and lists all ServiceAccounts.
// Interface provides constructor for informer and lister for ServiceAccounts
type ServiceAccountInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToServiceAccountLister
}
type serviceAccountInformer struct {
*sharedInformerFactory
}
// Informer checks whether ServiceAccountInformer exists in sharedInformerFactory and if not, it creates new informer of type
// ServiceAccountInformer and connects it to sharedInformerFactory
func (f *serviceAccountInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&v1.ServiceAccount{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = NewServiceAccountInformer(f.client, f.defaultResync)
f.informers[informerType] = informer
return informer
}
// Lister returns lister for ServiceAccountInformer
func (f *serviceAccountInformer) Lister() *listers.StoreToServiceAccountLister {
informer := f.Informer()
return &listers.StoreToServiceAccountLister{Indexer: informer.GetIndexer()}
}
// NewServiceAccountInformer returns a SharedIndexInformer that lists and watches all ServiceAccounts
func NewServiceAccountInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
sharedIndexInformer := cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.Core().ServiceAccounts(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.Core().ServiceAccounts(metav1.NamespaceAll).Watch(options)
},
},
&v1.ServiceAccount{},
resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
return sharedIndexInformer
}

View File

@ -1,155 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 informers
import (
"reflect"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/client/legacylisters"
)
// DaemonSetInformer is type of SharedIndexInformer which watches and lists all pods.
// Interface provides constructor for informer and lister for pods
type DaemonSetInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToDaemonSetLister
}
type daemonSetInformer struct {
*sharedInformerFactory
}
func (f *daemonSetInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&extensions.DaemonSet{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return f.client.Extensions().DaemonSets(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return f.client.Extensions().DaemonSets(metav1.NamespaceAll).Watch(options)
},
},
&extensions.DaemonSet{},
f.defaultResync,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
f.informers[informerType] = informer
return informer
}
func (f *daemonSetInformer) Lister() *listers.StoreToDaemonSetLister {
informer := f.Informer()
return &listers.StoreToDaemonSetLister{Store: informer.GetIndexer()}
}
// DeploymentInformer is a type of SharedIndexInformer which watches and lists all deployments.
type DeploymentInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToDeploymentLister
}
type deploymentInformer struct {
*sharedInformerFactory
}
func (f *deploymentInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&extensions.Deployment{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return f.client.Extensions().Deployments(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return f.client.Extensions().Deployments(metav1.NamespaceAll).Watch(options)
},
},
&extensions.Deployment{},
f.defaultResync,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
f.informers[informerType] = informer
return informer
}
func (f *deploymentInformer) Lister() *listers.StoreToDeploymentLister {
informer := f.Informer()
return &listers.StoreToDeploymentLister{Indexer: informer.GetIndexer()}
}
// ReplicaSetInformer is a type of SharedIndexInformer which watches and lists all replicasets.
type ReplicaSetInformer interface {
Informer() cache.SharedIndexInformer
Lister() *listers.StoreToReplicaSetLister
}
type replicaSetInformer struct {
*sharedInformerFactory
}
func (f *replicaSetInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&extensions.ReplicaSet{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return f.client.Extensions().ReplicaSets(metav1.NamespaceAll).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return f.client.Extensions().ReplicaSets(metav1.NamespaceAll).Watch(options)
},
},
&extensions.ReplicaSet{},
f.defaultResync,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
f.informers[informerType] = informer
return informer
}
func (f *replicaSetInformer) Lister() *listers.StoreToReplicaSetLister {
informer := f.Informer()
return &listers.StoreToReplicaSetLister{Indexer: informer.GetIndexer()}
}

View File

@ -1,193 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
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 informers
import (
"reflect"
"sync"
"time"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
)
// SharedInformerFactory provides interface which holds unique informers for pods, nodes, namespaces, persistent volume
// claims and persistent volumes
type SharedInformerFactory interface {
// Start starts informers that can start AFTER the API server and controllers have started
Start(stopCh <-chan struct{})
ForResource(schema.GroupResource) (GenericInformer, error)
// when you update these, update generic.go/ForResource, same package
Pods() PodInformer
LimitRanges() LimitRangeInformer
InternalLimitRanges() InternalLimitRangeInformer
Namespaces() NamespaceInformer
InternalNamespaces() InternalNamespaceInformer
Nodes() NodeInformer
PersistentVolumeClaims() PVCInformer
PersistentVolumes() PVInformer
ServiceAccounts() ServiceAccountInformer
DaemonSets() DaemonSetInformer
Deployments() DeploymentInformer
ReplicaSets() ReplicaSetInformer
ReplicationControllers() ReplicationControllerInformer
ClusterRoleBindings() ClusterRoleBindingInformer
ClusterRoles() ClusterRoleInformer
RoleBindings() RoleBindingInformer
Roles() RoleInformer
StorageClasses() StorageClassInformer
Jobs() JobInformer
}
type sharedInformerFactory struct {
client clientset.Interface
// for admission plugins etc.
internalclient internalclientset.Interface
lock sync.Mutex
defaultResync time.Duration
informers map[reflect.Type]cache.SharedIndexInformer
// startedInformers is used for tracking which informers have been started
// this allows calling of Start method multiple times
startedInformers map[reflect.Type]bool
}
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory
func NewSharedInformerFactory(client clientset.Interface, internalclient internalclientset.Interface, defaultResync time.Duration) SharedInformerFactory {
return &sharedInformerFactory{
client: client,
internalclient: internalclient,
defaultResync: defaultResync,
informers: make(map[reflect.Type]cache.SharedIndexInformer),
startedInformers: make(map[reflect.Type]bool),
}
}
// Start initializes all requested informers.
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
f.lock.Lock()
defer f.lock.Unlock()
glog.V(1).Infoln("Starting informer factory")
for informerType, informer := range f.informers {
if !f.startedInformers[informerType] {
glog.V(2).Infof("Starting informer for %v", informerType)
go informer.Run(stopCh)
f.startedInformers[informerType] = true
}
}
}
// Pods returns a SharedIndexInformer that lists and watches all pods
func (f *sharedInformerFactory) Pods() PodInformer {
return &podInformer{sharedInformerFactory: f}
}
// Nodes returns a SharedIndexInformer that lists and watches all nodes
func (f *sharedInformerFactory) Nodes() NodeInformer {
return &nodeInformer{sharedInformerFactory: f}
}
// Namespaces returns a SharedIndexInformer that lists and watches all namespaces
func (f *sharedInformerFactory) Namespaces() NamespaceInformer {
return &namespaceInformer{sharedInformerFactory: f}
}
// InternalNamespaces returns a SharedIndexInformer that lists and watches all namespaces
func (f *sharedInformerFactory) InternalNamespaces() InternalNamespaceInformer {
return &internalNamespaceInformer{sharedInformerFactory: f}
}
// PersistentVolumeClaims returns a SharedIndexInformer that lists and watches all persistent volume claims
func (f *sharedInformerFactory) PersistentVolumeClaims() PVCInformer {
return &pvcInformer{sharedInformerFactory: f}
}
// PersistentVolumes returns a SharedIndexInformer that lists and watches all persistent volumes
func (f *sharedInformerFactory) PersistentVolumes() PVInformer {
return &pvInformer{sharedInformerFactory: f}
}
// ServiceAccounts returns a SharedIndexInformer that lists and watches all service accounts.
func (f *sharedInformerFactory) ServiceAccounts() ServiceAccountInformer {
return &serviceAccountInformer{sharedInformerFactory: f}
}
// DaemonSets returns a SharedIndexInformer that lists and watches all daemon sets.
func (f *sharedInformerFactory) DaemonSets() DaemonSetInformer {
return &daemonSetInformer{sharedInformerFactory: f}
}
func (f *sharedInformerFactory) Deployments() DeploymentInformer {
return &deploymentInformer{sharedInformerFactory: f}
}
func (f *sharedInformerFactory) ReplicaSets() ReplicaSetInformer {
return &replicaSetInformer{sharedInformerFactory: f}
}
func (f *sharedInformerFactory) ReplicationControllers() ReplicationControllerInformer {
return &replicationControllerInformer{sharedInformerFactory: f}
}
func (f *sharedInformerFactory) ClusterRoles() ClusterRoleInformer {
return &clusterRoleInformer{sharedInformerFactory: f}
}
func (f *sharedInformerFactory) ClusterRoleBindings() ClusterRoleBindingInformer {
return &clusterRoleBindingInformer{sharedInformerFactory: f}
}
func (f *sharedInformerFactory) Roles() RoleInformer {
return &roleInformer{sharedInformerFactory: f}
}
func (f *sharedInformerFactory) RoleBindings() RoleBindingInformer {
return &roleBindingInformer{sharedInformerFactory: f}
}
// LimitRanges returns a SharedIndexInformer that lists and watches all limit ranges.
func (f *sharedInformerFactory) LimitRanges() LimitRangeInformer {
return &limitRangeInformer{sharedInformerFactory: f}
}
// InternalLimitRanges returns a SharedIndexInformer that lists and watches all limit ranges.
func (f *sharedInformerFactory) InternalLimitRanges() InternalLimitRangeInformer {
return &internalLimitRangeInformer{sharedInformerFactory: f}
}
// StorageClasses returns a SharedIndexInformer that lists and watches all storage classes
func (f *sharedInformerFactory) StorageClasses() StorageClassInformer {
return &storageClassInformer{sharedInformerFactory: f}
}
// Jobs returns a SharedIndexInformer that lists and watches all storage jobs
func (f *sharedInformerFactory) Jobs() JobInformer {
return &jobInformer{sharedInformerFactory: f}
}

View File

@ -1,90 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 informers
import (
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/batch"
extensionsinternal "k8s.io/kubernetes/pkg/apis/extensions"
rbacinternal "k8s.io/kubernetes/pkg/apis/rbac"
)
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
// sharedInformers based on type
type GenericInformer interface {
Informer() cache.SharedIndexInformer
Lister() cache.GenericLister
}
// ForResource gives generic access to a shared informer of the matching type
// TODO extend this to unknown resources with a client pool
func (f *sharedInformerFactory) ForResource(resource schema.GroupResource) (GenericInformer, error) {
switch resource {
case api.Resource("pods"):
return &genericInformer{resource: resource, informer: f.Pods().Informer()}, nil
case api.Resource("limitranges"):
return &genericInformer{resource: resource, informer: f.LimitRanges().Informer()}, nil
case api.Resource("namespaces"):
return &genericInformer{resource: resource, informer: f.Namespaces().Informer()}, nil
case api.Resource("nodes"):
return &genericInformer{resource: resource, informer: f.Nodes().Informer()}, nil
case api.Resource("persistentvolumeclaims"):
return &genericInformer{resource: resource, informer: f.PersistentVolumeClaims().Informer()}, nil
case api.Resource("persistentvolumes"):
return &genericInformer{resource: resource, informer: f.PersistentVolumes().Informer()}, nil
case api.Resource("serviceaccounts"):
return &genericInformer{resource: resource, informer: f.ServiceAccounts().Informer()}, nil
case extensionsinternal.Resource("daemonsets"):
return &genericInformer{resource: resource, informer: f.DaemonSets().Informer()}, nil
case extensionsinternal.Resource("deployments"):
return &genericInformer{resource: resource, informer: f.Deployments().Informer()}, nil
case extensionsinternal.Resource("replicasets"):
return &genericInformer{resource: resource, informer: f.ReplicaSets().Informer()}, nil
case rbacinternal.Resource("clusterrolebindings"):
return &genericInformer{resource: resource, informer: f.ClusterRoleBindings().Informer()}, nil
case rbacinternal.Resource("clusterroles"):
return &genericInformer{resource: resource, informer: f.ClusterRoles().Informer()}, nil
case rbacinternal.Resource("rolebindings"):
return &genericInformer{resource: resource, informer: f.RoleBindings().Informer()}, nil
case rbacinternal.Resource("roles"):
return &genericInformer{resource: resource, informer: f.Roles().Informer()}, nil
case batch.Resource("jobs"):
return &genericInformer{resource: resource, informer: f.Jobs().Informer()}, nil
}
return nil, fmt.Errorf("no informer found for %v", resource)
}
type genericInformer struct {
informer cache.SharedIndexInformer
resource schema.GroupResource
}
func (f *genericInformer) Informer() cache.SharedIndexInformer {
return f.informer
}
func (f *genericInformer) Lister() cache.GenericLister {
return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource)
}

View File

@ -1,197 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 informers
import (
"reflect"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/client/legacylisters"
)
type ClusterRoleInformer interface {
Informer() cache.SharedIndexInformer
Lister() listers.ClusterRoleLister
}
type clusterRoleInformer struct {
*sharedInformerFactory
}
func (f *clusterRoleInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&rbac.ClusterRole{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return f.internalclient.Rbac().ClusterRoles().List(convertListOptionsOrDie(options))
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return f.internalclient.Rbac().ClusterRoles().Watch(convertListOptionsOrDie(options))
},
},
&rbac.ClusterRole{},
f.defaultResync,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
f.informers[informerType] = informer
return informer
}
func (f *clusterRoleInformer) Lister() listers.ClusterRoleLister {
return listers.NewClusterRoleLister(f.Informer().GetIndexer())
}
type ClusterRoleBindingInformer interface {
Informer() cache.SharedIndexInformer
Lister() listers.ClusterRoleBindingLister
}
type clusterRoleBindingInformer struct {
*sharedInformerFactory
}
func (f *clusterRoleBindingInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&rbac.ClusterRoleBinding{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return f.internalclient.Rbac().ClusterRoleBindings().List(convertListOptionsOrDie(options))
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return f.internalclient.Rbac().ClusterRoleBindings().Watch(convertListOptionsOrDie(options))
},
},
&rbac.ClusterRoleBinding{},
f.defaultResync,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
f.informers[informerType] = informer
return informer
}
func (f *clusterRoleBindingInformer) Lister() listers.ClusterRoleBindingLister {
return listers.NewClusterRoleBindingLister(f.Informer().GetIndexer())
}
type RoleInformer interface {
Informer() cache.SharedIndexInformer
Lister() listers.RoleLister
}
type roleInformer struct {
*sharedInformerFactory
}
func (f *roleInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&rbac.Role{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return f.internalclient.Rbac().Roles(metav1.NamespaceAll).List(convertListOptionsOrDie(options))
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return f.internalclient.Rbac().Roles(metav1.NamespaceAll).Watch(convertListOptionsOrDie(options))
},
},
&rbac.Role{},
f.defaultResync,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
f.informers[informerType] = informer
return informer
}
func (f *roleInformer) Lister() listers.RoleLister {
return listers.NewRoleLister(f.Informer().GetIndexer())
}
type RoleBindingInformer interface {
Informer() cache.SharedIndexInformer
Lister() listers.RoleBindingLister
}
type roleBindingInformer struct {
*sharedInformerFactory
}
func (f *roleBindingInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&rbac.RoleBinding{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return f.internalclient.Rbac().RoleBindings(metav1.NamespaceAll).List(convertListOptionsOrDie(options))
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return f.internalclient.Rbac().RoleBindings(metav1.NamespaceAll).Watch(convertListOptionsOrDie(options))
},
},
&rbac.RoleBinding{},
f.defaultResync,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
f.informers[informerType] = informer
return informer
}
func (f *roleBindingInformer) Lister() listers.RoleBindingLister {
return listers.NewRoleBindingLister(f.Informer().GetIndexer())
}
func convertListOptionsOrDie(in metav1.ListOptions) metav1.ListOptions {
out := metav1.ListOptions{}
if err := api.Scheme.Convert(&in, &out, nil); err != nil {
panic(err)
}
return out
}

View File

@ -1,71 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
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 informers
import (
"reflect"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/tools/cache"
storage "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
"k8s.io/kubernetes/pkg/client/legacylisters"
)
// StorageClassInformer is type of SharedIndexInformer which watches and lists all storage classes.
// Interface provides constructor for informer and lister for storage classes
type StorageClassInformer interface {
Informer() cache.SharedIndexInformer
Lister() listers.StorageClassLister
}
type storageClassInformer struct {
*sharedInformerFactory
}
func (f *storageClassInformer) Informer() cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()
informerType := reflect.TypeOf(&storage.StorageClass{})
informer, exists := f.informers[informerType]
if exists {
return informer
}
informer = cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return f.client.Storage().StorageClasses().List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return f.client.Storage().StorageClasses().Watch(options)
},
},
&storage.StorageClass{},
f.defaultResync,
cache.Indexers{},
)
f.informers[informerType] = informer
return informer
}
func (f *storageClassInformer) Lister() listers.StorageClassLister {
informer := f.Informer()
return listers.NewStorageClassLister(informer.GetIndexer())
}

View File

@ -62,7 +62,6 @@ go_test(
"//pkg/client/informers/informers_generated/externalversions:go_default_library", "//pkg/client/informers/informers_generated/externalversions:go_default_library",
"//pkg/client/informers/informers_generated/externalversions/apps/v1beta1:go_default_library", "//pkg/client/informers/informers_generated/externalversions/apps/v1beta1:go_default_library",
"//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library", "//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library",
"//pkg/client/legacylisters:go_default_library",
"//pkg/client/listers/apps/v1beta1:go_default_library", "//pkg/client/listers/apps/v1beta1:go_default_library",
"//pkg/client/listers/core/v1:go_default_library", "//pkg/client/listers/core/v1:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",

View File

@ -21,7 +21,6 @@ import (
"strings" "strings"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
errorutils "k8s.io/apimachinery/pkg/util/errors" errorutils "k8s.io/apimachinery/pkg/util/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/pkg/api" "k8s.io/client-go/pkg/api"
@ -56,8 +55,14 @@ type StatefulPodControlInterface interface {
UpdateStatefulSetReplicas(set *apps.StatefulSet, replicas int32) error UpdateStatefulSetReplicas(set *apps.StatefulSet, replicas int32) error
} }
func NewRealStatefulPodControl(client clientset.Interface, setLister appslisters.StatefulSetLister, podLister corelisters.PodLister, recorder record.EventRecorder) StatefulPodControlInterface { func NewRealStatefulPodControl(
return &realStatefulPodControl{client, setLister, podLister, recorder} client clientset.Interface,
setLister appslisters.StatefulSetLister,
podLister corelisters.PodLister,
pvcLister corelisters.PersistentVolumeClaimLister,
recorder record.EventRecorder,
) StatefulPodControlInterface {
return &realStatefulPodControl{client, setLister, podLister, pvcLister, recorder}
} }
// realStatefulPodControl implements StatefulPodControlInterface using a clientset.Interface to communicate with the // realStatefulPodControl implements StatefulPodControlInterface using a clientset.Interface to communicate with the
@ -66,6 +71,7 @@ type realStatefulPodControl struct {
client clientset.Interface client clientset.Interface
setLister appslisters.StatefulSetLister setLister appslisters.StatefulSetLister
podLister corelisters.PodLister podLister corelisters.PodLister
pvcLister corelisters.PersistentVolumeClaimLister
recorder record.EventRecorder recorder record.EventRecorder
} }
@ -209,18 +215,19 @@ func (spc *realStatefulPodControl) recordClaimEvent(verb string, set *apps.State
func (spc *realStatefulPodControl) createPersistentVolumeClaims(set *apps.StatefulSet, pod *v1.Pod) error { func (spc *realStatefulPodControl) createPersistentVolumeClaims(set *apps.StatefulSet, pod *v1.Pod) error {
var errs []error var errs []error
for _, claim := range getPersistentVolumeClaims(set, pod) { for _, claim := range getPersistentVolumeClaims(set, pod) {
_, err := spc.client.Core().PersistentVolumeClaims(claim.Namespace).Get(claim.Name, metav1.GetOptions{}) _, err := spc.pvcLister.PersistentVolumeClaims(claim.Namespace).Get(claim.Name)
if err != nil { switch {
if apierrors.IsNotFound(err) { case apierrors.IsNotFound(err):
_, err := spc.client.Core().PersistentVolumeClaims(claim.Namespace).Create(&claim) _, err := spc.client.Core().PersistentVolumeClaims(claim.Namespace).Create(&claim)
if err != nil { if err != nil {
errs = append(errs, fmt.Errorf("Failed to create PVC %s: %s", claim.Name, err)) errs = append(errs, fmt.Errorf("Failed to create PVC %s: %s", claim.Name, err))
} }
spc.recordClaimEvent("create", set, pod, &claim, err) if err == nil || !apierrors.IsAlreadyExists(err) {
} else {
errs = append(errs, fmt.Errorf("Failed to retrieve PVC %s: %s", claim.Name, err))
spc.recordClaimEvent("create", set, pod, &claim, err) spc.recordClaimEvent("create", set, pod, &claim, err)
} }
case err != nil:
errs = append(errs, fmt.Errorf("Failed to retrieve PVC %s: %s", claim.Name, err))
spc.recordClaimEvent("create", set, pod, &claim, err)
} }
// TODO: Check resource requirements and accessmodes, update if necessary // TODO: Check resource requirements and accessmodes, update if necessary
} }

View File

@ -40,7 +40,9 @@ func TestStatefulPodControlCreatesPods(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) pvcIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
pvcLister := corelisters.NewPersistentVolumeClaimLister(pvcIndexer)
control := NewRealStatefulPodControl(fakeClient, nil, nil, pvcLister, recorder)
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), action.GetResource().Resource) return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), action.GetResource().Resource)
}) })
@ -71,12 +73,14 @@ func TestStatefulPodControlCreatePodExists(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder)
pvcs := getPersistentVolumeClaims(set, pod) pvcs := getPersistentVolumeClaims(set, pod)
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { pvcIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
claim := pvcs[action.GetResource().GroupResource().Resource] for k := range pvcs {
return true, &claim, nil pvc := pvcs[k]
}) pvcIndexer.Add(&pvc)
}
pvcLister := corelisters.NewPersistentVolumeClaimLister(pvcIndexer)
control := NewRealStatefulPodControl(fakeClient, nil, nil, pvcLister, recorder)
fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
create := action.(core.CreateAction) create := action.(core.CreateAction)
return true, create.GetObject(), nil return true, create.GetObject(), nil
@ -101,10 +105,9 @@ func TestStatefulPodControlCreatePodPvcCreateFailure(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) pvcIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { pvcLister := corelisters.NewPersistentVolumeClaimLister(pvcIndexer)
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), action.GetResource().Resource) control := NewRealStatefulPodControl(fakeClient, nil, nil, pvcLister, recorder)
})
fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, apierrors.NewInternalError(errors.New("API server down")) return true, nil, apierrors.NewInternalError(errors.New("API server down"))
}) })
@ -126,15 +129,23 @@ func TestStatefulPodControlCreatePodPvcCreateFailure(t *testing.T) {
} }
} }
type fakeIndexer struct {
cache.Indexer
getError error
}
func (f *fakeIndexer) GetByKey(key string) (interface{}, bool, error) {
return nil, false, f.getError
}
func TestStatefulPodControlCreatePodPvcGetFailure(t *testing.T) { func TestStatefulPodControlCreatePodPvcGetFailure(t *testing.T) {
recorder := record.NewFakeRecorder(10) recorder := record.NewFakeRecorder(10)
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) pvcIndexer := &fakeIndexer{getError: errors.New("API server down")}
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { pvcLister := corelisters.NewPersistentVolumeClaimLister(pvcIndexer)
return true, nil, apierrors.NewInternalError(errors.New("API server down")) control := NewRealStatefulPodControl(fakeClient, nil, nil, pvcLister, recorder)
})
fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, apierrors.NewInternalError(errors.New("API server down")) return true, nil, apierrors.NewInternalError(errors.New("API server down"))
}) })
@ -161,10 +172,9 @@ func TestStatefulPodControlCreatePodFailed(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) pvcIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { pvcLister := corelisters.NewPersistentVolumeClaimLister(pvcIndexer)
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), action.GetResource().Resource) control := NewRealStatefulPodControl(fakeClient, nil, nil, pvcLister, recorder)
})
fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
create := action.(core.CreateAction) create := action.(core.CreateAction)
return true, create.GetObject(), nil return true, create.GetObject(), nil
@ -192,7 +202,7 @@ func TestStatefulPodControlNoOpUpdate(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) control := NewRealStatefulPodControl(fakeClient, nil, nil, nil, recorder)
fakeClient.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) {
t.Error("no-op update should not make any client invocation") t.Error("no-op update should not make any client invocation")
return true, nil, apierrors.NewInternalError(errors.New("If we are here we have a problem")) return true, nil, apierrors.NewInternalError(errors.New("If we are here we have a problem"))
@ -211,7 +221,7 @@ func TestStatefulPodControlUpdatesIdentity(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := fake.NewSimpleClientset(set, pod) fakeClient := fake.NewSimpleClientset(set, pod)
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) control := NewRealStatefulPodControl(fakeClient, nil, nil, nil, recorder)
var updated *v1.Pod var updated *v1.Pod
fakeClient.PrependReactor("update", "pods", func(action core.Action) (bool, runtime.Object, error) { fakeClient.PrependReactor("update", "pods", func(action core.Action) (bool, runtime.Object, error) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
@ -243,7 +253,7 @@ func TestStatefulPodControlUpdateIdentityFailure(t *testing.T) {
gooPod.Name = "goo-0" gooPod.Name = "goo-0"
indexer.Add(gooPod) indexer.Add(gooPod)
podLister := corelisters.NewPodLister(indexer) podLister := corelisters.NewPodLister(indexer)
control := NewRealStatefulPodControl(fakeClient, nil, podLister, recorder) control := NewRealStatefulPodControl(fakeClient, nil, podLister, nil, recorder)
fakeClient.AddReactor("update", "pods", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("update", "pods", func(action core.Action) (bool, runtime.Object, error) {
pod.Name = "goo-0" pod.Name = "goo-0"
return true, nil, apierrors.NewInternalError(errors.New("API server down")) return true, nil, apierrors.NewInternalError(errors.New("API server down"))
@ -268,7 +278,9 @@ func TestStatefulPodControlUpdatesPodStorage(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) pvcIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
pvcLister := corelisters.NewPersistentVolumeClaimLister(pvcIndexer)
control := NewRealStatefulPodControl(fakeClient, nil, nil, pvcLister, recorder)
pvcs := getPersistentVolumeClaims(set, pod) pvcs := getPersistentVolumeClaims(set, pod)
volumes := make([]v1.Volume, len(pod.Spec.Volumes)) volumes := make([]v1.Volume, len(pod.Spec.Volumes))
for i := range pod.Spec.Volumes { for i := range pod.Spec.Volumes {
@ -281,9 +293,6 @@ func TestStatefulPodControlUpdatesPodStorage(t *testing.T) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
return true, update.GetObject(), nil return true, update.GetObject(), nil
}) })
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), action.GetResource().Resource)
})
fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
return true, update.GetObject(), nil return true, update.GetObject(), nil
@ -316,7 +325,9 @@ func TestStatefulPodControlUpdatePodStorageFailure(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) pvcIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
pvcLister := corelisters.NewPersistentVolumeClaimLister(pvcIndexer)
control := NewRealStatefulPodControl(fakeClient, nil, nil, pvcLister, recorder)
pvcs := getPersistentVolumeClaims(set, pod) pvcs := getPersistentVolumeClaims(set, pod)
volumes := make([]v1.Volume, len(pod.Spec.Volumes)) volumes := make([]v1.Volume, len(pod.Spec.Volumes))
for i := range pod.Spec.Volumes { for i := range pod.Spec.Volumes {
@ -329,9 +340,6 @@ func TestStatefulPodControlUpdatePodStorageFailure(t *testing.T) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
return true, update.GetObject(), nil return true, update.GetObject(), nil
}) })
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, apierrors.NewNotFound(action.GetResource().GroupResource(), action.GetResource().Resource)
})
fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("create", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, apierrors.NewInternalError(errors.New("API server down")) return true, nil, apierrors.NewInternalError(errors.New("API server down"))
}) })
@ -359,7 +367,7 @@ func TestStatefulPodControlUpdatePodConflictSuccess(t *testing.T) {
gooPod.Name = "goo-0" gooPod.Name = "goo-0"
indexer.Add(gooPod) indexer.Add(gooPod)
podLister := corelisters.NewPodLister(indexer) podLister := corelisters.NewPodLister(indexer)
control := NewRealStatefulPodControl(fakeClient, nil, podLister, recorder) control := NewRealStatefulPodControl(fakeClient, nil, podLister, nil, recorder)
conflict := false conflict := false
fakeClient.AddReactor("update", "pods", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("update", "pods", func(action core.Action) (bool, runtime.Object, error) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
@ -395,7 +403,7 @@ func TestStatefulPodControlUpdatePodConflictFailure(t *testing.T) {
updatedPod.Annotations[podapi.PodHostnameAnnotation] = "wrong" updatedPod.Annotations[podapi.PodHostnameAnnotation] = "wrong"
indexer.Add(updatedPod) indexer.Add(updatedPod)
podLister := corelisters.NewPodLister(indexer) podLister := corelisters.NewPodLister(indexer)
control := NewRealStatefulPodControl(fakeClient, nil, podLister, recorder) control := NewRealStatefulPodControl(fakeClient, nil, podLister, nil, recorder)
fakeClient.AddReactor("update", "pods", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("update", "pods", func(action core.Action) (bool, runtime.Object, error) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), pod.Name, errors.New("conflict")) return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), pod.Name, errors.New("conflict"))
@ -418,7 +426,7 @@ func TestStatefulPodControlDeletesStatefulPod(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) control := NewRealStatefulPodControl(fakeClient, nil, nil, nil, recorder)
fakeClient.AddReactor("delete", "pods", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("delete", "pods", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, nil return true, nil, nil
}) })
@ -438,7 +446,7 @@ func TestStatefulPodControlDeleteFailure(t *testing.T) {
set := newStatefulSet(3) set := newStatefulSet(3)
pod := newStatefulSetPod(set, 0) pod := newStatefulSetPod(set, 0)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) control := NewRealStatefulPodControl(fakeClient, nil, nil, nil, recorder)
fakeClient.AddReactor("delete", "pods", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("delete", "pods", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, apierrors.NewInternalError(errors.New("API server down")) return true, nil, apierrors.NewInternalError(errors.New("API server down"))
}) })
@ -457,7 +465,7 @@ func TestStatefulPodControlUpdatesSetStatus(t *testing.T) {
recorder := record.NewFakeRecorder(10) recorder := record.NewFakeRecorder(10)
set := newStatefulSet(3) set := newStatefulSet(3)
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
control := NewRealStatefulPodControl(fakeClient, nil, nil, recorder) control := NewRealStatefulPodControl(fakeClient, nil, nil, nil, recorder)
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
return true, update.GetObject(), nil return true, update.GetObject(), nil
@ -481,7 +489,7 @@ func TestStatefulPodControlUpdateReplicasFailure(t *testing.T) {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
indexer.Add(set) indexer.Add(set)
setLister := appslisters.NewStatefulSetLister(indexer) setLister := appslisters.NewStatefulSetLister(indexer)
control := NewRealStatefulPodControl(fakeClient, setLister, nil, recorder) control := NewRealStatefulPodControl(fakeClient, setLister, nil, nil, recorder)
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
return true, nil, apierrors.NewInternalError(errors.New("API server down")) return true, nil, apierrors.NewInternalError(errors.New("API server down"))
}) })
@ -502,7 +510,7 @@ func TestStatefulPodControlUpdateReplicasConflict(t *testing.T) {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
indexer.Add(set) indexer.Add(set)
setLister := appslisters.NewStatefulSetLister(indexer) setLister := appslisters.NewStatefulSetLister(indexer)
control := NewRealStatefulPodControl(fakeClient, setLister, nil, recorder) control := NewRealStatefulPodControl(fakeClient, setLister, nil, nil, recorder)
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
if !conflict { if !conflict {
@ -531,7 +539,7 @@ func TestStatefulPodControlUpdateReplicasConflictFailure(t *testing.T) {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
indexer.Add(set) indexer.Add(set)
setLister := appslisters.NewStatefulSetLister(indexer) setLister := appslisters.NewStatefulSetLister(indexer)
control := NewRealStatefulPodControl(fakeClient, setLister, nil, recorder) control := NewRealStatefulPodControl(fakeClient, setLister, nil, nil, recorder)
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
update := action.(core.UpdateAction) update := action.(core.UpdateAction)
return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), set.Name, errors.New("Object already exists")) return true, update.GetObject(), apierrors.NewConflict(action.GetResource().GroupResource(), set.Name, errors.New("Object already exists"))

View File

@ -72,6 +72,7 @@ type StatefulSetController struct {
func NewStatefulSetController( func NewStatefulSetController(
podInformer coreinformers.PodInformer, podInformer coreinformers.PodInformer,
setInformer appsinformers.StatefulSetInformer, setInformer appsinformers.StatefulSetInformer,
pvcInformer coreinformers.PersistentVolumeClaimInformer,
kubeClient clientset.Interface, kubeClient clientset.Interface,
) *StatefulSetController { ) *StatefulSetController {
eventBroadcaster := record.NewBroadcaster() eventBroadcaster := record.NewBroadcaster()
@ -81,8 +82,16 @@ func NewStatefulSetController(
ssc := &StatefulSetController{ ssc := &StatefulSetController{
kubeClient: kubeClient, kubeClient: kubeClient,
control: NewDefaultStatefulSetControl(NewRealStatefulPodControl(kubeClient, setInformer.Lister(), podInformer.Lister(), recorder)), control: NewDefaultStatefulSetControl(
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "statefulset"), NewRealStatefulPodControl(
kubeClient,
setInformer.Lister(),
podInformer.Lister(),
pvcInformer.Lister(),
recorder,
),
),
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "statefulset"),
} }
podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{

View File

@ -34,7 +34,6 @@ import (
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
appsinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions/apps/v1beta1" appsinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions/apps/v1beta1"
coreinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions/core/v1" coreinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions/core/v1"
listers "k8s.io/kubernetes/pkg/client/legacylisters"
appslisters "k8s.io/kubernetes/pkg/client/listers/apps/v1beta1" appslisters "k8s.io/kubernetes/pkg/client/listers/apps/v1beta1"
corelisters "k8s.io/kubernetes/pkg/client/listers/core/v1" corelisters "k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
@ -560,7 +559,7 @@ func (rt *requestTracker) reset() {
type fakeStatefulPodControl struct { type fakeStatefulPodControl struct {
podsLister corelisters.PodLister podsLister corelisters.PodLister
claimsLister listers.StoreToPersistentVolumeClaimLister claimsLister corelisters.PersistentVolumeClaimLister
setsLister appslisters.StatefulSetLister setsLister appslisters.StatefulSetLister
podsIndexer cache.Indexer podsIndexer cache.Indexer
claimsIndexer cache.Indexer claimsIndexer cache.Indexer
@ -572,11 +571,10 @@ type fakeStatefulPodControl struct {
} }
func newFakeStatefulPodControl(podInformer coreinformers.PodInformer, setInformer appsinformers.StatefulSetInformer) *fakeStatefulPodControl { func newFakeStatefulPodControl(podInformer coreinformers.PodInformer, setInformer appsinformers.StatefulSetInformer) *fakeStatefulPodControl {
claimsIndexer := cache.NewIndexer(controller.KeyFunc, claimsIndexer := cache.NewIndexer(controller.KeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
return &fakeStatefulPodControl{ return &fakeStatefulPodControl{
podInformer.Lister(), podInformer.Lister(),
listers.StoreToPersistentVolumeClaimLister{Indexer: claimsIndexer}, corelisters.NewPersistentVolumeClaimLister(claimsIndexer),
setInformer.Lister(), setInformer.Lister(),
podInformer.Informer().GetIndexer(), podInformer.Informer().GetIndexer(),
claimsIndexer, claimsIndexer,

View File

@ -352,6 +352,7 @@ func newFakeStatefulSetController() (*StatefulSetController, *fakeStatefulPodCon
ssc := NewStatefulSetController( ssc := NewStatefulSetController(
informerFactory.Core().V1().Pods(), informerFactory.Core().V1().Pods(),
informerFactory.Apps().V1beta1().StatefulSets(), informerFactory.Apps().V1beta1().StatefulSets(),
informerFactory.Core().V1().PersistentVolumeClaims(),
client, client,
) )
ssc.podListerSynced = alwaysReady ssc.podListerSynced = alwaysReady