Unverified Commit 6fc60428 authored by k8s-ci-robot's avatar k8s-ci-robot Committed by GitHub

Merge pull request #71020 from saad-ali/updateCSI10

Bump CSI Spec to 1.0.0 and gRPC to 1.13.0
parents 1cdc918e 503f654d
...@@ -811,9 +811,9 @@ ...@@ -811,9 +811,9 @@
"Rev": "20e2ce2cf8852dc78bd42b76698dcd8dcd77b7b1" "Rev": "20e2ce2cf8852dc78bd42b76698dcd8dcd77b7b1"
}, },
{ {
"ImportPath": "github.com/container-storage-interface/spec/lib/go/csi/v0", "ImportPath": "github.com/container-storage-interface/spec/lib/go/csi",
"Comment": "v0.3.0", "Comment": "v1.0.0",
"Rev": "2178fdeea87f1150a17a63252eee28d4d8141f72" "Rev": "ed0bb0e1557548aa028307f48728767cfe8f6345"
}, },
{ {
"ImportPath": "github.com/containerd/console", "ImportPath": "github.com/containerd/console",
...@@ -1808,6 +1808,11 @@ ...@@ -1808,6 +1808,11 @@
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265" "Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
}, },
{ {
"ImportPath": "github.com/golang/protobuf/protoc-gen-go/descriptor",
"Comment": "v1.1.0",
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
},
{
"ImportPath": "github.com/golang/protobuf/ptypes", "ImportPath": "github.com/golang/protobuf/ptypes",
"Comment": "v1.1.0", "Comment": "v1.1.0",
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265" "Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
...@@ -3747,98 +3752,143 @@ ...@@ -3747,98 +3752,143 @@
}, },
{ {
"ImportPath": "google.golang.org/grpc", "ImportPath": "google.golang.org/grpc",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/balancer", "ImportPath": "google.golang.org/grpc/balancer",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/base",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/roundrobin",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/codes", "ImportPath": "google.golang.org/grpc/codes",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/connectivity", "ImportPath": "google.golang.org/grpc/connectivity",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/credentials", "ImportPath": "google.golang.org/grpc/credentials",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/encoding",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/encoding/proto",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", "ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclog", "ImportPath": "google.golang.org/grpc/grpclog",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/health", "ImportPath": "google.golang.org/grpc/health",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/health/grpc_health_v1", "ImportPath": "google.golang.org/grpc/health/grpc_health_v1",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/internal", "ImportPath": "google.golang.org/grpc/internal",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/backoff",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/channelz",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/grpcrand",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/keepalive", "ImportPath": "google.golang.org/grpc/keepalive",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/metadata", "ImportPath": "google.golang.org/grpc/metadata",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/naming", "ImportPath": "google.golang.org/grpc/naming",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/peer", "ImportPath": "google.golang.org/grpc/peer",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/resolver", "ImportPath": "google.golang.org/grpc/resolver",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/dns",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/passthrough",
"Comment": "v1.13.0",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/stats", "ImportPath": "google.golang.org/grpc/stats",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/status", "ImportPath": "google.golang.org/grpc/status",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/tap", "ImportPath": "google.golang.org/grpc/tap",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/transport", "ImportPath": "google.golang.org/grpc/transport",
"Comment": "v1.7.5", "Comment": "v1.13.0",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "gopkg.in/gcfg.v1", "ImportPath": "gopkg.in/gcfg.v1",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -30,7 +30,7 @@ go_library( ...@@ -30,7 +30,7 @@ go_library(
"//staging/src/k8s.io/csi-api/pkg/client/informers/externalversions:go_default_library", "//staging/src/k8s.io/csi-api/pkg/client/informers/externalversions:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/client/informers/externalversions/csi/v1alpha1:go_default_library", "//staging/src/k8s.io/csi-api/pkg/client/informers/externalversions/csi/v1alpha1:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/client/listers/csi/v1alpha1:go_default_library", "//staging/src/k8s.io/csi-api/pkg/client/listers/csi/v1alpha1:go_default_library",
"//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library",
"//vendor/google.golang.org/grpc:go_default_library", "//vendor/google.golang.org/grpc:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
...@@ -69,7 +69,7 @@ go_test( ...@@ -69,7 +69,7 @@ go_test(
"//staging/src/k8s.io/client-go/util/testing:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned/fake:go_default_library", "//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned/fake:go_default_library",
"//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
) )
......
...@@ -29,7 +29,7 @@ import ( ...@@ -29,7 +29,7 @@ import (
"k8s.io/klog" "k8s.io/klog"
csipb "github.com/container-storage-interface/spec/lib/go/csi/v0" csipb "github.com/container-storage-interface/spec/lib/go/csi"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1beta1" storage "k8s.io/api/storage/v1beta1"
apierrs "k8s.io/apimachinery/pkg/api/errors" apierrs "k8s.io/apimachinery/pkg/api/errors"
......
...@@ -24,7 +24,7 @@ import ( ...@@ -24,7 +24,7 @@ import (
"net" "net"
"time" "time"
csipb "github.com/container-storage-interface/spec/lib/go/csi/v0" csipb "github.com/container-storage-interface/spec/lib/go/csi"
"google.golang.org/grpc" "google.golang.org/grpc"
api "k8s.io/api/core/v1" api "k8s.io/api/core/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
...@@ -46,8 +46,8 @@ type csiClient interface { ...@@ -46,8 +46,8 @@ type csiClient interface {
targetPath string, targetPath string,
accessMode api.PersistentVolumeAccessMode, accessMode api.PersistentVolumeAccessMode,
volumeInfo map[string]string, volumeInfo map[string]string,
volumeAttribs map[string]string, volumeContext map[string]string,
nodePublishSecrets map[string]string, secrets map[string]string,
fsType string, fsType string,
mountOptions []string, mountOptions []string,
) error ) error
...@@ -62,8 +62,8 @@ type csiClient interface { ...@@ -62,8 +62,8 @@ type csiClient interface {
stagingTargetPath string, stagingTargetPath string,
fsType string, fsType string,
accessMode api.PersistentVolumeAccessMode, accessMode api.PersistentVolumeAccessMode,
nodeStageSecrets map[string]string, secrets map[string]string,
volumeAttribs map[string]string, volumeContext map[string]string,
) error ) error
NodeUnstageVolume(ctx context.Context, volID, stagingTargetPath string) error NodeUnstageVolume(ctx context.Context, volID, stagingTargetPath string) error
NodeGetCapabilities(ctx context.Context) ([]*csipb.NodeServiceCapability, error) NodeGetCapabilities(ctx context.Context) ([]*csipb.NodeServiceCapability, error)
...@@ -136,8 +136,8 @@ func (c *csiDriverClient) NodePublishVolume( ...@@ -136,8 +136,8 @@ func (c *csiDriverClient) NodePublishVolume(
targetPath string, targetPath string,
accessMode api.PersistentVolumeAccessMode, accessMode api.PersistentVolumeAccessMode,
volumeInfo map[string]string, volumeInfo map[string]string,
volumeAttribs map[string]string, volumeContext map[string]string,
nodePublishSecrets map[string]string, secrets map[string]string,
fsType string, fsType string,
mountOptions []string, mountOptions []string,
) error { ) error {
...@@ -156,12 +156,12 @@ func (c *csiDriverClient) NodePublishVolume( ...@@ -156,12 +156,12 @@ func (c *csiDriverClient) NodePublishVolume(
defer closer.Close() defer closer.Close()
req := &csipb.NodePublishVolumeRequest{ req := &csipb.NodePublishVolumeRequest{
VolumeId: volID, VolumeId: volID,
TargetPath: targetPath, TargetPath: targetPath,
Readonly: readOnly, Readonly: readOnly,
PublishInfo: volumeInfo, PublishContext: volumeInfo,
VolumeAttributes: volumeAttribs, VolumeContext: volumeContext,
NodePublishSecrets: nodePublishSecrets, Secrets: secrets,
VolumeCapability: &csipb.VolumeCapability{ VolumeCapability: &csipb.VolumeCapability{
AccessMode: &csipb.VolumeCapability_AccessMode{ AccessMode: &csipb.VolumeCapability_AccessMode{
Mode: asCSIAccessMode(accessMode), Mode: asCSIAccessMode(accessMode),
...@@ -215,12 +215,12 @@ func (c *csiDriverClient) NodeUnpublishVolume(ctx context.Context, volID string, ...@@ -215,12 +215,12 @@ func (c *csiDriverClient) NodeUnpublishVolume(ctx context.Context, volID string,
func (c *csiDriverClient) NodeStageVolume(ctx context.Context, func (c *csiDriverClient) NodeStageVolume(ctx context.Context,
volID string, volID string,
publishInfo map[string]string, publishContext map[string]string,
stagingTargetPath string, stagingTargetPath string,
fsType string, fsType string,
accessMode api.PersistentVolumeAccessMode, accessMode api.PersistentVolumeAccessMode,
nodeStageSecrets map[string]string, secrets map[string]string,
volumeAttribs map[string]string, volumeContext map[string]string,
) error { ) error {
klog.V(4).Info(log("calling NodeStageVolume rpc [volid=%s,staging_target_path=%s]", volID, stagingTargetPath)) klog.V(4).Info(log("calling NodeStageVolume rpc [volid=%s,staging_target_path=%s]", volID, stagingTargetPath))
if volID == "" { if volID == "" {
...@@ -238,15 +238,15 @@ func (c *csiDriverClient) NodeStageVolume(ctx context.Context, ...@@ -238,15 +238,15 @@ func (c *csiDriverClient) NodeStageVolume(ctx context.Context,
req := &csipb.NodeStageVolumeRequest{ req := &csipb.NodeStageVolumeRequest{
VolumeId: volID, VolumeId: volID,
PublishInfo: publishInfo, PublishContext: publishContext,
StagingTargetPath: stagingTargetPath, StagingTargetPath: stagingTargetPath,
VolumeCapability: &csipb.VolumeCapability{ VolumeCapability: &csipb.VolumeCapability{
AccessMode: &csipb.VolumeCapability_AccessMode{ AccessMode: &csipb.VolumeCapability_AccessMode{
Mode: asCSIAccessMode(accessMode), Mode: asCSIAccessMode(accessMode),
}, },
}, },
NodeStageSecrets: nodeStageSecrets, Secrets: secrets,
VolumeAttributes: volumeAttribs, VolumeContext: volumeContext,
} }
if fsType == fsTypeBlockName { if fsType == fsTypeBlockName {
......
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
"reflect" "reflect"
"testing" "testing"
csipb "github.com/container-storage-interface/spec/lib/go/csi/v0" csipb "github.com/container-storage-interface/spec/lib/go/csi"
api "k8s.io/api/core/v1" api "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/volume/csi/fake" "k8s.io/kubernetes/pkg/volume/csi/fake"
) )
...@@ -57,19 +57,19 @@ func (c *fakeCsiDriverClient) NodePublishVolume( ...@@ -57,19 +57,19 @@ func (c *fakeCsiDriverClient) NodePublishVolume(
targetPath string, targetPath string,
accessMode api.PersistentVolumeAccessMode, accessMode api.PersistentVolumeAccessMode,
volumeInfo map[string]string, volumeInfo map[string]string,
volumeAttribs map[string]string, volumeContext map[string]string,
nodePublishSecrets map[string]string, secrets map[string]string,
fsType string, fsType string,
mountOptions []string, mountOptions []string,
) error { ) error {
c.t.Log("calling fake.NodePublishVolume...") c.t.Log("calling fake.NodePublishVolume...")
req := &csipb.NodePublishVolumeRequest{ req := &csipb.NodePublishVolumeRequest{
VolumeId: volID, VolumeId: volID,
TargetPath: targetPath, TargetPath: targetPath,
Readonly: readOnly, Readonly: readOnly,
PublishInfo: volumeInfo, PublishContext: volumeInfo,
VolumeAttributes: volumeAttribs, VolumeContext: volumeContext,
NodePublishSecrets: nodePublishSecrets, Secrets: secrets,
VolumeCapability: &csipb.VolumeCapability{ VolumeCapability: &csipb.VolumeCapability{
AccessMode: &csipb.VolumeCapability_AccessMode{ AccessMode: &csipb.VolumeCapability_AccessMode{
Mode: asCSIAccessMode(accessMode), Mode: asCSIAccessMode(accessMode),
...@@ -100,17 +100,17 @@ func (c *fakeCsiDriverClient) NodeUnpublishVolume(ctx context.Context, volID str ...@@ -100,17 +100,17 @@ func (c *fakeCsiDriverClient) NodeUnpublishVolume(ctx context.Context, volID str
func (c *fakeCsiDriverClient) NodeStageVolume(ctx context.Context, func (c *fakeCsiDriverClient) NodeStageVolume(ctx context.Context,
volID string, volID string,
publishInfo map[string]string, publishContext map[string]string,
stagingTargetPath string, stagingTargetPath string,
fsType string, fsType string,
accessMode api.PersistentVolumeAccessMode, accessMode api.PersistentVolumeAccessMode,
nodeStageSecrets map[string]string, secrets map[string]string,
volumeAttribs map[string]string, volumeContext map[string]string,
) error { ) error {
c.t.Log("calling fake.NodeStageVolume...") c.t.Log("calling fake.NodeStageVolume...")
req := &csipb.NodeStageVolumeRequest{ req := &csipb.NodeStageVolumeRequest{
VolumeId: volID, VolumeId: volID,
PublishInfo: publishInfo, PublishContext: publishContext,
StagingTargetPath: stagingTargetPath, StagingTargetPath: stagingTargetPath,
VolumeCapability: &csipb.VolumeCapability{ VolumeCapability: &csipb.VolumeCapability{
AccessMode: &csipb.VolumeCapability_AccessMode{ AccessMode: &csipb.VolumeCapability_AccessMode{
...@@ -122,8 +122,8 @@ func (c *fakeCsiDriverClient) NodeStageVolume(ctx context.Context, ...@@ -122,8 +122,8 @@ func (c *fakeCsiDriverClient) NodeStageVolume(ctx context.Context,
}, },
}, },
}, },
NodeStageSecrets: nodeStageSecrets, Secrets: secrets,
VolumeAttributes: volumeAttribs, VolumeContext: volumeContext,
} }
_, err := c.nodeClient.NodeStageVolume(ctx, req) _, err := c.nodeClient.NodeStageVolume(ctx, req)
...@@ -321,7 +321,7 @@ func TestClientNodeStageVolume(t *testing.T) { ...@@ -321,7 +321,7 @@ func TestClientNodeStageVolume(t *testing.T) {
volID string volID string
stagingTargetPath string stagingTargetPath string
fsType string fsType string
secret map[string]string secrets map[string]string
mustFail bool mustFail bool
err error err error
}{ }{
...@@ -351,7 +351,7 @@ func TestClientNodeStageVolume(t *testing.T) { ...@@ -351,7 +351,7 @@ func TestClientNodeStageVolume(t *testing.T) {
tc.stagingTargetPath, tc.stagingTargetPath,
tc.fsType, tc.fsType,
api.ReadWriteOnce, api.ReadWriteOnce,
tc.secret, tc.secrets,
map[string]string{"attr0": "val0"}, map[string]string{"attr0": "val0"},
) )
checkErr(t, tc.mustFail, err) checkErr(t, tc.mustFail, err)
......
...@@ -98,47 +98,46 @@ func TestMounterGetPath(t *testing.T) { ...@@ -98,47 +98,46 @@ func TestMounterGetPath(t *testing.T) {
func MounterSetUpTests(t *testing.T, podInfoEnabled bool) { func MounterSetUpTests(t *testing.T, podInfoEnabled bool) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIDriverRegistry, podInfoEnabled)() defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIDriverRegistry, podInfoEnabled)()
tests := []struct { tests := []struct {
name string name string
driver string driver string
attributes map[string]string volumeContext map[string]string
expectedVolumeContext map[string]string
expectedAttributes map[string]string
}{ }{
{ {
name: "no pod info", name: "no pod info",
driver: "no-info", driver: "no-info",
attributes: nil, volumeContext: nil,
expectedAttributes: nil, expectedVolumeContext: nil,
}, },
{ {
name: "no CSIDriver -> no pod info", name: "no CSIDriver -> no pod info",
driver: "unknown-driver", driver: "unknown-driver",
attributes: nil, volumeContext: nil,
expectedAttributes: nil, expectedVolumeContext: nil,
}, },
{ {
name: "CSIDriver with PodInfoRequiredOnMount=nil -> no pod info", name: "CSIDriver with PodInfoRequiredOnMount=nil -> no pod info",
driver: "nil", driver: "nil",
attributes: nil, volumeContext: nil,
expectedAttributes: nil, expectedVolumeContext: nil,
}, },
{ {
name: "no pod info -> keep existing attributes", name: "no pod info -> keep existing volumeContext",
driver: "no-info", driver: "no-info",
attributes: map[string]string{"foo": "bar"}, volumeContext: map[string]string{"foo": "bar"},
expectedAttributes: map[string]string{"foo": "bar"}, expectedVolumeContext: map[string]string{"foo": "bar"},
}, },
{ {
name: "add pod info", name: "add pod info",
driver: "info", driver: "info",
attributes: nil, volumeContext: nil,
expectedAttributes: map[string]string{"csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns"}, expectedVolumeContext: map[string]string{"csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns"},
}, },
{ {
name: "add pod info -> keep existing attributes", name: "add pod info -> keep existing volumeContext",
driver: "info", driver: "info",
attributes: map[string]string{"foo": "bar"}, volumeContext: map[string]string{"foo": "bar"},
expectedAttributes: map[string]string{"foo": "bar", "csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns"}, expectedVolumeContext: map[string]string{"foo": "bar", "csi.storage.k8s.io/pod.uid": "test-pod", "csi.storage.k8s.io/serviceAccount.name": "test-service-account", "csi.storage.k8s.io/pod.name": "test-pod", "csi.storage.k8s.io/pod.namespace": "test-ns"},
}, },
} }
...@@ -163,7 +162,7 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) { ...@@ -163,7 +162,7 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) {
} }
pv := makeTestPV("test-pv", 10, test.driver, testVol) pv := makeTestPV("test-pv", 10, test.driver, testVol)
pv.Spec.CSI.VolumeAttributes = test.attributes pv.Spec.CSI.VolumeAttributes = test.volumeContext
pv.Spec.MountOptions = []string{"foo=bar", "baz=qux"} pv.Spec.MountOptions = []string{"foo=bar", "baz=qux"}
pvName := pv.GetName() pvName := pv.GetName()
...@@ -245,13 +244,13 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) { ...@@ -245,13 +244,13 @@ func MounterSetUpTests(t *testing.T, podInfoEnabled bool) {
t.Errorf("csi server expected mount options %v, got %v", pv.Spec.MountOptions, vol.MountFlags) t.Errorf("csi server expected mount options %v, got %v", pv.Spec.MountOptions, vol.MountFlags)
} }
if podInfoEnabled { if podInfoEnabled {
if !reflect.DeepEqual(vol.Attributes, test.expectedAttributes) { if !reflect.DeepEqual(vol.VolumeContext, test.expectedVolumeContext) {
t.Errorf("csi server expected attributes %+v, got %+v", test.expectedAttributes, vol.Attributes) t.Errorf("csi server expected volumeContext %+v, got %+v", test.expectedVolumeContext, vol.VolumeContext)
} }
} else { } else {
// CSIPodInfo feature is disabled, we expect no modifications to attributes. // CSIPodInfo feature is disabled, we expect no modifications to volumeContext.
if !reflect.DeepEqual(vol.Attributes, test.attributes) { if !reflect.DeepEqual(vol.VolumeContext, test.volumeContext) {
t.Errorf("csi server expected attributes %+v, got %+v", test.attributes, vol.Attributes) t.Errorf("csi server expected volumeContext %+v, got %+v", test.volumeContext, vol.VolumeContext)
} }
} }
}) })
......
...@@ -9,7 +9,7 @@ go_library( ...@@ -9,7 +9,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/volume/csi/fake", importpath = "k8s.io/kubernetes/pkg/volume/csi/fake",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library",
"//vendor/google.golang.org/grpc:go_default_library", "//vendor/google.golang.org/grpc:go_default_library",
], ],
) )
......
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
csipb "github.com/container-storage-interface/spec/lib/go/csi/v0" csipb "github.com/container-storage-interface/spec/lib/go/csi"
) )
// IdentityClient is a CSI identity client used for testing // IdentityClient is a CSI identity client used for testing
...@@ -57,9 +57,9 @@ func (f *IdentityClient) Probe(ctx context.Context, in *csipb.ProbeRequest, opts ...@@ -57,9 +57,9 @@ func (f *IdentityClient) Probe(ctx context.Context, in *csipb.ProbeRequest, opts
} }
type CSIVolume struct { type CSIVolume struct {
Attributes map[string]string VolumeContext map[string]string
Path string Path string
MountFlags []string MountFlags []string
} }
// NodeClient returns CSI node client // NodeClient returns CSI node client
...@@ -99,10 +99,10 @@ func (f *NodeClient) GetNodeStagedVolumes() map[string]CSIVolume { ...@@ -99,10 +99,10 @@ func (f *NodeClient) GetNodeStagedVolumes() map[string]CSIVolume {
return f.nodeStagedVolumes return f.nodeStagedVolumes
} }
func (f *NodeClient) AddNodeStagedVolume(volID, deviceMountPath string, attributes map[string]string) { func (f *NodeClient) AddNodeStagedVolume(volID, deviceMountPath string, volumeContext map[string]string) {
f.nodeStagedVolumes[volID] = CSIVolume{ f.nodeStagedVolumes[volID] = CSIVolume{
Path: deviceMountPath, Path: deviceMountPath,
Attributes: attributes, VolumeContext: volumeContext,
} }
} }
...@@ -125,9 +125,9 @@ func (f *NodeClient) NodePublishVolume(ctx context.Context, req *csipb.NodePubli ...@@ -125,9 +125,9 @@ func (f *NodeClient) NodePublishVolume(ctx context.Context, req *csipb.NodePubli
return nil, errors.New("invalid fstype") return nil, errors.New("invalid fstype")
} }
f.nodePublishedVolumes[req.GetVolumeId()] = CSIVolume{ f.nodePublishedVolumes[req.GetVolumeId()] = CSIVolume{
Path: req.GetTargetPath(), Path: req.GetTargetPath(),
Attributes: req.GetVolumeAttributes(), VolumeContext: req.GetVolumeContext(),
MountFlags: req.GetVolumeCapability().GetMount().MountFlags, MountFlags: req.GetVolumeCapability().GetMount().MountFlags,
} }
return &csipb.NodePublishVolumeResponse{}, nil return &csipb.NodePublishVolumeResponse{}, nil
} }
...@@ -172,8 +172,8 @@ func (f *NodeClient) NodeStageVolume(ctx context.Context, req *csipb.NodeStageVo ...@@ -172,8 +172,8 @@ func (f *NodeClient) NodeStageVolume(ctx context.Context, req *csipb.NodeStageVo
} }
f.nodeStagedVolumes[req.GetVolumeId()] = CSIVolume{ f.nodeStagedVolumes[req.GetVolumeId()] = CSIVolume{
Path: req.GetStagingTargetPath(), Path: req.GetStagingTargetPath(),
Attributes: req.GetVolumeAttributes(), VolumeContext: req.GetVolumeContext(),
} }
return &csipb.NodeStageVolumeResponse{}, nil return &csipb.NodeStageVolumeResponse{}, nil
} }
...@@ -195,11 +195,6 @@ func (f *NodeClient) NodeUnstageVolume(ctx context.Context, req *csipb.NodeUnsta ...@@ -195,11 +195,6 @@ func (f *NodeClient) NodeUnstageVolume(ctx context.Context, req *csipb.NodeUnsta
return &csipb.NodeUnstageVolumeResponse{}, nil return &csipb.NodeUnstageVolumeResponse{}, nil
} }
// NodeGetId implements method
func (f *NodeClient) NodeGetId(ctx context.Context, in *csipb.NodeGetIdRequest, opts ...grpc.CallOption) (*csipb.NodeGetIdResponse, error) {
return nil, nil
}
// NodeGetId implements csi method // NodeGetId implements csi method
func (f *NodeClient) NodeGetInfo(ctx context.Context, in *csipb.NodeGetInfoRequest, opts ...grpc.CallOption) (*csipb.NodeGetInfoResponse, error) { func (f *NodeClient) NodeGetInfo(ctx context.Context, in *csipb.NodeGetInfoRequest, opts ...grpc.CallOption) (*csipb.NodeGetInfoResponse, error) {
if f.nextErr != nil { if f.nextErr != nil {
...@@ -227,6 +222,11 @@ func (f *NodeClient) NodeGetCapabilities(ctx context.Context, in *csipb.NodeGetC ...@@ -227,6 +222,11 @@ func (f *NodeClient) NodeGetCapabilities(ctx context.Context, in *csipb.NodeGetC
return nil, nil return nil, nil
} }
// NodeGetVolumeStats implements csi method
func (f *NodeClient) NodeGetVolumeStats(ctx context.Context, in *csipb.NodeGetVolumeStatsRequest, opts ...grpc.CallOption) (*csipb.NodeGetVolumeStatsResponse, error) {
return nil, nil
}
// ControllerClient represents a CSI Controller client // ControllerClient represents a CSI Controller client
type ControllerClient struct { type ControllerClient struct {
nextCapabilities []*csipb.ControllerServiceCapability nextCapabilities []*csipb.ControllerServiceCapability
......
...@@ -19,7 +19,7 @@ go_library( ...@@ -19,7 +19,7 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/util/retry:go_default_library", "//staging/src/k8s.io/client-go/util/retry:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library",
"//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
) )
...@@ -61,7 +61,7 @@ go_test( ...@@ -61,7 +61,7 @@ go_test(
"//staging/src/k8s.io/client-go/util/testing:go_default_library", "//staging/src/k8s.io/client-go/util/testing:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library",
"//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned/fake:go_default_library", "//staging/src/k8s.io/csi-api/pkg/client/clientset/versioned/fake:go_default_library",
"//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:go_default_library", "//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
], ],
) )
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
"fmt" "fmt"
"strings" "strings"
csipb "github.com/container-storage-interface/spec/lib/go/csi/v0" csipb "github.com/container-storage-interface/spec/lib/go/csi"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
......
...@@ -21,7 +21,7 @@ import ( ...@@ -21,7 +21,7 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/container-storage-interface/spec/lib/go/csi/v0" "github.com/container-storage-interface/spec/lib/go/csi"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
......
...@@ -820,79 +820,111 @@ ...@@ -820,79 +820,111 @@
}, },
{ {
"ImportPath": "google.golang.org/grpc", "ImportPath": "google.golang.org/grpc",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/balancer", "ImportPath": "google.golang.org/grpc/balancer",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/base",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/roundrobin",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/codes", "ImportPath": "google.golang.org/grpc/codes",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/connectivity", "ImportPath": "google.golang.org/grpc/connectivity",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/credentials", "ImportPath": "google.golang.org/grpc/credentials",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", "ImportPath": "google.golang.org/grpc/encoding",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/encoding/proto",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclog", "ImportPath": "google.golang.org/grpc/grpclog",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/health", "ImportPath": "google.golang.org/grpc/health",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/health/grpc_health_v1", "ImportPath": "google.golang.org/grpc/health/grpc_health_v1",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/internal", "ImportPath": "google.golang.org/grpc/internal",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/backoff",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/channelz",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/grpcrand",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/keepalive", "ImportPath": "google.golang.org/grpc/keepalive",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/metadata", "ImportPath": "google.golang.org/grpc/metadata",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/naming", "ImportPath": "google.golang.org/grpc/naming",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/peer", "ImportPath": "google.golang.org/grpc/peer",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/resolver", "ImportPath": "google.golang.org/grpc/resolver",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/dns",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/passthrough",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/stats", "ImportPath": "google.golang.org/grpc/stats",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/status", "ImportPath": "google.golang.org/grpc/status",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/tap", "ImportPath": "google.golang.org/grpc/tap",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/transport", "ImportPath": "google.golang.org/grpc/transport",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "gopkg.in/inf.v0", "ImportPath": "gopkg.in/inf.v0",
......
...@@ -812,79 +812,111 @@ ...@@ -812,79 +812,111 @@
}, },
{ {
"ImportPath": "google.golang.org/grpc", "ImportPath": "google.golang.org/grpc",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/balancer", "ImportPath": "google.golang.org/grpc/balancer",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/base",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/roundrobin",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/codes", "ImportPath": "google.golang.org/grpc/codes",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/connectivity", "ImportPath": "google.golang.org/grpc/connectivity",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/credentials", "ImportPath": "google.golang.org/grpc/credentials",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", "ImportPath": "google.golang.org/grpc/encoding",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/encoding/proto",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclog", "ImportPath": "google.golang.org/grpc/grpclog",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/health", "ImportPath": "google.golang.org/grpc/health",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/health/grpc_health_v1", "ImportPath": "google.golang.org/grpc/health/grpc_health_v1",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/internal", "ImportPath": "google.golang.org/grpc/internal",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/backoff",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/channelz",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/grpcrand",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/keepalive", "ImportPath": "google.golang.org/grpc/keepalive",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/metadata", "ImportPath": "google.golang.org/grpc/metadata",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/naming", "ImportPath": "google.golang.org/grpc/naming",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/peer", "ImportPath": "google.golang.org/grpc/peer",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/resolver", "ImportPath": "google.golang.org/grpc/resolver",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/dns",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/passthrough",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/stats", "ImportPath": "google.golang.org/grpc/stats",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/status", "ImportPath": "google.golang.org/grpc/status",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/tap", "ImportPath": "google.golang.org/grpc/tap",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/transport", "ImportPath": "google.golang.org/grpc/transport",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "gopkg.in/inf.v0", "ImportPath": "gopkg.in/inf.v0",
......
...@@ -416,75 +416,107 @@ ...@@ -416,75 +416,107 @@
}, },
{ {
"ImportPath": "google.golang.org/grpc", "ImportPath": "google.golang.org/grpc",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/balancer", "ImportPath": "google.golang.org/grpc/balancer",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/base",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/roundrobin",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/codes", "ImportPath": "google.golang.org/grpc/codes",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/connectivity", "ImportPath": "google.golang.org/grpc/connectivity",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/credentials", "ImportPath": "google.golang.org/grpc/credentials",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", "ImportPath": "google.golang.org/grpc/encoding",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/encoding/proto",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclog", "ImportPath": "google.golang.org/grpc/grpclog",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/health/grpc_health_v1", "ImportPath": "google.golang.org/grpc/health/grpc_health_v1",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/internal", "ImportPath": "google.golang.org/grpc/internal",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/backoff",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/channelz",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/grpcrand",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/keepalive", "ImportPath": "google.golang.org/grpc/keepalive",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/metadata", "ImportPath": "google.golang.org/grpc/metadata",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/naming", "ImportPath": "google.golang.org/grpc/naming",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/peer", "ImportPath": "google.golang.org/grpc/peer",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/resolver", "ImportPath": "google.golang.org/grpc/resolver",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/dns",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/passthrough",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/stats", "ImportPath": "google.golang.org/grpc/stats",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/status", "ImportPath": "google.golang.org/grpc/status",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/tap", "ImportPath": "google.golang.org/grpc/tap",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/transport", "ImportPath": "google.golang.org/grpc/transport",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "gopkg.in/inf.v0", "ImportPath": "gopkg.in/inf.v0",
......
...@@ -388,75 +388,107 @@ ...@@ -388,75 +388,107 @@
}, },
{ {
"ImportPath": "google.golang.org/grpc", "ImportPath": "google.golang.org/grpc",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/balancer", "ImportPath": "google.golang.org/grpc/balancer",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/base",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/balancer/roundrobin",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/codes", "ImportPath": "google.golang.org/grpc/codes",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/connectivity", "ImportPath": "google.golang.org/grpc/connectivity",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/credentials", "ImportPath": "google.golang.org/grpc/credentials",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", "ImportPath": "google.golang.org/grpc/encoding",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/encoding/proto",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/grpclog", "ImportPath": "google.golang.org/grpc/grpclog",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/health/grpc_health_v1", "ImportPath": "google.golang.org/grpc/health/grpc_health_v1",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/internal", "ImportPath": "google.golang.org/grpc/internal",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/backoff",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/channelz",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/internal/grpcrand",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/keepalive", "ImportPath": "google.golang.org/grpc/keepalive",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/metadata", "ImportPath": "google.golang.org/grpc/metadata",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/naming", "ImportPath": "google.golang.org/grpc/naming",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/peer", "ImportPath": "google.golang.org/grpc/peer",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/resolver", "ImportPath": "google.golang.org/grpc/resolver",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/dns",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
},
{
"ImportPath": "google.golang.org/grpc/resolver/passthrough",
"Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/stats", "ImportPath": "google.golang.org/grpc/stats",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/status", "ImportPath": "google.golang.org/grpc/status",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/tap", "ImportPath": "google.golang.org/grpc/tap",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "google.golang.org/grpc/transport", "ImportPath": "google.golang.org/grpc/transport",
"Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" "Rev": "168a6198bcb0ef175f7dacec0b8691fc141dc9b8"
}, },
{ {
"ImportPath": "gopkg.in/inf.v0", "ImportPath": "gopkg.in/inf.v0",
......
...@@ -147,7 +147,7 @@ var _ DynamicPVTestDriver = &gcePDCSIDriver{} ...@@ -147,7 +147,7 @@ var _ DynamicPVTestDriver = &gcePDCSIDriver{}
func InitGcePDCSIDriver() TestDriver { func InitGcePDCSIDriver() TestDriver {
return &gcePDCSIDriver{ return &gcePDCSIDriver{
driverInfo: DriverInfo{ driverInfo: DriverInfo{
Name: "com.google.csi.gcepd", Name: "pd.csi.storage.gke.io",
FeatureTag: "[Serial]", FeatureTag: "[Serial]",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
SupportedFsType: sets.NewString( SupportedFsType: sets.NewString(
...@@ -237,7 +237,7 @@ var _ DynamicPVTestDriver = &gcePDExternalCSIDriver{} ...@@ -237,7 +237,7 @@ var _ DynamicPVTestDriver = &gcePDExternalCSIDriver{}
func InitGcePDExternalCSIDriver() TestDriver { func InitGcePDExternalCSIDriver() TestDriver {
return &gcePDExternalCSIDriver{ return &gcePDExternalCSIDriver{
driverInfo: DriverInfo{ driverInfo: DriverInfo{
Name: "com.google.csi.gcepd", Name: "pd.csi.storage.gke.io",
// TODO(#70258): this is temporary until we can figure out how to make e2e tests a library // TODO(#70258): this is temporary until we can figure out how to make e2e tests a library
FeatureTag: "[Feature: gcePD-external]", FeatureTag: "[Feature: gcePD-external]",
MaxFileSize: testpatterns.FileSizeMedium, MaxFileSize: testpatterns.FileSizeMedium,
......
...@@ -342,7 +342,7 @@ func testVolumeModeSuccessForDynamicPV(input *volumeModeTestInput) { ...@@ -342,7 +342,7 @@ func testVolumeModeSuccessForDynamicPV(input *volumeModeTestInput) {
var err error var err error
// TODO: This skip should be removed once #70760 is fixed // TODO: This skip should be removed once #70760 is fixed
skipTestUntilBugfix("70760", input.driverName, []string{"com.google.csi.gcepd"}) skipTestUntilBugfix("70760", input.driverName, []string{"pd.csi.storage.gke.io"})
By("Creating sc") By("Creating sc")
input.sc, err = cs.StorageV1().StorageClasses().Create(input.sc) input.sc, err = cs.StorageV1().StorageClasses().Create(input.sc)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
apiVersion: v1 apiVersion: v1
kind: ServiceAccount kind: ServiceAccount
metadata: metadata:
name: csi-driver-registrar name: csi-node-sa
# replace with non-default namespace name # replace with non-default namespace name
namespace: default namespace: default
...@@ -42,7 +42,7 @@ metadata: ...@@ -42,7 +42,7 @@ metadata:
name: csi-driver-registrar-role name: csi-driver-registrar-role
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: csi-driver-registrar name: csi-node-sa
# replace with non-default namespace name # replace with non-default namespace name
namespace: default namespace: default
roleRef: roleRef:
......
kind: StatefulSet kind: StatefulSet
apiVersion: apps/v1 apiVersion: apps/v1
metadata: metadata:
name: csi-gce-controller name: csi-gce-pd-controller
spec: spec:
serviceName: "csi-gce-pd" serviceName: "csi-gce-pd"
replicas: 1 replicas: 1
selector: selector:
matchLabels: matchLabels:
app: csi-gce-pd-driver app: gcp-compute-persistent-disk-csi-driver
template: template:
metadata: metadata:
labels: labels:
app: csi-gce-pd-driver app: gcp-compute-persistent-disk-csi-driver
spec: spec:
serviceAccountName: csi-controller serviceAccountName: csi-controller-sa
containers: containers:
- name: csi-external-provisioner - name: csi-provisioner
imagePullPolicy: Always image: gcr.io/gke-release/csi-provisioner:v1.0.0-gke.0
image: gcr.io/gke-release/csi-provisioner:v0.4.1-gke.0
args: args:
- "--v=5" - "--v=5"
- "--provisioner=com.google.csi.gcepd" - "--provisioner=pd.csi.storage.gke.io"
- "--csi-address=/csi/csi.sock" - "--csi-address=/csi/csi.sock"
volumeMounts: volumeMounts:
- name: socket-dir - name: socket-dir
mountPath: /csi mountPath: /csi
- name: csi-attacher - name: csi-attacher
imagePullPolicy: Always image: gcr.io/gke-release/csi-attacher:v1.0.0-gke.0
image: gcr.io/gke-release/csi-attacher:v0.4.1-gke.0
args: args:
- "--v=5" - "--v=5"
- "--csi-address=/csi/csi.sock" - "--csi-address=/csi/csi.sock"
volumeMounts: volumeMounts:
- name: socket-dir - name: socket-dir
mountPath: /csi mountPath: /csi
- name: gce-driver - name: gce-pd-driver
imagePullPolicy: Always image: gcr.io/gke-release/gcp-compute-persistent-disk-csi-driver:v0.3.0-gke.0
image: gcr.io/gke-release/gcp-compute-persistent-disk-csi-driver:v0.2.0-gke.0
args: args:
- "--v=5" - "--v=5"
- "--endpoint=unix:///csi/csi.sock" - "--endpoint=unix:/csi/csi.sock"
env: env:
- name: GOOGLE_APPLICATION_CREDENTIALS - name: GOOGLE_APPLICATION_CREDENTIALS
value: "/etc/service-account/cloud-sa.json" value: "/etc/cloud-sa/cloud-sa.json"
volumeMounts: volumeMounts:
- name: socket-dir - name: socket-dir
mountPath: /csi mountPath: /csi
- name: cloud-sa-volume - name: cloud-sa-volume
readOnly: true readOnly: true
mountPath: "/etc/service-account" mountPath: "/etc/cloud-sa"
volumes: volumes:
- name: socket-dir - name: socket-dir
emptyDir: {} emptyDir: {}
......
apiVersion: v1 apiVersion: v1
kind: ServiceAccount kind: ServiceAccount
metadata: metadata:
name: csi-controller name: csi-controller-sa
--- ---
kind: ClusterRoleBinding kind: ClusterRoleBinding
...@@ -10,7 +10,7 @@ metadata: ...@@ -10,7 +10,7 @@ metadata:
name: csi-controller-attacher-role name: csi-controller-attacher-role
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: csi-controller name: csi-controller-sa
namespace: default namespace: default
roleRef: roleRef:
kind: ClusterRole kind: ClusterRole
...@@ -25,7 +25,7 @@ metadata: ...@@ -25,7 +25,7 @@ metadata:
namespace: default namespace: default
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: csi-controller name: csi-controller-sa
namespace: default namespace: default
roleRef: roleRef:
kind: Role kind: Role
...@@ -38,7 +38,7 @@ metadata: ...@@ -38,7 +38,7 @@ metadata:
name: csi-controller-provisioner-role name: csi-controller-provisioner-role
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: csi-controller name: csi-controller-sa
namespace: default namespace: default
roleRef: roleRef:
kind: ClusterRole kind: ClusterRole
...@@ -53,7 +53,7 @@ metadata: ...@@ -53,7 +53,7 @@ metadata:
namespace: default namespace: default
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: csi-controller name: csi-controller-sa
namespace: default namespace: default
roleRef: roleRef:
kind: Role kind: Role
...@@ -67,10 +67,10 @@ metadata: ...@@ -67,10 +67,10 @@ metadata:
name: psp-csi-controller-driver-registrar-role name: psp-csi-controller-driver-registrar-role
subjects: subjects:
- kind: ServiceAccount - kind: ServiceAccount
name: csi-controller name: csi-controller-sa
namespace: default namespace: default
- kind: ServiceAccount - kind: ServiceAccount
name: csi-driver-registrar name: csi-node-sa
namespace: default namespace: default
roleRef: roleRef:
kind: ClusterRole kind: ClusterRole
......
kind: DaemonSet kind: DaemonSet
apiVersion: apps/v1 apiVersion: apps/v1
metadata: metadata:
name: csi-gce-node name: csi-gce-pd-node
spec: spec:
selector: selector:
matchLabels: matchLabels:
app: csi-gce-driver app: gcp-compute-persistent-disk-csi-driver
serviceName: csi-gce
template: template:
metadata: metadata:
labels: labels:
app: csi-gce-driver app: gcp-compute-persistent-disk-csi-driver
spec: spec:
serviceAccountName: csi-driver-registrar serviceAccountName: csi-node-sa
containers: containers:
- name: csi-driver-registrar - name: csi-driver-registrar
imagePullPolicy: Always image: gcr.io/gke-release/csi-driver-registrar:v1.0.0-gke.0
image: gcr.io/gke-release/csi-driver-registrar:v0.4.1-gke.0
args: args:
- "--v=5" - "--v=5"
- "--csi-address=/csi/csi.sock" - "--csi-address=/var/lib/kubelet/plugins/pd.csi.storage.gke.io/csi.sock"
- "--kubelet-registration-path=/var/lib/kubelet/plugins/com.google.csi.gcepd/csi.sock" - "--kubelet-registration-path=/var/lib/kubelet/plugins/pd.csi.storage.gke.io/csi.sock"
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "rm -rf /registration/pd.csi.storage.gke.io /registration/pd.csi.storage.gke.io-reg.sock"]
env: env:
- name: KUBE_NODE_NAME - name: KUBE_NODE_NAME
valueFrom: valueFrom:
...@@ -28,17 +30,16 @@ spec: ...@@ -28,17 +30,16 @@ spec:
fieldPath: spec.nodeName fieldPath: spec.nodeName
volumeMounts: volumeMounts:
- name: plugin-dir - name: plugin-dir
mountPath: /csi mountPath: /var/lib/kubelet/plugins/pd.csi.storage.gke.io/
- name: registration-dir - name: registration-dir
mountPath: /registration mountPath: /registration
- name: gce-driver - name: gce-pd-driver
securityContext: securityContext:
privileged: true privileged: true
imagePullPolicy: Always image: gcr.io/gke-release/gcp-compute-persistent-disk-csi-driver:v0.3.0-gke.0
image: gcr.io/gke-release/gcp-compute-persistent-disk-csi-driver:v0.2.0-gke.0
args: args:
- "--v=5" - "--v=5"
- "--endpoint=unix:///csi/csi.sock" - "--endpoint=unix:/csi/csi.sock"
volumeMounts: volumeMounts:
- name: kubelet-dir - name: kubelet-dir
mountPath: /var/lib/kubelet mountPath: /var/lib/kubelet
...@@ -67,7 +68,7 @@ spec: ...@@ -67,7 +68,7 @@ spec:
type: Directory type: Directory
- name: plugin-dir - name: plugin-dir
hostPath: hostPath:
path: /var/lib/kubelet/plugins/com.google.csi.gcepd/ path: /var/lib/kubelet/plugins/pd.csi.storage.gke.io/
type: DirectoryOrCreate type: DirectoryOrCreate
- name: device-dir - name: device-dir
hostPath: hostPath:
...@@ -90,4 +91,3 @@ spec: ...@@ -90,4 +91,3 @@ spec:
hostPath: hostPath:
path: /sys path: /sys
type: Directory type: Directory
...@@ -30,7 +30,7 @@ spec: ...@@ -30,7 +30,7 @@ spec:
serviceAccountName: csi-attacher serviceAccountName: csi-attacher
containers: containers:
- name: csi-attacher - name: csi-attacher
image: quay.io/k8scsi/csi-attacher:v0.4.1 image: gcr.io/gke-release/csi-attacher:v1.0.0-gke.0
args: args:
- --v=5 - --v=5
- --csi-address=$(ADDRESS) - --csi-address=$(ADDRESS)
......
...@@ -30,7 +30,7 @@ spec: ...@@ -30,7 +30,7 @@ spec:
serviceAccountName: csi-provisioner serviceAccountName: csi-provisioner
containers: containers:
- name: csi-provisioner - name: csi-provisioner
image: quay.io/k8scsi/csi-provisioner:v0.4.1 image: gcr.io/gke-release/csi-provisioner:v1.0.0-gke.0
args: args:
- "--provisioner=csi-hostpath" - "--provisioner=csi-hostpath"
- "--csi-address=$(ADDRESS)" - "--csi-address=$(ADDRESS)"
......
...@@ -11,11 +11,11 @@ spec: ...@@ -11,11 +11,11 @@ spec:
labels: labels:
app: csi-hostpathplugin app: csi-hostpathplugin
spec: spec:
serviceAccountName: csi-driver-registrar serviceAccountName: csi-node-sa
hostNetwork: true hostNetwork: true
containers: containers:
- name: driver-registrar - name: driver-registrar
image: quay.io/k8scsi/driver-registrar:v0.4.1 image: gcr.io/gke-release/csi-driver-registrar:v1.0.0-gke.0
args: args:
- --v=5 - --v=5
- --csi-address=/csi/csi.sock - --csi-address=/csi/csi.sock
...@@ -33,7 +33,7 @@ spec: ...@@ -33,7 +33,7 @@ spec:
- mountPath: /registration - mountPath: /registration
name: registration-dir name: registration-dir
- name: hostpath - name: hostpath
image: quay.io/k8scsi/hostpathplugin:v0.4.1 image: quay.io/k8scsi/hostpathplugin:v1.0.0
args: args:
- "--v=5" - "--v=5"
- "--endpoint=$(CSI_ENDPOINT)" - "--endpoint=$(CSI_ENDPOINT)"
......
...@@ -8,7 +8,7 @@ subjects: ...@@ -8,7 +8,7 @@ subjects:
name: csi-attacher name: csi-attacher
namespace: default namespace: default
- kind: ServiceAccount - kind: ServiceAccount
name: csi-driver-registrar name: csi-node-sa
namespace: default namespace: default
- kind: ServiceAccount - kind: ServiceAccount
name: csi-provisioner name: csi-provisioner
......
...@@ -304,7 +304,7 @@ func TestObjectSizeResponses(t *testing.T) { ...@@ -304,7 +304,7 @@ func TestObjectSizeResponses(t *testing.T) {
const DeploymentTwoMegabyteSize = 1000000 const DeploymentTwoMegabyteSize = 1000000
expectedMsgFor1MB := `etcdserver: request is too large` expectedMsgFor1MB := `etcdserver: request is too large`
expectedMsgFor2MB := `rpc error: code = ResourceExhausted desc = grpc: trying to send message larger than max` expectedMsgFor2MB := `rpc error: code = ResourceExhausted desc = trying to send message larger than max`
expectedMsgForLargeAnnotation := `metadata.annotations: Too long: must have at most 262144 characters` expectedMsgForLargeAnnotation := `metadata.annotations: Too long: must have at most 262144 characters`
deployment1 := constructBody("a", DeploymentMegabyteSize, "labels", t) // >1 MB file deployment1 := constructBody("a", DeploymentMegabyteSize, "labels", t) // >1 MB file
......
...@@ -94,7 +94,7 @@ filegroup( ...@@ -94,7 +94,7 @@ filegroup(
"//vendor/github.com/cloudflare/cfssl/ubiquity:all-srcs", "//vendor/github.com/cloudflare/cfssl/ubiquity:all-srcs",
"//vendor/github.com/clusterhq/flocker-go:all-srcs", "//vendor/github.com/clusterhq/flocker-go:all-srcs",
"//vendor/github.com/codedellemc/goscaleio:all-srcs", "//vendor/github.com/codedellemc/goscaleio:all-srcs",
"//vendor/github.com/container-storage-interface/spec/lib/go/csi/v0:all-srcs", "//vendor/github.com/container-storage-interface/spec/lib/go/csi:all-srcs",
"//vendor/github.com/containerd/console:all-srcs", "//vendor/github.com/containerd/console:all-srcs",
"//vendor/github.com/containerd/containerd/api/services/containers/v1:all-srcs", "//vendor/github.com/containerd/containerd/api/services/containers/v1:all-srcs",
"//vendor/github.com/containerd/containerd/api/services/tasks/v1:all-srcs", "//vendor/github.com/containerd/containerd/api/services/tasks/v1:all-srcs",
...@@ -239,6 +239,7 @@ filegroup( ...@@ -239,6 +239,7 @@ filegroup(
"//vendor/github.com/golang/mock/gomock:all-srcs", "//vendor/github.com/golang/mock/gomock:all-srcs",
"//vendor/github.com/golang/protobuf/jsonpb:all-srcs", "//vendor/github.com/golang/protobuf/jsonpb:all-srcs",
"//vendor/github.com/golang/protobuf/proto:all-srcs", "//vendor/github.com/golang/protobuf/proto:all-srcs",
"//vendor/github.com/golang/protobuf/protoc-gen-go/descriptor:all-srcs",
"//vendor/github.com/golang/protobuf/ptypes:all-srcs", "//vendor/github.com/golang/protobuf/ptypes:all-srcs",
"//vendor/github.com/google/btree:all-srcs", "//vendor/github.com/google/btree:all-srcs",
"//vendor/github.com/google/cadvisor/accelerators:all-srcs", "//vendor/github.com/google/cadvisor/accelerators:all-srcs",
......
...@@ -3,11 +3,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") ...@@ -3,11 +3,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["csi.pb.go"], srcs = ["csi.pb.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/container-storage-interface/spec/lib/go/csi/v0", importmap = "k8s.io/kubernetes/vendor/github.com/container-storage-interface/spec/lib/go/csi",
importpath = "github.com/container-storage-interface/spec/lib/go/csi/v0", importpath = "github.com/container-storage-interface/spec/lib/go/csi",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/golang/protobuf/proto:go_default_library", "//vendor/github.com/golang/protobuf/proto:go_default_library",
"//vendor/github.com/golang/protobuf/protoc-gen-go/descriptor:go_default_library",
"//vendor/github.com/golang/protobuf/ptypes/timestamp:go_default_library",
"//vendor/github.com/golang/protobuf/ptypes/wrappers:go_default_library", "//vendor/github.com/golang/protobuf/ptypes/wrappers:go_default_library",
"//vendor/golang.org/x/net/context:go_default_library", "//vendor/golang.org/x/net/context:go_default_library",
"//vendor/google.golang.org/grpc:go_default_library", "//vendor/google.golang.org/grpc:go_default_library",
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["descriptor.pb.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor",
importpath = "github.com/golang/protobuf/protoc-gen-go/descriptor",
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/golang/protobuf/proto:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
This source diff could not be displayed because it is too large. You can view the blob instead.
language: go language: go
go: go:
- 1.6.x
- 1.7.x - 1.7.x
- 1.8.x - 1.8.x
- 1.9.x - 1.9.x
- 1.10.x
matrix: matrix:
include: include:
- go: 1.9.x - go: 1.10.x
env: ARCH=386 env: RUN386=1
go_import_path: google.golang.org/grpc go_import_path: google.golang.org/grpc
before_install: before_install:
- if [[ "$TRAVIS_GO_VERSION" = 1.9* && "$ARCH" != "386" ]]; then ./vet.sh -install || exit 1; fi - if [[ -n "$RUN386" ]]; then export GOARCH=386; fi
- if [[ "$TRAVIS_GO_VERSION" = 1.10* && "$GOARCH" != "386" ]]; then ./vet.sh -install || exit 1; fi
script: script:
- if [[ "$TRAVIS_GO_VERSION" = 1.9* && "$ARCH" != "386" ]]; then ./vet.sh || exit 1; fi - if [[ "$TRAVIS_GO_VERSION" = 1.10* && "$GOARCH" != "386" ]]; then ./vet.sh || exit 1; fi
- make test testrace - make test || exit 1
- if [[ "$GOARCH" != "386" ]]; then make testrace; fi
...@@ -11,7 +11,9 @@ go_library( ...@@ -11,7 +11,9 @@ go_library(
"clientconn.go", "clientconn.go",
"codec.go", "codec.go",
"doc.go", "doc.go",
"grpclb.go", "envconfig.go",
"go16.go",
"go17.go",
"interceptor.go", "interceptor.go",
"picker_wrapper.go", "picker_wrapper.go",
"pickfirst.go", "pickfirst.go",
...@@ -19,29 +21,37 @@ go_library( ...@@ -19,29 +21,37 @@ go_library(
"resolver_conn_wrapper.go", "resolver_conn_wrapper.go",
"rpc_util.go", "rpc_util.go",
"server.go", "server.go",
"service_config.go",
"stickiness_linkedmap.go",
"stream.go", "stream.go",
"trace.go", "trace.go",
"version.go",
], ],
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc", importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc",
importpath = "google.golang.org/grpc", importpath = "google.golang.org/grpc",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/golang/protobuf/proto:go_default_library",
"//vendor/golang.org/x/net/context:go_default_library", "//vendor/golang.org/x/net/context:go_default_library",
"//vendor/golang.org/x/net/http2:go_default_library", "//vendor/golang.org/x/net/http2:go_default_library",
"//vendor/golang.org/x/net/trace:go_default_library", "//vendor/golang.org/x/net/trace:go_default_library",
"//vendor/google.golang.org/grpc/balancer:go_default_library", "//vendor/google.golang.org/grpc/balancer:go_default_library",
"//vendor/google.golang.org/grpc/balancer/roundrobin:go_default_library",
"//vendor/google.golang.org/grpc/codes:go_default_library", "//vendor/google.golang.org/grpc/codes:go_default_library",
"//vendor/google.golang.org/grpc/connectivity:go_default_library", "//vendor/google.golang.org/grpc/connectivity:go_default_library",
"//vendor/google.golang.org/grpc/credentials:go_default_library", "//vendor/google.golang.org/grpc/credentials:go_default_library",
"//vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages:go_default_library", "//vendor/google.golang.org/grpc/encoding:go_default_library",
"//vendor/google.golang.org/grpc/encoding/proto:go_default_library",
"//vendor/google.golang.org/grpc/grpclog:go_default_library", "//vendor/google.golang.org/grpc/grpclog:go_default_library",
"//vendor/google.golang.org/grpc/internal:go_default_library", "//vendor/google.golang.org/grpc/internal:go_default_library",
"//vendor/google.golang.org/grpc/internal/backoff:go_default_library",
"//vendor/google.golang.org/grpc/internal/channelz:go_default_library",
"//vendor/google.golang.org/grpc/keepalive:go_default_library", "//vendor/google.golang.org/grpc/keepalive:go_default_library",
"//vendor/google.golang.org/grpc/metadata:go_default_library", "//vendor/google.golang.org/grpc/metadata:go_default_library",
"//vendor/google.golang.org/grpc/naming:go_default_library", "//vendor/google.golang.org/grpc/naming:go_default_library",
"//vendor/google.golang.org/grpc/peer:go_default_library", "//vendor/google.golang.org/grpc/peer:go_default_library",
"//vendor/google.golang.org/grpc/resolver:go_default_library", "//vendor/google.golang.org/grpc/resolver:go_default_library",
"//vendor/google.golang.org/grpc/resolver/dns:go_default_library",
"//vendor/google.golang.org/grpc/resolver/passthrough:go_default_library",
"//vendor/google.golang.org/grpc/stats:go_default_library", "//vendor/google.golang.org/grpc/stats:go_default_library",
"//vendor/google.golang.org/grpc/status:go_default_library", "//vendor/google.golang.org/grpc/status:go_default_library",
"//vendor/google.golang.org/grpc/tap:go_default_library", "//vendor/google.golang.org/grpc/tap:go_default_library",
...@@ -64,6 +74,7 @@ filegroup( ...@@ -64,6 +74,7 @@ filegroup(
"//vendor/google.golang.org/grpc/codes:all-srcs", "//vendor/google.golang.org/grpc/codes:all-srcs",
"//vendor/google.golang.org/grpc/connectivity:all-srcs", "//vendor/google.golang.org/grpc/connectivity:all-srcs",
"//vendor/google.golang.org/grpc/credentials:all-srcs", "//vendor/google.golang.org/grpc/credentials:all-srcs",
"//vendor/google.golang.org/grpc/encoding:all-srcs",
"//vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages:all-srcs", "//vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages:all-srcs",
"//vendor/google.golang.org/grpc/grpclog:all-srcs", "//vendor/google.golang.org/grpc/grpclog:all-srcs",
"//vendor/google.golang.org/grpc/health:all-srcs", "//vendor/google.golang.org/grpc/health:all-srcs",
......
...@@ -7,7 +7,7 @@ If you are new to github, please start by reading [Pull Request howto](https://h ...@@ -7,7 +7,7 @@ If you are new to github, please start by reading [Pull Request howto](https://h
## Legal requirements ## Legal requirements
In order to protect both you and ourselves, you will need to sign the In order to protect both you and ourselves, you will need to sign the
[Contributor License Agreement](https://cla.developers.google.com/clas). [Contributor License Agreement](https://identity.linuxfoundation.org/projects/cncf).
## Guidelines for Pull Requests ## Guidelines for Pull Requests
How to get your contributions merged smoothly and quickly. How to get your contributions merged smoothly and quickly.
...@@ -27,6 +27,10 @@ How to get your contributions merged smoothly and quickly. ...@@ -27,6 +27,10 @@ How to get your contributions merged smoothly and quickly.
- Keep your PR up to date with upstream/master (if there are merge conflicts, we can't really merge your change). - Keep your PR up to date with upstream/master (if there are merge conflicts, we can't really merge your change).
- **All tests need to be passing** before your change can be merged. We recommend you **run tests locally** before creating your PR to catch breakages early on. - **All tests need to be passing** before your change can be merged. We recommend you **run tests locally** before creating your PR to catch breakages early on.
- `make all` to test everything, OR
- `make vet` to catch vet errors
- `make test` to run the tests
- `make testrace` to run tests in race mode
- Exceptions to the rules can be made if there's a compelling reason for doing so. - Exceptions to the rules can be made if there's a compelling reason for doing so.
all: test testrace all: vet test testrace
deps: deps:
go get -d -v google.golang.org/grpc/... go get -d -v google.golang.org/grpc/...
...@@ -22,11 +22,14 @@ proto: ...@@ -22,11 +22,14 @@ proto:
fi fi
go generate google.golang.org/grpc/... go generate google.golang.org/grpc/...
vet:
./vet.sh
test: testdeps test: testdeps
go test -cpu 1,4 google.golang.org/grpc/... go test -cpu 1,4 -timeout 5m google.golang.org/grpc/...
testrace: testdeps testrace: testdeps
go test -race -cpu 1,4 google.golang.org/grpc/... go test -race -cpu 1,4 -timeout 7m google.golang.org/grpc/...
clean: clean:
go clean -i google.golang.org/grpc/... go clean -i google.golang.org/grpc/...
...@@ -39,7 +42,7 @@ clean: ...@@ -39,7 +42,7 @@ clean:
updatetestdeps \ updatetestdeps \
build \ build \
proto \ proto \
vet \
test \ test \
testrace \ testrace \
clean \ clean
coverage
# gRPC-Go # gRPC-Go
[![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc) [![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc) [![GoReportCard](https://goreportcard.com/badge/grpc/grpc-go)](https://goreportcard.com/report/github.com/grpc/grpc-go)
The Go implementation of [gRPC](https://grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start: Go](https://grpc.io/docs/quickstart/go.html) guide. The Go implementation of [gRPC](https://grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start: Go](https://grpc.io/docs/quickstart/go.html) guide.
...@@ -16,7 +16,7 @@ $ go get -u google.golang.org/grpc ...@@ -16,7 +16,7 @@ $ go get -u google.golang.org/grpc
Prerequisites Prerequisites
------------- -------------
This requires Go 1.7 or later. This requires Go 1.6 or later. Go 1.7 will be required soon.
Constraints Constraints
----------- -----------
......
...@@ -16,83 +16,23 @@ ...@@ -16,83 +16,23 @@
* *
*/ */
// See internal/backoff package for the backoff implementation. This file is
// kept for the exported types and API backward compatility.
package grpc package grpc
import ( import (
"math/rand"
"time" "time"
) )
// DefaultBackoffConfig uses values specified for backoff in // DefaultBackoffConfig uses values specified for backoff in
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
var ( var DefaultBackoffConfig = BackoffConfig{
DefaultBackoffConfig = BackoffConfig{ MaxDelay: 120 * time.Second,
MaxDelay: 120 * time.Second,
baseDelay: 1.0 * time.Second,
factor: 1.6,
jitter: 0.2,
}
)
// backoffStrategy defines the methodology for backing off after a grpc
// connection failure.
//
// This is unexported until the gRPC project decides whether or not to allow
// alternative backoff strategies. Once a decision is made, this type and its
// method may be exported.
type backoffStrategy interface {
// backoff returns the amount of time to wait before the next retry given
// the number of consecutive failures.
backoff(retries int) time.Duration
} }
// BackoffConfig defines the parameters for the default gRPC backoff strategy. // BackoffConfig defines the parameters for the default gRPC backoff strategy.
type BackoffConfig struct { type BackoffConfig struct {
// MaxDelay is the upper bound of backoff delay. // MaxDelay is the upper bound of backoff delay.
MaxDelay time.Duration MaxDelay time.Duration
// TODO(stevvooe): The following fields are not exported, as allowing
// changes would violate the current gRPC specification for backoff. If
// gRPC decides to allow more interesting backoff strategies, these fields
// may be opened up in the future.
// baseDelay is the amount of time to wait before retrying after the first
// failure.
baseDelay time.Duration
// factor is applied to the backoff after each retry.
factor float64
// jitter provides a range to randomize backoff delays.
jitter float64
}
func setDefaults(bc *BackoffConfig) {
md := bc.MaxDelay
*bc = DefaultBackoffConfig
if md > 0 {
bc.MaxDelay = md
}
}
func (bc BackoffConfig) backoff(retries int) time.Duration {
if retries == 0 {
return bc.baseDelay
}
backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay)
for backoff < max && retries > 0 {
backoff *= bc.factor
retries--
}
if backoff > max {
backoff = max
}
// Randomize backoff delays so that if a cluster of requests start at
// the same time, they won't operate in lockstep.
backoff *= 1 + bc.jitter*(rand.Float64()*2-1)
if backoff < 0 {
return 0
}
return time.Duration(backoff)
} }
...@@ -28,10 +28,12 @@ import ( ...@@ -28,10 +28,12 @@ import (
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/naming" "google.golang.org/grpc/naming"
"google.golang.org/grpc/status"
) )
// Address represents a server the client connects to. // Address represents a server the client connects to.
// This is the EXPERIMENTAL API and may be changed or extended in the future. //
// Deprecated: please use package balancer.
type Address struct { type Address struct {
// Addr is the server address on which a connection will be established. // Addr is the server address on which a connection will be established.
Addr string Addr string
...@@ -41,6 +43,8 @@ type Address struct { ...@@ -41,6 +43,8 @@ type Address struct {
} }
// BalancerConfig specifies the configurations for Balancer. // BalancerConfig specifies the configurations for Balancer.
//
// Deprecated: please use package balancer.
type BalancerConfig struct { type BalancerConfig struct {
// DialCreds is the transport credential the Balancer implementation can // DialCreds is the transport credential the Balancer implementation can
// use to dial to a remote load balancer server. The Balancer implementations // use to dial to a remote load balancer server. The Balancer implementations
...@@ -53,7 +57,8 @@ type BalancerConfig struct { ...@@ -53,7 +57,8 @@ type BalancerConfig struct {
} }
// BalancerGetOptions configures a Get call. // BalancerGetOptions configures a Get call.
// This is the EXPERIMENTAL API and may be changed or extended in the future. //
// Deprecated: please use package balancer.
type BalancerGetOptions struct { type BalancerGetOptions struct {
// BlockingWait specifies whether Get should block when there is no // BlockingWait specifies whether Get should block when there is no
// connected address. // connected address.
...@@ -61,7 +66,8 @@ type BalancerGetOptions struct { ...@@ -61,7 +66,8 @@ type BalancerGetOptions struct {
} }
// Balancer chooses network addresses for RPCs. // Balancer chooses network addresses for RPCs.
// This is the EXPERIMENTAL API and may be changed or extended in the future. //
// Deprecated: please use package balancer.
type Balancer interface { type Balancer interface {
// Start does the initialization work to bootstrap a Balancer. For example, // Start does the initialization work to bootstrap a Balancer. For example,
// this function may start the name resolution and watch the updates. It will // this function may start the name resolution and watch the updates. It will
...@@ -134,6 +140,8 @@ func downErrorf(timeout, temporary bool, format string, a ...interface{}) downEr ...@@ -134,6 +140,8 @@ func downErrorf(timeout, temporary bool, format string, a ...interface{}) downEr
// RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch // RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch
// the name resolution updates and updates the addresses available correspondingly. // the name resolution updates and updates the addresses available correspondingly.
//
// Deprecated: please use package balancer/roundrobin.
func RoundRobin(r naming.Resolver) Balancer { func RoundRobin(r naming.Resolver) Balancer {
return &roundRobin{r: r} return &roundRobin{r: r}
} }
...@@ -310,7 +318,7 @@ func (rr *roundRobin) Get(ctx context.Context, opts BalancerGetOptions) (addr Ad ...@@ -310,7 +318,7 @@ func (rr *roundRobin) Get(ctx context.Context, opts BalancerGetOptions) (addr Ad
if !opts.BlockingWait { if !opts.BlockingWait {
if len(rr.addrs) == 0 { if len(rr.addrs) == 0 {
rr.mu.Unlock() rr.mu.Unlock()
err = Errorf(codes.Unavailable, "there is no address available") err = status.Errorf(codes.Unavailable, "there is no address available")
return return
} }
// Returns the next addr on rr.addrs for failfast RPCs. // Returns the next addr on rr.addrs for failfast RPCs.
......
...@@ -23,7 +23,11 @@ filegroup( ...@@ -23,7 +23,11 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//vendor/google.golang.org/grpc/balancer/base:all-srcs",
"//vendor/google.golang.org/grpc/balancer/roundrobin:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
...@@ -23,6 +23,7 @@ package balancer ...@@ -23,6 +23,7 @@ package balancer
import ( import (
"errors" "errors"
"net" "net"
"strings"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc/connectivity" "google.golang.org/grpc/connectivity"
...@@ -33,24 +34,26 @@ import ( ...@@ -33,24 +34,26 @@ import (
var ( var (
// m is a map from name to balancer builder. // m is a map from name to balancer builder.
m = make(map[string]Builder) m = make(map[string]Builder)
// defaultBuilder is the default balancer to use.
defaultBuilder Builder // TODO(bar) install pickfirst as default.
) )
// Register registers the balancer builder to the balancer map. // Register registers the balancer builder to the balancer map. b.Name
// b.Name will be used as the name registered with this builder. // (lowercased) will be used as the name registered with this builder.
//
// NOTE: this function must only be called during initialization time (i.e. in
// an init() function), and is not thread-safe. If multiple Balancers are
// registered with the same name, the one registered last will take effect.
func Register(b Builder) { func Register(b Builder) {
m[b.Name()] = b m[strings.ToLower(b.Name())] = b
} }
// Get returns the resolver builder registered with the given name. // Get returns the resolver builder registered with the given name.
// If no builder is register with the name, the default pickfirst will // Note that the compare is done in a case-insenstive fashion.
// be used. // If no builder is register with the name, nil will be returned.
func Get(name string) Builder { func Get(name string) Builder {
if b, ok := m[name]; ok { if b, ok := m[strings.ToLower(name)]; ok {
return b return b
} }
return defaultBuilder return nil
} }
// SubConn represents a gRPC sub connection. // SubConn represents a gRPC sub connection.
...@@ -66,6 +69,11 @@ func Get(name string) Builder { ...@@ -66,6 +69,11 @@ func Get(name string) Builder {
// When the connection encounters an error, it will reconnect immediately. // When the connection encounters an error, it will reconnect immediately.
// When the connection becomes IDLE, it will not reconnect unless Connect is // When the connection becomes IDLE, it will not reconnect unless Connect is
// called. // called.
//
// This interface is to be implemented by gRPC. Users should not need a
// brand new implementation of this interface. For the situations like
// testing, the new implementation should embed this interface. This allows
// gRPC to add new methods to this interface.
type SubConn interface { type SubConn interface {
// UpdateAddresses updates the addresses used in this SubConn. // UpdateAddresses updates the addresses used in this SubConn.
// gRPC checks if currently-connected address is still in the new list. // gRPC checks if currently-connected address is still in the new list.
...@@ -83,6 +91,11 @@ type SubConn interface { ...@@ -83,6 +91,11 @@ type SubConn interface {
type NewSubConnOptions struct{} type NewSubConnOptions struct{}
// ClientConn represents a gRPC ClientConn. // ClientConn represents a gRPC ClientConn.
//
// This interface is to be implemented by gRPC. Users should not need a
// brand new implementation of this interface. For the situations like
// testing, the new implementation should embed this interface. This allows
// gRPC to add new methods to this interface.
type ClientConn interface { type ClientConn interface {
// NewSubConn is called by balancer to create a new SubConn. // NewSubConn is called by balancer to create a new SubConn.
// It doesn't block and wait for the connections to be established. // It doesn't block and wait for the connections to be established.
...@@ -99,6 +112,9 @@ type ClientConn interface { ...@@ -99,6 +112,9 @@ type ClientConn interface {
// on the new picker to pick new SubConn. // on the new picker to pick new SubConn.
UpdateBalancerState(s connectivity.State, p Picker) UpdateBalancerState(s connectivity.State, p Picker)
// ResolveNow is called by balancer to notify gRPC to do a name resolving.
ResolveNow(resolver.ResolveNowOption)
// Target returns the dial target for this ClientConn. // Target returns the dial target for this ClientConn.
Target() string Target() string
} }
...@@ -113,6 +129,8 @@ type BuildOptions struct { ...@@ -113,6 +129,8 @@ type BuildOptions struct {
// to a remote load balancer server. The Balancer implementations // to a remote load balancer server. The Balancer implementations
// can ignore this if it doesn't need to talk to remote balancer. // can ignore this if it doesn't need to talk to remote balancer.
Dialer func(context.Context, string) (net.Conn, error) Dialer func(context.Context, string) (net.Conn, error)
// ChannelzParentID is the entity parent's channelz unique identification number.
ChannelzParentID int64
} }
// Builder creates a balancer. // Builder creates a balancer.
...@@ -131,6 +149,10 @@ type PickOptions struct{} ...@@ -131,6 +149,10 @@ type PickOptions struct{}
type DoneInfo struct { type DoneInfo struct {
// Err is the rpc error the RPC finished with. It could be nil. // Err is the rpc error the RPC finished with. It could be nil.
Err error Err error
// BytesSent indicates if any bytes have been sent to the server.
BytesSent bool
// BytesReceived indicates if any byte has been received from the server.
BytesReceived bool
} }
var ( var (
...@@ -143,7 +165,7 @@ var ( ...@@ -143,7 +165,7 @@ var (
) )
// Picker is used by gRPC to pick a SubConn to send an RPC. // Picker is used by gRPC to pick a SubConn to send an RPC.
// Balancer is expected to generate a new picker from its snapshot everytime its // Balancer is expected to generate a new picker from its snapshot every time its
// internal state has changed. // internal state has changed.
// //
// The pickers used by gRPC can be updated by ClientConn.UpdateBalancerState(). // The pickers used by gRPC can be updated by ClientConn.UpdateBalancerState().
...@@ -161,7 +183,7 @@ type Picker interface { ...@@ -161,7 +183,7 @@ type Picker interface {
// If a SubConn is returned: // If a SubConn is returned:
// - If it is READY, gRPC will send the RPC on it; // - If it is READY, gRPC will send the RPC on it;
// - If it is not ready, or becomes not ready after it's returned, gRPC will block // - If it is not ready, or becomes not ready after it's returned, gRPC will block
// this call until a new picker is updated and will call pick on the new picker. // until UpdateBalancerState() is called and will call pick on the new picker.
// //
// If the returned error is not nil: // If the returned error is not nil:
// - If the error is ErrNoSubConnAvailable, gRPC will block until UpdateBalancerState() // - If the error is ErrNoSubConnAvailable, gRPC will block until UpdateBalancerState()
...@@ -204,3 +226,45 @@ type Balancer interface { ...@@ -204,3 +226,45 @@ type Balancer interface {
// ClientConn.RemoveSubConn for its existing SubConns. // ClientConn.RemoveSubConn for its existing SubConns.
Close() Close()
} }
// ConnectivityStateEvaluator takes the connectivity states of multiple SubConns
// and returns one aggregated connectivity state.
//
// It's not thread safe.
type ConnectivityStateEvaluator struct {
numReady uint64 // Number of addrConns in ready state.
numConnecting uint64 // Number of addrConns in connecting state.
numTransientFailure uint64 // Number of addrConns in transientFailure.
}
// RecordTransition records state change happening in subConn and based on that
// it evaluates what aggregated state should be.
//
// - If at least one SubConn in Ready, the aggregated state is Ready;
// - Else if at least one SubConn in Connecting, the aggregated state is Connecting;
// - Else the aggregated state is TransientFailure.
//
// Idle and Shutdown are not considered.
func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState connectivity.State) connectivity.State {
// Update counters.
for idx, state := range []connectivity.State{oldState, newState} {
updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
switch state {
case connectivity.Ready:
cse.numReady += updateVal
case connectivity.Connecting:
cse.numConnecting += updateVal
case connectivity.TransientFailure:
cse.numTransientFailure += updateVal
}
}
// Evaluate.
if cse.numReady > 0 {
return connectivity.Ready
}
if cse.numConnecting > 0 {
return connectivity.Connecting
}
return connectivity.TransientFailure
}
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"balancer.go",
"base.go",
],
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/balancer/base",
importpath = "google.golang.org/grpc/balancer/base",
visibility = ["//visibility:public"],
deps = [
"//vendor/golang.org/x/net/context:go_default_library",
"//vendor/google.golang.org/grpc/balancer:go_default_library",
"//vendor/google.golang.org/grpc/connectivity:go_default_library",
"//vendor/google.golang.org/grpc/grpclog:go_default_library",
"//vendor/google.golang.org/grpc/resolver:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
*
* Copyright 2017 gRPC 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 base
import (
"golang.org/x/net/context"
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/resolver"
)
type baseBuilder struct {
name string
pickerBuilder PickerBuilder
}
func (bb *baseBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
return &baseBalancer{
cc: cc,
pickerBuilder: bb.pickerBuilder,
subConns: make(map[resolver.Address]balancer.SubConn),
scStates: make(map[balancer.SubConn]connectivity.State),
csEvltr: &connectivityStateEvaluator{},
// Initialize picker to a picker that always return
// ErrNoSubConnAvailable, because when state of a SubConn changes, we
// may call UpdateBalancerState with this picker.
picker: NewErrPicker(balancer.ErrNoSubConnAvailable),
}
}
func (bb *baseBuilder) Name() string {
return bb.name
}
type baseBalancer struct {
cc balancer.ClientConn
pickerBuilder PickerBuilder
csEvltr *connectivityStateEvaluator
state connectivity.State
subConns map[resolver.Address]balancer.SubConn
scStates map[balancer.SubConn]connectivity.State
picker balancer.Picker
}
func (b *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) {
if err != nil {
grpclog.Infof("base.baseBalancer: HandleResolvedAddrs called with error %v", err)
return
}
grpclog.Infoln("base.baseBalancer: got new resolved addresses: ", addrs)
// addrsSet is the set converted from addrs, it's used for quick lookup of an address.
addrsSet := make(map[resolver.Address]struct{})
for _, a := range addrs {
addrsSet[a] = struct{}{}
if _, ok := b.subConns[a]; !ok {
// a is a new address (not existing in b.subConns).
sc, err := b.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{})
if err != nil {
grpclog.Warningf("base.baseBalancer: failed to create new SubConn: %v", err)
continue
}
b.subConns[a] = sc
b.scStates[sc] = connectivity.Idle
sc.Connect()
}
}
for a, sc := range b.subConns {
// a was removed by resolver.
if _, ok := addrsSet[a]; !ok {
b.cc.RemoveSubConn(sc)
delete(b.subConns, a)
// Keep the state of this sc in b.scStates until sc's state becomes Shutdown.
// The entry will be deleted in HandleSubConnStateChange.
}
}
}
// regeneratePicker takes a snapshot of the balancer, and generates a picker
// from it. The picker is
// - errPicker with ErrTransientFailure if the balancer is in TransientFailure,
// - built by the pickerBuilder with all READY SubConns otherwise.
func (b *baseBalancer) regeneratePicker() {
if b.state == connectivity.TransientFailure {
b.picker = NewErrPicker(balancer.ErrTransientFailure)
return
}
readySCs := make(map[resolver.Address]balancer.SubConn)
// Filter out all ready SCs from full subConn map.
for addr, sc := range b.subConns {
if st, ok := b.scStates[sc]; ok && st == connectivity.Ready {
readySCs[addr] = sc
}
}
b.picker = b.pickerBuilder.Build(readySCs)
}
func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) {
grpclog.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s)
oldS, ok := b.scStates[sc]
if !ok {
grpclog.Infof("base.baseBalancer: got state changes for an unknown SubConn: %p, %v", sc, s)
return
}
b.scStates[sc] = s
switch s {
case connectivity.Idle:
sc.Connect()
case connectivity.Shutdown:
// When an address was removed by resolver, b called RemoveSubConn but
// kept the sc's state in scStates. Remove state for this sc here.
delete(b.scStates, sc)
}
oldAggrState := b.state
b.state = b.csEvltr.recordTransition(oldS, s)
// Regenerate picker when one of the following happens:
// - this sc became ready from not-ready
// - this sc became not-ready from ready
// - the aggregated state of balancer became TransientFailure from non-TransientFailure
// - the aggregated state of balancer became non-TransientFailure from TransientFailure
if (s == connectivity.Ready) != (oldS == connectivity.Ready) ||
(b.state == connectivity.TransientFailure) != (oldAggrState == connectivity.TransientFailure) {
b.regeneratePicker()
}
b.cc.UpdateBalancerState(b.state, b.picker)
}
// Close is a nop because base balancer doesn't have internal state to clean up,
// and it doesn't need to call RemoveSubConn for the SubConns.
func (b *baseBalancer) Close() {
}
// NewErrPicker returns a picker that always returns err on Pick().
func NewErrPicker(err error) balancer.Picker {
return &errPicker{err: err}
}
type errPicker struct {
err error // Pick() always returns this err.
}
func (p *errPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
return nil, nil, p.err
}
// connectivityStateEvaluator gets updated by addrConns when their
// states transition, based on which it evaluates the state of
// ClientConn.
type connectivityStateEvaluator struct {
numReady uint64 // Number of addrConns in ready state.
numConnecting uint64 // Number of addrConns in connecting state.
numTransientFailure uint64 // Number of addrConns in transientFailure.
}
// recordTransition records state change happening in every subConn and based on
// that it evaluates what aggregated state should be.
// It can only transition between Ready, Connecting and TransientFailure. Other states,
// Idle and Shutdown are transitioned into by ClientConn; in the beginning of the connection
// before any subConn is created ClientConn is in idle state. In the end when ClientConn
// closes it is in Shutdown state.
//
// recordTransition should only be called synchronously from the same goroutine.
func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) connectivity.State {
// Update counters.
for idx, state := range []connectivity.State{oldState, newState} {
updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
switch state {
case connectivity.Ready:
cse.numReady += updateVal
case connectivity.Connecting:
cse.numConnecting += updateVal
case connectivity.TransientFailure:
cse.numTransientFailure += updateVal
}
}
// Evaluate.
if cse.numReady > 0 {
return connectivity.Ready
}
if cse.numConnecting > 0 {
return connectivity.Connecting
}
return connectivity.TransientFailure
}
/*
*
* Copyright 2017 gRPC 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 base defines a balancer base that can be used to build balancers with
// different picking algorithms.
//
// The base balancer creates a new SubConn for each resolved address. The
// provided picker will only be notified about READY SubConns.
//
// This package is the base of round_robin balancer, its purpose is to be used
// to build round_robin like balancers with complex picking algorithms.
// Balancers with more complicated logic should try to implement a balancer
// builder from scratch.
//
// All APIs in this package are experimental.
package base
import (
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/resolver"
)
// PickerBuilder creates balancer.Picker.
type PickerBuilder interface {
// Build takes a slice of ready SubConns, and returns a picker that will be
// used by gRPC to pick a SubConn.
Build(readySCs map[resolver.Address]balancer.SubConn) balancer.Picker
}
// NewBalancerBuilder returns a balancer builder. The balancers
// built by this builder will use the picker builder to build pickers.
func NewBalancerBuilder(name string, pb PickerBuilder) balancer.Builder {
return &baseBuilder{
name: name,
pickerBuilder: pb,
}
}
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["roundrobin.go"],
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/balancer/roundrobin",
importpath = "google.golang.org/grpc/balancer/roundrobin",
visibility = ["//visibility:public"],
deps = [
"//vendor/golang.org/x/net/context:go_default_library",
"//vendor/google.golang.org/grpc/balancer:go_default_library",
"//vendor/google.golang.org/grpc/balancer/base:go_default_library",
"//vendor/google.golang.org/grpc/grpclog:go_default_library",
"//vendor/google.golang.org/grpc/resolver:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
*
* Copyright 2017 gRPC 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 roundrobin defines a roundrobin balancer. Roundrobin balancer is
// installed as one of the default balancers in gRPC, users don't need to
// explicitly install this balancer.
package roundrobin
import (
"sync"
"golang.org/x/net/context"
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/base"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/resolver"
)
// Name is the name of round_robin balancer.
const Name = "round_robin"
// newBuilder creates a new roundrobin balancer builder.
func newBuilder() balancer.Builder {
return base.NewBalancerBuilder(Name, &rrPickerBuilder{})
}
func init() {
balancer.Register(newBuilder())
}
type rrPickerBuilder struct{}
func (*rrPickerBuilder) Build(readySCs map[resolver.Address]balancer.SubConn) balancer.Picker {
grpclog.Infof("roundrobinPicker: newPicker called with readySCs: %v", readySCs)
var scs []balancer.SubConn
for _, sc := range readySCs {
scs = append(scs, sc)
}
return &rrPicker{
subConns: scs,
}
}
type rrPicker struct {
// subConns is the snapshot of the roundrobin balancer when this picker was
// created. The slice is immutable. Each Get() will do a round robin
// selection from it and return the selected SubConn.
subConns []balancer.SubConn
mu sync.Mutex
next int
}
func (p *rrPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
if len(p.subConns) <= 0 {
return nil, nil, balancer.ErrNoSubConnAvailable
}
p.mu.Lock()
sc := p.subConns[p.next]
p.next = (p.next + 1) % len(p.subConns)
p.mu.Unlock()
return sc, nil, nil
}
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
package grpc package grpc
import ( import (
"fmt"
"sync" "sync"
"google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer"
...@@ -73,7 +74,7 @@ func (b *scStateUpdateBuffer) load() { ...@@ -73,7 +74,7 @@ func (b *scStateUpdateBuffer) load() {
} }
} }
// get returns the channel that receives a recvMsg in the buffer. // get returns the channel that the scStateUpdate will be sent to.
// //
// Upon receiving, the caller should call load to send another // Upon receiving, the caller should call load to send another
// scStateChangeTuple onto the channel if there is any. // scStateChangeTuple onto the channel if there is any.
...@@ -96,6 +97,9 @@ type ccBalancerWrapper struct { ...@@ -96,6 +97,9 @@ type ccBalancerWrapper struct {
stateChangeQueue *scStateUpdateBuffer stateChangeQueue *scStateUpdateBuffer
resolverUpdateCh chan *resolverUpdate resolverUpdateCh chan *resolverUpdate
done chan struct{} done chan struct{}
mu sync.Mutex
subConns map[*acBalancerWrapper]struct{}
} }
func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.BuildOptions) *ccBalancerWrapper { func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.BuildOptions) *ccBalancerWrapper {
...@@ -104,21 +108,34 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui ...@@ -104,21 +108,34 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui
stateChangeQueue: newSCStateUpdateBuffer(), stateChangeQueue: newSCStateUpdateBuffer(),
resolverUpdateCh: make(chan *resolverUpdate, 1), resolverUpdateCh: make(chan *resolverUpdate, 1),
done: make(chan struct{}), done: make(chan struct{}),
subConns: make(map[*acBalancerWrapper]struct{}),
} }
go ccb.watcher() go ccb.watcher()
ccb.balancer = b.Build(ccb, bopts) ccb.balancer = b.Build(ccb, bopts)
return ccb return ccb
} }
// watcher balancer functions sequencially, so the balancer can be implemeneted // watcher balancer functions sequentially, so the balancer can be implemented
// lock-free. // lock-free.
func (ccb *ccBalancerWrapper) watcher() { func (ccb *ccBalancerWrapper) watcher() {
for { for {
select { select {
case t := <-ccb.stateChangeQueue.get(): case t := <-ccb.stateChangeQueue.get():
ccb.stateChangeQueue.load() ccb.stateChangeQueue.load()
select {
case <-ccb.done:
ccb.balancer.Close()
return
default:
}
ccb.balancer.HandleSubConnStateChange(t.sc, t.state) ccb.balancer.HandleSubConnStateChange(t.sc, t.state)
case t := <-ccb.resolverUpdateCh: case t := <-ccb.resolverUpdateCh:
select {
case <-ccb.done:
ccb.balancer.Close()
return
default:
}
ccb.balancer.HandleResolvedAddrs(t.addrs, t.err) ccb.balancer.HandleResolvedAddrs(t.addrs, t.err)
case <-ccb.done: case <-ccb.done:
} }
...@@ -126,6 +143,13 @@ func (ccb *ccBalancerWrapper) watcher() { ...@@ -126,6 +143,13 @@ func (ccb *ccBalancerWrapper) watcher() {
select { select {
case <-ccb.done: case <-ccb.done:
ccb.balancer.Close() ccb.balancer.Close()
ccb.mu.Lock()
scs := ccb.subConns
ccb.subConns = nil
ccb.mu.Unlock()
for acbw := range scs {
ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
}
return return
default: default:
} }
...@@ -165,33 +189,54 @@ func (ccb *ccBalancerWrapper) handleResolvedAddrs(addrs []resolver.Address, err ...@@ -165,33 +189,54 @@ func (ccb *ccBalancerWrapper) handleResolvedAddrs(addrs []resolver.Address, err
} }
func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
grpclog.Infof("ccBalancerWrapper: new subconn: %v", addrs) if len(addrs) <= 0 {
return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list")
}
ccb.mu.Lock()
defer ccb.mu.Unlock()
if ccb.subConns == nil {
return nil, fmt.Errorf("grpc: ClientConn balancer wrapper was closed")
}
ac, err := ccb.cc.newAddrConn(addrs) ac, err := ccb.cc.newAddrConn(addrs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
acbw := &acBalancerWrapper{ac: ac} acbw := &acBalancerWrapper{ac: ac}
ac.mu.Lock() acbw.ac.mu.Lock()
ac.acbw = acbw ac.acbw = acbw
ac.mu.Unlock() acbw.ac.mu.Unlock()
ccb.subConns[acbw] = struct{}{}
return acbw, nil return acbw, nil
} }
func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) { func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
grpclog.Infof("ccBalancerWrapper: removing subconn")
acbw, ok := sc.(*acBalancerWrapper) acbw, ok := sc.(*acBalancerWrapper)
if !ok { if !ok {
return return
} }
ccb.mu.Lock()
defer ccb.mu.Unlock()
if ccb.subConns == nil {
return
}
delete(ccb.subConns, acbw)
ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain) ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
} }
func (ccb *ccBalancerWrapper) UpdateBalancerState(s connectivity.State, p balancer.Picker) { func (ccb *ccBalancerWrapper) UpdateBalancerState(s connectivity.State, p balancer.Picker) {
grpclog.Infof("ccBalancerWrapper: updating state and picker called by balancer: %v, %p", s, p) ccb.mu.Lock()
defer ccb.mu.Unlock()
if ccb.subConns == nil {
return
}
ccb.cc.csMgr.updateState(s) ccb.cc.csMgr.updateState(s)
ccb.cc.blockingpicker.updatePicker(p) ccb.cc.blockingpicker.updatePicker(p)
} }
func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOption) {
ccb.cc.resolveNow(o)
}
func (ccb *ccBalancerWrapper) Target() string { func (ccb *ccBalancerWrapper) Target() string {
return ccb.cc.target return ccb.cc.target
} }
...@@ -204,9 +249,12 @@ type acBalancerWrapper struct { ...@@ -204,9 +249,12 @@ type acBalancerWrapper struct {
} }
func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) {
grpclog.Infof("acBalancerWrapper: UpdateAddresses called with %v", addrs)
acbw.mu.Lock() acbw.mu.Lock()
defer acbw.mu.Unlock() defer acbw.mu.Unlock()
if len(addrs) <= 0 {
acbw.ac.tearDown(errConnDrain)
return
}
if !acbw.ac.tryUpdateAddrs(addrs) { if !acbw.ac.tryUpdateAddrs(addrs) {
cc := acbw.ac.cc cc := acbw.ac.cc
acbw.ac.mu.Lock() acbw.ac.mu.Lock()
...@@ -234,7 +282,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { ...@@ -234,7 +282,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) {
ac.acbw = acbw ac.acbw = acbw
ac.mu.Unlock() ac.mu.Unlock()
if acState != connectivity.Idle { if acState != connectivity.Idle {
ac.connect(false) ac.connect()
} }
} }
} }
...@@ -242,7 +290,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) { ...@@ -242,7 +290,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) {
func (acbw *acBalancerWrapper) Connect() { func (acbw *acBalancerWrapper) Connect() {
acbw.mu.Lock() acbw.mu.Lock()
defer acbw.mu.Unlock() defer acbw.mu.Unlock()
acbw.ac.connect(false) acbw.ac.connect()
} }
func (acbw *acBalancerWrapper) getAddrConn() *addrConn { func (acbw *acBalancerWrapper) getAddrConn() *addrConn {
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
package grpc package grpc
import ( import (
"strings"
"sync" "sync"
"golang.org/x/net/context" "golang.org/x/net/context"
...@@ -27,6 +28,7 @@ import ( ...@@ -27,6 +28,7 @@ import (
"google.golang.org/grpc/connectivity" "google.golang.org/grpc/connectivity"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/resolver" "google.golang.org/grpc/resolver"
"google.golang.org/grpc/status"
) )
type balancerWrapperBuilder struct { type balancerWrapperBuilder struct {
...@@ -34,20 +36,27 @@ type balancerWrapperBuilder struct { ...@@ -34,20 +36,27 @@ type balancerWrapperBuilder struct {
} }
func (bwb *balancerWrapperBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer { func (bwb *balancerWrapperBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
bwb.b.Start(cc.Target(), BalancerConfig{ targetAddr := cc.Target()
targetSplitted := strings.Split(targetAddr, ":///")
if len(targetSplitted) >= 2 {
targetAddr = targetSplitted[1]
}
bwb.b.Start(targetAddr, BalancerConfig{
DialCreds: opts.DialCreds, DialCreds: opts.DialCreds,
Dialer: opts.Dialer, Dialer: opts.Dialer,
}) })
_, pickfirst := bwb.b.(*pickFirst) _, pickfirst := bwb.b.(*pickFirst)
bw := &balancerWrapper{ bw := &balancerWrapper{
balancer: bwb.b, balancer: bwb.b,
pickfirst: pickfirst, pickfirst: pickfirst,
cc: cc, cc: cc,
startCh: make(chan struct{}), targetAddr: targetAddr,
conns: make(map[resolver.Address]balancer.SubConn), startCh: make(chan struct{}),
connSt: make(map[balancer.SubConn]*scState), conns: make(map[resolver.Address]balancer.SubConn),
csEvltr: &connectivityStateEvaluator{}, connSt: make(map[balancer.SubConn]*scState),
state: connectivity.Idle, csEvltr: &balancer.ConnectivityStateEvaluator{},
state: connectivity.Idle,
} }
cc.UpdateBalancerState(connectivity.Idle, bw) cc.UpdateBalancerState(connectivity.Idle, bw)
go bw.lbWatcher() go bw.lbWatcher()
...@@ -68,11 +77,8 @@ type balancerWrapper struct { ...@@ -68,11 +77,8 @@ type balancerWrapper struct {
balancer Balancer // The v1 balancer. balancer Balancer // The v1 balancer.
pickfirst bool pickfirst bool
cc balancer.ClientConn cc balancer.ClientConn
targetAddr string // Target without the scheme.
// To aggregate the connectivity state.
csEvltr *connectivityStateEvaluator
state connectivity.State
mu sync.Mutex mu sync.Mutex
conns map[resolver.Address]balancer.SubConn conns map[resolver.Address]balancer.SubConn
...@@ -82,18 +88,21 @@ type balancerWrapper struct { ...@@ -82,18 +88,21 @@ type balancerWrapper struct {
// - NewSubConn is created, cc wants to notify balancer of state changes; // - NewSubConn is created, cc wants to notify balancer of state changes;
// - Build hasn't return, cc doesn't have access to balancer. // - Build hasn't return, cc doesn't have access to balancer.
startCh chan struct{} startCh chan struct{}
// To aggregate the connectivity state.
csEvltr *balancer.ConnectivityStateEvaluator
state connectivity.State
} }
// lbWatcher watches the Notify channel of the balancer and manages // lbWatcher watches the Notify channel of the balancer and manages
// connections accordingly. // connections accordingly.
func (bw *balancerWrapper) lbWatcher() { func (bw *balancerWrapper) lbWatcher() {
<-bw.startCh <-bw.startCh
grpclog.Infof("balancerWrapper: is pickfirst: %v\n", bw.pickfirst)
notifyCh := bw.balancer.Notify() notifyCh := bw.balancer.Notify()
if notifyCh == nil { if notifyCh == nil {
// There's no resolver in the balancer. Connect directly. // There's no resolver in the balancer. Connect directly.
a := resolver.Address{ a := resolver.Address{
Addr: bw.cc.Target(), Addr: bw.targetAddr,
Type: resolver.Backend, Type: resolver.Backend,
} }
sc, err := bw.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{}) sc, err := bw.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{})
...@@ -103,7 +112,7 @@ func (bw *balancerWrapper) lbWatcher() { ...@@ -103,7 +112,7 @@ func (bw *balancerWrapper) lbWatcher() {
bw.mu.Lock() bw.mu.Lock()
bw.conns[a] = sc bw.conns[a] = sc
bw.connSt[sc] = &scState{ bw.connSt[sc] = &scState{
addr: Address{Addr: bw.cc.Target()}, addr: Address{Addr: bw.targetAddr},
s: connectivity.Idle, s: connectivity.Idle,
} }
bw.mu.Unlock() bw.mu.Unlock()
...@@ -165,10 +174,10 @@ func (bw *balancerWrapper) lbWatcher() { ...@@ -165,10 +174,10 @@ func (bw *balancerWrapper) lbWatcher() {
sc.Connect() sc.Connect()
} }
} else { } else {
oldSC.UpdateAddresses(newAddrs)
bw.mu.Lock() bw.mu.Lock()
bw.connSt[oldSC].addr = addrs[0] bw.connSt[oldSC].addr = addrs[0]
bw.mu.Unlock() bw.mu.Unlock()
oldSC.UpdateAddresses(newAddrs)
} }
} else { } else {
var ( var (
...@@ -221,7 +230,6 @@ func (bw *balancerWrapper) lbWatcher() { ...@@ -221,7 +230,6 @@ func (bw *balancerWrapper) lbWatcher() {
} }
func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) { func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) {
grpclog.Infof("balancerWrapper: handle subconn state change: %p, %v", sc, s)
bw.mu.Lock() bw.mu.Lock()
defer bw.mu.Unlock() defer bw.mu.Unlock()
scSt, ok := bw.connSt[sc] scSt, ok := bw.connSt[sc]
...@@ -240,7 +248,7 @@ func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s conne ...@@ -240,7 +248,7 @@ func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s conne
scSt.down(errConnClosing) scSt.down(errConnClosing)
} }
} }
sa := bw.csEvltr.recordTransition(oldS, s) sa := bw.csEvltr.RecordTransition(oldS, s)
if bw.state != sa { if bw.state != sa {
bw.state = sa bw.state = sa
} }
...@@ -249,7 +257,6 @@ func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s conne ...@@ -249,7 +257,6 @@ func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s conne
// Remove state for this sc. // Remove state for this sc.
delete(bw.connSt, sc) delete(bw.connSt, sc)
} }
return
} }
func (bw *balancerWrapper) HandleResolvedAddrs([]resolver.Address, error) { func (bw *balancerWrapper) HandleResolvedAddrs([]resolver.Address, error) {
...@@ -262,7 +269,6 @@ func (bw *balancerWrapper) HandleResolvedAddrs([]resolver.Address, error) { ...@@ -262,7 +269,6 @@ func (bw *balancerWrapper) HandleResolvedAddrs([]resolver.Address, error) {
} }
// There should be a resolver inside the balancer. // There should be a resolver inside the balancer.
// All updates here, if any, are ignored. // All updates here, if any, are ignored.
return
} }
func (bw *balancerWrapper) Close() { func (bw *balancerWrapper) Close() {
...@@ -274,7 +280,6 @@ func (bw *balancerWrapper) Close() { ...@@ -274,7 +280,6 @@ func (bw *balancerWrapper) Close() {
close(bw.startCh) close(bw.startCh)
} }
bw.balancer.Close() bw.balancer.Close()
return
} }
// The picker is the balancerWrapper itself. // The picker is the balancerWrapper itself.
...@@ -310,58 +315,14 @@ func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions) ...@@ -310,58 +315,14 @@ func (bw *balancerWrapper) Pick(ctx context.Context, opts balancer.PickOptions)
Metadata: a.Metadata, Metadata: a.Metadata,
}] }]
if !ok && failfast { if !ok && failfast {
return nil, nil, Errorf(codes.Unavailable, "there is no connection available") return nil, nil, status.Errorf(codes.Unavailable, "there is no connection available")
} }
if s, ok := bw.connSt[sc]; failfast && (!ok || s.s != connectivity.Ready) { if s, ok := bw.connSt[sc]; failfast && (!ok || s.s != connectivity.Ready) {
// If the returned sc is not ready and RPC is failfast, // If the returned sc is not ready and RPC is failfast,
// return error, and this RPC will fail. // return error, and this RPC will fail.
return nil, nil, Errorf(codes.Unavailable, "there is no connection available") return nil, nil, status.Errorf(codes.Unavailable, "there is no connection available")
} }
} }
return sc, done, nil return sc, done, nil
} }
// connectivityStateEvaluator gets updated by addrConns when their
// states transition, based on which it evaluates the state of
// ClientConn.
type connectivityStateEvaluator struct {
mu sync.Mutex
numReady uint64 // Number of addrConns in ready state.
numConnecting uint64 // Number of addrConns in connecting state.
numTransientFailure uint64 // Number of addrConns in transientFailure.
}
// recordTransition records state change happening in every subConn and based on
// that it evaluates what aggregated state should be.
// It can only transition between Ready, Connecting and TransientFailure. Other states,
// Idle and Shutdown are transitioned into by ClientConn; in the beginning of the connection
// before any subConn is created ClientConn is in idle state. In the end when ClientConn
// closes it is in Shutdown state.
// TODO Note that in later releases, a ClientConn with no activity will be put into an Idle state.
func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) connectivity.State {
cse.mu.Lock()
defer cse.mu.Unlock()
// Update counters.
for idx, state := range []connectivity.State{oldState, newState} {
updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
switch state {
case connectivity.Ready:
cse.numReady += updateVal
case connectivity.Connecting:
cse.numConnecting += updateVal
case connectivity.TransientFailure:
cse.numTransientFailure += updateVal
}
}
// Evaluate.
if cse.numReady > 0 {
return connectivity.Ready
}
if cse.numConnecting > 0 {
return connectivity.Connecting
}
return connectivity.TransientFailure
}
...@@ -19,86 +19,32 @@ ...@@ -19,86 +19,32 @@
package grpc package grpc
import ( import (
"math" "google.golang.org/grpc/encoding"
"sync" _ "google.golang.org/grpc/encoding/proto" // to register the Codec for "proto"
"github.com/golang/protobuf/proto"
) )
// baseCodec contains the functionality of both Codec and encoding.Codec, but
// omits the name/string, which vary between the two and are not needed for
// anything besides the registry in the encoding package.
type baseCodec interface {
Marshal(v interface{}) ([]byte, error)
Unmarshal(data []byte, v interface{}) error
}
var _ baseCodec = Codec(nil)
var _ baseCodec = encoding.Codec(nil)
// Codec defines the interface gRPC uses to encode and decode messages. // Codec defines the interface gRPC uses to encode and decode messages.
// Note that implementations of this interface must be thread safe; // Note that implementations of this interface must be thread safe;
// a Codec's methods can be called from concurrent goroutines. // a Codec's methods can be called from concurrent goroutines.
//
// Deprecated: use encoding.Codec instead.
type Codec interface { type Codec interface {
// Marshal returns the wire format of v. // Marshal returns the wire format of v.
Marshal(v interface{}) ([]byte, error) Marshal(v interface{}) ([]byte, error)
// Unmarshal parses the wire format into v. // Unmarshal parses the wire format into v.
Unmarshal(data []byte, v interface{}) error Unmarshal(data []byte, v interface{}) error
// String returns the name of the Codec implementation. The returned // String returns the name of the Codec implementation. This is unused by
// string will be used as part of content type in transmission. // gRPC.
String() string String() string
} }
// protoCodec is a Codec implementation with protobuf. It is the default codec for gRPC.
type protoCodec struct {
}
type cachedProtoBuffer struct {
lastMarshaledSize uint32
proto.Buffer
}
func capToMaxInt32(val int) uint32 {
if val > math.MaxInt32 {
return uint32(math.MaxInt32)
}
return uint32(val)
}
func (p protoCodec) marshal(v interface{}, cb *cachedProtoBuffer) ([]byte, error) {
protoMsg := v.(proto.Message)
newSlice := make([]byte, 0, cb.lastMarshaledSize)
cb.SetBuf(newSlice)
cb.Reset()
if err := cb.Marshal(protoMsg); err != nil {
return nil, err
}
out := cb.Bytes()
cb.lastMarshaledSize = capToMaxInt32(len(out))
return out, nil
}
func (p protoCodec) Marshal(v interface{}) ([]byte, error) {
cb := protoBufferPool.Get().(*cachedProtoBuffer)
out, err := p.marshal(v, cb)
// put back buffer and lose the ref to the slice
cb.SetBuf(nil)
protoBufferPool.Put(cb)
return out, err
}
func (p protoCodec) Unmarshal(data []byte, v interface{}) error {
cb := protoBufferPool.Get().(*cachedProtoBuffer)
cb.SetBuf(data)
v.(proto.Message).Reset()
err := cb.Unmarshal(v.(proto.Message))
cb.SetBuf(nil)
protoBufferPool.Put(cb)
return err
}
func (protoCodec) String() string {
return "proto"
}
var (
protoBufferPool = &sync.Pool{
New: func() interface{} {
return &cachedProtoBuffer{
Buffer: proto.Buffer{},
lastMarshaledSize: 16,
}
},
}
)
// Code generated by "stringer -type=Code"; DO NOT EDIT. /*
*
* Copyright 2017 gRPC 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 codes package codes
import "fmt" import "strconv"
const _Code_name = "OKCanceledUnknownInvalidArgumentDeadlineExceededNotFoundAlreadyExistsPermissionDeniedResourceExhaustedFailedPreconditionAbortedOutOfRangeUnimplementedInternalUnavailableDataLossUnauthenticated" func (c Code) String() string {
switch c {
var _Code_index = [...]uint8{0, 2, 10, 17, 32, 48, 56, 69, 85, 102, 120, 127, 137, 150, 158, 169, 177, 192} case OK:
return "OK"
func (i Code) String() string { case Canceled:
if i >= Code(len(_Code_index)-1) { return "Canceled"
return fmt.Sprintf("Code(%d)", i) case Unknown:
return "Unknown"
case InvalidArgument:
return "InvalidArgument"
case DeadlineExceeded:
return "DeadlineExceeded"
case NotFound:
return "NotFound"
case AlreadyExists:
return "AlreadyExists"
case PermissionDenied:
return "PermissionDenied"
case ResourceExhausted:
return "ResourceExhausted"
case FailedPrecondition:
return "FailedPrecondition"
case Aborted:
return "Aborted"
case OutOfRange:
return "OutOfRange"
case Unimplemented:
return "Unimplemented"
case Internal:
return "Internal"
case Unavailable:
return "Unavailable"
case DataLoss:
return "DataLoss"
case Unauthenticated:
return "Unauthenticated"
default:
return "Code(" + strconv.FormatInt(int64(c), 10) + ")"
} }
return _Code_name[_Code_index[i]:_Code_index[i+1]]
} }
...@@ -20,11 +20,14 @@ ...@@ -20,11 +20,14 @@
// consistent across various languages. // consistent across various languages.
package codes package codes
import (
"fmt"
"strconv"
)
// A Code is an unsigned 32-bit error code as defined in the gRPC spec. // A Code is an unsigned 32-bit error code as defined in the gRPC spec.
type Code uint32 type Code uint32
//go:generate stringer -type=Code
const ( const (
// OK is returned on success. // OK is returned on success.
OK Code = 0 OK Code = 0
...@@ -32,9 +35,9 @@ const ( ...@@ -32,9 +35,9 @@ const (
// Canceled indicates the operation was canceled (typically by the caller). // Canceled indicates the operation was canceled (typically by the caller).
Canceled Code = 1 Canceled Code = 1
// Unknown error. An example of where this error may be returned is // Unknown error. An example of where this error may be returned is
// if a Status value received from another address space belongs to // if a Status value received from another address space belongs to
// an error-space that is not known in this address space. Also // an error-space that is not known in this address space. Also
// errors raised by APIs that do not return enough error information // errors raised by APIs that do not return enough error information
// may be converted to this error. // may be converted to this error.
Unknown Code = 2 Unknown Code = 2
...@@ -63,15 +66,11 @@ const ( ...@@ -63,15 +66,11 @@ const (
// PermissionDenied indicates the caller does not have permission to // PermissionDenied indicates the caller does not have permission to
// execute the specified operation. It must not be used for rejections // execute the specified operation. It must not be used for rejections
// caused by exhausting some resource (use ResourceExhausted // caused by exhausting some resource (use ResourceExhausted
// instead for those errors). It must not be // instead for those errors). It must not be
// used if the caller cannot be identified (use Unauthenticated // used if the caller cannot be identified (use Unauthenticated
// instead for those errors). // instead for those errors).
PermissionDenied Code = 7 PermissionDenied Code = 7
// Unauthenticated indicates the request does not have valid
// authentication credentials for the operation.
Unauthenticated Code = 16
// ResourceExhausted indicates some resource has been exhausted, perhaps // ResourceExhausted indicates some resource has been exhausted, perhaps
// a per-user quota, or perhaps the entire file system is out of space. // a per-user quota, or perhaps the entire file system is out of space.
ResourceExhausted Code = 8 ResourceExhausted Code = 8
...@@ -87,7 +86,7 @@ const ( ...@@ -87,7 +86,7 @@ const (
// (b) Use Aborted if the client should retry at a higher-level // (b) Use Aborted if the client should retry at a higher-level
// (e.g., restarting a read-modify-write sequence). // (e.g., restarting a read-modify-write sequence).
// (c) Use FailedPrecondition if the client should not retry until // (c) Use FailedPrecondition if the client should not retry until
// the system state has been explicitly fixed. E.g., if an "rmdir" // the system state has been explicitly fixed. E.g., if an "rmdir"
// fails because the directory is non-empty, FailedPrecondition // fails because the directory is non-empty, FailedPrecondition
// should be returned since the client should not retry unless // should be returned since the client should not retry unless
// they have first fixed up the directory by deleting files from it. // they have first fixed up the directory by deleting files from it.
...@@ -116,7 +115,7 @@ const ( ...@@ -116,7 +115,7 @@ const (
// file size. // file size.
// //
// There is a fair bit of overlap between FailedPrecondition and // There is a fair bit of overlap between FailedPrecondition and
// OutOfRange. We recommend using OutOfRange (the more specific // OutOfRange. We recommend using OutOfRange (the more specific
// error) when it applies so that callers who are iterating through // error) when it applies so that callers who are iterating through
// a space can easily look for an OutOfRange error to detect when // a space can easily look for an OutOfRange error to detect when
// they are done. // they are done.
...@@ -126,8 +125,8 @@ const ( ...@@ -126,8 +125,8 @@ const (
// supported/enabled in this service. // supported/enabled in this service.
Unimplemented Code = 12 Unimplemented Code = 12
// Internal errors. Means some invariants expected by underlying // Internal errors. Means some invariants expected by underlying
// system has been broken. If you see one of these errors, // system has been broken. If you see one of these errors,
// something is very broken. // something is very broken.
Internal Code = 13 Internal Code = 13
...@@ -141,4 +140,58 @@ const ( ...@@ -141,4 +140,58 @@ const (
// DataLoss indicates unrecoverable data loss or corruption. // DataLoss indicates unrecoverable data loss or corruption.
DataLoss Code = 15 DataLoss Code = 15
// Unauthenticated indicates the request does not have valid
// authentication credentials for the operation.
Unauthenticated Code = 16
_maxCode = 17
) )
var strToCode = map[string]Code{
`"OK"`: OK,
`"CANCELLED"`:/* [sic] */ Canceled,
`"UNKNOWN"`: Unknown,
`"INVALID_ARGUMENT"`: InvalidArgument,
`"DEADLINE_EXCEEDED"`: DeadlineExceeded,
`"NOT_FOUND"`: NotFound,
`"ALREADY_EXISTS"`: AlreadyExists,
`"PERMISSION_DENIED"`: PermissionDenied,
`"RESOURCE_EXHAUSTED"`: ResourceExhausted,
`"FAILED_PRECONDITION"`: FailedPrecondition,
`"ABORTED"`: Aborted,
`"OUT_OF_RANGE"`: OutOfRange,
`"UNIMPLEMENTED"`: Unimplemented,
`"INTERNAL"`: Internal,
`"UNAVAILABLE"`: Unavailable,
`"DATA_LOSS"`: DataLoss,
`"UNAUTHENTICATED"`: Unauthenticated,
}
// UnmarshalJSON unmarshals b into the Code.
func (c *Code) UnmarshalJSON(b []byte) error {
// From json.Unmarshaler: By convention, to approximate the behavior of
// Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte("null")) as
// a no-op.
if string(b) == "null" {
return nil
}
if c == nil {
return fmt.Errorf("nil receiver passed to UnmarshalJSON")
}
if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {
if ci >= _maxCode {
return fmt.Errorf("invalid code: %q", ci)
}
*c = Code(ci)
return nil
}
if jc, ok := strToCode[string(b)]; ok {
*c = jc
return nil
}
return fmt.Errorf("invalid code: %q", string(b))
}
...@@ -34,10 +34,8 @@ import ( ...@@ -34,10 +34,8 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
) )
var ( // alpnProtoStr are the specified application level protocols for gRPC.
// alpnProtoStr are the specified application level protocols for gRPC. var alpnProtoStr = []string{"h2"}
alpnProtoStr = []string{"h2"}
)
// PerRPCCredentials defines the common interface for the credentials which need to // PerRPCCredentials defines the common interface for the credentials which need to
// attach security information to every RPC (e.g., oauth2). // attach security information to every RPC (e.g., oauth2).
...@@ -45,8 +43,9 @@ type PerRPCCredentials interface { ...@@ -45,8 +43,9 @@ type PerRPCCredentials interface {
// GetRequestMetadata gets the current request metadata, refreshing // GetRequestMetadata gets the current request metadata, refreshing
// tokens if required. This should be called by the transport layer on // tokens if required. This should be called by the transport layer on
// each request, and the data should be populated in headers or other // each request, and the data should be populated in headers or other
// context. uri is the URI of the entry point for the request. When // context. If a status code is returned, it will be used as the status
// supported by the underlying implementation, ctx can be used for // for the RPC. uri is the URI of the entry point for the request.
// When supported by the underlying implementation, ctx can be used for
// timeout and cancellation. // timeout and cancellation.
// TODO(zhaoq): Define the set of the qualified keys instead of leaving // TODO(zhaoq): Define the set of the qualified keys instead of leaving
// it as an arbitrary string. // it as an arbitrary string.
...@@ -74,11 +73,9 @@ type AuthInfo interface { ...@@ -74,11 +73,9 @@ type AuthInfo interface {
AuthType() string AuthType() string
} }
var ( // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
// ErrConnDispatched indicates that rawConn has been dispatched out of gRPC // and the caller should not close rawConn.
// and the caller should not close rawConn. var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
)
// TransportCredentials defines the common interface for all the live gRPC wire // TransportCredentials defines the common interface for all the live gRPC wire
// protocols and supported transport security protocols (e.g., TLS, SSL). // protocols and supported transport security protocols (e.g., TLS, SSL).
...@@ -135,15 +132,15 @@ func (c tlsCreds) Info() ProtocolInfo { ...@@ -135,15 +132,15 @@ func (c tlsCreds) Info() ProtocolInfo {
} }
} }
func (c *tlsCreds) ClientHandshake(ctx context.Context, addr string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) { func (c *tlsCreds) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (_ net.Conn, _ AuthInfo, err error) {
// use local cfg to avoid clobbering ServerName if using multiple endpoints // use local cfg to avoid clobbering ServerName if using multiple endpoints
cfg := cloneTLSConfig(c.config) cfg := cloneTLSConfig(c.config)
if cfg.ServerName == "" { if cfg.ServerName == "" {
colonPos := strings.LastIndex(addr, ":") colonPos := strings.LastIndex(authority, ":")
if colonPos == -1 { if colonPos == -1 {
colonPos = len(addr) colonPos = len(authority)
} }
cfg.ServerName = addr[:colonPos] cfg.ServerName = authority[:colonPos]
} }
conn := tls.Client(rawConn, cfg) conn := tls.Client(rawConn, cfg)
errChannel := make(chan error, 1) errChannel := make(chan error, 1)
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["encoding.go"],
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/encoding",
importpath = "google.golang.org/grpc/encoding",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//vendor/google.golang.org/grpc/encoding/proto:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
*
* Copyright 2017 gRPC 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 encoding defines the interface for the compressor and codec, and
// functions to register and retrieve compressors and codecs.
//
// This package is EXPERIMENTAL.
package encoding
import (
"io"
"strings"
)
// Identity specifies the optional encoding for uncompressed streams.
// It is intended for grpc internal use only.
const Identity = "identity"
// Compressor is used for compressing and decompressing when sending or
// receiving messages.
type Compressor interface {
// Compress writes the data written to wc to w after compressing it. If an
// error occurs while initializing the compressor, that error is returned
// instead.
Compress(w io.Writer) (io.WriteCloser, error)
// Decompress reads data from r, decompresses it, and provides the
// uncompressed data via the returned io.Reader. If an error occurs while
// initializing the decompressor, that error is returned instead.
Decompress(r io.Reader) (io.Reader, error)
// Name is the name of the compression codec and is used to set the content
// coding header. The result must be static; the result cannot change
// between calls.
Name() string
}
var registeredCompressor = make(map[string]Compressor)
// RegisterCompressor registers the compressor with gRPC by its name. It can
// be activated when sending an RPC via grpc.UseCompressor(). It will be
// automatically accessed when receiving a message based on the content coding
// header. Servers also use it to send a response with the same encoding as
// the request.
//
// NOTE: this function must only be called during initialization time (i.e. in
// an init() function), and is not thread-safe. If multiple Compressors are
// registered with the same name, the one registered last will take effect.
func RegisterCompressor(c Compressor) {
registeredCompressor[c.Name()] = c
}
// GetCompressor returns Compressor for the given compressor name.
func GetCompressor(name string) Compressor {
return registeredCompressor[name]
}
// Codec defines the interface gRPC uses to encode and decode messages. Note
// that implementations of this interface must be thread safe; a Codec's
// methods can be called from concurrent goroutines.
type Codec interface {
// Marshal returns the wire format of v.
Marshal(v interface{}) ([]byte, error)
// Unmarshal parses the wire format into v.
Unmarshal(data []byte, v interface{}) error
// Name returns the name of the Codec implementation. The returned string
// will be used as part of content type in transmission. The result must be
// static; the result cannot change between calls.
Name() string
}
var registeredCodecs = make(map[string]Codec)
// RegisterCodec registers the provided Codec for use with all gRPC clients and
// servers.
//
// The Codec will be stored and looked up by result of its Name() method, which
// should match the content-subtype of the encoding handled by the Codec. This
// is case-insensitive, and is stored and looked up as lowercase. If the
// result of calling Name() is an empty string, RegisterCodec will panic. See
// Content-Type on
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
// more details.
//
// NOTE: this function must only be called during initialization time (i.e. in
// an init() function), and is not thread-safe. If multiple Compressors are
// registered with the same name, the one registered last will take effect.
func RegisterCodec(codec Codec) {
if codec == nil {
panic("cannot register a nil Codec")
}
contentSubtype := strings.ToLower(codec.Name())
if contentSubtype == "" {
panic("cannot register Codec with empty string result for String()")
}
registeredCodecs[contentSubtype] = codec
}
// GetCodec gets a registered Codec by content-subtype, or nil if no Codec is
// registered for the content-subtype.
//
// The content-subtype is expected to be lowercase.
func GetCodec(contentSubtype string) Codec {
return registeredCodecs[contentSubtype]
}
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["proto.go"],
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/encoding/proto",
importpath = "google.golang.org/grpc/encoding/proto",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/golang/protobuf/proto:go_default_library",
"//vendor/google.golang.org/grpc/encoding:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
*
* Copyright 2018 gRPC 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 proto defines the protobuf codec. Importing this package will
// register the codec.
package proto
import (
"math"
"sync"
"github.com/golang/protobuf/proto"
"google.golang.org/grpc/encoding"
)
// Name is the name registered for the proto compressor.
const Name = "proto"
func init() {
encoding.RegisterCodec(codec{})
}
// codec is a Codec implementation with protobuf. It is the default codec for gRPC.
type codec struct{}
type cachedProtoBuffer struct {
lastMarshaledSize uint32
proto.Buffer
}
func capToMaxInt32(val int) uint32 {
if val > math.MaxInt32 {
return uint32(math.MaxInt32)
}
return uint32(val)
}
func marshal(v interface{}, cb *cachedProtoBuffer) ([]byte, error) {
protoMsg := v.(proto.Message)
newSlice := make([]byte, 0, cb.lastMarshaledSize)
cb.SetBuf(newSlice)
cb.Reset()
if err := cb.Marshal(protoMsg); err != nil {
return nil, err
}
out := cb.Bytes()
cb.lastMarshaledSize = capToMaxInt32(len(out))
return out, nil
}
func (codec) Marshal(v interface{}) ([]byte, error) {
if pm, ok := v.(proto.Marshaler); ok {
// object can marshal itself, no need for buffer
return pm.Marshal()
}
cb := protoBufferPool.Get().(*cachedProtoBuffer)
out, err := marshal(v, cb)
// put back buffer and lose the ref to the slice
cb.SetBuf(nil)
protoBufferPool.Put(cb)
return out, err
}
func (codec) Unmarshal(data []byte, v interface{}) error {
protoMsg := v.(proto.Message)
protoMsg.Reset()
if pu, ok := protoMsg.(proto.Unmarshaler); ok {
// object can unmarshal itself, no need for buffer
return pu.Unmarshal(data)
}
cb := protoBufferPool.Get().(*cachedProtoBuffer)
cb.SetBuf(data)
err := cb.Unmarshal(protoMsg)
cb.SetBuf(nil)
protoBufferPool.Put(cb)
return err
}
func (codec) Name() string {
return Name
}
var protoBufferPool = &sync.Pool{
New: func() interface{} {
return &cachedProtoBuffer{
Buffer: proto.Buffer{},
lastMarshaledSize: 16,
}
},
}
/*
*
* Copyright 2018 gRPC 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 grpc
import (
"os"
"strings"
)
const (
envConfigPrefix = "GRPC_GO_"
envConfigStickinessStr = envConfigPrefix + "STICKINESS"
)
var (
envConfigStickinessOn bool
)
func init() {
envConfigStickinessOn = strings.EqualFold(os.Getenv(envConfigStickinessStr), "on")
}
// +build go1.6,!go1.7
/*
*
* Copyright 2016 gRPC 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 grpc
import (
"fmt"
"io"
"net"
"net/http"
"golang.org/x/net/context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/grpc/transport"
)
// dialContext connects to the address on the named network.
func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address)
}
func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error {
req.Cancel = ctx.Done()
if err := req.Write(conn); err != nil {
return fmt.Errorf("failed to write the HTTP request: %v", err)
}
return nil
}
// toRPCErr converts an error into an error from the status package.
func toRPCErr(err error) error {
if err == nil || err == io.EOF {
return err
}
if _, ok := status.FromError(err); ok {
return err
}
switch e := err.(type) {
case transport.StreamError:
return status.Error(e.Code, e.Desc)
case transport.ConnectionError:
return status.Error(codes.Unavailable, e.Desc)
default:
switch err {
case context.DeadlineExceeded:
return status.Error(codes.DeadlineExceeded, err.Error())
case context.Canceled:
return status.Error(codes.Canceled, err.Error())
}
}
return status.Error(codes.Unknown, err.Error())
}
// +build go1.7
/*
*
* Copyright 2016 gRPC 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 grpc
import (
"context"
"fmt"
"io"
"net"
"net/http"
netctx "golang.org/x/net/context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/grpc/transport"
)
// dialContext connects to the address on the named network.
func dialContext(ctx context.Context, network, address string) (net.Conn, error) {
return (&net.Dialer{}).DialContext(ctx, network, address)
}
func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error {
req = req.WithContext(ctx)
if err := req.Write(conn); err != nil {
return fmt.Errorf("failed to write the HTTP request: %v", err)
}
return nil
}
// toRPCErr converts an error into an error from the status package.
func toRPCErr(err error) error {
if err == nil || err == io.EOF {
return err
}
if _, ok := status.FromError(err); ok {
return err
}
switch e := err.(type) {
case transport.StreamError:
return status.Error(e.Code, e.Desc)
case transport.ConnectionError:
return status.Error(codes.Unavailable, e.Desc)
default:
switch err {
case context.DeadlineExceeded, netctx.DeadlineExceeded:
return status.Error(codes.DeadlineExceeded, err.Error())
case context.Canceled, netctx.Canceled:
return status.Error(codes.Canceled, err.Error())
}
}
return status.Error(codes.Unknown, err.Error())
}
...@@ -6,7 +6,11 @@ go_library( ...@@ -6,7 +6,11 @@ go_library(
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages", importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/grpclb/grpc_lb_v1/messages",
importpath = "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", importpath = "google.golang.org/grpc/grpclb/grpc_lb_v1/messages",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = ["//vendor/github.com/golang/protobuf/proto:go_default_library"], deps = [
"//vendor/github.com/golang/protobuf/proto:go_default_library",
"//vendor/github.com/golang/protobuf/ptypes/duration:go_default_library",
"//vendor/github.com/golang/protobuf/ptypes/timestamp:go_default_library",
],
) )
filegroup( filegroup(
......
...@@ -14,35 +14,11 @@ ...@@ -14,35 +14,11 @@
syntax = "proto3"; syntax = "proto3";
package grpc.lb.v1; import "google/protobuf/duration.proto";
option go_package = "messages"; import "google/protobuf/timestamp.proto";
message Duration {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive.
int64 seconds = 1;
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
int32 nanos = 2;
}
message Timestamp { package grpc.lb.v1;
// Represents seconds of UTC time since Unix epoch option go_package = "google.golang.org/grpc/grpclb/grpc_lb_v1/messages";
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
int64 seconds = 1;
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
int32 nanos = 2;
}
message LoadBalanceRequest { message LoadBalanceRequest {
oneof load_balance_request_type { oneof load_balance_request_type {
...@@ -56,16 +32,25 @@ message LoadBalanceRequest { ...@@ -56,16 +32,25 @@ message LoadBalanceRequest {
} }
message InitialLoadBalanceRequest { message InitialLoadBalanceRequest {
// Name of load balanced service (IE, balancer.service.com) // Name of load balanced service (IE, balancer.service.com). Its
// length should be less than 256 bytes. // length should be less than 256 bytes.
string name = 1; string name = 1;
} }
// Contains the number of calls finished for a particular load balance token.
message ClientStatsPerToken {
// See Server.load_balance_token.
string load_balance_token = 1;
// The total number of RPCs that finished associated with the token.
int64 num_calls = 2;
}
// Contains client level statistics that are useful to load balancing. Each // Contains client level statistics that are useful to load balancing. Each
// count except the timestamp should be reset to zero after reporting the stats. // count except the timestamp should be reset to zero after reporting the stats.
message ClientStats { message ClientStats {
// The timestamp of generating the report. // The timestamp of generating the report.
Timestamp timestamp = 1; google.protobuf.Timestamp timestamp = 1;
// The total number of RPCs that started. // The total number of RPCs that started.
int64 num_calls_started = 2; int64 num_calls_started = 2;
...@@ -73,20 +58,17 @@ message ClientStats { ...@@ -73,20 +58,17 @@ message ClientStats {
// The total number of RPCs that finished. // The total number of RPCs that finished.
int64 num_calls_finished = 3; int64 num_calls_finished = 3;
// The total number of RPCs that were dropped by the client because of rate
// limiting.
int64 num_calls_finished_with_drop_for_rate_limiting = 4;
// The total number of RPCs that were dropped by the client because of load
// balancing.
int64 num_calls_finished_with_drop_for_load_balancing = 5;
// The total number of RPCs that failed to reach a server except dropped RPCs. // The total number of RPCs that failed to reach a server except dropped RPCs.
int64 num_calls_finished_with_client_failed_to_send = 6; int64 num_calls_finished_with_client_failed_to_send = 6;
// The total number of RPCs that finished and are known to have been received // The total number of RPCs that finished and are known to have been received
// by a server. // by a server.
int64 num_calls_finished_known_received = 7; int64 num_calls_finished_known_received = 7;
// The list of dropped calls.
repeated ClientStatsPerToken calls_finished_with_drop = 8;
reserved 4, 5;
} }
message LoadBalanceResponse { message LoadBalanceResponse {
...@@ -111,7 +93,7 @@ message InitialLoadBalanceResponse { ...@@ -111,7 +93,7 @@ message InitialLoadBalanceResponse {
// This interval defines how often the client should send the client stats // This interval defines how often the client should send the client stats
// to the load balancer. Stats should only be reported when the duration is // to the load balancer. Stats should only be reported when the duration is
// positive. // positive.
Duration client_stats_report_interval = 2; google.protobuf.Duration client_stats_report_interval = 2;
} }
message ServerList { message ServerList {
...@@ -125,10 +107,8 @@ message ServerList { ...@@ -125,10 +107,8 @@ message ServerList {
reserved 3; reserved 3;
} }
// Contains server information. When none of the [drop_for_*] fields are true, // Contains server information. When the drop field is not true, use the other
// use the other fields. When drop_for_rate_limiting is true, ignore all other // fields.
// fields. Use drop_for_load_balancing only when it is true and
// drop_for_rate_limiting is false.
message Server { message Server {
// A resolved address for the server, serialized in network-byte-order. It may // A resolved address for the server, serialized in network-byte-order. It may
// either be an IPv4 or IPv6 address. // either be an IPv4 or IPv6 address.
...@@ -140,16 +120,14 @@ message Server { ...@@ -140,16 +120,14 @@ message Server {
// An opaque but printable token given to the frontend for each pick. All // An opaque but printable token given to the frontend for each pick. All
// frontend requests for that pick must include the token in its initial // frontend requests for that pick must include the token in its initial
// metadata. The token is used by the backend to verify the request and to // metadata. The token is used by the backend to verify the request and to
// allow the backend to report load to the gRPC LB system. // allow the backend to report load to the gRPC LB system. The token is also
// // used in client stats for reporting dropped calls.
// Its length is variable but less than 50 bytes.
string load_balance_token = 3; string load_balance_token = 3;
// Indicates whether this particular request should be dropped by the client // Indicates whether this particular request should be dropped by the client.
// for rate limiting. // If the request is dropped, there will be a corresponding entry in
bool drop_for_rate_limiting = 4; // ClientStats.calls_finished_with_drop.
bool drop = 4;
// Indicates whether this particular request should be dropped by the client reserved 5;
// for load balancing.
bool drop_for_load_balancing = 5;
} }
...@@ -105,18 +105,21 @@ func Fatalln(args ...interface{}) { ...@@ -105,18 +105,21 @@ func Fatalln(args ...interface{}) {
} }
// Print prints to the logger. Arguments are handled in the manner of fmt.Print. // Print prints to the logger. Arguments are handled in the manner of fmt.Print.
//
// Deprecated: use Info. // Deprecated: use Info.
func Print(args ...interface{}) { func Print(args ...interface{}) {
logger.Info(args...) logger.Info(args...)
} }
// Printf prints to the logger. Arguments are handled in the manner of fmt.Printf. // Printf prints to the logger. Arguments are handled in the manner of fmt.Printf.
//
// Deprecated: use Infof. // Deprecated: use Infof.
func Printf(format string, args ...interface{}) { func Printf(format string, args ...interface{}) {
logger.Infof(format, args...) logger.Infof(format, args...)
} }
// Println prints to the logger. Arguments are handled in the manner of fmt.Println. // Println prints to the logger. Arguments are handled in the manner of fmt.Println.
//
// Deprecated: use Infoln. // Deprecated: use Infoln.
func Println(args ...interface{}) { func Println(args ...interface{}) {
logger.Infoln(args...) logger.Infoln(args...)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
package grpclog package grpclog
// Logger mimics golang's standard Logger as an interface. // Logger mimics golang's standard Logger as an interface.
//
// Deprecated: use LoggerV2. // Deprecated: use LoggerV2.
type Logger interface { type Logger interface {
Fatal(args ...interface{}) Fatal(args ...interface{})
...@@ -31,6 +32,7 @@ type Logger interface { ...@@ -31,6 +32,7 @@ type Logger interface {
// SetLogger sets the logger that is used in grpc. Call only from // SetLogger sets the logger that is used in grpc. Call only from
// init() functions. // init() functions.
//
// Deprecated: use SetLoggerV2. // Deprecated: use SetLoggerV2.
func SetLogger(l Logger) { func SetLogger(l Logger) {
logger = &loggerWrapper{Logger: l} logger = &loggerWrapper{Logger: l}
......
...@@ -8,9 +8,9 @@ go_library( ...@@ -8,9 +8,9 @@ go_library(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/golang.org/x/net/context:go_default_library", "//vendor/golang.org/x/net/context:go_default_library",
"//vendor/google.golang.org/grpc:go_default_library",
"//vendor/google.golang.org/grpc/codes:go_default_library", "//vendor/google.golang.org/grpc/codes:go_default_library",
"//vendor/google.golang.org/grpc/health/grpc_health_v1:go_default_library", "//vendor/google.golang.org/grpc/health/grpc_health_v1:go_default_library",
"//vendor/google.golang.org/grpc/status:go_default_library",
], ],
) )
......
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// source: grpc_health_v1/health.proto // source: grpc/health/v1/health.proto
/*
Package grpc_health_v1 is a generated protocol buffer package.
It is generated from these files:
grpc_health_v1/health.proto
It has these top-level messages:
HealthCheckRequest
HealthCheckResponse
*/
package grpc_health_v1 package grpc_health_v1
import proto "github.com/golang/protobuf/proto" import proto "github.com/golang/protobuf/proto"
...@@ -56,17 +46,39 @@ func (x HealthCheckResponse_ServingStatus) String() string { ...@@ -56,17 +46,39 @@ func (x HealthCheckResponse_ServingStatus) String() string {
return proto.EnumName(HealthCheckResponse_ServingStatus_name, int32(x)) return proto.EnumName(HealthCheckResponse_ServingStatus_name, int32(x))
} }
func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) { func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) {
return fileDescriptor0, []int{1, 0} return fileDescriptor_health_85731b6c49265086, []int{1, 0}
} }
type HealthCheckRequest struct { type HealthCheckRequest struct {
Service string `protobuf:"bytes,1,opt,name=service" json:"service,omitempty"` Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *HealthCheckRequest) Reset() { *m = HealthCheckRequest{} }
func (m *HealthCheckRequest) String() string { return proto.CompactTextString(m) }
func (*HealthCheckRequest) ProtoMessage() {}
func (*HealthCheckRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_health_85731b6c49265086, []int{0}
}
func (m *HealthCheckRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_HealthCheckRequest.Unmarshal(m, b)
}
func (m *HealthCheckRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_HealthCheckRequest.Marshal(b, m, deterministic)
}
func (dst *HealthCheckRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_HealthCheckRequest.Merge(dst, src)
}
func (m *HealthCheckRequest) XXX_Size() int {
return xxx_messageInfo_HealthCheckRequest.Size(m)
}
func (m *HealthCheckRequest) XXX_DiscardUnknown() {
xxx_messageInfo_HealthCheckRequest.DiscardUnknown(m)
} }
func (m *HealthCheckRequest) Reset() { *m = HealthCheckRequest{} } var xxx_messageInfo_HealthCheckRequest proto.InternalMessageInfo
func (m *HealthCheckRequest) String() string { return proto.CompactTextString(m) }
func (*HealthCheckRequest) ProtoMessage() {}
func (*HealthCheckRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *HealthCheckRequest) GetService() string { func (m *HealthCheckRequest) GetService() string {
if m != nil { if m != nil {
...@@ -76,13 +88,35 @@ func (m *HealthCheckRequest) GetService() string { ...@@ -76,13 +88,35 @@ func (m *HealthCheckRequest) GetService() string {
} }
type HealthCheckResponse struct { type HealthCheckResponse struct {
Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,enum=grpc.health.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"` Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=grpc.health.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *HealthCheckResponse) Reset() { *m = HealthCheckResponse{} } func (m *HealthCheckResponse) Reset() { *m = HealthCheckResponse{} }
func (m *HealthCheckResponse) String() string { return proto.CompactTextString(m) } func (m *HealthCheckResponse) String() string { return proto.CompactTextString(m) }
func (*HealthCheckResponse) ProtoMessage() {} func (*HealthCheckResponse) ProtoMessage() {}
func (*HealthCheckResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } func (*HealthCheckResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_health_85731b6c49265086, []int{1}
}
func (m *HealthCheckResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_HealthCheckResponse.Unmarshal(m, b)
}
func (m *HealthCheckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_HealthCheckResponse.Marshal(b, m, deterministic)
}
func (dst *HealthCheckResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_HealthCheckResponse.Merge(dst, src)
}
func (m *HealthCheckResponse) XXX_Size() int {
return xxx_messageInfo_HealthCheckResponse.Size(m)
}
func (m *HealthCheckResponse) XXX_DiscardUnknown() {
xxx_messageInfo_HealthCheckResponse.DiscardUnknown(m)
}
var xxx_messageInfo_HealthCheckResponse proto.InternalMessageInfo
func (m *HealthCheckResponse) GetStatus() HealthCheckResponse_ServingStatus { func (m *HealthCheckResponse) GetStatus() HealthCheckResponse_ServingStatus {
if m != nil { if m != nil {
...@@ -105,8 +139,9 @@ var _ grpc.ClientConn ...@@ -105,8 +139,9 @@ var _ grpc.ClientConn
// is compatible with the grpc package it is being compiled against. // is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4 const _ = grpc.SupportPackageIsVersion4
// Client API for Health service // HealthClient is the client API for Health service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type HealthClient interface { type HealthClient interface {
Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error)
} }
...@@ -121,15 +156,14 @@ func NewHealthClient(cc *grpc.ClientConn) HealthClient { ...@@ -121,15 +156,14 @@ func NewHealthClient(cc *grpc.ClientConn) HealthClient {
func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) {
out := new(HealthCheckResponse) out := new(HealthCheckResponse)
err := grpc.Invoke(ctx, "/grpc.health.v1.Health/Check", in, out, c.cc, opts...) err := c.cc.Invoke(ctx, "/grpc.health.v1.Health/Check", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
// Server API for Health service // HealthServer is the server API for Health service.
type HealthServer interface { type HealthServer interface {
Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error)
} }
...@@ -166,25 +200,28 @@ var _Health_serviceDesc = grpc.ServiceDesc{ ...@@ -166,25 +200,28 @@ var _Health_serviceDesc = grpc.ServiceDesc{
}, },
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "grpc_health_v1/health.proto", Metadata: "grpc/health/v1/health.proto",
} }
func init() { proto.RegisterFile("grpc_health_v1/health.proto", fileDescriptor0) } func init() { proto.RegisterFile("grpc/health/v1/health.proto", fileDescriptor_health_85731b6c49265086) }
var fileDescriptor0 = []byte{ var fileDescriptor_health_85731b6c49265086 = []byte{
// 213 bytes of a gzipped FileDescriptorProto // 271 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0x2f, 0x2a, 0x48, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0x2f, 0x2a, 0x48,
0x8e, 0xcf, 0x48, 0x4d, 0xcc, 0x29, 0xc9, 0x88, 0x2f, 0x33, 0xd4, 0x87, 0xb0, 0xf4, 0x0a, 0x8a, 0xd6, 0xcf, 0x48, 0x4d, 0xcc, 0x29, 0xc9, 0xd0, 0x2f, 0x33, 0x84, 0xb2, 0xf4, 0x0a, 0x8a, 0xf2,
0xf2, 0x4b, 0xf2, 0x85, 0xf8, 0x40, 0x92, 0x7a, 0x50, 0xa1, 0x32, 0x43, 0x25, 0x3d, 0x2e, 0x21, 0x4b, 0xf2, 0x85, 0xf8, 0x40, 0x92, 0x7a, 0x50, 0xa1, 0x32, 0x43, 0x25, 0x3d, 0x2e, 0x21, 0x0f,
0x0f, 0x30, 0xc7, 0x39, 0x23, 0x35, 0x39, 0x3b, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x48, 0x30, 0xc7, 0x39, 0x23, 0x35, 0x39, 0x3b, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x48, 0x82,
0x82, 0x8b, 0xbd, 0x38, 0xb5, 0xa8, 0x2c, 0x33, 0x39, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x8b, 0xbd, 0x38, 0xb5, 0xa8, 0x2c, 0x33, 0x39, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08,
0x08, 0xc6, 0x55, 0x9a, 0xc3, 0xc8, 0x25, 0x8c, 0xa2, 0xa1, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc6, 0x55, 0x9a, 0xc3, 0xc8, 0x25, 0x8c, 0xa2, 0xa1, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc8,
0xc8, 0x93, 0x8b, 0xad, 0xb8, 0x24, 0xb1, 0xa4, 0xb4, 0x18, 0xac, 0x81, 0xcf, 0xc8, 0x50, 0x0f, 0x93, 0x8b, 0xad, 0xb8, 0x24, 0xb1, 0xa4, 0xb4, 0x18, 0xac, 0x81, 0xcf, 0xc8, 0x50, 0x0f, 0xd5,
0xd5, 0x22, 0x3d, 0x2c, 0x9a, 0xf4, 0x82, 0x41, 0x86, 0xe6, 0xa5, 0x07, 0x83, 0x35, 0x06, 0x41, 0x22, 0x3d, 0x2c, 0x9a, 0xf4, 0x82, 0x41, 0x86, 0xe6, 0xa5, 0x07, 0x83, 0x35, 0x06, 0x41, 0x0d,
0x0d, 0x50, 0xb2, 0xe2, 0xe2, 0x45, 0x91, 0x10, 0xe2, 0xe6, 0x62, 0x0f, 0xf5, 0xf3, 0xf6, 0xf3, 0x50, 0xb2, 0xe2, 0xe2, 0x45, 0x91, 0x10, 0xe2, 0xe6, 0x62, 0x0f, 0xf5, 0xf3, 0xf6, 0xf3, 0x0f,
0x0f, 0xf7, 0x13, 0x60, 0x00, 0x71, 0x82, 0x5d, 0x83, 0xc2, 0x3c, 0xfd, 0xdc, 0x05, 0x18, 0x85, 0xf7, 0x13, 0x60, 0x00, 0x71, 0x82, 0x5d, 0x83, 0xc2, 0x3c, 0xfd, 0xdc, 0x05, 0x18, 0x85, 0xf8,
0xf8, 0xb9, 0xb8, 0xfd, 0xfc, 0x43, 0xe2, 0x61, 0x02, 0x4c, 0x46, 0x51, 0x5c, 0x6c, 0x10, 0x8b, 0xb9, 0xb8, 0xfd, 0xfc, 0x43, 0xe2, 0x61, 0x02, 0x4c, 0x46, 0x51, 0x5c, 0x6c, 0x10, 0x8b, 0x84,
0x84, 0x02, 0xb8, 0x58, 0xc1, 0x96, 0x09, 0x29, 0xe1, 0x75, 0x09, 0xd8, 0xbf, 0x52, 0xca, 0x44, 0x02, 0xb8, 0x58, 0xc1, 0x96, 0x09, 0x29, 0xe1, 0x75, 0x09, 0xd8, 0xbf, 0x52, 0xca, 0x44, 0xb8,
0xb8, 0x36, 0x89, 0x0d, 0x1c, 0x82, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x53, 0x2b, 0x65, 0xd6, 0x29, 0x91, 0x4b, 0x30, 0x33, 0x1f, 0x4d, 0xa1, 0x13, 0x37, 0x44, 0x65, 0x00, 0x28, 0x70,
0x20, 0x60, 0x01, 0x00, 0x00, 0x03, 0x18, 0xa3, 0x74, 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0xd2, 0xf3, 0x73, 0x12, 0xf3,
0xd2, 0xf5, 0xf2, 0x8b, 0xd2, 0xf5, 0x91, 0x63, 0x03, 0xc4, 0x8e, 0x87, 0xb0, 0xe3, 0xcb, 0x0c,
0x57, 0x31, 0xf1, 0xb9, 0x83, 0x4c, 0x83, 0x18, 0xa1, 0x17, 0x66, 0x98, 0xc4, 0x06, 0x8e, 0x24,
0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xec, 0x66, 0x81, 0xcb, 0xc3, 0x01, 0x00, 0x00,
} }
// Copyright 2017 gRPC 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.
syntax = "proto3";
package grpc.health.v1;
message HealthCheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
}
ServingStatus status = 1;
}
service Health{
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
}
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* *
*/ */
//go:generate protoc --go_out=plugins=grpc:. grpc_health_v1/health.proto //go:generate ./regenerate.sh
// Package health provides some utility functions to health-check a server. The implementation // Package health provides some utility functions to health-check a server. The implementation
// is based on protobuf. Users need to write their own implementations if other IDLs are used. // is based on protobuf. Users need to write their own implementations if other IDLs are used.
...@@ -26,9 +26,9 @@ import ( ...@@ -26,9 +26,9 @@ import (
"sync" "sync"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
healthpb "google.golang.org/grpc/health/grpc_health_v1" healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/status"
) )
// Server implements `service Health`. // Server implements `service Health`.
...@@ -60,7 +60,7 @@ func (s *Server) Check(ctx context.Context, in *healthpb.HealthCheckRequest) (*h ...@@ -60,7 +60,7 @@ func (s *Server) Check(ctx context.Context, in *healthpb.HealthCheckRequest) (*h
Status: status, Status: status,
}, nil }, nil
} }
return nil, grpc.Errorf(codes.NotFound, "unknown service") return nil, status.Error(codes.NotFound, "unknown service")
} }
// SetServingStatus is called when need to reset the serving status of a service // SetServingStatus is called when need to reset the serving status of a service
......
#!/bin/bash
# Copyright 2018 gRPC 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.
set -eux -o pipefail
TMP=$(mktemp -d)
function finish {
rm -rf "$TMP"
}
trap finish EXIT
pushd "$TMP"
mkdir -p grpc/health/v1
curl https://raw.githubusercontent.com/grpc/grpc-proto/master/grpc/health/v1/health.proto > grpc/health/v1/health.proto
protoc --go_out=plugins=grpc,paths=source_relative:. -I. grpc/health/v1/*.proto
popd
rm -f grpc_health_v1/*.pb.go
cp "$TMP"/grpc/health/v1/*.pb.go grpc_health_v1/
...@@ -48,7 +48,9 @@ type UnaryServerInfo struct { ...@@ -48,7 +48,9 @@ type UnaryServerInfo struct {
} }
// UnaryHandler defines the handler invoked by UnaryServerInterceptor to complete the normal // UnaryHandler defines the handler invoked by UnaryServerInterceptor to complete the normal
// execution of a unary RPC. // execution of a unary RPC. If a UnaryHandler returns an error, it should be produced by the
// status package, or else gRPC will use codes.Unknown as the status code and err.Error() as
// the status message of the RPC.
type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error) type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error)
// UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info // UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info
......
...@@ -17,7 +17,12 @@ filegroup( ...@@ -17,7 +17,12 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//vendor/google.golang.org/grpc/internal/backoff:all-srcs",
"//vendor/google.golang.org/grpc/internal/channelz:all-srcs",
"//vendor/google.golang.org/grpc/internal/grpcrand:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["backoff.go"],
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/internal/backoff",
importpath = "google.golang.org/grpc/internal/backoff",
visibility = ["//vendor/google.golang.org/grpc:__subpackages__"],
deps = ["//vendor/google.golang.org/grpc/internal/grpcrand:go_default_library"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
*
* Copyright 2017 gRPC 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 backoff implement the backoff strategy for gRPC.
//
// This is kept in internal until the gRPC project decides whether or not to
// allow alternative backoff strategies.
package backoff
import (
"time"
"google.golang.org/grpc/internal/grpcrand"
)
// Strategy defines the methodology for backing off after a grpc connection
// failure.
//
type Strategy interface {
// Backoff returns the amount of time to wait before the next retry given
// the number of consecutive failures.
Backoff(retries int) time.Duration
}
const (
// baseDelay is the amount of time to wait before retrying after the first
// failure.
baseDelay = 1.0 * time.Second
// factor is applied to the backoff after each retry.
factor = 1.6
// jitter provides a range to randomize backoff delays.
jitter = 0.2
)
// Exponential implements exponential backoff algorithm as defined in
// https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
type Exponential struct {
// MaxDelay is the upper bound of backoff delay.
MaxDelay time.Duration
}
// Backoff returns the amount of time to wait before the next retry given the
// number of retries.
func (bc Exponential) Backoff(retries int) time.Duration {
if retries == 0 {
return baseDelay
}
backoff, max := float64(baseDelay), float64(bc.MaxDelay)
for backoff < max && retries > 0 {
backoff *= factor
retries--
}
if backoff > max {
backoff = max
}
// Randomize backoff delays so that if a cluster of requests start at
// the same time, they won't operate in lockstep.
backoff *= 1 + jitter*(grpcrand.Float64()*2-1)
if backoff < 0 {
return 0
}
return time.Duration(backoff)
}
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"funcs.go",
"types.go",
],
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/internal/channelz",
importpath = "google.golang.org/grpc/internal/channelz",
visibility = ["//vendor/google.golang.org/grpc:__subpackages__"],
deps = [
"//vendor/google.golang.org/grpc/connectivity:go_default_library",
"//vendor/google.golang.org/grpc/grpclog:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["grpcrand.go"],
importmap = "k8s.io/kubernetes/vendor/google.golang.org/grpc/internal/grpcrand",
importpath = "google.golang.org/grpc/internal/grpcrand",
visibility = ["//vendor/google.golang.org/grpc:__subpackages__"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
*
* Copyright 2018 gRPC 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 grpcrand implements math/rand functions in a concurrent-safe way
// with a global random source, independent of math/rand's global source.
package grpcrand
import (
"math/rand"
"sync"
"time"
)
var (
r = rand.New(rand.NewSource(time.Now().UnixNano()))
mu sync.Mutex
)
// Int63n implements rand.Int63n on the grpcrand global source.
func Int63n(n int64) int64 {
mu.Lock()
res := r.Int63n(n)
mu.Unlock()
return res
}
// Intn implements rand.Intn on the grpcrand global source.
func Intn(n int) int {
mu.Lock()
res := r.Intn(n)
mu.Unlock()
return res
}
// Float64 implements rand.Float64 on the grpcrand global source.
func Float64() float64 {
mu.Lock()
res := r.Float64()
mu.Unlock()
return res
}
...@@ -15,20 +15,22 @@ ...@@ -15,20 +15,22 @@
* *
*/ */
// Package internal contains gRPC-internal code for testing, to avoid polluting // Package internal contains gRPC-internal code, to avoid polluting
// the godoc of the top-level grpc package. // the godoc of the top-level grpc package. It must not import any grpc
// symbols to avoid circular dependencies.
package internal package internal
// TestingCloseConns closes all existing transports but keeps var (
// grpcServer.lis accepting new connections.
//
// The provided grpcServer must be of type *grpc.Server. It is untyped
// for circular dependency reasons.
var TestingCloseConns func(grpcServer interface{})
// TestingUseHandlerImpl enables the http.Handler-based server implementation. // TestingUseHandlerImpl enables the http.Handler-based server implementation.
// It must be called before Serve and requires TLS credentials. // It must be called before Serve and requires TLS credentials.
// //
// The provided grpcServer must be of type *grpc.Server. It is untyped // The provided grpcServer must be of type *grpc.Server. It is untyped
// for circular dependency reasons. // for circular dependency reasons.
var TestingUseHandlerImpl func(grpcServer interface{}) TestingUseHandlerImpl func(grpcServer interface{})
// WithContextDialer is exported by clientconn.go
WithContextDialer interface{} // func(context.Context, string) (net.Conn, error) grpc.DialOption
// WithResolverBuilder is exported by clientconn.go
WithResolverBuilder interface{} // func (resolver.Builder) grpc.DialOption
)
...@@ -17,7 +17,8 @@ ...@@ -17,7 +17,8 @@
*/ */
// Package metadata define the structure of the metadata supported by gRPC library. // Package metadata define the structure of the metadata supported by gRPC library.
// Please refer to https://grpc.io/docs/guides/wire.html for more information about custom-metadata. // Please refer to https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
// for more information about custom-metadata.
package metadata package metadata
import ( import (
...@@ -27,7 +28,9 @@ import ( ...@@ -27,7 +28,9 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
) )
// DecodeKeyValue returns k, v, nil. It is deprecated and should not be used. // DecodeKeyValue returns k, v, nil.
//
// Deprecated: use k and v directly instead.
func DecodeKeyValue(k, v string) (string, string, error) { func DecodeKeyValue(k, v string) (string, string, error) {
return k, v, nil return k, v, nil
} }
...@@ -94,6 +97,30 @@ func (md MD) Copy() MD { ...@@ -94,6 +97,30 @@ func (md MD) Copy() MD {
return Join(md) return Join(md)
} }
// Get obtains the values for a given key.
func (md MD) Get(k string) []string {
k = strings.ToLower(k)
return md[k]
}
// Set sets the value of a given key with a slice of values.
func (md MD) Set(k string, vals ...string) {
if len(vals) == 0 {
return
}
k = strings.ToLower(k)
md[k] = vals
}
// Append adds the values to key k, not overwriting what was already stored at that key.
func (md MD) Append(k string, vals ...string) {
if len(vals) == 0 {
return
}
k = strings.ToLower(k)
md[k] = append(md[k], vals...)
}
// Join joins any number of mds into a single MD. // Join joins any number of mds into a single MD.
// The order of values for each key is determined by the order in which // The order of values for each key is determined by the order in which
// the mds containing those values are presented to Join. // the mds containing those values are presented to Join.
...@@ -115,9 +142,26 @@ func NewIncomingContext(ctx context.Context, md MD) context.Context { ...@@ -115,9 +142,26 @@ func NewIncomingContext(ctx context.Context, md MD) context.Context {
return context.WithValue(ctx, mdIncomingKey{}, md) return context.WithValue(ctx, mdIncomingKey{}, md)
} }
// NewOutgoingContext creates a new context with outgoing md attached. // NewOutgoingContext creates a new context with outgoing md attached. If used
// in conjunction with AppendToOutgoingContext, NewOutgoingContext will
// overwrite any previously-appended metadata.
func NewOutgoingContext(ctx context.Context, md MD) context.Context { func NewOutgoingContext(ctx context.Context, md MD) context.Context {
return context.WithValue(ctx, mdOutgoingKey{}, md) return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md})
}
// AppendToOutgoingContext returns a new context with the provided kv merged
// with any existing metadata in the context. Please refer to the
// documentation of Pairs for a description of kv.
func AppendToOutgoingContext(ctx context.Context, kv ...string) context.Context {
if len(kv)%2 == 1 {
panic(fmt.Sprintf("metadata: AppendToOutgoingContext got an odd number of input pairs for metadata: %d", len(kv)))
}
md, _ := ctx.Value(mdOutgoingKey{}).(rawMD)
added := make([][]string, len(md.added)+1)
copy(added, md.added)
added[len(added)-1] = make([]string, len(kv))
copy(added[len(added)-1], kv)
return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md.md, added: added})
} }
// FromIncomingContext returns the incoming metadata in ctx if it exists. The // FromIncomingContext returns the incoming metadata in ctx if it exists. The
...@@ -128,10 +172,39 @@ func FromIncomingContext(ctx context.Context) (md MD, ok bool) { ...@@ -128,10 +172,39 @@ func FromIncomingContext(ctx context.Context) (md MD, ok bool) {
return return
} }
// FromOutgoingContextRaw returns the un-merged, intermediary contents
// of rawMD. Remember to perform strings.ToLower on the keys. The returned
// MD should not be modified. Writing to it may cause races. Modification
// should be made to copies of the returned MD.
//
// This is intended for gRPC-internal use ONLY.
func FromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) {
raw, ok := ctx.Value(mdOutgoingKey{}).(rawMD)
if !ok {
return nil, nil, false
}
return raw.md, raw.added, true
}
// FromOutgoingContext returns the outgoing metadata in ctx if it exists. The // FromOutgoingContext returns the outgoing metadata in ctx if it exists. The
// returned MD should not be modified. Writing to it may cause races. // returned MD should not be modified. Writing to it may cause races.
// Modification should be made to the copies of the returned MD. // Modification should be made to copies of the returned MD.
func FromOutgoingContext(ctx context.Context) (md MD, ok bool) { func FromOutgoingContext(ctx context.Context) (MD, bool) {
md, ok = ctx.Value(mdOutgoingKey{}).(MD) raw, ok := ctx.Value(mdOutgoingKey{}).(rawMD)
return if !ok {
return nil, false
}
mds := make([]MD, 0, len(raw.added)+1)
mds = append(mds, raw.md)
for _, vv := range raw.added {
mds = append(mds, Pairs(vv...))
}
return Join(mds...), ok
}
type rawMD struct {
md MD
added [][]string
} }
...@@ -153,10 +153,10 @@ type ipWatcher struct { ...@@ -153,10 +153,10 @@ type ipWatcher struct {
updateChan chan *Update updateChan chan *Update
} }
// Next returns the adrress resolution Update for the target. For IP address, // Next returns the address resolution Update for the target. For IP address,
// the resolution is itself, thus polling name server is unncessary. Therefore, // the resolution is itself, thus polling name server is unnecessary. Therefore,
// Next() will return an Update the first time it is called, and will be blocked // Next() will return an Update the first time it is called, and will be blocked
// for all following calls as no Update exisits until watcher is closed. // for all following calls as no Update exists until watcher is closed.
func (i *ipWatcher) Next() ([]*Update, error) { func (i *ipWatcher) Next() ([]*Update, error) {
u, ok := <-i.updateChan u, ok := <-i.updateChan
if !ok { if !ok {
......
// +build go1.7, !go1.8 // +build go1.6,!go1.8
/* /*
* *
......
...@@ -18,20 +18,26 @@ ...@@ -18,20 +18,26 @@
// Package naming defines the naming API and related data structures for gRPC. // Package naming defines the naming API and related data structures for gRPC.
// The interface is EXPERIMENTAL and may be suject to change. // The interface is EXPERIMENTAL and may be suject to change.
//
// Deprecated: please use package resolver.
package naming package naming
// Operation defines the corresponding operations for a name resolution change. // Operation defines the corresponding operations for a name resolution change.
//
// Deprecated: please use package resolver.
type Operation uint8 type Operation uint8
const ( const (
// Add indicates a new address is added. // Add indicates a new address is added.
Add Operation = iota Add Operation = iota
// Delete indicates an exisiting address is deleted. // Delete indicates an existing address is deleted.
Delete Delete
) )
// Update defines a name resolution update. Notice that it is not valid having both // Update defines a name resolution update. Notice that it is not valid having both
// empty string Addr and nil Metadata in an Update. // empty string Addr and nil Metadata in an Update.
//
// Deprecated: please use package resolver.
type Update struct { type Update struct {
// Op indicates the operation of the update. // Op indicates the operation of the update.
Op Operation Op Operation
...@@ -43,12 +49,16 @@ type Update struct { ...@@ -43,12 +49,16 @@ type Update struct {
} }
// Resolver creates a Watcher for a target to track its resolution changes. // Resolver creates a Watcher for a target to track its resolution changes.
//
// Deprecated: please use package resolver.
type Resolver interface { type Resolver interface {
// Resolve creates a Watcher for target. // Resolve creates a Watcher for target.
Resolve(target string) (Watcher, error) Resolve(target string) (Watcher, error)
} }
// Watcher watches for the updates on the specified target. // Watcher watches for the updates on the specified target.
//
// Deprecated: please use package resolver.
type Watcher interface { type Watcher interface {
// Next blocks until an update or error happens. It may return one or more // Next blocks until an update or error happens. It may return one or more
// updates. The first call should get the full set of the results. It should // updates. The first call should get the full set of the results. It should
......
...@@ -19,12 +19,17 @@ ...@@ -19,12 +19,17 @@
package grpc package grpc
import ( import (
"io"
"sync" "sync"
"sync/atomic"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"google.golang.org/grpc/transport" "google.golang.org/grpc/transport"
) )
...@@ -36,13 +41,57 @@ type pickerWrapper struct { ...@@ -36,13 +41,57 @@ type pickerWrapper struct {
done bool done bool
blockingCh chan struct{} blockingCh chan struct{}
picker balancer.Picker picker balancer.Picker
// The latest connection happened.
connErrMu sync.Mutex
connErr error
stickinessMDKey atomic.Value
stickiness *stickyStore
} }
func newPickerWrapper() *pickerWrapper { func newPickerWrapper() *pickerWrapper {
bp := &pickerWrapper{blockingCh: make(chan struct{})} bp := &pickerWrapper{
blockingCh: make(chan struct{}),
stickiness: newStickyStore(),
}
return bp return bp
} }
func (bp *pickerWrapper) updateConnectionError(err error) {
bp.connErrMu.Lock()
bp.connErr = err
bp.connErrMu.Unlock()
}
func (bp *pickerWrapper) connectionError() error {
bp.connErrMu.Lock()
err := bp.connErr
bp.connErrMu.Unlock()
return err
}
func (bp *pickerWrapper) updateStickinessMDKey(newKey string) {
// No need to check ok because mdKey == "" if ok == false.
if oldKey, _ := bp.stickinessMDKey.Load().(string); oldKey != newKey {
bp.stickinessMDKey.Store(newKey)
bp.stickiness.reset(newKey)
}
}
func (bp *pickerWrapper) getStickinessMDKey() string {
// No need to check ok because mdKey == "" if ok == false.
mdKey, _ := bp.stickinessMDKey.Load().(string)
return mdKey
}
func (bp *pickerWrapper) clearStickinessState() {
if oldKey := bp.getStickinessMDKey(); oldKey != "" {
// There's no need to reset store if mdKey was "".
bp.stickiness.reset(oldKey)
}
}
// updatePicker is called by UpdateBalancerState. It unblocks all blocked pick. // updatePicker is called by UpdateBalancerState. It unblocks all blocked pick.
func (bp *pickerWrapper) updatePicker(p balancer.Picker) { func (bp *pickerWrapper) updatePicker(p balancer.Picker) {
bp.mu.Lock() bp.mu.Lock()
...@@ -57,6 +106,23 @@ func (bp *pickerWrapper) updatePicker(p balancer.Picker) { ...@@ -57,6 +106,23 @@ func (bp *pickerWrapper) updatePicker(p balancer.Picker) {
bp.mu.Unlock() bp.mu.Unlock()
} }
func doneChannelzWrapper(acw *acBalancerWrapper, done func(balancer.DoneInfo)) func(balancer.DoneInfo) {
acw.mu.Lock()
ac := acw.ac
acw.mu.Unlock()
ac.incrCallsStarted()
return func(b balancer.DoneInfo) {
if b.Err != nil && b.Err != io.EOF {
ac.incrCallsFailed()
} else {
ac.incrCallsSucceeded()
}
if done != nil {
done(b)
}
}
}
// pick returns the transport that will be used for the RPC. // pick returns the transport that will be used for the RPC.
// It may block in the following cases: // It may block in the following cases:
// - there's no picker // - there's no picker
...@@ -65,6 +131,27 @@ func (bp *pickerWrapper) updatePicker(p balancer.Picker) { ...@@ -65,6 +131,27 @@ func (bp *pickerWrapper) updatePicker(p balancer.Picker) {
// - the subConn returned by the current picker is not READY // - the subConn returned by the current picker is not READY
// When one of these situations happens, pick blocks until the picker gets updated. // When one of these situations happens, pick blocks until the picker gets updated.
func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer.PickOptions) (transport.ClientTransport, func(balancer.DoneInfo), error) { func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer.PickOptions) (transport.ClientTransport, func(balancer.DoneInfo), error) {
mdKey := bp.getStickinessMDKey()
stickyKey, isSticky := stickyKeyFromContext(ctx, mdKey)
// Potential race here: if stickinessMDKey is updated after the above two
// lines, and this pick is a sticky pick, the following put could add an
// entry to sticky store with an outdated sticky key.
//
// The solution: keep the current md key in sticky store, and at the
// beginning of each get/put, check the mdkey against store.curMDKey.
// - Cons: one more string comparing for each get/put.
// - Pros: the string matching happens inside get/put, so the overhead for
// non-sticky RPCs will be minimal.
if isSticky {
if t, ok := bp.stickiness.get(mdKey, stickyKey); ok {
// Done function returned is always nil.
return t, nil, nil
}
}
var ( var (
p balancer.Picker p balancer.Picker
ch chan struct{} ch chan struct{}
...@@ -97,7 +184,7 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer. ...@@ -97,7 +184,7 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer.
p = bp.picker p = bp.picker
bp.mu.Unlock() bp.mu.Unlock()
subConn, put, err := p.Pick(ctx, opts) subConn, done, err := p.Pick(ctx, opts)
if err != nil { if err != nil {
switch err { switch err {
...@@ -107,7 +194,7 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer. ...@@ -107,7 +194,7 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer.
if !failfast { if !failfast {
continue continue
} }
return nil, nil, status.Errorf(codes.Unavailable, "%v", err) return nil, nil, status.Errorf(codes.Unavailable, "%v, latest connection error: %v", err, bp.connectionError())
default: default:
// err is some other error. // err is some other error.
return nil, nil, toRPCErr(err) return nil, nil, toRPCErr(err)
...@@ -120,7 +207,13 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer. ...@@ -120,7 +207,13 @@ func (bp *pickerWrapper) pick(ctx context.Context, failfast bool, opts balancer.
continue continue
} }
if t, ok := acw.getAddrConn().getReadyTransport(); ok { if t, ok := acw.getAddrConn().getReadyTransport(); ok {
return t, put, nil if isSticky {
bp.stickiness.put(mdKey, stickyKey, acw)
}
if channelz.IsOn() {
return t, doneChannelzWrapper(acw, done), nil
}
return t, done, nil
} }
grpclog.Infof("blockingPicker: the picked transport is not ready, loop back to repick") grpclog.Infof("blockingPicker: the picked transport is not ready, loop back to repick")
// If ok == false, ac.state is not READY. // If ok == false, ac.state is not READY.
...@@ -139,3 +232,105 @@ func (bp *pickerWrapper) close() { ...@@ -139,3 +232,105 @@ func (bp *pickerWrapper) close() {
bp.done = true bp.done = true
close(bp.blockingCh) close(bp.blockingCh)
} }
const stickinessKeyCountLimit = 1000
type stickyStoreEntry struct {
acw *acBalancerWrapper
addr resolver.Address
}
type stickyStore struct {
mu sync.Mutex
// curMDKey is check before every get/put to avoid races. The operation will
// abort immediately when the given mdKey is different from the curMDKey.
curMDKey string
store *linkedMap
}
func newStickyStore() *stickyStore {
return &stickyStore{
store: newLinkedMap(),
}
}
// reset clears the map in stickyStore, and set the currentMDKey to newMDKey.
func (ss *stickyStore) reset(newMDKey string) {
ss.mu.Lock()
ss.curMDKey = newMDKey
ss.store.clear()
ss.mu.Unlock()
}
// stickyKey is the key to look up in store. mdKey will be checked against
// curMDKey to avoid races.
func (ss *stickyStore) put(mdKey, stickyKey string, acw *acBalancerWrapper) {
ss.mu.Lock()
defer ss.mu.Unlock()
if mdKey != ss.curMDKey {
return
}
// TODO(stickiness): limit the total number of entries.
ss.store.put(stickyKey, &stickyStoreEntry{
acw: acw,
addr: acw.getAddrConn().getCurAddr(),
})
if ss.store.len() > stickinessKeyCountLimit {
ss.store.removeOldest()
}
}
// stickyKey is the key to look up in store. mdKey will be checked against
// curMDKey to avoid races.
func (ss *stickyStore) get(mdKey, stickyKey string) (transport.ClientTransport, bool) {
ss.mu.Lock()
defer ss.mu.Unlock()
if mdKey != ss.curMDKey {
return nil, false
}
entry, ok := ss.store.get(stickyKey)
if !ok {
return nil, false
}
ac := entry.acw.getAddrConn()
if ac.getCurAddr() != entry.addr {
ss.store.remove(stickyKey)
return nil, false
}
t, ok := ac.getReadyTransport()
if !ok {
ss.store.remove(stickyKey)
return nil, false
}
return t, true
}
// Get one value from metadata in ctx with key stickinessMDKey.
//
// It returns "", false if stickinessMDKey is an empty string.
func stickyKeyFromContext(ctx context.Context, stickinessMDKey string) (string, bool) {
if stickinessMDKey == "" {
return "", false
}
md, added, ok := metadata.FromOutgoingContextRaw(ctx)
if !ok {
return "", false
}
if vv, ok := md[stickinessMDKey]; ok {
if len(vv) > 0 {
return vv[0], true
}
}
for _, ss := range added {
for i := 0; i < len(ss)-1; i += 2 {
if ss[i] == stickinessMDKey {
return ss[i+1], true
}
}
}
return "", false
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment