Skip to content
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

Changes to support sync replication for Powerstore #348

Merged
merged 5 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/dell/gofsutil v1.16.1
github.com/dell/goiscsi v1.9.0
github.com/dell/gonvme v1.8.1
github.com/dell/gopowerstore v1.15.2-0.20240910164429-0d49e3cc916c
github.com/dell/gopowerstore v1.15.2-0.20240924141025-1c719e612669
github.com/fsnotify/fsnotify v1.7.0
github.com/go-openapi/strfmt v0.23.0
github.com/golang/mock v1.6.0
Expand Down Expand Up @@ -93,16 +93,16 @@ require (
go.etcd.io/etcd/api/v3 v3.5.14 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect
go.etcd.io/etcd/client/v3 v3.5.14 // indirect
go.mongodb.org/mongo-driver v1.16.1 // indirect
go.mongodb.org/mongo-driver v1.17.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect
Expand Down
18 changes: 8 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ github.com/dell/dell-csi-extensions/replication v1.8.0 h1:a4pNIRy6+rLss9KiPVqBkN
github.com/dell/dell-csi-extensions/replication v1.8.0/go.mod h1:9AyB/fKd15NLBZd0vXegnw6UOCsQA1ISSXhbEIdovEw=
github.com/dell/dell-csi-extensions/volumeGroupSnapshot v1.6.0 h1:QDSkjBwoRsENWz0cvnEzOSYzwgsibvqXRv+OFUtHsxM=
github.com/dell/dell-csi-extensions/volumeGroupSnapshot v1.6.0/go.mod h1:MSItyMKIc5oCbqc28v73AbpbmP+rJID+KQgjv0ZpRrY=
github.com/dell/gobrick v0.0.0-20240919095217-08217598cbb4 h1:KnaVM/RfV2ACsMmdci/L1ziXye+6rS9x3B7XLifDBIs=
github.com/dell/gobrick v0.0.0-20240919095217-08217598cbb4/go.mod h1:+qnDjbft08dV0s5BWG/R6KUFnS3nxJRqfALV1ficbWI=
github.com/dell/gobrick v1.11.3-0.20240919095217-08217598cbb4 h1:GvtnCpaNxrkF2XtXWOaDeJgEiY9ddFqy9asYfR/6ssY=
github.com/dell/gobrick v1.11.3-0.20240919095217-08217598cbb4/go.mod h1:+qnDjbft08dV0s5BWG/R6KUFnS3nxJRqfALV1ficbWI=
github.com/dell/gocsi v1.11.0 h1:P84VOPd1V55JQjx4tfd/6QOlVQRQkYUqmGqbzPKeyUQ=
Expand All @@ -139,8 +137,8 @@ github.com/dell/goiscsi v1.9.0 h1:VvMHbAO4vk80oc/TAbQPYlxysscCqVBW78GyPoUxgik=
github.com/dell/goiscsi v1.9.0/go.mod h1:NI/W/0O1UrMW2zVdMxy4z395Jn0r7utH6RQDFSZiFyQ=
github.com/dell/gonvme v1.8.1 h1:46M5lPqj7+Xjen+qxooRN9cx/+uJG4xtK9TpwduWDgE=
github.com/dell/gonvme v1.8.1/go.mod h1:ajbuF+fswq+ty2tRTG5FN4ecIMJsG7aDu/bkMynTKAs=
github.com/dell/gopowerstore v1.15.2-0.20240910164429-0d49e3cc916c h1:smm9zPiApcZxqUQ0A0oDTgGCRD0LIoj014KUDodtcwY=
github.com/dell/gopowerstore v1.15.2-0.20240910164429-0d49e3cc916c/go.mod h1:Q4E2eMgBSdzUKVPlEoeOXuRbk9xaq1il4LTdSanV1oc=
github.com/dell/gopowerstore v1.15.2-0.20240924141025-1c719e612669 h1:XktIu9B0VskV/nLyDFtsurvCVedi3czY0ziq52lf5RU=
github.com/dell/gopowerstore v1.15.2-0.20240924141025-1c719e612669/go.mod h1:vyN1JAZ+TO7Px+gNVa61a23/KwlI/Nj/6ttzMOQFyG0=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
Expand Down Expand Up @@ -561,8 +559,8 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxv
go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI=
go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg=
go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk=
go.mongodb.org/mongo-driver v1.16.1 h1:rIVLL3q0IHM39dvE+z2ulZLp9ENZKThVfuvN/IiN4l8=
go.mongodb.org/mongo-driver v1.16.1/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
go.mongodb.org/mongo-driver v1.17.0 h1:Hp4q2MCjvY19ViwimTs00wHi7G4yzxh4/2+nTx8r40k=
go.mongodb.org/mongo-driver v1.17.0/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
Expand Down Expand Up @@ -727,8 +725,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down Expand Up @@ -810,8 +808,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand Down
8 changes: 8 additions & 0 deletions pkg/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@ const (
PublishContextFCWWPNPrefix = "FCWWPN"
// WWNPrefix indicates WWN prefix
WWNPrefix = "naa."
// SyncMode indicates Synchronous Replication
SyncMode = "SYNC"
// AsyncMode indicats Asynchronous Replication
AsyncMode = "ASYNC"
// Zero indicates value zero for RPO
Zero = "Zero"
// Metro indicates Metro mode
Metro = "METRO"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'MetroMode' - to be consistent with other mode names? Or an enum that defines the modes.


contextLogFieldsKey key = iota

Expand Down
43 changes: 37 additions & 6 deletions pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,27 +263,43 @@ func (s *Service) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest
}
repMode := params[s.WithRP(KeyReplicationMode)]
if repMode == "" {
repMode = "ASYNC"
repMode = common.AsyncMode
}
repMode = strings.ToUpper(repMode)

switch repMode {
case "SYNC", "ASYNC":
case common.SyncMode, common.AsyncMode:
// handle Sync and Async modes where protection policy with replication rule is applied on volume group
log.Infof("%s replication mode requested", repMode)
vgPrefix, ok := params[s.WithRP(KeyReplicationVGPrefix)]
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "replication enabled but no volume group prefix specified in storage class")
}

rpo, ok := params[s.WithRP(KeyReplicationRPO)]
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "replication enabled but no RPO specified in storage class")
// If Replication mode is ASYNC and there is no RPO specified, returning an error
if repMode == common.AsyncMode {
return nil, status.Errorf(codes.InvalidArgument, "replication mode is ASYNC but no RPO specified in storage class")
}
// If Replication mode is SYNC and there is no RPO, defaulting the value to Zero
rpo = common.Zero
}
rpoEnum := gopowerstore.RPOEnum(rpo)
if err := rpoEnum.IsValid(); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid RPO value")
}

// Validating RPO to be non Zero when replication mode is ASYNC
if repMode == common.AsyncMode && rpo == common.Zero {
log.Errorf("RPO value for %s cannot be : %s", repMode, rpo)
return nil, status.Errorf(codes.InvalidArgument, "replication mode ASYNC requires RPO value to be non Zero")
rajendraindukuri marked this conversation as resolved.
Show resolved Hide resolved
}

// Validating RPO to be Zero whe replication mode is SYNC
rajendraindukuri marked this conversation as resolved.
Show resolved Hide resolved
if repMode == common.SyncMode && rpo != common.Zero {
return nil, status.Errorf(codes.InvalidArgument, "replication mode SYNC requires RPO value to be Zero")
}
namespace := ""
if ignoreNS, ok := params[s.WithRP(KeyReplicationIgnoreNamespaces)]; ok && ignoreNS == "false" {
pvcNS, ok := params[KeyCSIPVCNamespace]
Expand All @@ -302,15 +318,24 @@ func (s *Service) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest
if apiError, ok := err.(gopowerstore.APIError); ok && apiError.NotFound() {
log.Infof("Volume group with name %s not found, creating it", vgName)

// Attribute that indicates whether snapshot sets of the volumegroup will be write-order consistent.
isWriteOrderConsistent := false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will make write-order-consistent to be false for ASYNC mode while the API/UI's enables it by default for volume group creation.
CC @alankar-verma

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about enabling it (sending true) irrespective of the mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @santhoshatdell Currently for async we are not passing is-write-consistent ... so by default the value is going as false due to boolean default value (though from API perspective by default it is true ). For Sync, it should be true always so used this variable to pass as true.. Can we discuss on this and handle as part of upcoming PR s ?


// ensure protection policy exists
pp, err := EnsureProtectionPolicyExists(ctx, arr, vgName, remoteSystemName, rpoEnum)
if err != nil {
return nil, status.Errorf(codes.Internal, "can't ensure protection policy exists %s", err.Error())
}

// To apply a ProtectionPolicy with Sync rule, VolumeGroup must be write-order-consistent
if repMode == common.SyncMode {
isWriteOrderConsistent = true
}

group, err := arr.Client.CreateVolumeGroup(ctx, &gopowerstore.VolumeGroupCreate{
Name: vgName,
ProtectionPolicyID: pp,
Name: vgName,
ProtectionPolicyID: pp,
IsWriteOrderConsistent: isWriteOrderConsistent,
})
if err != nil {
return nil, status.Errorf(codes.Internal, "can't create volume group: %s", err.Error())
Expand All @@ -325,6 +350,12 @@ func (s *Service) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest
return nil, status.Errorf(codes.Internal, "can't query volume group by name %s : %s", vgName, err.Error())
}
} else {
// if Replication mode is SYNC, check if the VolumeGroup is write-order consistent
if repMode == common.SyncMode {
if !vg.IsWriteOrderConsistent {
return nil, status.Errorf(codes.Internal, "can't apply protection policy with sync rule if volume group is not write-order consistent")
}
}
// group exists, check that protection policy applied
if vg.ProtectionPolicyID == "" {
pp, err := EnsureProtectionPolicyExists(ctx, arr, vgName, remoteSystemName, rpoEnum)
Expand All @@ -342,7 +373,7 @@ func (s *Service) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest
if c, ok := creator.(*SCSICreator); ok {
c.vg = &vg
}
case "METRO":
case common.Metro:
// handle Metro mode where metro is configured directly on the volume (or volume group if requested)
log.Info("Metro replication mode requested")

Expand Down
Loading