-
Notifications
You must be signed in to change notification settings - Fork 545
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
rbd: refactor mirroring to work with volume and volumegroup #4720
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
) | ||
|
||
//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
@@ -40,4 +42,21 @@ type Volume interface { | |||
|
|||
// RemoveFromGroup removes the Volume from the VolumeGroup. | |||
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.
default: | ||
err = status.Errorf(codes.Internal, err.Error()) | ||
} | ||
|
||
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
@@ -25,6 +25,8 @@ import ( | |||
|
|||
//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
@@ -77,3 +77,7 @@ func (rv *rbdVolume) RemoveFromGroup(ctx context.Context, vg types.VolumeGroup) | |||
|
|||
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 <madhupr007@gmail.com>
Add helper methods for the rbd image mirroring. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
Refractoring code to use mirror interface. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
✅ 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.
@@ -219,7 +219,7 @@ func (r *Driver) setupCSIAddonsServer(conf *util.Config) error { | |||
fcs := casrbd.NewFenceControllerServer() | |||
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