Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
7fa120c1
Commit
7fa120c1
authored
Aug 07, 2018
by
Cheng Xing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CSI plugin now calls NodeGetInfo() to get driver's node ID
parent
7a901417
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
126 additions
and
9 deletions
+126
-9
csi_client.go
pkg/volume/csi/csi_client.go
+23
-0
csi_client_test.go
pkg/volume/csi/csi_client_test.go
+64
-0
csi_plugin.go
pkg/volume/csi/csi_plugin.go
+23
-5
fake_client.go
pkg/volume/csi/fake/fake_client.go
+13
-0
labelmanager.go
pkg/volume/csi/labelmanager/labelmanager.go
+3
-4
No files found.
pkg/volume/csi/csi_client.go
View file @
7fa120c1
...
@@ -32,6 +32,11 @@ import (
...
@@ -32,6 +32,11 @@ import (
)
)
type
csiClient
interface
{
type
csiClient
interface
{
NodeGetInfo
(
ctx
context
.
Context
)
(
nodeID
string
,
maxVolumePerNode
int64
,
accessibleTopology
*
csipb
.
Topology
,
err
error
)
NodePublishVolume
(
NodePublishVolume
(
ctx
context
.
Context
,
ctx
context
.
Context
,
volumeid
string
,
volumeid
string
,
...
@@ -75,6 +80,24 @@ func newCsiDriverClient(driverName string) *csiDriverClient {
...
@@ -75,6 +80,24 @@ func newCsiDriverClient(driverName string) *csiDriverClient {
return
c
return
c
}
}
func
(
c
*
csiDriverClient
)
NodeGetInfo
(
ctx
context
.
Context
)
(
nodeID
string
,
maxVolumePerNode
int64
,
accessibleTopology
*
csipb
.
Topology
,
err
error
)
{
glog
.
V
(
4
)
.
Info
(
log
(
"calling NodeGetInfo rpc"
))
conn
,
err
:=
newGrpcConn
(
c
.
driverName
)
if
err
!=
nil
{
return
""
,
0
,
nil
,
err
}
defer
conn
.
Close
()
nodeClient
:=
csipb
.
NewNodeClient
(
conn
)
res
,
err
:=
nodeClient
.
NodeGetInfo
(
ctx
,
&
csipb
.
NodeGetInfoRequest
{})
return
res
.
GetNodeId
(),
res
.
GetMaxVolumesPerNode
(),
res
.
GetAccessibleTopology
(),
nil
}
func
(
c
*
csiDriverClient
)
NodePublishVolume
(
func
(
c
*
csiDriverClient
)
NodePublishVolume
(
ctx
context
.
Context
,
ctx
context
.
Context
,
volID
string
,
volID
string
,
...
...
pkg/volume/csi/csi_client_test.go
View file @
7fa120c1
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
csipb
"github.com/container-storage-interface/spec/lib/go/csi/v0"
csipb
"github.com/container-storage-interface/spec/lib/go/csi/v0"
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"
"reflect"
)
)
type
fakeCsiDriverClient
struct
{
type
fakeCsiDriverClient
struct
{
...
@@ -38,6 +39,15 @@ func newFakeCsiDriverClient(t *testing.T, stagingCapable bool) *fakeCsiDriverCli
...
@@ -38,6 +39,15 @@ func newFakeCsiDriverClient(t *testing.T, stagingCapable bool) *fakeCsiDriverCli
}
}
}
}
func
(
c
*
fakeCsiDriverClient
)
NodeGetInfo
(
ctx
context
.
Context
)
(
nodeID
string
,
maxVolumePerNode
int64
,
accessibleTopology
*
csipb
.
Topology
,
err
error
)
{
resp
,
err
:=
c
.
nodeClient
.
NodeGetInfo
(
ctx
,
&
csipb
.
NodeGetInfoRequest
{})
return
resp
.
GetNodeId
(),
resp
.
GetMaxVolumesPerNode
(),
resp
.
GetAccessibleTopology
(),
err
}
func
(
c
*
fakeCsiDriverClient
)
NodePublishVolume
(
func
(
c
*
fakeCsiDriverClient
)
NodePublishVolume
(
ctx
context
.
Context
,
ctx
context
.
Context
,
volID
string
,
volID
string
,
...
@@ -141,6 +151,60 @@ func setupClient(t *testing.T, stageUnstageSet bool) csiClient {
...
@@ -141,6 +151,60 @@ func setupClient(t *testing.T, stageUnstageSet bool) csiClient {
return
newFakeCsiDriverClient
(
t
,
stageUnstageSet
)
return
newFakeCsiDriverClient
(
t
,
stageUnstageSet
)
}
}
func
TestClientNodeGetInfo
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
name
string
expectedNodeID
string
expectedMaxVolumePerNode
int64
expectedAccessibleTopology
*
csipb
.
Topology
mustFail
bool
err
error
}{
{
name
:
"test ok"
,
expectedNodeID
:
"node1"
,
expectedMaxVolumePerNode
:
16
,
expectedAccessibleTopology
:
&
csipb
.
Topology
{
Segments
:
map
[
string
]
string
{
"com.example.csi-topology/zone"
:
"zone1"
},
},
},
{
name
:
"grpc error"
,
mustFail
:
true
,
err
:
errors
.
New
(
"grpc error"
)},
}
client
:=
setupClient
(
t
,
false
/* stageUnstageSet */
)
for
_
,
tc
:=
range
testCases
{
t
.
Logf
(
"test case: %s"
,
tc
.
name
)
client
.
(
*
fakeCsiDriverClient
)
.
nodeClient
.
SetNextError
(
tc
.
err
)
client
.
(
*
fakeCsiDriverClient
)
.
nodeClient
.
SetNodeGetInfoResp
(
&
csipb
.
NodeGetInfoResponse
{
NodeId
:
tc
.
expectedNodeID
,
MaxVolumesPerNode
:
tc
.
expectedMaxVolumePerNode
,
AccessibleTopology
:
tc
.
expectedAccessibleTopology
,
})
nodeID
,
maxVolumePerNode
,
accessibleTopology
,
err
:=
client
.
NodeGetInfo
(
context
.
Background
())
if
tc
.
mustFail
&&
err
==
nil
{
t
.
Error
(
"expected an error but got none"
)
}
if
!
tc
.
mustFail
&&
err
!=
nil
{
t
.
Errorf
(
"expected no errors but got: %v"
,
err
)
}
if
nodeID
!=
tc
.
expectedNodeID
{
t
.
Errorf
(
"expected nodeID: %v; got: %v"
,
tc
.
expectedNodeID
,
nodeID
)
}
if
maxVolumePerNode
!=
tc
.
expectedMaxVolumePerNode
{
t
.
Errorf
(
"expected maxVolumePerNode: %v; got: %v"
,
tc
.
expectedMaxVolumePerNode
,
maxVolumePerNode
)
}
if
!
reflect
.
DeepEqual
(
accessibleTopology
,
tc
.
expectedAccessibleTopology
)
{
t
.
Errorf
(
"expected accessibleTopology: %v; got: %v"
,
*
tc
.
expectedAccessibleTopology
,
*
accessibleTopology
)
}
}
}
func
TestClientNodePublishVolume
(
t
*
testing
.
T
)
{
func
TestClientNodePublishVolume
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
testCases
:=
[]
struct
{
name
string
name
string
...
...
pkg/volume/csi/csi_plugin.go
View file @
7fa120c1
...
@@ -25,6 +25,7 @@ import (
...
@@ -25,6 +25,7 @@ import (
"sync"
"sync"
"time"
"time"
"context"
"github.com/golang/glog"
"github.com/golang/glog"
api
"k8s.io/api/core/v1"
api
"k8s.io/api/core/v1"
meta
"k8s.io/apimachinery/pkg/apis/meta/v1"
meta
"k8s.io/apimachinery/pkg/apis/meta/v1"
...
@@ -76,6 +77,7 @@ type csiDriversStore struct {
...
@@ -76,6 +77,7 @@ type csiDriversStore struct {
sync
.
RWMutex
sync
.
RWMutex
}
}
// TODO (verult) consider using a struct instead of global variables
// csiDrivers map keep track of all registered CSI drivers on the node and their
// csiDrivers map keep track of all registered CSI drivers on the node and their
// corresponding sockets
// corresponding sockets
var
csiDrivers
csiDriversStore
var
csiDrivers
csiDriversStore
...
@@ -92,17 +94,33 @@ func RegistrationCallback(pluginName string, endpoint string, versions []string,
...
@@ -92,17 +94,33 @@ func RegistrationCallback(pluginName string, endpoint string, versions []string,
if
endpoint
==
""
{
if
endpoint
==
""
{
endpoint
=
socketPath
endpoint
=
socketPath
}
}
// Calling nodeLabelManager to update label for newly registered CSI driver
err
:=
lm
.
AddLabels
(
pluginName
)
if
err
!=
nil
{
return
nil
,
err
}
// Storing endpoint of newly registered CSI driver into the map, where CSI driver name will be the key
// Storing endpoint of newly registered CSI driver into the map, where CSI driver name will be the key
// all other CSI components will be able to get the actual socket of CSI drivers by its name.
// all other CSI components will be able to get the actual socket of CSI drivers by its name.
csiDrivers
.
Lock
()
csiDrivers
.
Lock
()
defer
csiDrivers
.
Unlock
()
defer
csiDrivers
.
Unlock
()
csiDrivers
.
driversMap
[
pluginName
]
=
csiDriver
{
driverName
:
pluginName
,
driverEndpoint
:
endpoint
}
csiDrivers
.
driversMap
[
pluginName
]
=
csiDriver
{
driverName
:
pluginName
,
driverEndpoint
:
endpoint
}
// Get node info from the driver.
csi
:=
newCsiDriverClient
(
pluginName
)
// TODO (verult) retry with exponential backoff, possibly added in csi client library.
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
csiTimeout
)
defer
cancel
()
driverNodeID
,
_
,
_
,
err
:=
csi
.
NodeGetInfo
(
ctx
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"error during CSI NodeGetInfo() call: %v"
,
err
)
}
// Calling nodeLabelManager to update annotations and labels for newly registered CSI driver
err
=
lm
.
AddLabels
(
pluginName
,
driverNodeID
)
if
err
!=
nil
{
// Unregister the driver and return error
csiDrivers
.
Lock
()
defer
csiDrivers
.
Unlock
()
delete
(
csiDrivers
.
driversMap
,
pluginName
)
return
nil
,
err
}
return
nil
,
nil
return
nil
,
nil
}
}
...
...
pkg/volume/csi/fake/fake_client.go
View file @
7fa120c1
...
@@ -61,6 +61,7 @@ type NodeClient struct {
...
@@ -61,6 +61,7 @@ type NodeClient struct {
nodePublishedVolumes
map
[
string
]
string
nodePublishedVolumes
map
[
string
]
string
nodeStagedVolumes
map
[
string
]
string
nodeStagedVolumes
map
[
string
]
string
stageUnstageSet
bool
stageUnstageSet
bool
nodeGetInfoResp
*
csipb
.
NodeGetInfoResponse
nextErr
error
nextErr
error
}
}
...
@@ -78,6 +79,10 @@ func (f *NodeClient) SetNextError(err error) {
...
@@ -78,6 +79,10 @@ func (f *NodeClient) SetNextError(err error) {
f
.
nextErr
=
err
f
.
nextErr
=
err
}
}
func
(
f
*
NodeClient
)
SetNodeGetInfoResp
(
resp
*
csipb
.
NodeGetInfoResponse
)
{
f
.
nodeGetInfoResp
=
resp
}
// GetNodePublishedVolumes returns node published volumes
// GetNodePublishedVolumes returns node published volumes
func
(
f
*
NodeClient
)
GetNodePublishedVolumes
()
map
[
string
]
string
{
func
(
f
*
NodeClient
)
GetNodePublishedVolumes
()
map
[
string
]
string
{
return
f
.
nodePublishedVolumes
return
f
.
nodePublishedVolumes
...
@@ -179,6 +184,14 @@ func (f *NodeClient) NodeGetId(ctx context.Context, in *csipb.NodeGetIdRequest,
...
@@ -179,6 +184,14 @@ func (f *NodeClient) NodeGetId(ctx context.Context, in *csipb.NodeGetIdRequest,
return
nil
,
nil
return
nil
,
nil
}
}
// NodeGetId implements csi method
func
(
f
*
NodeClient
)
NodeGetInfo
(
ctx
context
.
Context
,
in
*
csipb
.
NodeGetInfoRequest
,
opts
...
grpc
.
CallOption
)
(
*
csipb
.
NodeGetInfoResponse
,
error
)
{
if
f
.
nextErr
!=
nil
{
return
nil
,
f
.
nextErr
}
return
f
.
nodeGetInfoResp
,
nil
}
// NodeGetCapabilities implements csi method
// NodeGetCapabilities implements csi method
func
(
f
*
NodeClient
)
NodeGetCapabilities
(
ctx
context
.
Context
,
in
*
csipb
.
NodeGetCapabilitiesRequest
,
opts
...
grpc
.
CallOption
)
(
*
csipb
.
NodeGetCapabilitiesResponse
,
error
)
{
func
(
f
*
NodeClient
)
NodeGetCapabilities
(
ctx
context
.
Context
,
in
*
csipb
.
NodeGetCapabilitiesRequest
,
opts
...
grpc
.
CallOption
)
(
*
csipb
.
NodeGetCapabilitiesResponse
,
error
)
{
resp
:=
&
csipb
.
NodeGetCapabilitiesResponse
{
resp
:=
&
csipb
.
NodeGetCapabilitiesResponse
{
...
...
pkg/volume/csi/labelmanager/labelmanager.go
View file @
7fa120c1
...
@@ -34,7 +34,6 @@ const (
...
@@ -34,7 +34,6 @@ const (
// Name of node annotation that contains JSON map of driver names to node
// Name of node annotation that contains JSON map of driver names to node
// names
// names
annotationKey
=
"csi.volume.kubernetes.io/nodeid"
annotationKey
=
"csi.volume.kubernetes.io/nodeid"
csiPluginName
=
"kubernetes.io/csi"
)
)
// labelManagementStruct is struct of channels used for communication between the driver registration
// labelManagementStruct is struct of channels used for communication between the driver registration
...
@@ -46,7 +45,7 @@ type labelManagerStruct struct {
...
@@ -46,7 +45,7 @@ type labelManagerStruct struct {
// Interface implements an interface for managing labels of a node
// Interface implements an interface for managing labels of a node
type
Interface
interface
{
type
Interface
interface
{
AddLabels
(
driverName
string
)
error
AddLabels
(
driverName
string
,
driverNodeId
string
)
error
}
}
// NewLabelManager initializes labelManagerStruct and returns available interfaces
// NewLabelManager initializes labelManagerStruct and returns available interfaces
...
@@ -59,8 +58,8 @@ func NewLabelManager(nodeName types.NodeName, kubeClient kubernetes.Interface) I
...
@@ -59,8 +58,8 @@ func NewLabelManager(nodeName types.NodeName, kubeClient kubernetes.Interface) I
// nodeLabelManager waits for labeling requests initiated by the driver's registration
// nodeLabelManager waits for labeling requests initiated by the driver's registration
// process.
// process.
func
(
lm
labelManagerStruct
)
AddLabels
(
driverName
string
)
error
{
func
(
lm
labelManagerStruct
)
AddLabels
(
driverName
string
,
driverNodeId
string
)
error
{
err
:=
verifyAndAddNodeId
(
string
(
lm
.
nodeName
),
lm
.
k8s
.
CoreV1
()
.
Nodes
(),
driverName
,
string
(
lm
.
nodeName
)
)
err
:=
verifyAndAddNodeId
(
string
(
lm
.
nodeName
),
lm
.
k8s
.
CoreV1
()
.
Nodes
(),
driverName
,
driverNodeId
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to update node %s's annotation with error: %+v"
,
lm
.
nodeName
,
err
)
return
fmt
.
Errorf
(
"failed to update node %s's annotation with error: %+v"
,
lm
.
nodeName
,
err
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment