in pkg/nfs/controllerserver.go [370:437]
func (cs *ControllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) {
if len(req.GetName()) == 0 {
return nil, status.Error(codes.InvalidArgument, "CreateSnapshot name must be provided")
}
if len(req.GetSourceVolumeId()) == 0 {
return nil, status.Error(codes.InvalidArgument, "CreateSnapshot source volume ID must be provided")
}
srcVol, err := getNfsVolFromID(req.GetSourceVolumeId())
if err != nil {
return nil, status.Errorf(codes.NotFound, "failed to create source volume: %v", err)
}
snapshot, err := newNFSSnapshot(req.GetName(), req.GetParameters(), srcVol)
if err != nil {
return nil, status.Errorf(codes.NotFound, "failed to create nfsSnapshot: %v", err)
}
snapVol := volumeFromSnapshot(snapshot)
if err = cs.internalMount(ctx, snapVol, nil, nil); err != nil {
return nil, status.Errorf(codes.Internal, "failed to mount snapshot nfs server: %v", err)
}
defer func() {
if err = cs.internalUnmount(ctx, snapVol); err != nil {
klog.Warningf("failed to unmount snapshot nfs server: %v", err)
}
}()
snapInternalVolPath := getInternalVolumePath(cs.Driver.workingMountDir, snapVol)
if err = os.MkdirAll(snapInternalVolPath, 0777); err != nil {
return nil, status.Errorf(codes.Internal, "failed to make subdirectory: %v", err)
}
if err := validateSnapshot(snapInternalVolPath, snapshot); err != nil {
return nil, err
}
if err = cs.internalMount(ctx, srcVol, nil, nil); err != nil {
return nil, 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 src nfs server: %v", err)
}
}()
srcPath := getInternalVolumePath(cs.Driver.workingMountDir, srcVol)
dstPath := filepath.Join(snapInternalVolPath, snapshot.archiveName())
klog.V(2).Infof("archiving %v -> %v", srcPath, dstPath)
out, err := exec.Command("tar", "-C", srcPath, "-czvf", dstPath, ".").CombinedOutput()
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to create archive for snapshot: %v: %v", err, string(out))
}
klog.V(2).Infof("archived %s -> %s", srcPath, dstPath)
var snapshotSize int64
fi, err := os.Stat(dstPath)
if err != nil {
klog.Warningf("failed to determine snapshot size: %v", err)
} else {
snapshotSize = fi.Size()
}
return &csi.CreateSnapshotResponse{
Snapshot: &csi.Snapshot{
SnapshotId: snapshot.id,
SourceVolumeId: srcVol.id,
SizeBytes: snapshotSize,
CreationTime: timestamppb.Now(),
ReadyToUse: true,
},
}, nil
}