diff --git a/internal/cephfs/clone.go b/internal/cephfs/clone.go index f725a6b45..f875fb906 100644 --- a/internal/cephfs/clone.go +++ b/internal/cephfs/clone.go @@ -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 // identified during PVC-PVC cloning. snapShotID := cloneID - snapInfo, err := getSnapshotInfo(ctx, parentVolOpt, cr, snapShotID, volID) + snapInfo, err := parentVolOpt.getSnapshotInfo(ctx, snapShotID, volID) if err != nil { if errors.Is(err, ErrSnapNotFound) { return nil diff --git a/internal/cephfs/controllerserver.go b/internal/cephfs/controllerserver.go index a83121bfb..11067535c 100644 --- a/internal/cephfs/controllerserver.go +++ b/internal/cephfs/controllerserver.go @@ -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 { 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) diff --git a/internal/cephfs/errors.go b/internal/cephfs/errors.go index 73b86b97f..608d91b07 100644 --- a/internal/cephfs/errors.go +++ b/internal/cephfs/errors.go @@ -24,9 +24,6 @@ import ( const ( // volumeNotFound is returned when a subvolume is not found in CephFS. 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 = "Error ENOTEMPTY" ) diff --git a/internal/cephfs/fsjournal.go b/internal/cephfs/fsjournal.go index cfec0a9ab..5a3899800 100644 --- a/internal/cephfs/fsjournal.go +++ b/internal/cephfs/fsjournal.go @@ -342,7 +342,7 @@ func checkSnapExists( snapUUID := snapData.ImageUUID snapID := 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 errors.Is(err, ErrSnapNotFound) { err = j.UndoReservation(ctx, volOptions.MetadataPool, diff --git a/internal/cephfs/snapshot.go b/internal/cephfs/snapshot.go index 5c5823f35..0811a97fb 100644 --- a/internal/cephfs/snapshot.go +++ b/internal/cephfs/snapshot.go @@ -19,7 +19,7 @@ package cephfs import ( "context" "errors" - "strings" + "time" "github.com/ceph/ceph-csi/internal/util" @@ -81,44 +81,31 @@ func (vo *volumeOptions) deleteSnapshot(ctx context.Context, snapID, volID volum } type snapshotInfo struct { - CreatedAt string `json:"created_at"` + CreatedAt time.Time CreationTime *timestamp.Timestamp - DataPool string `json:"data_pool"` - HasPendingClones string `json:"has_pending_clones"` - Protected string `json:"protected"` - Size int `json:"size"` + HasPendingClones string + Protected string } -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{} - args := []string{ - "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[:]...) + fsa, err := vo.conn.GetFSAdmin() if err != nil { - if strings.Contains(err.Error(), snapNotFound) { - return snapshotInfo{}, ErrSnapNotFound - } - 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 + util.ErrorLog(ctx, "could not get FSAdmin: %s", err) + return snap, 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 } diff --git a/internal/cephfs/util.go b/internal/cephfs/util.go index 56ef1a970..573268ba5 100644 --- a/internal/cephfs/util.go +++ b/internal/cephfs/util.go @@ -18,7 +18,6 @@ package cephfs import ( "context" - "encoding/json" "fmt" "time" @@ -38,19 +37,6 @@ func execCommandErr(ctx context.Context, program string, args ...string) error { 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. func (cs *ControllerServer) validateCreateVolumeRequest(req *csi.CreateVolumeRequest) error { 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 } -func parseTime(ctx context.Context, createTime string) (*timestamp.Timestamp, error) { - tm := ×tamp.Timestamp{} - 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) +func parseTime(ctx context.Context, createTime time.Time) (*timestamp.Timestamp, error) { + tm, err := ptypes.TimestampProto(createTime) if err != nil { util.ErrorLog(ctx, "failed to convert time %s %v", createTime, err) return tm, err diff --git a/internal/cephfs/volumeoptions.go b/internal/cephfs/volumeoptions.go index 6f9db0a8c..ab93906b2 100644 --- a/internal/cephfs/volumeoptions.go +++ b/internal/cephfs/volumeoptions.go @@ -532,7 +532,7 @@ func newSnapshotOptionsFromID(ctx context.Context, snapID string, cr *util.Crede } 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 { return &volOptions, nil, &sid, err }