Skip to content

Commit

Permalink
use trivial resizer if only node expansion supported
Browse files Browse the repository at this point in the history
  • Loading branch information
mlmhl committed Mar 7, 2019
1 parent 95bd287 commit c9272a1
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 15 deletions.
2 changes: 1 addition & 1 deletion cmd/csi-resizer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func main() {

informerFactory := informers.NewSharedInformerFactory(kubeClient, *resyncPeriod)

csiResizer, err := resizer.NewCSIResizer(*csiAddress, *csiTimeout, kubeClient, informerFactory)
csiResizer, err := resizer.NewResizer(*csiAddress, *csiTimeout, kubeClient, informerFactory)
if err != nil {
klog.Fatal(err.Error())
}
Expand Down
26 changes: 26 additions & 0 deletions pkg/csi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ type Client interface {
// in ControllerGetCapabilities() gRPC call.
SupportsControllerResize(ctx context.Context) (bool, error)

// SupportsNodeResize returns whether the CSI driver reports EXPAND_VOLUME
// in NodeGetCapabilities() gRPC call.
SupportsNodeResize(ctx context.Context) (bool, error)

// Expand expands the volume to a new size at least as big as requestBytes.
// It returns the new size and whether the volume need expand operation on the node.
Expand(ctx context.Context, volumeID string, requestBytes int64, secrets map[string]string) (int64, bool, error)
Expand All @@ -60,12 +64,14 @@ func New(address string, timeout time.Duration) (Client, error) {

return &client{
conn: conn,
nodeClient: csi.NewNodeClient(conn),
ctrlClient: csi.NewControllerClient(conn),
}, nil
}

type client struct {
conn *grpc.ClientConn
nodeClient csi.NodeClient
ctrlClient csi.ControllerClient
}

Expand All @@ -89,6 +95,26 @@ func (c *client) SupportsControllerResize(ctx context.Context) (bool, error) {
return caps[csi.ControllerServiceCapability_RPC_EXPAND_VOLUME], nil
}

func (c *client) SupportsNodeResize(ctx context.Context) (bool, error) {
rsp, err := c.nodeClient.NodeGetCapabilities(ctx, &csi.NodeGetCapabilitiesRequest{})
if err != nil {
return false, fmt.Errorf("error getting node capabilities: %v", err)
}
for _, capacity := range rsp.GetCapabilities() {
if capacity == nil {
continue
}
rpc := capacity.GetRpc()
if rpc == nil {
continue
}
if rpc.GetType() == csi.NodeServiceCapability_RPC_EXPAND_VOLUME {
return true, nil
}
}
return false, nil
}

func (c *client) Expand(
ctx context.Context,
volumeID string,
Expand Down
28 changes: 21 additions & 7 deletions pkg/resizer/csi_resizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ const (
resizerSecretNamespaceKey = "csi.storage.k8s.io/resizer-secret-namespace"
)

// NewCSIResizer creates a new resizer responsible for resizing CSI volumes.
func NewCSIResizer(
// NewResizer creates a new resizer responsible for resizing CSI volumes.
func NewResizer(
address string, timeout time.Duration,
k8sClient kubernetes.Interface, informerFactory informers.SharedInformerFactory) (Resizer, error) {
csiClient, err := csi.New(address, timeout)
Expand All @@ -55,22 +55,30 @@ func NewCSIResizer(
return nil, fmt.Errorf("get driver name failed: %v", err)
}

supports, err := supportsPluginControllerService(csiClient, timeout)
supportControllerService, err := supportsPluginControllerService(csiClient, timeout)
if err != nil {
return nil, fmt.Errorf("failed to check if plugin supports controller service: %v", err)
}

if !supports {
if !supportControllerService {
return nil, errors.New("CSI driver does not support controller service")
}

supports, err = supportsControllerResize(csiClient, timeout)
supportControllerResize, err := supportsControllerResize(csiClient, timeout)
if err != nil {
return nil, fmt.Errorf("failed to check if plugin supports controller resize: %v", err)
}

if !supports {
return nil, fmt.Errorf("CSI driver does not support controller resize")
if !supportControllerResize {
supportsNodeResize, err := supportsNodeResize(csiClient, timeout)
if err != nil {
return nil, fmt.Errorf("failed to check if plugin supports node resize: %v", err)
}
if supportsNodeResize {
klog.Info("The CSI driver supports node resize only, using trivial resizer to handle resize requests")
return newTrivialResizer(driverName), nil
}
return nil, fmt.Errorf("CSI driver neither supports controller resize nor node resize")
}

return &csiResizer{
Expand Down Expand Up @@ -166,6 +174,12 @@ func supportsControllerResize(client csi.Client, timeout time.Duration) (bool, e
return client.SupportsControllerResize(ctx)
}

func supportsNodeResize(client csi.Client, timeout time.Duration) (bool, error) {
ctx, cancel := timeoutCtx(timeout)
defer cancel()
return client.SupportsNodeResize(ctx)
}

func timeoutCtx(timeout time.Duration) (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), timeout)
}
Expand Down
14 changes: 7 additions & 7 deletions pkg/resizer/trivial_resizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
)

const exampleResizerName = "csi/example-resizer"

// newTrivialResizer returns a trivial resizer which will mark all pvs' resize process as finished.
func newTrivialResizer() Resizer {
return &trivialResizer{}
func newTrivialResizer(name string) Resizer {
return &trivialResizer{name: name}
}

type trivialResizer struct{}
type trivialResizer struct {
name string
}

func (r *trivialResizer) Name() string {
return exampleResizerName
return r.name
}

func (r *trivialResizer) CanSupport(pv *v1.PersistentVolume) bool {
return true
}

func (r *trivialResizer) Resize(pv *v1.PersistentVolume, requestSize resource.Quantity) (newSize resource.Quantity, fsResizeRequired bool, err error) {
return requestSize, false, nil
return requestSize, true, nil
}

0 comments on commit c9272a1

Please sign in to comment.