Skip to content

Commit

Permalink
Implement Cloning for csi-hostpath driver
Browse files Browse the repository at this point in the history
This PR adds support for cloning of hostpath volumes.
  • Loading branch information
j-griffith committed Jun 12, 2019
1 parent f4f3b14 commit 2ef1251
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
14 changes: 14 additions & 0 deletions examples/csi-clone.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hp-pvc-clone
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: src-hp-pvc
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
20 changes: 20 additions & 0 deletions pkg/hostpath/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func NewControllerServer(ephemeral bool) *controllerServer {
csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT,
csi.ControllerServiceCapability_RPC_LIST_SNAPSHOTS,
csi.ControllerServiceCapability_RPC_CLONE_VOLUME,
}),
}
}
Expand Down Expand Up @@ -178,19 +179,38 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
snapshotId := contentSource.GetSnapshot().GetSnapshotId()
snapshot, ok := hostPathVolumeSnapshots[snapshotId]
if !ok {
deleteHostpathVolume(volumeID)
return nil, status.Errorf(codes.NotFound, "cannot find snapshot %v", snapshotId)
}
if snapshot.ReadyToUse != true {
deleteHostpathVolume(volumeID)
return nil, status.Errorf(codes.Internal, "Snapshot %v is not yet ready to use.", snapshotId)
}
snapshotPath := snapshot.Path
args := []string{"zxvf", snapshotPath, "-C", path}
executor := utilexec.New()
out, err := executor.Command("tar", args...).CombinedOutput()
if err != nil {
deleteHostpathVolume(volumeID)
return nil, status.Error(codes.Internal, fmt.Sprintf("failed pre-populate data for volume: %v: %s", err, out))
}
}
if srcVolume := contentSource.GetVolume(); srcVolume != nil {
srcVolumeID := srcVolume.GetVolumeId()
hostPathVolume, ok := hostPathVolumes[srcVolumeID]
if !ok {
deleteHostpathVolume(volumeID)
return nil, status.Error(codes.Internal, "source volumeID does not exist, are source/destination in the same storage class?")
}
srcPath := hostPathVolume.VolPath
args := []string{"-a", srcPath + "/*", path + "/"}
executor := utilexec.New()
out, err := executor.Command("cp", args...).CombinedOutput()
if err != nil {
deleteHostpathVolume(volumeID)
return nil, status.Error(codes.Internal, fmt.Sprintf("failed pre-populate data (clone) for volume: %v: %s", err, out))
}
}
}

createVolumeResponse := &csi.CreateVolumeResponse{}
Expand Down
1 change: 1 addition & 0 deletions pkg/hostpath/hostpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ func createHostpathVolume(volID, name string, cap int64, volAccessType accessTyp

// deleteVolume deletes the directory for the hostpath volume.
func deleteHostpathVolume(volID string) error {
glog.V(4).Infof("deleting hostpath volume: %s", volID)
path := getVolumePath(volID)
if err := os.RemoveAll(path); err != nil {
return err
Expand Down

0 comments on commit 2ef1251

Please sign in to comment.