Skip to content

Commit f3c041b

Browse files
authored
Merge pull request #65 from sbezverk/external_provisioner_cleanup
External provisioner cleanup
2 parents 77426c4 + 9954d50 commit f3c041b

File tree

220 files changed

+20537
-1387
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

220 files changed

+20537
-1387
lines changed

cmd/csi-provisioner/csi-provisioner.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828
ctrl "github.com/kubernetes-csi/external-provisioner/pkg/controller"
2929
"github.com/kubernetes-incubator/external-storage/lib/controller"
3030

31+
"google.golang.org/grpc"
32+
3133
"k8s.io/apimachinery/pkg/util/wait"
3234
"k8s.io/client-go/kubernetes"
3335
"k8s.io/client-go/rest"
@@ -38,7 +40,7 @@ var (
3840
provisioner = flag.String("provisioner", "", "Name of the provisioner. The provisioner will only provision volumes for claims that request a StorageClass with a provisioner field set equal to this name.")
3941
master = flag.String("master", "", "Master URL to build a client config from. Either this or kubeconfig needs to be set if the provisioner is being run out of cluster.")
4042
kubeconfig = flag.String("kubeconfig", "", "Absolute path to the kubeconfig file. Either this or master needs to be set if the provisioner is being run out of cluster.")
41-
csiEndpoint = flag.String("csi-address", "", "The gRPC endpoint for Target CSI Volume")
43+
csiEndpoint = flag.String("csi-address", "/run/csi/socket", "The gRPC endpoint for Target CSI Volume")
4244
connectionTimeout = flag.Duration("connection-timeout", 10*time.Second, "Timeout for waiting for CSI driver socket.")
4345
volumeNamePrefix = flag.String("volume-name-prefix", "kubernetes-dynamic-pv", "Prefix to apply to the name of a created volume")
4446
volumeNameUUIDLength = flag.Int("volume-name-uuid-length", 16, "Length in characters for the generated uuid of a created volume")
@@ -87,9 +89,21 @@ func init() {
8789
timeStamp := time.Now().UnixNano() / int64(time.Millisecond)
8890
identity := strconv.FormatInt(timeStamp, 10) + "-" + strconv.Itoa(rand.Intn(10000)) + "-" + *provisioner
8991

92+
// Provisioner will stay in Init until driver opens csi socket, once it's done
93+
// controller will exit this loop and proceed normally.
94+
socketDown := true
95+
grpcClient := &grpc.ClientConn{}
96+
for socketDown {
97+
grpcClient, err = ctrl.Connect(*csiEndpoint, *connectionTimeout)
98+
if err == nil {
99+
socketDown = false
100+
continue
101+
}
102+
time.Sleep(10 * time.Second)
103+
}
90104
// Create the provisioner: it implements the Provisioner interface expected by
91105
// the controller
92-
csiProvisioner := ctrl.NewCSIProvisioner(clientset, *csiEndpoint, *connectionTimeout, identity, *volumeNamePrefix, *volumeNameUUIDLength)
106+
csiProvisioner := ctrl.NewCSIProvisioner(clientset, *csiEndpoint, *connectionTimeout, identity, *volumeNamePrefix, *volumeNameUUIDLength, grpcClient)
93107
provisionController = controller.NewProvisionController(
94108
clientset,
95109
*provisioner,

main.go

Lines changed: 0 additions & 7 deletions
This file was deleted.

pkg/controller/controller.go

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ const (
4444
secretNamespaceKey = "csiProvisionerSecretNamespace"
4545
)
4646

47+
// CSIProvisioner struct
4748
type csiProvisioner struct {
4849
client kubernetes.Interface
4950
csiClient csi.ControllerClient
50-
driverName string
51+
grpcClient *grpc.ClientConn
5152
timeout time.Duration
5253
identity string
5354
volumeNamePrefix string
@@ -80,7 +81,7 @@ func logGRPC(ctx context.Context, method string, req, reply interface{}, cc *grp
8081
return err
8182
}
8283

83-
func connect(address string, timeout time.Duration) (*grpc.ClientConn, error) {
84+
func Connect(address string, timeout time.Duration) (*grpc.ClientConn, error) {
8485
glog.V(2).Infof("Connecting to %s", address)
8586
dialOptions := []grpc.DialOption{
8687
grpc.WithInsecure(),
@@ -102,7 +103,7 @@ func connect(address string, timeout time.Duration) (*grpc.ClientConn, error) {
102103
for {
103104
if !conn.WaitForStateChange(ctx, conn.GetState()) {
104105
glog.V(4).Infof("Connection timed out")
105-
return conn, nil // return nil, subsequent GetPluginInfo will show the real connection error
106+
return conn, fmt.Errorf("Connection timed out")
106107
}
107108
if conn.GetState() == connectivity.Ready {
108109
glog.V(3).Infof("Connected")
@@ -185,34 +186,19 @@ func supportsControllerCreateVolume(conn *grpc.ClientConn, timeout time.Duration
185186
return false, nil
186187
}
187188

188-
func NewCSIProvisioner(client kubernetes.Interface, csiEndpoint string, connectionTimeout time.Duration, identity string, volumeNamePrefix string, volumeNameUUIDLength int) controller.Provisioner {
189-
grpcClient, err := connect(csiEndpoint, connectionTimeout)
190-
if err != nil || grpcClient == nil {
191-
glog.Fatalf("failed to connect to csi endpoint :%v", err)
192-
}
193-
ok, err := supportsPluginControllerService(grpcClient, connectionTimeout)
194-
if err != nil {
195-
glog.Fatalf("failed to get support info :%v", err)
196-
}
197-
if !ok {
198-
glog.Fatalf("no plugin controller service support detected")
199-
}
200-
ok, err = supportsControllerCreateVolume(grpcClient, connectionTimeout)
201-
if err != nil {
202-
glog.Fatalf("failed to get support info :%v", err)
203-
}
204-
if !ok {
205-
glog.Fatalf("no create/delete volume support detected")
206-
}
207-
driver, err := getDriverName(grpcClient, connectionTimeout)
208-
if err != nil {
209-
glog.Fatalf("failed to get driver info :%v", err)
210-
}
189+
// NewCSIProvisioner creates new CSI provisioner
190+
func NewCSIProvisioner(client kubernetes.Interface,
191+
csiEndpoint string,
192+
connectionTimeout time.Duration,
193+
identity string,
194+
volumeNamePrefix string,
195+
volumeNameUUIDLength int,
196+
grpcClient *grpc.ClientConn) controller.Provisioner {
211197

212198
csiClient := csi.NewControllerClient(grpcClient)
213199
provisioner := &csiProvisioner{
214200
client: client,
215-
driverName: driver,
201+
grpcClient: grpcClient,
216202
csiClient: csiClient,
217203
timeout: connectionTimeout,
218204
identity: identity,
@@ -222,10 +208,45 @@ func NewCSIProvisioner(client kubernetes.Interface, csiEndpoint string, connecti
222208
return provisioner
223209
}
224210

211+
// This function get called before any attepmt to communicate with the driver.
212+
// Before initiating Create/Delete API calls provisioner checks if Capabilities:
213+
// PluginControllerService, ControllerCreateVolume sre supported and gets the driver name.
214+
func checkDriverState(grpcClient *grpc.ClientConn, timeout time.Duration) (string, error) {
215+
ok, err := supportsPluginControllerService(grpcClient, timeout)
216+
if err != nil {
217+
glog.Errorf("failed to get support info :%v", err)
218+
return "", err
219+
}
220+
if !ok {
221+
glog.Errorf("no plugin controller service support detected")
222+
return "", fmt.Errorf("no plugin controller service support detected")
223+
}
224+
ok, err = supportsControllerCreateVolume(grpcClient, timeout)
225+
if err != nil {
226+
glog.Errorf("failed to get support info :%v", err)
227+
return "", err
228+
}
229+
if !ok {
230+
glog.Error("no create/delete volume support detected")
231+
return "", fmt.Errorf("no create/delete volume support detected")
232+
}
233+
driverName, err := getDriverName(grpcClient, timeout)
234+
if err != nil {
235+
glog.Errorf("failed to get driver info :%v", err)
236+
return "", err
237+
}
238+
return driverName, nil
239+
}
240+
225241
func (p *csiProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) {
226242
if options.PVC.Spec.Selector != nil {
227243
return nil, fmt.Errorf("claim Selector is not supported")
228244
}
245+
246+
driverName, err := checkDriverState(p.grpcClient, p.timeout)
247+
if err != nil {
248+
return nil, err
249+
}
229250
// create random share name
230251
share := fmt.Sprintf("%s-%s", p.volumeNamePrefix, strings.Replace(string(uuid.NewUUID()), "-", "", -1)[0:p.volumeNameUUIDLength])
231252
capacity := options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
@@ -283,7 +304,7 @@ func (p *csiProvisioner) Provision(options controller.VolumeOptions) (*v1.Persis
283304
// TODO wait for CSI VolumeSource API
284305
PersistentVolumeSource: v1.PersistentVolumeSource{
285306
CSI: &v1.CSIPersistentVolumeSource{
286-
Driver: p.driverName,
307+
Driver: driverName,
287308
VolumeHandle: p.volumeIdToHandle(rep.Volume.Id),
288309
VolumeAttributes: volumeAttributes,
289310
},
@@ -304,6 +325,11 @@ func (p *csiProvisioner) Delete(volume *v1.PersistentVolume) error {
304325
}
305326
volumeId := p.volumeHandleToId(volume.Spec.CSI.VolumeHandle)
306327

328+
_, err := checkDriverState(p.grpcClient, p.timeout)
329+
if err != nil {
330+
return err
331+
}
332+
307333
req := csi.DeleteVolumeRequest{
308334
VolumeId: volumeId,
309335
}
@@ -322,7 +348,7 @@ func (p *csiProvisioner) Delete(volume *v1.PersistentVolume) error {
322348
ctx, cancel := context.WithTimeout(context.Background(), p.timeout)
323349
defer cancel()
324350

325-
_, err := p.csiClient.DeleteVolume(ctx, &req)
351+
_, err = p.csiClient.DeleteVolume(ctx, &req)
326352

327353
return err
328354
}

pkg/controller/controller_test.go

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type csiConnection struct {
3636
}
3737

3838
func New(address string, timeout time.Duration) (csiConnection, error) {
39-
conn, err := connect(address, timeout)
39+
conn, err := Connect(address, timeout)
4040
if err != nil {
4141
return csiConnection{}, err
4242
}
@@ -70,6 +70,64 @@ func createMockServer(t *testing.T) (*gomock.Controller,
7070
return mockController, drv, identityServer, controllerServer, csiConn, nil
7171
}
7272

73+
func TestGetPluginName(t *testing.T) {
74+
test := struct {
75+
name string
76+
output []*csi.GetPluginInfoResponse
77+
}{
78+
name: "success",
79+
output: []*csi.GetPluginInfoResponse{
80+
{
81+
Name: "csi/example-1",
82+
VendorVersion: "0.2.0",
83+
Manifest: map[string]string{
84+
"hello": "world",
85+
},
86+
},
87+
{
88+
Name: "csi/example-2",
89+
VendorVersion: "0.2.0",
90+
Manifest: map[string]string{
91+
"hello": "world",
92+
},
93+
},
94+
},
95+
}
96+
97+
mockController, driver, identityServer, _, csiConn, err := createMockServer(t)
98+
if err != nil {
99+
t.Fatal(err)
100+
}
101+
defer mockController.Finish()
102+
defer driver.Stop()
103+
104+
in := &csi.GetPluginInfoRequest{}
105+
out := test.output[0]
106+
107+
identityServer.EXPECT().GetPluginInfo(gomock.Any(), in).Return(out, nil).Times(1)
108+
oldName, err := getDriverName(csiConn.conn, timeout)
109+
if err != nil {
110+
t.Errorf("test %q: Failed to get driver's name", test.name)
111+
}
112+
if oldName != test.output[0].Name {
113+
t.Errorf("test %s: failed, expected %s got %s", test.name, test.output[0].Name, oldName)
114+
}
115+
116+
out = test.output[1]
117+
identityServer.EXPECT().GetPluginInfo(gomock.Any(), in).Return(out, nil).Times(1)
118+
newName, err := getDriverName(csiConn.conn, timeout)
119+
if err != nil {
120+
t.Errorf("test %s: Failed to get driver's name", test.name)
121+
}
122+
if newName != test.output[1].Name {
123+
t.Errorf("test %q: failed, expected %s got %s", test.name, test.output[1].Name, newName)
124+
}
125+
126+
if oldName == newName {
127+
t.Errorf("test: %s failed, driver's names should not match", test.name)
128+
}
129+
}
130+
73131
func TestSupportsControllerCreateVolume(t *testing.T) {
74132

75133
tests := []struct {

vendor/github.com/golang/mock/.gitignore

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/golang/mock/.travis.yml

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/golang/mock/AUTHORS

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/golang/mock/CONTRIBUTORS

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)