-
Couldn't load subscription status.
- Fork 580
rbd: refactor mirroring to work with volume and volumegroup #4720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@nixpanic can you please check this PR for early review, i still need to do testing, once everything is good i will move this to Ready state. |
internal/rbd/types/mirror.go
Outdated
| Resync() error | ||
|
|
||
| // GetMirroringInfo returns the mirroring information of the resource | ||
| GetMirroringInfo() (interface{}, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is really ugly to return an untyped interface. Can that be improved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i tried but it gets more difficult for implementation where i need to have different duplicate checks for both volume and group, that's the reason to settle on this after lot of other considerations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a MirrorInfo interface too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am not sure adding MirrorInfo interface helps but the problem is that the volumemirror and groupmirror in go-ceph return different structs, if both are returning the same i could have solved this or else I need to own a local struct and fill the required values from both, i can do this if you prefer (this will have lot of duplication logic and maintenance work)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, or have a MirrorInfo interface with only some basic function, or completely empty? At least the type can then describe that it is actually one of the go-ceph types.
1899b64 to
7dbb200
Compare
| "google.golang.org/protobuf/types/known/timestamppb" | ||
| ) | ||
|
|
||
| //nolint:interfacebloat // more than 10 methods are needed for the interface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In #4719 I added the journalledObject interface. Such an approach also prevents the need for skipping the interfacebloat linter.
| rbdVol.Destroy(ctx) | ||
| } | ||
| }() | ||
| mgr := rbd.NewManager(req.GetParameters(), req.GetSecrets()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that the CSI-instance id (drivername) needs to be passed to the manager in an upcoming change.
|
@nixpanic I have tested this code and works as expected, let me know if you want to make any changes you are referring to the manager as part of this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Splitting the commit would be nice.
At least add the new types in a separate commit, and use them in subsequent ones.
The single commit is +488 -300 lines of code, which is rather a lot.
| // IsPrimary returns true if the resource is primary | ||
| IsPrimary() bool | ||
| // GetState returns the state of the resource | ||
| GetState() string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider adding a MirrorState type to replace the string value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs more work, will take it in next update when implementing this for group
| RemoveFromGroup(ctx context.Context, vg VolumeGroup) error | ||
|
|
||
| // GetPoolName returns the name of the pool where the volume is stored. | ||
| GetPoolName() string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe Volume should inherit the journalledObject too?
ceph-csi/internal/rbd/types/group.go
Lines 26 to 38 in aa88b4c
| type journalledObject interface { | |
| // GetID returns the CSI-Addons VolumeGroupId of the VolumeGroup. | |
| GetID(ctx context.Context) (string, error) | |
| // GetName returns the name in the backend storage for the VolumeGroup. | |
| GetName(ctx context.Context) (string, error) | |
| // GetPool returns the name of the pool that holds the VolumeGroup. | |
| GetPool(ctx context.Context) (string, error) | |
| // GetClusterID returns the ID of the cluster of the VolumeGroup. | |
| GetClusterID(ctx context.Context) (string, error) | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a little more refactoring as journalledObject is specific to volumeGroup now, will address this in follow-up when implementing for group support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is only the comments that refer to VolumeGroup. The functions could be for Volume as well.
|
|
||
| return nil, err | ||
| } | ||
| mirror = rbdVol |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to have rbdVol.ToMirror() that validates everything required for the new Mirror type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nixpanic can you explain a bit more on this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated the code, PTAL and see if this matches your expectation
internal/rbd/types/volume.go
Outdated
| //nolint:interfacebloat // more than 10 methods are needed for the interface | ||
| type Volume interface { | ||
| // Mirror interface implementation for Volume | ||
| Mirror |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because you use mirror = rbdVol, I would expect that the Mirror interface is kept seperate. I do not see a need to have it part of the Volume interface. The rbdVolume struct can still implement both interfaces.
internal/rbd/group.go
Outdated
| return librbd.GroupImageRemove(ioctx, name, rv.ioctx, rv.RbdImageName) | ||
| } | ||
|
|
||
| func (rv *rbdVolume) ToMirror() types.Mirror { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Would it make sense to have some checking if mirror attributes are valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for now, do you have any specific checks in your mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really. Mostly just to have the function match func (*rbdVolume) ToCSI(ctx) (csi.Volume, error)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the signature is matching now, it returns nil for now but can be updated later as required.
|
@Mergifyio rebase |
Adding mirror interface for rbd image and group which can be used to manage mirroring for both. Signed-off-by: Madhu Rajanna <[email protected]>
Add helper methods for the rbd image mirroring. Signed-off-by: Madhu Rajanna <[email protected]>
Refractoring code to use mirror interface. Signed-off-by: Madhu Rajanna <[email protected]>
✅ Branch has been successfully rebased |
|
/test ci/centos/upgrade-tests-cephfs |
|
/test ci/centos/upgrade-tests-rbd |
|
/test ci/centos/k8s-e2e-external-storage/1.27 |
|
/test ci/centos/k8s-e2e-external-storage/1.29 |
|
/test ci/centos/mini-e2e-helm/k8s-1.27 |
|
/test ci/centos/mini-e2e/k8s-1.27 |
|
/test ci/centos/mini-e2e-helm/k8s-1.29 |
|
/test ci/centos/k8s-e2e-external-storage/1.28 |
|
/test ci/centos/mini-e2e/k8s-1.29 |
|
/test ci/centos/mini-e2e-helm/k8s-1.28 |
|
/test ci/centos/mini-e2e/k8s-1.28 |
|
/test ci/centos/k8s-e2e-external-storage/1.30 |
|
/test ci/centos/mini-e2e-helm/k8s-1.30 |
|
/test ci/centos/mini-e2e/k8s-1.30 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
| AddSnapshotScheduling(interval admin.Interval, startTime admin.StartTime) error | ||
| } | ||
|
|
||
| // MirrorImage is the interface for managing mirroring on an RBD image or group of images. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // MirrorImage is the interface for managing mirroring on an RBD image or group of images. | |
| // MirrorInfo is the interface for managing mirroring on an RBD image or group of images. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will address this in follow up. Thanks @Madhu-1 for catching it.
| r.cas.RegisterService(fcs) | ||
|
|
||
| rcs := casrbd.NewReplicationServer(NewControllerServer(r.cd)) | ||
| rcs := casrbd.NewReplicationServer(rbd.CSIInstanceID, NewControllerServer(r.cd)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Madhu-1 , shouldn't this be
| rcs := casrbd.NewReplicationServer(rbd.CSIInstanceID, NewControllerServer(r.cd)) | |
| rcs := casrbd.NewReplicationServer(conf.InstanceID, NewControllerServer(r.cd)) |
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I think so. Can you send a PR for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conf.InstanceID will not work if its not set, we need to use default in that case we are not updating conf.InstanceID with rbd.CSIInstanceID, that's the reason to use rbd.CSIInstanceID as its gets updated always or it contains the default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Madhu-1, we are doing that for InitJournals -
ceph-csi/internal/rbd/globals.go
Lines 93 to 100 in db6f54f
| func InitJournals(instance string) { | |
| // Use passed in instance ID, if provided for omap suffix naming | |
| if instance != "" { | |
| CSIInstanceID = instance | |
| } | |
| volJournal = journal.NewCSIVolumeJournal(CSIInstanceID) | |
| snapJournal = journal.NewCSISnapshotJournal(CSIInstanceID) |
And conf.InstanceID is passed to InitJournals
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the conf.InsatceID is empty its not updated with the default one that we have in the code right rbd.InitJournals(conf.InstanceID)? with this one
ceph-csi/internal/rbd/globals.go
Line 28 in db6f54f
| CSIInstanceID = "default" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies, I was mistaken it was other way around.
Thanks @Madhu-1.
Then I guess for VolumeGroupServer we need to use rbd.CSIInstanceID
ceph-csi/internal/rbd/driver/driver.go
Line 223 in db6f54f
| vgcs := casrbd.NewVolumeGroupServer(conf.InstanceID) |
@nixpanic ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rbd.CSIInstanceID seems to be a global value, it is configurable on the commandline, so I think using the configured value is cleaner (all config options should have default values anyway?).
In internal/rbd/driver/driver.go there is rbd.InitJournals(conf.InstanceID), so in the end it is all the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conf.InstanceID default value is empty and rbd.CSIInstanceID is replaced with conf.InstanceID when it is configured in command line.
So using conf.InstanceID when its not configured will lead to creating journal directory csi.groups. ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I noticed that too. The global rbd.CSIInstanceID could be set to something earlier on, in case the ordering of (seemingly unrelated) initialization of the journals is done later. This is a little fragile, and using global variables is quite ugly in any case. I'm preparing a PR for improving it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see #4747
refactor mirroring to work with volume and volumegroup