func()

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
}