Skip to content

Commit

Permalink
feat(resize): Implement Volume Expansion Endpoints (#13)
Browse files Browse the repository at this point in the history
Signed-off-by: Payes <[email protected]>
  • Loading branch information
payes authored and vishnuitta committed Aug 28, 2019
1 parent 9456cd6 commit 442a25d
Show file tree
Hide file tree
Showing 13 changed files with 327 additions and 12 deletions.
27 changes: 25 additions & 2 deletions deploy/csi-operator-ubuntu-18.04.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,13 @@ rules:
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["persistentvolumes", "services"]
verbs: ["get", "list", "watch", "create", "delete"]
verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: [""]
resources: ["persistentvolumeclaims/status"]
verbs: ["update", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses", "csinodes"]
verbs: ["get", "list", "watch"]
Expand All @@ -117,6 +120,9 @@ rules:
- apiGroups: ["*"]
resources: ["cstorvolumeclaims"]
verbs: ["*"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["*"]
---

kind: ClusterRoleBinding
Expand Down Expand Up @@ -154,6 +160,19 @@ spec:
priorityClassName: system-cluster-critical
serviceAccount: openebs-csi-controller-sa
containers:
- name: csi-resizer
image: quay.io/k8scsi/csi-resizer:v0.1.0
args:
- "--v=5"
- "--csi-address=$(ADDRESS)"
- "--leader-election"
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
imagePullPolicy: IfNotPresent
volumeMounts:
- name: socket-dir
mountPath: /var/lib/csi/sockets/pluginproxy/
- name: csi-provisioner
image: quay.io/k8scsi/csi-provisioner:v1.0.1
imagePullPolicy: IfNotPresent
Expand All @@ -163,6 +182,10 @@ spec:
- "--v=5"
- "--feature-gates=Topology=true"
env:
- name: MY_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
volumeMounts:
Expand Down Expand Up @@ -354,7 +377,7 @@ rules:
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["persistentvolumes", "nodes", "services"]
verbs: ["get", "list"]
verbs: ["get", "list", "patch"]
- apiGroups: ["*"]
resources: ["csivolumes", "cstorvolumes","cstorvolumeclaims"]
verbs: ["get", "list", "watch", "create", "update", "delete", "patch"]
Expand Down
27 changes: 25 additions & 2 deletions deploy/csi-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,13 @@ rules:
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["persistentvolumes", "services"]
verbs: ["get", "list", "watch", "create", "delete"]
verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: [""]
resources: ["persistentvolumeclaims/status"]
verbs: ["update", "patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses", "csinodes"]
verbs: ["get", "list", "watch"]
Expand All @@ -117,6 +120,9 @@ rules:
- apiGroups: ["*"]
resources: ["cstorvolumeclaims"]
verbs: ["*"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["*"]
---

kind: ClusterRoleBinding
Expand Down Expand Up @@ -154,6 +160,19 @@ spec:
priorityClassName: system-cluster-critical
serviceAccount: openebs-csi-controller-sa
containers:
- name: csi-resizer
image: quay.io/k8scsi/csi-resizer:v0.1.0
args:
- "--v=5"
- "--csi-address=$(ADDRESS)"
- "--leader-election"
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
imagePullPolicy: IfNotPresent
volumeMounts:
- name: socket-dir
mountPath: /var/lib/csi/sockets/pluginproxy/
- name: csi-provisioner
image: quay.io/k8scsi/csi-provisioner:v1.0.1
imagePullPolicy: IfNotPresent
Expand All @@ -163,6 +182,10 @@ spec:
- "--v=5"
- "--feature-gates=Topology=true"
env:
- name: MY_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
volumeMounts:
Expand Down Expand Up @@ -354,7 +377,7 @@ rules:
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["persistentvolumes", "nodes", "services"]
verbs: ["get", "list"]
verbs: ["get", "list", "patch"]
- apiGroups: ["*"]
resources: ["csivolumes", "cstorvolumes","cstorvolumeclaims"]
verbs: ["get", "list", "watch", "create", "update", "delete", "patch"]
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/openebs.io/core/v1alpha1/csivolume.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ const (
// by the application, therefore CSI has only performed iSCSI login
// operation on this volume and avoided filesystem creation and mount.
CSIVolumeStatusRaw CSIVolumeStatus = "Raw"
// CSIVolumeStatusResizeInProgress indicates that the volume is being
// resized
CSIVolumeStatusResizeInProgress CSIVolumeStatus = "ResizeInProgress"
// CSIVolumeStatusMountFailed indicates that login and mount process from
// the volume has bben started but failed kubernetes needs to retry sending
// nodepublish
Expand Down
4 changes: 3 additions & 1 deletion pkg/apis/openebs.io/maya/v1alpha1/cstor_volume_claim.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ const (
// defines the observed state of CStorVolumeClaim
type CStorVolumeClaimStatus struct {
// Phase represents the current phase of CStorVolumeClaim.
Phase CStorVolumeClaimPhase `json:"phase"`
Phase CStorVolumeClaimPhase `json:"phase"`
// Capacity the actual resources of the underlying volume.
Capacity corev1.ResourceList `json:"capacity,omitempty"`
Conditions []CStorVolumeClaimCondition `json:"condition,omitempty"`
}

Expand Down
7 changes: 7 additions & 0 deletions pkg/apis/openebs.io/maya/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions pkg/iscsi/v1alpha1/iscsi_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,3 +684,30 @@ func (util *ISCSIUtil) UnmountDisk(

return c.mounter.Unmount(targetPath)
}

// ReScan rescans all the iSCSI sessions on the host
func (util *ISCSIUtil) ReScan() error {
b := &iscsiDiskMounter{
exec: mount.NewOsExec(),
}
out, err := b.exec.Run("iscsiadm", "-m", "session", "--rescan")
if err != nil {
glog.Errorf("iscsi: rescan failed error: %s", string(out))
return err
}
return nil
}

// ReSizeFS can be used to run a resize command on the filesystem to expand the
// filesystem to the actual size of the device
func (util *ISCSIUtil) ReSizeFS(path string) error {
b := &iscsiDiskMounter{
exec: mount.NewOsExec(),
}
out, err := b.exec.Run("resize2fs", path)
if err != nil {
glog.Errorf("iscsi: resize failed error: %s", string(out))
return err
}
return nil
}
20 changes: 20 additions & 0 deletions pkg/iscsi/v1alpha1/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,23 @@ func Unmount(path string) error {
util := &ISCSIUtil{}
return util.UnmountDisk(*diskUnmounter, path)
}

// ResizeVolume rescans the iSCSI session and runs the resize to filesystem
// command on that particular device
func ResizeVolume(volumePath string) error {
mounter := mount.New("")
list, _ := mounter.List()
for _, mpt := range list {
if mpt.Path == volumePath {
util := &ISCSIUtil{}
if err := util.ReScan(); err != nil {
return err
}
if err := util.ReSizeFS(mpt.Device); err != nil {
return err
}
break
}
}
return nil
}
54 changes: 54 additions & 0 deletions pkg/payload/v1alpha1/resize.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Copyright © 2018-2019 The OpenEBS Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"github.com/container-storage-interface/spec/lib/go/csi"
)

// ControllerExpandVolumeResponseBuilder helps building an
// instance of csi ControllerExpandVolumeResponse
type ControllerExpandVolumeResponseBuilder struct {
response *csi.ControllerExpandVolumeResponse
}

// NewControllerExpandVolumeResponseBuilder returns a new
// instance of ControllerExpandVolumeResponse
func NewControllerExpandVolumeResponseBuilder() *ControllerExpandVolumeResponseBuilder {
return &ControllerExpandVolumeResponseBuilder{
response: &csi.ControllerExpandVolumeResponse{},
}
}

// WithCapacityBytes sets the CapacityBytes against the
// ControllerExpandVolumeResponse instance
func (b *ControllerExpandVolumeResponseBuilder) WithCapacityBytes(
capacity int64) *ControllerExpandVolumeResponseBuilder {
b.response.CapacityBytes = capacity
return b
}

// WithNodeExpansionRequired sets the NodeExpansionRequired against the
// ControllerExpandVolumeResponse instance
func (b *ControllerExpandVolumeResponseBuilder) WithNodeExpansionRequired(
nodeExpansionRequired bool) *ControllerExpandVolumeResponseBuilder {
b.response.NodeExpansionRequired = nodeExpansionRequired
return b
}

// Build returns the constructed instance
// of csi ControllerExpandVolumeResponse
func (b *ControllerExpandVolumeResponseBuilder) Build() *csi.ControllerExpandVolumeResponse {
return b.response
}
16 changes: 14 additions & 2 deletions pkg/service/v1alpha1/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,19 @@ func (cs *controller) ControllerExpandVolume(
ctx context.Context,
req *csi.ControllerExpandVolumeRequest,
) (*csi.ControllerExpandVolumeResponse, error) {

return nil, status.Error(codes.Unimplemented, "")
updatedSize := req.GetCapacityRange().GetRequiredBytes()
if err := utils.ResizeVolume(req.VolumeId, updatedSize); err != nil {
return nil, status.Errorf(
codes.Internal,
"failed to handle ControllerExpandVolumeRequest for %s, {%s}",
req.VolumeId,
err.Error(),
)
}
return csipayload.NewControllerExpandVolumeResponseBuilder().
WithCapacityBytes(updatedSize).
WithNodeExpansionRequired(true).
Build(), nil
}

// CreateSnapshot creates a snapshot for given volume
Expand Down Expand Up @@ -315,6 +326,7 @@ func newControllerCapabilities() []*csi.ControllerServiceCapability {
var capabilities []*csi.ControllerServiceCapability
for _, cap := range []csi.ControllerServiceCapability_RPC_Type{
csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
csi.ControllerServiceCapability_RPC_EXPAND_VOLUME,
} {
capabilities = append(capabilities, fromType(cap))
}
Expand Down
26 changes: 24 additions & 2 deletions pkg/service/v1alpha1/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ func (ns *node) NodeGetCapabilities(
{
Type: &csi.NodeServiceCapability_Rpc{
Rpc: &csi.NodeServiceCapability_RPC{
Type: csi.NodeServiceCapability_RPC_UNKNOWN,
Type: csi.NodeServiceCapability_RPC_EXPAND_VOLUME,
},
},
},
Expand Down Expand Up @@ -382,8 +382,30 @@ func (ns *node) NodeExpandVolume(
ctx context.Context,
req *csi.NodeExpandVolumeRequest,
) (*csi.NodeExpandVolumeResponse, error) {
volumeID := req.GetVolumeId()
err := addVolumeToTransitionList(volumeID, apis.CSIVolumeStatusResizeInProgress)
if err != nil {
return nil, status.Errorf(
codes.Internal,
"failed to handle NodeExpandVolumeRequest for %s, {%s}",
req.VolumeId,
err.Error(),
)
}
defer removeVolumeFromTransitionList(volumeID)

return nil, nil
if err = iscsi.ResizeVolume(req.GetVolumePath()); err != nil {
return nil, status.Errorf(
codes.Internal,
"failed to handle NodeExpandVolumeRequest for %s, {%s}",
req.VolumeId,
err.Error(),
)
}

return &csi.NodeExpandVolumeResponse{
CapacityBytes: req.GetCapacityRange().GetRequiredBytes(),
}, nil
}

// NodeGetVolumeStats returns statistics for the
Expand Down
Loading

0 comments on commit 442a25d

Please sign in to comment.