Skip to content
This repository was archived by the owner on Mar 22, 2018. It is now read-only.

Commit 781a89a

Browse files
committed
rebuild cinder driver by new architecture
0 parents  commit 781a89a

7 files changed

Lines changed: 884 additions & 0 deletions

File tree

app/cinderplugin/main.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"fmt"
21+
"os"
22+
23+
"github.com/kubernetes-csi/drivers/pkg/cinder"
24+
"github.com/spf13/cobra"
25+
)
26+
27+
var (
28+
endpoint string
29+
nodeID string
30+
)
31+
32+
func main() {
33+
cmd := &cobra.Command{
34+
Use: "Cinder",
35+
Short: "CSI based Cinder driver",
36+
Run: func(cmd *cobra.Command, args []string) {
37+
handle()
38+
},
39+
}
40+
41+
cmd.PersistentFlags().StringVar(&nodeID, "nodeid", "", "node id")
42+
cmd.MarkPersistentFlagRequired("nodeid")
43+
44+
cmd.PersistentFlags().StringVar(&endpoint, "endpoint", "", "CSI endpoint")
45+
cmd.MarkPersistentFlagRequired("endpoint")
46+
47+
if err := cmd.Execute(); err != nil {
48+
fmt.Fprintf(os.Stderr, "%s", err.Error())
49+
os.Exit(1)
50+
}
51+
52+
os.Exit(0)
53+
}
54+
55+
func handle() {
56+
d := cinder.NewDriver(nodeID, endpoint)
57+
d.Run()
58+
}

pkg/cinder/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# CSI Cinder driver
2+
3+
## Usage:
4+
5+
### Start Cinder driver
6+
```
7+
$ export OS_USERNAME=admin
8+
$ export OS_PASSWORD=password
9+
$ export OS_TENANT_NAME=admin
10+
$ export OS_AUTH_URL="http://10.0.0.1/identity"
11+
$ export OS_DOMAIN_NAME=Default
12+
$ sudo ./_output/cinderplugin --endpoint tcp://127.0.0.1:10000 --nodeid CSINodeID
13+
```
14+
15+
### Test using csc
16+
Get ```csc``` tool from https://github.com/chakri-nelluri/gocsi/tree/master/csc
17+
18+
#### Get plugin info
19+
```
20+
$ csc identity plugin-info --endpoint tcp://127.0.0.1:10000
21+
"Cinder" "0.1.0"
22+
```
23+
24+
#### Get supported versions
25+
```
26+
$ csc identity supported-versions --endpoint tcp://127.0.0.1:10000
27+
0.1.0
28+
```
29+
30+
#### Create a volume
31+
```
32+
$ csc controller new --endpoint tcp://127.0.0.1:10000 CSIVolumeName
33+
CSIVolumeID
34+
```
35+
36+
#### Delete a volume
37+
```
38+
$ csc controller del --endpoint tcp://127.0.0.1:10000 CSIVolumeID
39+
CSIVolumeID
40+
```
41+
42+
#### ControllerPublish a volume
43+
```
44+
$ csc controller publish --endpoint tcp://127.0.0.1:10000 --node-id=CSINodeID CSIVolumeID
45+
CSIVolumeID "DevicePath"="/dev/xxx"
46+
```
47+
48+
#### ControllerUnpublish a volume
49+
```
50+
$ csc controller unpublish --endpoint tcp://127.0.0.1:10000 --node-id=CSINodeID CSIVolumeID
51+
CSIVolumeID
52+
```
53+
54+
#### NodePublish a volume
55+
```
56+
$ csc node publish --endpoint tcp://127.0.0.1:10000 --target-path /mnt/cinder --pub-info DevicePath="/dev/xxx" CSIVolumeID
57+
CSIVolumeID
58+
```
59+
60+
#### NodeUnpublish a volume
61+
```
62+
$ csc node unpublish --endpoint tcp://127.0.0.1:10000 --target-path /mnt/cinder CSIVolumeID
63+
CSIVolumeID
64+
```
65+
66+
#### Get NodeID
67+
```
68+
$ csc node get-id --endpoint tcp://127.0.0.1:10000
69+
CSINodeID
70+
```

pkg/cinder/controllerserver.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cinder
18+
19+
import (
20+
"github.com/container-storage-interface/spec/lib/go/csi"
21+
"github.com/golang/glog"
22+
"github.com/kubernetes-csi/drivers/pkg/cinder/openstack"
23+
csicommon "github.com/kubernetes-csi/drivers/pkg/csi-common"
24+
"github.com/pborman/uuid"
25+
"golang.org/x/net/context"
26+
"k8s.io/kubernetes/pkg/volume"
27+
)
28+
29+
type controllerServer struct {
30+
*csicommon.DefaultControllerServer
31+
}
32+
33+
func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
34+
35+
// Volume Name
36+
volName := req.GetName()
37+
if len(volName) == 0 {
38+
volName = uuid.NewUUID().String()
39+
}
40+
41+
// Volume Size - Default is 1 GiB
42+
volSizeBytes := int64(1 * 1024 * 1024 * 1024)
43+
if req.GetCapacityRange() != nil {
44+
volSizeBytes = int64(req.GetCapacityRange().GetRequiredBytes())
45+
}
46+
volSizeGB := int(volume.RoundUpSize(volSizeBytes, 1024*1024*1024))
47+
48+
// Volume Type
49+
volType := req.GetParameters()["type"]
50+
if len(volType) == 0 {
51+
volType = "lvmdriver-1"
52+
}
53+
54+
// Volume Availability - Default is nova
55+
volAvailability := req.GetParameters()["availability"]
56+
if len(volType) == 0 {
57+
volAvailability = "nova"
58+
}
59+
60+
// Get OpenStack Provider
61+
cloud, err := openstack.GetOpenStackProvider()
62+
if err != nil {
63+
glog.V(3).Infof("Failed to GetOpenStackProvider: %v", err)
64+
return nil, err
65+
}
66+
67+
// Volume Create
68+
resID, resAvailability, err := cloud.CreateVolume(volName, volSizeGB, volType, volAvailability, nil)
69+
if err != nil {
70+
glog.V(3).Infof("Failed to CreateVolume: %v", err)
71+
return nil, err
72+
}
73+
74+
glog.V(4).Infof("Create volume %s in Availability Zone: %s", resID, resAvailability)
75+
76+
return &csi.CreateVolumeResponse{
77+
VolumeInfo: &csi.VolumeInfo{
78+
Id: resID,
79+
Attributes: map[string]string{
80+
"availability": resAvailability,
81+
},
82+
},
83+
}, nil
84+
}
85+
86+
func (cs *controllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) {
87+
88+
// Get OpenStack Provider
89+
cloud, err := openstack.GetOpenStackProvider()
90+
if err != nil {
91+
glog.V(3).Infof("Failed to GetOpenStackProvider: %v", err)
92+
return nil, err
93+
}
94+
95+
// Volume Delete
96+
volID := req.GetVolumeId()
97+
err = cloud.DeleteVolume(volID)
98+
if err != nil {
99+
glog.V(3).Infof("Failed to CreateVolume: %v", err)
100+
return nil, err
101+
}
102+
103+
glog.V(4).Infof("Delete volume %s", volID)
104+
105+
return &csi.DeleteVolumeResponse{}, nil
106+
}
107+
108+
func (cs *controllerServer) ControllerPublishVolume(ctx context.Context, req *csi.ControllerPublishVolumeRequest) (*csi.ControllerPublishVolumeResponse, error) {
109+
110+
// Get OpenStack Provider
111+
cloud, err := openstack.GetOpenStackProvider()
112+
if err != nil {
113+
glog.V(3).Infof("Failed to GetOpenStackProvider: %v", err)
114+
return nil, err
115+
}
116+
117+
// Volume Attach
118+
instanceID := req.GetNodeId()
119+
volumeID := req.GetVolumeId()
120+
121+
_, err = cloud.AttachVolume(instanceID, volumeID)
122+
if err != nil {
123+
glog.V(3).Infof("Failed to AttachVolume: %v", err)
124+
return nil, err
125+
}
126+
127+
err = cloud.WaitDiskAttached(instanceID, volumeID)
128+
if err != nil {
129+
glog.V(3).Infof("Failed to WaitDiskAttached: %v", err)
130+
return nil, err
131+
}
132+
133+
devicePath, err := cloud.GetAttachmentDiskPath(instanceID, volumeID)
134+
if err != nil {
135+
glog.V(3).Infof("Failed to GetAttachmentDiskPath: %v", err)
136+
return nil, err
137+
}
138+
139+
glog.V(4).Infof("ControllerPublishVolume %s on %s", volumeID, instanceID)
140+
141+
// Publish Volume Info
142+
pvInfo := map[string]string{}
143+
pvInfo["DevicePath"] = devicePath
144+
145+
return &csi.ControllerPublishVolumeResponse{
146+
PublishVolumeInfo: pvInfo,
147+
}, nil
148+
}
149+
150+
func (cs *controllerServer) ControllerUnpublishVolume(ctx context.Context, req *csi.ControllerUnpublishVolumeRequest) (*csi.ControllerUnpublishVolumeResponse, error) {
151+
152+
// Get OpenStack Provider
153+
cloud, err := openstack.GetOpenStackProvider()
154+
if err != nil {
155+
glog.V(3).Infof("Failed to GetOpenStackProvider: %v", err)
156+
return nil, err
157+
}
158+
159+
// Volume Detach
160+
instanceID := req.GetNodeId()
161+
volumeID := req.GetVolumeId()
162+
163+
err = cloud.DetachVolume(instanceID, volumeID)
164+
if err != nil {
165+
glog.V(3).Infof("Failed to DetachVolume: %v", err)
166+
return nil, err
167+
}
168+
169+
err = cloud.WaitDiskDetached(instanceID, volumeID)
170+
if err != nil {
171+
glog.V(3).Infof("Failed to WaitDiskDetached: %v", err)
172+
return nil, err
173+
}
174+
175+
glog.V(4).Infof("ControllerUnpublishVolume %s on %s", volumeID, instanceID)
176+
177+
return &csi.ControllerUnpublishVolumeResponse{}, nil
178+
}

pkg/cinder/driver.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cinder
18+
19+
import (
20+
"github.com/container-storage-interface/spec/lib/go/csi"
21+
"github.com/golang/glog"
22+
23+
"github.com/kubernetes-csi/drivers/pkg/csi-common"
24+
)
25+
26+
type driver struct {
27+
csiDriver *csicommon.CSIDriver
28+
endpoint string
29+
30+
ids *csicommon.DefaultIdentityServer
31+
cs *controllerServer
32+
ns *nodeServer
33+
34+
cap []*csi.VolumeCapability_AccessMode
35+
cscap []*csi.ControllerServiceCapability
36+
}
37+
38+
const (
39+
driverName = "Cinder"
40+
)
41+
42+
var (
43+
version = csi.Version{
44+
Minor: 1,
45+
}
46+
)
47+
48+
func GetSupportedVersions() []*csi.Version {
49+
return []*csi.Version{&version}
50+
}
51+
52+
func NewDriver(nodeID, endpoint string) *driver {
53+
glog.Infof("Driver: %v version: %v", driverName, csicommon.GetVersionString(&version))
54+
55+
d := &driver{}
56+
57+
d.endpoint = endpoint
58+
59+
csiDriver := csicommon.NewCSIDriver(driverName, &version, GetSupportedVersions(), nodeID)
60+
csiDriver.AddControllerServiceCapabilities([]csi.ControllerServiceCapability_RPC_Type{csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME})
61+
csiDriver.AddControllerServiceCapabilities([]csi.ControllerServiceCapability_RPC_Type{csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME})
62+
csiDriver.AddVolumeCapabilityAccessModes([]csi.VolumeCapability_AccessMode_Mode{csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER})
63+
64+
d.csiDriver = csiDriver
65+
66+
return d
67+
}
68+
69+
func NewControllerServer(d *driver) *controllerServer {
70+
return &controllerServer{
71+
DefaultControllerServer: csicommon.NewDefaultControllerServer(d.csiDriver),
72+
}
73+
}
74+
75+
func NewNodeServer(d *driver) *nodeServer {
76+
return &nodeServer{
77+
DefaultNodeServer: csicommon.NewDefaultNodeServer(d.csiDriver),
78+
}
79+
}
80+
81+
func (d *driver) Run() {
82+
csicommon.RunControllerandNodePublishServer(d.endpoint, d.csiDriver, NewControllerServer(d), NewNodeServer(d))
83+
}

0 commit comments

Comments
 (0)