diff --git a/internal/ceph/ceph.go b/internal/ceph/ceph.go index 11793002..795bca6f 100644 --- a/internal/ceph/ceph.go +++ b/internal/ceph/ceph.go @@ -5,10 +5,15 @@ import ( "time" ) -type RBDInfo struct { - ParentPool string - ParentImage string - ParentSnap string +type RBDImageInfo struct { + ID string `json:"id"` + Parent *RBDImageInfoParent `json:"parent,omitempty"` +} + +type RBDImageInfoParent struct { + Pool string `json:"pool"` + Image string `json:"image"` + Snapshot string `json:"snapshot"` } type RBDTimeStamp struct { @@ -35,7 +40,7 @@ type RBDSnapshot struct { type CephCmd interface { RBDClone(pool, srcImage, srcSnap, dstImage, features string) error - RBDInfo(pool, image string) (*RBDInfo, error) + RBDInfo(pool, image string) (*RBDImageInfo, error) RBDLs(pool string) ([]string, error) RBDRm(pool, image string) error RBDSnapCreate(pool, image, snap string) error diff --git a/internal/ceph/rbd.go b/internal/ceph/rbd.go index 2ca1ee2b..c46e6b3c 100644 --- a/internal/ceph/rbd.go +++ b/internal/ceph/rbd.go @@ -5,16 +5,6 @@ import ( "fmt" ) -type rbdInfoParentJS struct { - Pool string `json:"pool"` - Image string `json:"image"` - Snapshot string `json:"snapshot"` -} - -type rbdInfoJS struct { - Parent *rbdInfoParentJS `json:"parent,omitempty"` -} - // RBDClone clones an RBD image from a snapshot with specified features. func (c *cephCmdImpl) RBDClone(pool, srcImage, srcSnap, dstImage, features string) error { src := fmt.Sprintf("%s/%s@%s", pool, srcImage, srcSnap) @@ -32,28 +22,18 @@ func (c *cephCmdImpl) RBDClone(pool, srcImage, srcSnap, dstImage, features strin } // RBDInfo gets information about an RBD image. -func (c *cephCmdImpl) RBDInfo(pool, image string) (*RBDInfo, error) { +func (c *cephCmdImpl) RBDInfo(pool, image string) (*RBDImageInfo, error) { out, err := c.command.execute("rbd", "info", "--format", "json", fmt.Sprintf("%s/%s", pool, image)) if err != nil { return nil, fmt.Errorf("failed to get RBD info: %v", err) } - infoJS := &rbdInfoJS{} - err = json.Unmarshal(out, infoJS) + imageInfo := &RBDImageInfo{} + err = json.Unmarshal(out, imageInfo) if err != nil { return nil, fmt.Errorf("failed to unmarshal RBD info: %v", err) } - - if infoJS.Parent == nil { - return nil, fmt.Errorf("RBD info parent field is empty") - } - info := &RBDInfo{ - ParentPool: infoJS.Parent.Pool, - ParentImage: infoJS.Parent.Image, - ParentSnap: infoJS.Parent.Snapshot, - } - - return info, nil + return imageInfo, nil } // RBDLs lists RBD images in a pool. diff --git a/internal/ceph/rbd_test.go b/internal/ceph/rbd_test.go index 061fc457..72717379 100644 --- a/internal/ceph/rbd_test.go +++ b/internal/ceph/rbd_test.go @@ -97,9 +97,9 @@ var _ = Describe("CephCmd.RBDInfo", func() { cmd := mockedCephCmd(m) info, err := cmd.RBDInfo("pool", "image") Expect(err).ToNot(HaveOccurred()) - Expect(info.ParentPool).To(Equal("pool")) - Expect(info.ParentImage).To(Equal("csi-vol-39ca122a-88e1-44b6-aa2b-cae64fb383db")) - Expect(info.ParentSnap).To(Equal("test-snap")) + Expect(info.Parent.Pool).To(Equal("pool")) + Expect(info.Parent.Image).To(Equal("csi-vol-39ca122a-88e1-44b6-aa2b-cae64fb383db")) + Expect(info.Parent.Snapshot).To(Equal("test-snap")) }) It("should return an error, if the command failed", func() { diff --git a/internal/controller/internal/testutil/fake_rbd.go b/internal/controller/internal/testutil/fake_rbd.go index a83ebe18..fb3c39e0 100644 --- a/internal/controller/internal/testutil/fake_rbd.go +++ b/internal/controller/internal/testutil/fake_rbd.go @@ -26,7 +26,7 @@ func (f *fakeRBD) RBDClone(pool, srcImage, srcSnap, dstImage, features string) e return nil } -func (f *fakeRBD) RBDInfo(pool, image string) (*ceph.RBDInfo, error) { +func (f *fakeRBD) RBDInfo(pool, image string) (*ceph.RBDImageInfo, error) { return nil, nil } diff --git a/internal/controller/mantlerestore_controller.go b/internal/controller/mantlerestore_controller.go index d4b52d08..15d8a997 100644 --- a/internal/controller/mantlerestore_controller.go +++ b/internal/controller/mantlerestore_controller.go @@ -224,8 +224,11 @@ func (r *MantleRestoreReconciler) cloneImageFromBackup(ctx context.Context, rest if err != nil { return fmt.Errorf("failed to get RBD info: %v", err) } + if info.Parent == nil { + return fmt.Errorf("failed to get RBD info: parent field is empty") + } - if info.ParentPool == restore.Status.Pool && info.ParentImage == bkImage && info.ParentSnap == backup.Name { + if info.Parent.Pool == restore.Status.Pool && info.Parent.Image == bkImage && info.Parent.Snapshot == backup.Name { logger.Info("image already exists", "image", r.restoringRBDImageName(restore)) return nil } else {