rbd: simplify error handling

This change replaces the sentinel errors in rbd module with
standard errors created with errors.New().

Related: #1203

Signed-off-by: Sven Anderson <sven@redhat.com>
This commit is contained in:
Sven Anderson 2020-07-10 03:05:42 +02:00 committed by mergify[bot]
parent dba2c27bcb
commit 92884f56f4
7 changed files with 61 additions and 167 deletions

View File

@ -51,15 +51,13 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume)
RbdSnapName: rv.RbdImageName, RbdSnapName: rv.RbdImageName,
Pool: rv.Pool, Pool: rv.Pool,
} }
var einf ErrImageNotFound
var esnf ErrSnapNotFound
// check if cloned image exists // check if cloned image exists
err := rv.getImageInfo() err := rv.getImageInfo()
if err == nil { if err == nil {
// check if do we have temporary snapshot on temporary cloned image // check if do we have temporary snapshot on temporary cloned image
sErr := tempClone.checkSnapExists(snap) sErr := tempClone.checkSnapExists(snap)
if sErr != nil { if sErr != nil {
if errors.As(err, &esnf) { if errors.Is(err, ErrSnapNotFound) {
return true, nil return true, nil
} }
return false, err return false, err
@ -70,14 +68,14 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume)
} }
return false, err return false, err
} }
if !errors.As(err, &einf) { if !errors.Is(err, ErrImageNotFound) {
// return error if its not image not found // return error if its not image not found
return false, err return false, err
} }
err = tempClone.checkSnapExists(snap) err = tempClone.checkSnapExists(snap)
if err != nil { if err != nil {
if errors.As(err, &esnf) { if errors.Is(err, ErrSnapNotFound) {
// check temporary image needs flatten, if yes add task to flatten the // check temporary image needs flatten, if yes add task to flatten the
// temporary clone // temporary clone
err = tempClone.flattenRbdImage(ctx, rv.conn.Creds, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth) err = tempClone.flattenRbdImage(ctx, rv.conn.Creds, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
@ -91,7 +89,7 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume)
return false, err return false, err
} }
return true, nil return true, nil
} else if !errors.As(err, &einf) { } else if !errors.Is(err, ErrImageNotFound) {
// any error other than image not found return error // any error other than image not found return error
return false, err return false, err
} }
@ -122,7 +120,7 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume)
// create new resources for clearner approach // create new resources for clearner approach
err = parentVol.deleteSnapshot(ctx, snap) err = parentVol.deleteSnapshot(ctx, snap)
} }
if errors.As(err, &esnf) { if errors.Is(err, ErrSnapNotFound) {
return false, nil return false, nil
} }
return false, err return false, err
@ -164,7 +162,6 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol
errFlatten error errFlatten error
err error err error
) )
var efip ErrFlattenInProgress
var j = &journal.Connection{} var j = &journal.Connection{}
j, err = volJournal.Connect(rv.Monitors, rv.conn.Creds) j, err = volJournal.Connect(rv.Monitors, rv.conn.Creds)
@ -181,7 +178,7 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol
defer func() { defer func() {
if err != nil || errFlatten != nil { if err != nil || errFlatten != nil {
if !errors.Is(errFlatten, &efip) { if !errors.Is(errFlatten, ErrFlattenInProgress) {
// cleanup snapshot // cleanup snapshot
cErr := cleanUpSnapshot(ctx, parentVol, tempSnap, tempClone, rv.conn.Creds) cErr := cleanUpSnapshot(ctx, parentVol, tempSnap, tempClone, rv.conn.Creds)
if cErr != nil { if cErr != nil {
@ -247,8 +244,7 @@ func (rv *rbdVolume) flattenCloneImage(ctx context.Context) error {
return tempClone.flattenRbdImage(ctx, tempClone.conn.Creds, false, hardLimit, softLimit) return tempClone.flattenRbdImage(ctx, tempClone.conn.Creds, false, hardLimit, softLimit)
} }
if err != nil { if err != nil {
var einf ErrImageNotFound if !errors.Is(err, ErrImageNotFound) {
if !errors.As(err, &einf) {
return err return err
} }
} }

View File

@ -167,12 +167,10 @@ func buildCreateVolumeResponse(ctx context.Context, req *csi.CreateVolumeRequest
// the input error types it expected to use only for CreateVolume as we need to // the input error types it expected to use only for CreateVolume as we need to
// return different GRPC codes for different functions based on the input. // return different GRPC codes for different functions based on the input.
func getGRPCErrorForCreateVolume(err error) error { func getGRPCErrorForCreateVolume(err error) error {
var evnc ErrVolNameConflict if errors.Is(err, ErrVolNameConflict) {
if errors.As(err, &evnc) {
return status.Error(codes.AlreadyExists, err.Error()) return status.Error(codes.AlreadyExists, err.Error())
} }
var efip ErrFlattenInProgress if errors.Is(err, ErrFlattenInProgress) {
if errors.As(err, &efip) {
return status.Error(codes.Aborted, err.Error()) return status.Error(codes.Aborted, err.Error())
} }
return status.Error(codes.Internal, err.Error()) return status.Error(codes.Internal, err.Error())
@ -273,8 +271,7 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
} }
defer func() { defer func() {
if err != nil { if err != nil {
var efip ErrFlattenInProgress if !errors.Is(err, ErrFlattenInProgress) {
if !errors.As(err, &efip) {
errDefer := undoVolReservation(ctx, rbdVol, cr) errDefer := undoVolReservation(ctx, rbdVol, cr)
if errDefer != nil { if errDefer != nil {
klog.Warningf(util.Log(ctx, "failed undoing reservation of volume: %s (%s)"), req.GetName(), errDefer) klog.Warningf(util.Log(ctx, "failed undoing reservation of volume: %s (%s)"), req.GetName(), errDefer)
@ -285,8 +282,7 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
err = cs.createBackingImage(ctx, cr, rbdVol, parentVol, rbdSnap) err = cs.createBackingImage(ctx, cr, rbdVol, parentVol, rbdSnap)
if err != nil { if err != nil {
var efip ErrFlattenInProgress if errors.Is(err, ErrFlattenInProgress) {
if errors.As(err, &efip) {
return nil, status.Error(codes.Aborted, err.Error()) return nil, status.Error(codes.Aborted, err.Error())
} }
return nil, err return nil, err
@ -340,8 +336,7 @@ func flattenParentImage(ctx context.Context, rbdVol *rbdVolume, cr *util.Credent
func flattenTemporaryClonedImages(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error { func flattenTemporaryClonedImages(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error {
snaps, err := rbdVol.listSnapshots(ctx, cr) snaps, err := rbdVol.listSnapshots(ctx, cr)
if err != nil { if err != nil {
var einf ErrImageNotFound if errors.Is(err, ErrImageNotFound) {
if errors.As(err, &einf) {
return status.Error(codes.InvalidArgument, err.Error()) return status.Error(codes.InvalidArgument, err.Error())
} }
return status.Error(codes.Internal, err.Error()) return status.Error(codes.Internal, err.Error())
@ -364,8 +359,7 @@ func flattenTemporaryClonedImages(ctx context.Context, rbdVol *rbdVolume, cr *ut
func checkFlatten(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error { func checkFlatten(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error {
err := rbdVol.flattenRbdImage(ctx, cr, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth) err := rbdVol.flattenRbdImage(ctx, cr, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
if err != nil { if err != nil {
var efip ErrFlattenInProgress if errors.Is(err, ErrFlattenInProgress) {
if errors.As(err, &efip) {
return status.Error(codes.Aborted, err.Error()) return status.Error(codes.Aborted, err.Error())
} }
if errDefer := deleteImage(ctx, rbdVol, cr); errDefer != nil { if errDefer := deleteImage(ctx, rbdVol, cr); errDefer != nil {
@ -453,8 +447,7 @@ func (cs *ControllerServer) createBackingImage(ctx context.Context, cr *util.Cre
defer func() { defer func() {
if err != nil { if err != nil {
var efip ErrFlattenInProgress if !errors.Is(err, ErrFlattenInProgress) {
if !errors.As(err, &efip) {
if deleteErr := deleteImage(ctx, rbdVol, cr); deleteErr != nil { if deleteErr := deleteImage(ctx, rbdVol, cr); deleteErr != nil {
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s with error: %v"), rbdVol, deleteErr) klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s with error: %v"), rbdVol, deleteErr)
} }
@ -509,8 +502,7 @@ func checkContentSource(ctx context.Context, req *csi.CreateVolumeRequest, cr *u
rbdSnap := &rbdSnapshot{} rbdSnap := &rbdSnapshot{}
if err := genSnapFromSnapID(ctx, rbdSnap, snapshotID, cr); err != nil { if err := genSnapFromSnapID(ctx, rbdSnap, snapshotID, cr); err != nil {
klog.Errorf(util.Log(ctx, "failed to get backend snapshot for %s: %v"), snapshotID, err) klog.Errorf(util.Log(ctx, "failed to get backend snapshot for %s: %v"), snapshotID, err)
var esnf ErrSnapNotFound if !errors.Is(err, ErrSnapNotFound) {
if !errors.As(err, &esnf) {
return nil, nil, status.Error(codes.Internal, err.Error()) return nil, nil, status.Error(codes.Internal, err.Error())
} }
return nil, nil, status.Errorf(codes.NotFound, "%s snapshot doesnot exists", snapshotID) return nil, nil, status.Errorf(codes.NotFound, "%s snapshot doesnot exists", snapshotID)
@ -529,8 +521,7 @@ func checkContentSource(ctx context.Context, req *csi.CreateVolumeRequest, cr *u
rbdvol, err := genVolFromVolID(ctx, volID, cr, nil) rbdvol, err := genVolFromVolID(ctx, volID, cr, nil)
if err != nil { if err != nil {
klog.Errorf(util.Log(ctx, "failed to get backend image for %s: %v"), volID, err) klog.Errorf(util.Log(ctx, "failed to get backend image for %s: %v"), volID, err)
var esnf ErrImageNotFound if !errors.Is(err, ErrImageNotFound) {
if !errors.As(err, &esnf) {
return nil, nil, status.Error(codes.Internal, err.Error()) return nil, nil, status.Error(codes.Internal, err.Error())
} }
return nil, nil, status.Errorf(codes.NotFound, "%s image doesnot exists", volID) return nil, nil, status.Errorf(codes.NotFound, "%s image doesnot exists", volID)
@ -594,8 +585,7 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
} }
// All errors other than ErrImageNotFound should return an error back to the caller // All errors other than ErrImageNotFound should return an error back to the caller
var einf ErrImageNotFound if !errors.Is(err, ErrImageNotFound) {
if !errors.As(err, &einf) {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
@ -635,12 +625,11 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
// delete the temporary rbd image created as part of volume clone during // delete the temporary rbd image created as part of volume clone during
// create volume // create volume
var einf ErrImageNotFound
tempClone := rbdVol.generateTempClone() tempClone := rbdVol.generateTempClone()
err = deleteImage(ctx, tempClone, cr) err = deleteImage(ctx, tempClone, cr)
if err != nil { if err != nil {
// return error if it is not ErrImageNotFound // return error if it is not ErrImageNotFound
if !errors.As(err, &einf) { if !errors.Is(err, ErrImageNotFound) {
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s with error: %v"), klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s with error: %v"),
tempClone, err) tempClone, err)
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
@ -713,9 +702,8 @@ func (cs *ControllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS
// Fetch source volume information // Fetch source volume information
rbdVol, err = genVolFromVolID(ctx, req.GetSourceVolumeId(), cr, req.GetSecrets()) rbdVol, err = genVolFromVolID(ctx, req.GetSourceVolumeId(), cr, req.GetSecrets())
if err != nil { if err != nil {
var einf ErrImageNotFound
// nolint:gocritic // this ifElseChain can not be rewritten to a switch statement // nolint:gocritic // this ifElseChain can not be rewritten to a switch statement
if errors.As(err, &einf) { if errors.Is(err, ErrImageNotFound) {
err = status.Errorf(codes.NotFound, "source Volume ID %s not found", req.GetSourceVolumeId()) err = status.Errorf(codes.NotFound, "source Volume ID %s not found", req.GetSourceVolumeId())
} else if errors.Is(err, util.ErrPoolNotFound) { } else if errors.Is(err, util.ErrPoolNotFound) {
klog.Errorf(util.Log(ctx, "failed to get backend volume for %s: %v"), req.GetSourceVolumeId(), err) klog.Errorf(util.Log(ctx, "failed to get backend volume for %s: %v"), req.GetSourceVolumeId(), err)
@ -779,8 +767,7 @@ func (cs *ControllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS
defer vol.Destroy() defer vol.Destroy()
err = vol.flattenRbdImage(ctx, cr, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth) err = vol.flattenRbdImage(ctx, cr, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
var efip ErrFlattenInProgress if errors.Is(err, ErrFlattenInProgress) {
if errors.As(err, &efip) {
return &csi.CreateSnapshotResponse{ return &csi.CreateSnapshotResponse{
Snapshot: &csi.Snapshot{ Snapshot: &csi.Snapshot{
SizeBytes: rbdSnap.SizeBytes, SizeBytes: rbdSnap.SizeBytes,
@ -891,8 +878,7 @@ func (cs *ControllerServer) doSnapshotClone(ctx context.Context, parentVol *rbdV
defer func() { defer func() {
if err != nil { if err != nil {
var efip ErrFlattenInProgress if !errors.Is(err, ErrFlattenInProgress) {
if !errors.As(err, &efip) {
// cleanup clone and snapshot // cleanup clone and snapshot
errCleanUp := cleanUpSnapshot(ctx, cloneRbd, rbdSnap, cloneRbd, cr) errCleanUp := cleanUpSnapshot(ctx, cloneRbd, rbdSnap, cloneRbd, cr)
if errCleanUp != nil { if errCleanUp != nil {
@ -932,8 +918,7 @@ func (cs *ControllerServer) doSnapshotClone(ctx context.Context, parentVol *rbdV
err = cloneRbd.flattenRbdImage(ctx, cr, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth) err = cloneRbd.flattenRbdImage(ctx, cr, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
if err != nil { if err != nil {
var efip ErrFlattenInProgress if errors.Is(err, ErrFlattenInProgress) {
if errors.As(err, &efip) {
return ready, cloneRbd, nil return ready, cloneRbd, nil
} }
return ready, cloneRbd, err return ready, cloneRbd, err
@ -1014,8 +999,7 @@ func (cs *ControllerServer) DeleteSnapshot(ctx context.Context, req *csi.DeleteS
err = rbdVol.getImageInfo() err = rbdVol.getImageInfo()
if err != nil { if err != nil {
var einf ErrImageNotFound if !errors.Is(err, ErrImageNotFound) {
if !errors.As(err, &einf) {
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s/%s with error: %v"), rbdVol.Pool, rbdVol.VolName, err) klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s/%s with error: %v"), rbdVol.Pool, rbdVol.VolName, err)
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
@ -1081,9 +1065,8 @@ func (cs *ControllerServer) ControllerExpandVolume(ctx context.Context, req *csi
rbdVol, err = genVolFromVolID(ctx, volID, cr, req.GetSecrets()) rbdVol, err = genVolFromVolID(ctx, volID, cr, req.GetSecrets())
if err != nil { if err != nil {
var einf ErrImageNotFound
// nolint:gocritic // this ifElseChain can not be rewritten to a switch statement // nolint:gocritic // this ifElseChain can not be rewritten to a switch statement
if errors.As(err, &einf) { if errors.Is(err, ErrImageNotFound) {
err = status.Errorf(codes.NotFound, "volume ID %s not found", volID) err = status.Errorf(codes.NotFound, "volume ID %s not found", volID)
} else if errors.Is(err, util.ErrPoolNotFound) { } else if errors.Is(err, util.ErrPoolNotFound) {
klog.Errorf(util.Log(ctx, "failed to get backend volume for %s: %v"), volID, err) klog.Errorf(util.Log(ctx, "failed to get backend volume for %s: %v"), volID, err)

View File

@ -16,98 +16,22 @@ limitations under the License.
package rbd package rbd
// ErrImageNotFound is returned when image name is not found in the cluster on the given pool. import "errors"
type ErrImageNotFound struct {
imageName string
err error
}
// Error returns a user presentable string of the error. var (
func (e ErrImageNotFound) Error() string { // ErrImageNotFound is returned when image name is not found in the cluster on the given pool.
return e.err.Error() ErrImageNotFound = errors.New("image not found")
} // ErrSnapNotFound is returned when snap name passed is not found in the list of snapshots for the
// given image.
// Unwrap returns the encapsulated error of ErrImageNotFound. ErrSnapNotFound = errors.New("snapshot not found")
func (e ErrImageNotFound) Unwrap() error { // ErrVolNameConflict is generated when a requested CSI volume name already exists on RBD but with
return e.err // different properties, and hence is in conflict with the passed in CSI volume name.
} ErrVolNameConflict = errors.New("volume name conflict")
// ErrInvalidVolID is returned when a CSI passed VolumeID does not conform to any known volume ID
// ErrSnapNotFound is returned when snap name passed is not found in the list of snapshots for the // formats.
// given image. ErrInvalidVolID = errors.New("invalid VolumeID")
type ErrSnapNotFound struct { // ErrMissingStash is returned when the image metadata stash file is not found.
snapName string ErrMissingStash = errors.New("missing stash")
err error // ErrFlattenInProgress is returned when flatten is in progess for an image.
} ErrFlattenInProgress = errors.New("flatten in progress")
)
// Error returns a user presentable string of the error.
func (e ErrSnapNotFound) Error() string {
return e.err.Error()
}
// Unwrap returns the encapsulated error of ErrSnapNotFound.
func (e ErrSnapNotFound) Unwrap() error {
return e.err
}
// ErrVolNameConflict is generated when a requested CSI volume name already exists on RBD but with
// different properties, and hence is in conflict with the passed in CSI volume name.
type ErrVolNameConflict struct {
requestName string
err error
}
// Error returns a user presentable string of the error.
func (e ErrVolNameConflict) Error() string {
return e.err.Error()
}
// Unwrap returns the encapsulated error of ErrVolNameConflict.
func (e ErrVolNameConflict) Unwrap() error {
return e.err
}
// ErrInvalidVolID is returned when a CSI passed VolumeID does not conform to any known volume ID
// formats.
type ErrInvalidVolID struct {
err error
}
// Error returns a user presentable string of the error.
func (e ErrInvalidVolID) Error() string {
return e.err.Error()
}
// Unwrap returns the encapsulated error of ErrInvalidVolID.
func (e ErrInvalidVolID) Unwrap() error {
return e.err
}
// ErrMissingStash is returned when the image metadata stash file is not found.
type ErrMissingStash struct {
err error
}
// Error returns a user presentable string of the error.
func (e ErrMissingStash) Error() string {
return e.err.Error()
}
// Unwrap returns the encapsulated error of ErrMissingStash.
func (e ErrMissingStash) Unwrap() error {
return e.err
}
// ErrFlattenInProgress is returned when flatten is inprogess for an image.
type ErrFlattenInProgress struct {
err error
}
// Error returns a user presentable string of the error.
func (e ErrFlattenInProgress) Error() string {
return e.err.Error()
}
// Unwrap returns the encapsulated error of ErrFlattenInProgress.
func (e ErrFlattenInProgress) Unwrap() error {
return e.err
}

View File

@ -654,8 +654,7 @@ func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
} }
// If not mounted, and error is anything other than metadata file missing, it is an error // If not mounted, and error is anything other than metadata file missing, it is an error
var ems ErrMissingStash if !errors.Is(err, ErrMissingStash) {
if !errors.As(err, &ems) {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }

View File

@ -151,12 +151,10 @@ func checkSnapCloneExists(ctx context.Context, parentVol *rbdVolume, rbdSnap *rb
// Fetch on-disk image attributes // Fetch on-disk image attributes
err = vol.getImageInfo() err = vol.getImageInfo()
if err != nil { if err != nil {
var einf ErrImageNotFound if errors.Is(err, ErrImageNotFound) {
if errors.As(err, &einf) {
err = parentVol.deleteSnapshot(ctx, rbdSnap) err = parentVol.deleteSnapshot(ctx, rbdSnap)
if err != nil { if err != nil {
var esnf ErrSnapNotFound if !errors.Is(err, ErrSnapNotFound) {
if !errors.As(err, &esnf) {
klog.Errorf(util.Log(ctx, "failed to delete snapshot %s: %v"), rbdSnap, err) klog.Errorf(util.Log(ctx, "failed to delete snapshot %s: %v"), rbdSnap, err)
return false, err return false, err
} }
@ -182,8 +180,7 @@ func checkSnapCloneExists(ctx context.Context, parentVol *rbdVolume, rbdSnap *rb
// check snapshot exists if not create it // check snapshot exists if not create it
err = vol.checkSnapExists(rbdSnap) err = vol.checkSnapExists(rbdSnap)
var esnf ErrSnapNotFound if errors.Is(err, ErrSnapNotFound) {
if errors.As(err, &esnf) {
// create snapshot // create snapshot
sErr := vol.createSnapshot(ctx, rbdSnap) sErr := vol.createSnapshot(ctx, rbdSnap)
if sErr != nil { if sErr != nil {
@ -281,8 +278,7 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er
// Fetch on-disk image attributes and compare against request // Fetch on-disk image attributes and compare against request
err = rv.getImageInfo() err = rv.getImageInfo()
if err != nil { if err != nil {
var einf ErrImageNotFound if errors.Is(err, ErrImageNotFound) {
if errors.As(err, &einf) {
// Need to check cloned info here not on createvolume, // Need to check cloned info here not on createvolume,
if parentVol != nil { if parentVol != nil {
found, cErr := rv.checkCloneImage(ctx, parentVol) found, cErr := rv.checkCloneImage(ctx, parentVol)
@ -319,9 +315,8 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er
// size checks // size checks
if rv.VolSize < requestSize { if rv.VolSize < requestSize {
err = fmt.Errorf("image with the same name (%s) but with different size already exists", return false, fmt.Errorf("%w: image with the same name (%s) but with different size already exists",
rv.RbdImageName) ErrVolNameConflict, rv.RbdImageName)
return false, ErrVolNameConflict{rv.RbdImageName, err}
} }
// TODO: We should also ensure image features and format is the same // TODO: We should also ensure image features and format is the same

View File

@ -268,7 +268,7 @@ func (rv *rbdVolume) open() (*librbd.Image, error) {
image, err := librbd.OpenImage(rv.ioctx, rv.RbdImageName, librbd.NoSnapshot) image, err := librbd.OpenImage(rv.ioctx, rv.RbdImageName, librbd.NoSnapshot)
if err != nil { if err != nil {
if errors.Is(err, librbd.ErrNotFound) { if errors.Is(err, librbd.ErrNotFound) {
err = ErrImageNotFound{rv.RbdImageName, err} err = util.JoinErrors(ErrImageNotFound, err)
} }
return nil, err return nil, err
} }
@ -408,8 +408,7 @@ func (rv *rbdVolume) getCloneDepth(ctx context.Context) (uint, error) {
// if the parent image is moved to trash the name will be present // if the parent image is moved to trash the name will be present
// in rbd image info but the image will be in trash, in that case // in rbd image info but the image will be in trash, in that case
// return the found depth // return the found depth
var einf ErrImageNotFound if errors.Is(err, ErrImageNotFound) {
if errors.As(err, &einf) {
return depth, nil return depth, nil
} }
klog.Errorf(util.Log(ctx, "failed to check depth on image %s: %s"), vol, err) klog.Errorf(util.Log(ctx, "failed to check depth on image %s: %s"), vol, err)
@ -468,7 +467,7 @@ func (rv *rbdVolume) flattenRbdImage(ctx context.Context, cr *util.Credentials,
return err return err
} }
if forceFlatten || depth >= hardlimit { if forceFlatten || depth >= hardlimit {
return ErrFlattenInProgress{err: fmt.Errorf("flatten is in progress for image %s", rv.RbdImageName)} return fmt.Errorf("%w: flatten is in progress for image %s", ErrFlattenInProgress, rv.RbdImageName)
} }
} }
if !supported { if !supported {
@ -601,8 +600,8 @@ func genVolFromVolID(ctx context.Context, volumeID string, cr *util.Credentials,
err := vi.DecomposeCSIID(rbdVol.VolID) err := vi.DecomposeCSIID(rbdVol.VolID)
if err != nil { if err != nil {
err = fmt.Errorf("error decoding volume ID (%s) (%s)", err, rbdVol.VolID) return rbdVol, fmt.Errorf("%w: error decoding volume ID (%s) (%s)",
return rbdVol, ErrInvalidVolID{err} ErrInvalidVolID, err, rbdVol.VolID)
} }
rbdVol.ClusterID = vi.ClusterID rbdVol.ClusterID = vi.ClusterID
@ -822,7 +821,7 @@ func (rv *rbdVolume) deleteSnapshot(ctx context.Context, pOpts *rbdSnapshot) err
} }
err = snap.Remove() err = snap.Remove()
if errors.Is(err, librbd.ErrNotFound) { if errors.Is(err, librbd.ErrNotFound) {
return ErrSnapNotFound{snapName: pOpts.RbdSnapName, err: err} return util.JoinErrors(ErrSnapNotFound, err)
} }
return err return err
} }
@ -904,7 +903,7 @@ func (rv *rbdVolume) updateVolWithImageInfo(cr *util.Credentials) error {
klog.Errorf("failed getting information for image (%s): (%s)", rv, err) klog.Errorf("failed getting information for image (%s): (%s)", rv, err)
if strings.Contains(string(stderr), "rbd: error opening image "+rv.RbdImageName+ if strings.Contains(string(stderr), "rbd: error opening image "+rv.RbdImageName+
": (2) No such file or directory") { ": (2) No such file or directory") {
return ErrImageNotFound{rv.String(), err} return util.JoinErrors(ErrImageNotFound, err)
} }
return err return err
} }
@ -979,7 +978,7 @@ func (rv *rbdVolume) checkSnapExists(rbdSnap *rbdSnapshot) error {
} }
} }
return ErrSnapNotFound{rbdSnap.RbdSnapName, fmt.Errorf("snap %s not found", rbdSnap.String())} return fmt.Errorf("%w: snap %s not found", ErrSnapNotFound, rbdSnap.String())
} }
// rbdImageMetadataStash strongly typed JSON spec for stashed RBD image metadata. // rbdImageMetadataStash strongly typed JSON spec for stashed RBD image metadata.
@ -1040,7 +1039,7 @@ func lookupRBDImageMetadataStash(path string) (rbdImageMetadataStash, error) {
return imgMeta, fmt.Errorf("failed to read stashed JSON image metadata from path (%s): (%v)", fPath, err) return imgMeta, fmt.Errorf("failed to read stashed JSON image metadata from path (%s): (%v)", fPath, err)
} }
return imgMeta, ErrMissingStash{err} return imgMeta, util.JoinErrors(ErrMissingStash, err)
} }
err = json.Unmarshal(encodedBytes, &imgMeta) err = json.Unmarshal(encodedBytes, &imgMeta)
@ -1150,7 +1149,7 @@ func (rv *rbdVolume) listSnapshots(ctx context.Context, cr *util.Credentials) ([
klog.Errorf(util.Log(ctx, "failed getting information for image (%s): (%s)"), rv, err) klog.Errorf(util.Log(ctx, "failed getting information for image (%s): (%s)"), rv, err)
if strings.Contains(string(stderr), "rbd: error opening image "+rv.RbdImageName+ if strings.Contains(string(stderr), "rbd: error opening image "+rv.RbdImageName+
": (2) No such file or directory") { ": (2) No such file or directory") {
return snapInfo, ErrImageNotFound{rv.String(), err} return snapInfo, util.JoinErrors(ErrImageNotFound, err)
} }
return snapInfo, err return snapInfo, err
} }

View File

@ -66,16 +66,14 @@ func createRBDClone(ctx context.Context, parentVol, cloneRbdVol *rbdVolume, snap
func cleanUpSnapshot(ctx context.Context, parentVol *rbdVolume, rbdSnap *rbdSnapshot, rbdVol *rbdVolume, cr *util.Credentials) error { func cleanUpSnapshot(ctx context.Context, parentVol *rbdVolume, rbdSnap *rbdSnapshot, rbdVol *rbdVolume, cr *util.Credentials) error {
err := parentVol.deleteSnapshot(ctx, rbdSnap) err := parentVol.deleteSnapshot(ctx, rbdSnap)
if err != nil { if err != nil {
var esnf ErrSnapNotFound if !errors.Is(err, ErrSnapNotFound) {
if !errors.As(err, &esnf) {
klog.Errorf(util.Log(ctx, "failed to delete snapshot: %v"), err) klog.Errorf(util.Log(ctx, "failed to delete snapshot: %v"), err)
return err return err
} }
} }
err = deleteImage(ctx, rbdVol, cr) err = deleteImage(ctx, rbdVol, cr)
if err != nil { if err != nil {
var einf ErrImageNotFound if !errors.Is(err, ErrImageNotFound) {
if !errors.As(err, &einf) {
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s/%s with error: %v"), rbdVol.Pool, rbdVol.VolName, err) klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s/%s with error: %v"), rbdVol.Pool, rbdVol.VolName, err)
return err return err
} }