cephfs: implement getSnapshotInfo with go-ceph

implement getSnapshotInfo function with go-ceph
to get subvolume information.

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna 2020-12-02 13:57:03 +05:30 committed by mergify[bot]
parent b0f3b27209
commit 0f451ed465
7 changed files with 26 additions and 65 deletions

View File

@ -138,7 +138,7 @@ func cleanupCloneFromSubvolumeSnapshot(ctx context.Context, volID, cloneID volum
// snapshot name is same as clone name as we need a name which can be // snapshot name is same as clone name as we need a name which can be
// identified during PVC-PVC cloning. // identified during PVC-PVC cloning.
snapShotID := cloneID snapShotID := cloneID
snapInfo, err := getSnapshotInfo(ctx, parentVolOpt, cr, snapShotID, volID) snapInfo, err := parentVolOpt.getSnapshotInfo(ctx, snapShotID, volID)
if err != nil { if err != nil {
if errors.Is(err, ErrSnapNotFound) { if errors.Is(err, ErrSnapNotFound) {
return nil return nil

View File

@ -600,7 +600,7 @@ func doSnapshot(ctx context.Context, volOpt *volumeOptions, subvolumeName, snaps
} }
} }
}() }()
snap, err = getSnapshotInfo(ctx, volOpt, cr, snapID, volID) snap, err = volOpt.getSnapshotInfo(ctx, snapID, volID)
if err != nil { if err != nil {
util.ErrorLog(ctx, "failed to get snapshot info %s %v", snapID, err) util.ErrorLog(ctx, "failed to get snapshot info %s %v", snapID, err)
return snap, fmt.Errorf("failed to get snapshot info for snapshot:%s", snapID) return snap, fmt.Errorf("failed to get snapshot info for snapshot:%s", snapID)

View File

@ -24,9 +24,6 @@ import (
const ( const (
// volumeNotFound is returned when a subvolume is not found in CephFS. // volumeNotFound is returned when a subvolume is not found in CephFS.
volumeNotFound = "Error ENOENT" volumeNotFound = "Error ENOENT"
// snapNotFound is returned when snap name passed is not found in the list
// of snapshots for the given image.
snapNotFound = "Error ENOENT"
// volumeNotEmpty is returned when the volume is not empty. // volumeNotEmpty is returned when the volume is not empty.
volumeNotEmpty = "Error ENOTEMPTY" volumeNotEmpty = "Error ENOTEMPTY"
) )

View File

@ -342,7 +342,7 @@ func checkSnapExists(
snapUUID := snapData.ImageUUID snapUUID := snapData.ImageUUID
snapID := snapData.ImageAttributes.ImageName snapID := snapData.ImageAttributes.ImageName
sid.FsSnapshotName = snapData.ImageAttributes.ImageName sid.FsSnapshotName = snapData.ImageAttributes.ImageName
snapInfo, err := getSnapshotInfo(ctx, volOptions, cr, volumeID(snapID), volumeID(parentSubVolName)) snapInfo, err := volOptions.getSnapshotInfo(ctx, volumeID(snapID), volumeID(parentSubVolName))
if err != nil { if err != nil {
if errors.Is(err, ErrSnapNotFound) { if errors.Is(err, ErrSnapNotFound) {
err = j.UndoReservation(ctx, volOptions.MetadataPool, err = j.UndoReservation(ctx, volOptions.MetadataPool,

View File

@ -19,7 +19,7 @@ package cephfs
import ( import (
"context" "context"
"errors" "errors"
"strings" "time"
"github.com/ceph/ceph-csi/internal/util" "github.com/ceph/ceph-csi/internal/util"
@ -81,44 +81,31 @@ func (vo *volumeOptions) deleteSnapshot(ctx context.Context, snapID, volID volum
} }
type snapshotInfo struct { type snapshotInfo struct {
CreatedAt string `json:"created_at"` CreatedAt time.Time
CreationTime *timestamp.Timestamp CreationTime *timestamp.Timestamp
DataPool string `json:"data_pool"` HasPendingClones string
HasPendingClones string `json:"has_pending_clones"` Protected string
Protected string `json:"protected"`
Size int `json:"size"`
} }
func getSnapshotInfo(ctx context.Context, volOptions *volumeOptions, cr *util.Credentials, snapID, volID volumeID) (snapshotInfo, error) { func (vo *volumeOptions) getSnapshotInfo(ctx context.Context, snapID, volID volumeID) (snapshotInfo, error) {
snap := snapshotInfo{} snap := snapshotInfo{}
args := []string{ fsa, err := vo.conn.GetFSAdmin()
"fs",
"subvolume",
"snapshot",
"info",
volOptions.FsName,
string(volID),
string(snapID),
"--group_name",
volOptions.SubvolumeGroup,
"-m", volOptions.Monitors,
"-c", util.CephConfigPath,
"-n", cephEntityClientPrefix + cr.ID,
"--keyfile=" + cr.KeyFile,
"--format=json",
}
err := execCommandJSON(
ctx,
&snap,
"ceph",
args[:]...)
if err != nil { if err != nil {
if strings.Contains(err.Error(), snapNotFound) { util.ErrorLog(ctx, "could not get FSAdmin: %s", err)
return snapshotInfo{}, ErrSnapNotFound return snap, err
}
util.ErrorLog(ctx, "failed to get subvolume snapshot info %s %s(%s) in fs %s", string(snapID), string(volID), err, volOptions.FsName)
return snapshotInfo{}, err
} }
info, err := fsa.SubVolumeSnapshotInfo(vo.FsName, vo.SubvolumeGroup, string(volID), string(snapID))
if err != nil {
if errors.Is(err, rados.ErrNotFound) {
return snap, ErrSnapNotFound
}
util.ErrorLog(ctx, "failed to get subvolume snapshot info %s %s in fs %s with error %s", string(volID), string(snapID), vo.FsName, err)
return snap, err
}
snap.CreatedAt = info.CreatedAt.Time
snap.HasPendingClones = info.HasPendingClones
snap.Protected = info.Protected
return snap, nil return snap, nil
} }

View File

@ -18,7 +18,6 @@ package cephfs
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"time" "time"
@ -38,19 +37,6 @@ func execCommandErr(ctx context.Context, program string, args ...string) error {
return err return err
} }
func execCommandJSON(ctx context.Context, v interface{}, program string, args ...string) error {
stdout, _, err := util.ExecCommand(ctx, program, args...)
if err != nil {
return err
}
if err = json.Unmarshal([]byte(stdout), v); err != nil {
return fmt.Errorf("failed to unmarshal JSON for %s %v: %s: %w", program, util.StripSecretInArgs(args), stdout, err)
}
return nil
}
// Controller service request validation. // Controller service request validation.
func (cs *ControllerServer) validateCreateVolumeRequest(req *csi.CreateVolumeRequest) error { func (cs *ControllerServer) validateCreateVolumeRequest(req *csi.CreateVolumeRequest) error {
if err := cs.Driver.ValidateControllerServiceRequest(csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME); err != nil { if err := cs.Driver.ValidateControllerServiceRequest(csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME); err != nil {
@ -149,17 +135,8 @@ func genSnapFromOptions(ctx context.Context, req *csi.CreateSnapshotRequest) (sn
return cephfsSnap, nil return cephfsSnap, nil
} }
func parseTime(ctx context.Context, createTime string) (*timestamp.Timestamp, error) { func parseTime(ctx context.Context, createTime time.Time) (*timestamp.Timestamp, error) {
tm := &timestamp.Timestamp{} tm, err := ptypes.TimestampProto(createTime)
layout := "2006-01-02 15:04:05.000000"
// TODO currently parsing of timestamp to time.ANSIC generate from ceph fs is failing
var t time.Time
t, err := time.Parse(layout, createTime)
if err != nil {
util.ErrorLog(ctx, "failed to parse time %s %v", createTime, err)
return tm, err
}
tm, err = ptypes.TimestampProto(t)
if err != nil { if err != nil {
util.ErrorLog(ctx, "failed to convert time %s %v", createTime, err) util.ErrorLog(ctx, "failed to convert time %s %v", createTime, err)
return tm, err return tm, err

View File

@ -532,7 +532,7 @@ func newSnapshotOptionsFromID(ctx context.Context, snapID string, cr *util.Crede
} }
volOptions.Features = subvolInfo.Features volOptions.Features = subvolInfo.Features
info, err := getSnapshotInfo(ctx, &volOptions, cr, volumeID(sid.FsSnapshotName), volumeID(sid.FsSubvolName)) info, err := volOptions.getSnapshotInfo(ctx, volumeID(sid.FsSnapshotName), volumeID(sid.FsSubvolName))
if err != nil { if err != nil {
return &volOptions, nil, &sid, err return &volOptions, nil, &sid, err
} }