Skip to content

Commit 7e6bbe5

Browse files
authored
Feature/Add basic csi-node to the driver (#23)
New basic csi node, that implements: - CSI Identity - Node API NodeGetCapabilities - Node APIs stubs and basic verifications: NodeUn\StageVolume, NodeUn\PublishVolume, NodeGetInfo - Node APIs that we don't need to implement: NodeGetVolumeStats, NodeExpandVolume - Makefile for local builds\test\gofmt
1 parent 349adbc commit 7e6bbe5

14 files changed

+1371
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
.coverage
44
.project
55
.pydevproject
6+
/.metadata/
7+
/bin/

Makefile

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#
2+
# Copyright 2019 IBM Corp.
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+
PKG=github.com/ibm/ibm-block-csi-driver
18+
IMAGE=ibmcom/ibm-block-csi-driver
19+
GIT_COMMIT?=$(shell git rev-parse HEAD)
20+
BUILD_DATE?=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
21+
LDFLAGS?="-X ${PKG}/node/pkg/driver.gitCommit=${GIT_COMMIT} -X ${PKG}/node/pkg/driver.buildDate=${BUILD_DATE} -s -w"
22+
GO111MODULE=on
23+
DRIVER_CONFIG_YML=$(shell pwd)/common/config.yaml
24+
25+
.EXPORT_ALL_VARIABLES:
26+
27+
.PHONY: ibm-block-csi-driver
28+
ibm-block-csi-driver:
29+
mkdir -p bin
30+
CGO_ENABLED=0 GOOS=linux go build -ldflags ${LDFLAGS} -o bin/ibm-block-csi-node-driver ./node/cmd
31+
32+
.PHONY: test
33+
test:
34+
go test -v -race ./node/...
35+
36+
.PHONY: gofmt
37+
gofmt:
38+
gofmt -w .
39+
40+
#.PHONY: image-release
41+
#image-release:
42+
# docker build -t $(IMAGE):$(VERSION) .
43+
#
44+
#.PHONY: push-release
45+
#push-release:
46+
# docker push $(IMAGE):$(VERSION)
47+
48+
.PHONY: list
49+
list:
50+
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
51+

go.mod

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module github.com/ibm/ibm-block-csi-driver
2+
3+
go 1.12
4+
5+
require (
6+
github.com/container-storage-interface/spec v1.1.0
7+
github.com/golang/mock v1.1.1
8+
google.golang.org/grpc v1.21.1
9+
gopkg.in/yaml.v2 v2.2.2
10+
k8s.io/klog v0.3.3
11+
)

go.sum

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2+
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
3+
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
4+
github.com/container-storage-interface/spec v1.1.0 h1:qPsTqtR1VUPvMPeK0UnCZMtXaKGyyLPG8gj/wG6VqMs=
5+
github.com/container-storage-interface/spec v1.1.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
6+
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
7+
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
8+
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
9+
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
10+
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
11+
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
12+
github.com/ibm/ibm-block-csi-driver v0.0.0-20190617074002-4a2be9926496 h1:9SV9CXMhrlXiiK8kYe35FnX7pns4zMeNm6UfhrCh8Dw=
13+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
14+
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
15+
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
16+
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
17+
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
18+
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
19+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
20+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
21+
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
22+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
23+
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
24+
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
25+
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
26+
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
27+
google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8=
28+
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
29+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
30+
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
31+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
32+
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
33+
k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c=
34+
k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=

node/cmd/main.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Copyright 2019 IBM Corp.
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+
"flag"
21+
"fmt"
22+
"os"
23+
24+
driver "github.com/ibm/ibm-block-csi-driver/node/pkg/driver"
25+
"k8s.io/klog"
26+
)
27+
28+
func main() {
29+
var (
30+
endpoint = flag.String("csi-endpoint", "unix://csi/csi.sock", "CSI Endpoint")
31+
version = flag.Bool("version", false, "Print the version and exit.")
32+
)
33+
34+
klog.InitFlags(nil)
35+
flag.Parse()
36+
37+
if *version {
38+
info, err := driver.GetVersionJSON()
39+
if err != nil {
40+
klog.Fatalln(err)
41+
}
42+
fmt.Println(info)
43+
os.Exit(0)
44+
}
45+
46+
drv, err := driver.NewDriver(*endpoint)
47+
if err != nil {
48+
klog.Fatalln(err)
49+
}
50+
if err := drv.Run(); err != nil {
51+
klog.Fatalln(err)
52+
}
53+
}

node/pkg/driver/driver.go

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/**
2+
* Copyright 2019 IBM Corp.
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 driver
18+
19+
import (
20+
"context"
21+
csi "github.com/container-storage-interface/spec/lib/go/csi"
22+
util "github.com/ibm/ibm-block-csi-driver/node/util"
23+
"io/ioutil"
24+
"net"
25+
"os"
26+
27+
"google.golang.org/grpc"
28+
"gopkg.in/yaml.v2"
29+
"k8s.io/klog"
30+
)
31+
32+
type Driver struct {
33+
nodeService
34+
srv *grpc.Server
35+
endpoint string
36+
config ConfigFile
37+
}
38+
39+
func NewDriver(endpoint string) (*Driver, error) {
40+
configFile, err := ReadConfigFile()
41+
if err != nil {
42+
return nil, err
43+
}
44+
klog.Infof("Driver: %v Version: %v", configFile.Identity.Name, configFile.Identity.Version)
45+
46+
return &Driver{
47+
endpoint: endpoint,
48+
config: configFile,
49+
nodeService: newNodeService(configFile),
50+
}, nil
51+
}
52+
53+
func (d *Driver) Run() error {
54+
scheme, addr, err := util.ParseEndpoint(d.endpoint)
55+
if err != nil {
56+
return err
57+
}
58+
59+
listener, err := net.Listen(scheme, addr)
60+
if err != nil {
61+
return err
62+
}
63+
64+
logErr := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
65+
resp, err := handler(ctx, req)
66+
if err != nil {
67+
klog.Errorf("GRPC error: %v", err)
68+
}
69+
return resp, err
70+
}
71+
opts := []grpc.ServerOption{
72+
grpc.UnaryInterceptor(logErr),
73+
}
74+
d.srv = grpc.NewServer(opts...)
75+
76+
csi.RegisterIdentityServer(d.srv, d)
77+
csi.RegisterNodeServer(d.srv, d)
78+
79+
klog.Infof("Listening for connections on address: %#v", listener.Addr())
80+
return d.srv.Serve(listener)
81+
}
82+
83+
func (d *Driver) Stop() {
84+
klog.Infof("Stopping server")
85+
d.srv.Stop()
86+
}
87+
88+
type ConfigFile struct {
89+
Identity struct {
90+
Name string
91+
Version string
92+
// TODO missing capabilities
93+
}
94+
Controller struct {
95+
Publish_context_lun_parameter string
96+
Publish_context_connectivity_parameter string
97+
}
98+
}
99+
100+
const (
101+
DefualtConfigFile string = "config.yaml"
102+
EnvNameDriverConfFile string = "DRIVER_CONFIG_YML"
103+
)
104+
105+
func ReadConfigFile() (ConfigFile, error) {
106+
var configFile ConfigFile
107+
108+
configYamlPath := os.Getenv(EnvNameDriverConfFile)
109+
if configYamlPath == "" {
110+
configYamlPath = DefualtConfigFile
111+
klog.V(4).Infof("Not found config file environment variable %s. Set default value %s.", EnvNameDriverConfFile, configYamlPath)
112+
} else {
113+
klog.V(4).Infof("Config file environment variable %s=%s", EnvNameDriverConfFile, configYamlPath)
114+
}
115+
116+
yamlFile, err := ioutil.ReadFile(configYamlPath)
117+
if err != nil {
118+
klog.Errorf("failed to read file %q: %v", yamlFile, err)
119+
return ConfigFile{}, err
120+
}
121+
122+
err = yaml.Unmarshal(yamlFile, &configFile)
123+
if err != nil {
124+
klog.Errorf("error unmarshaling yaml: %v", err)
125+
return ConfigFile{}, err
126+
}
127+
128+
// Verify mandatory attributes in config file
129+
if configFile.Identity.Name == "" {
130+
err := &ConfigYmlEmptyAttribute{"Identity.Name"}
131+
klog.Errorf("%v", err)
132+
return ConfigFile{}, err
133+
}
134+
135+
if configFile.Identity.Version == "" {
136+
err := &ConfigYmlEmptyAttribute{"Identity.Version"}
137+
klog.Errorf("%v", err)
138+
return ConfigFile{}, err
139+
}
140+
141+
return configFile, nil
142+
}

node/pkg/driver/errors.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright 2019 IBM Corp.
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 driver
18+
19+
import (
20+
"fmt"
21+
)
22+
23+
type ConfigYmlEmptyAttribute struct {
24+
Attr string
25+
}
26+
27+
func (e *ConfigYmlEmptyAttribute) Error() string {
28+
return fmt.Sprintf("Missing attribute [%s] in driver config yaml file", e.Attr)
29+
}
30+
31+
type RequestValidationError struct {
32+
Msg string
33+
}
34+
35+
func (e *RequestValidationError) Error() string {
36+
return fmt.Sprintf("Request Validation Error: %s", e.Msg)
37+
}

node/pkg/driver/identity.go

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Copyright 2019 IBM Corp.
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 driver
18+
19+
import (
20+
"context"
21+
22+
csi "github.com/container-storage-interface/spec/lib/go/csi"
23+
"k8s.io/klog"
24+
)
25+
26+
func (d *Driver) GetPluginInfo(ctx context.Context, req *csi.GetPluginInfoRequest) (*csi.GetPluginInfoResponse, error) {
27+
klog.V(5).Infof("GetPluginInfo: called with args %+v", *req)
28+
resp := &csi.GetPluginInfoResponse{
29+
Name: d.config.Identity.Name,
30+
VendorVersion: d.config.Identity.Version,
31+
}
32+
33+
return resp, nil
34+
}
35+
36+
func (d *Driver) GetPluginCapabilities(ctx context.Context, req *csi.GetPluginCapabilitiesRequest) (*csi.GetPluginCapabilitiesResponse, error) {
37+
// TODO take it from ini file
38+
klog.V(5).Infof("GetPluginCapabilities: called with args %+v", *req)
39+
resp := &csi.GetPluginCapabilitiesResponse{
40+
Capabilities: []*csi.PluginCapability{
41+
{
42+
Type: &csi.PluginCapability_Service_{
43+
Service: &csi.PluginCapability_Service{
44+
Type: csi.PluginCapability_Service_CONTROLLER_SERVICE,
45+
},
46+
},
47+
},
48+
},
49+
}
50+
51+
return resp, nil
52+
}
53+
54+
func (d *Driver) Probe(ctx context.Context, req *csi.ProbeRequest) (*csi.ProbeResponse, error) {
55+
klog.V(5).Infof("Probe: called with args %+v", *req)
56+
return &csi.ProbeResponse{}, nil
57+
}

0 commit comments

Comments
 (0)