in pkg/nfs/controllerserver.go [582:620]
func (cs *ControllerServer) copyFromVolume(ctx context.Context, req *csi.CreateVolumeRequest, dstVol *nfsVolume) error {
srcVol, err := getNfsVolFromID(req.GetVolumeContentSource().GetVolume().GetVolumeId())
if err != nil {
return status.Error(codes.NotFound, err.Error())
}
// Note that the source path must include trailing '/.', can't use 'filepath.Join()' as it performs path cleaning
srcPath := fmt.Sprintf("%v/.", getInternalVolumePath(cs.Driver.workingMountDir, srcVol))
dstPath := getInternalVolumePath(cs.Driver.workingMountDir, dstVol)
klog.V(2).Infof("copy volume from volume %v -> %v", srcPath, dstPath)
var volCap *csi.VolumeCapability
if len(req.GetVolumeCapabilities()) > 0 {
volCap = req.GetVolumeCapabilities()[0]
}
if err = cs.internalMount(ctx, srcVol, nil, volCap); err != nil {
return status.Errorf(codes.Internal, "failed to mount src nfs server: %v", err)
}
defer func() {
if err = cs.internalUnmount(ctx, srcVol); err != nil {
klog.Warningf("failed to unmount nfs server: %v", err)
}
}()
if err = cs.internalMount(ctx, dstVol, nil, volCap); err != nil {
return status.Errorf(codes.Internal, "failed to mount dst nfs server: %v", err)
}
defer func() {
if err = cs.internalUnmount(ctx, dstVol); err != nil {
klog.Warningf("failed to unmount dst nfs server: %v", err)
}
}()
// recursive 'cp' with '-a' to handle symlinks
out, err := exec.Command("cp", "-a", srcPath, dstPath).CombinedOutput()
if err != nil {
return status.Errorf(codes.Internal, "failed to copy volume %v: %v", err, string(out))
}
klog.V(2).Infof("copied %s -> %s", srcPath, dstPath)
return nil
}