Skip to content

Commit

Permalink
DAOS-16292 control: Allow optional pool UUID for Create API (#15142)
Browse files Browse the repository at this point in the history
In some API use cases, the PoolCreate RPC may be invoked
by different processes. Allowing the pool UUID to be
supplied as part of the create makes the operation
idempotent in these scenarios. This commit does not
change the dmg UI.

Signed-off-by: Michael MacDonald <mjmac@google.com>
  • Loading branch information
mjmac committed Sep 18, 2024
1 parent acfa271 commit 3464753
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
12 changes: 11 additions & 1 deletion src/control/lib/control/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,17 @@ func (pcr *PoolCreateReq) MarshalJSON() ([]byte, error) {

type toJSON PoolCreateReq
return json.Marshal(struct {
UUID string `json:"uuid,omitempty"`
Properties []*mgmtpb.PoolProperty `json:"properties"`
ACL []string `json:"acl"`
*toJSON
}{
UUID: func() string {
if pcr.UUID == uuid.Nil {
return ""
}
return pcr.UUID.String()
}(),
Properties: props,
ACL: acl,
toJSON: (*toJSON)(pcr),
Expand Down Expand Up @@ -199,6 +206,7 @@ type (
// PoolCreateReq contains the parameters for a pool create request.
PoolCreateReq struct {
poolRequest
UUID uuid.UUID `json:"uuid,omitempty"` // Optional UUID; auto-generate if not supplied
User string `json:"user"`
UserGroup string `json:"user_group"`
ACL *AccessControlList `json:"-"`
Expand Down Expand Up @@ -299,7 +307,9 @@ func poolCreateGenPBReq(ctx context.Context, rpcClient UnaryInvoker, in *PoolCre
return
}

out.Uuid = uuid.New().String()
if out.Uuid == "" {
out.Uuid = uuid.New().String()
}
return
}

Expand Down
39 changes: 37 additions & 2 deletions src/control/lib/control/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,11 +516,13 @@ func TestControl_PoolCreate(t *testing.T) {
humanize.GiByte * 10,
},
}
customPoolUUID := test.MockPoolUUID()

for name, tc := range map[string]struct {
mic *MockInvokerConfig
req *PoolCreateReq
expResp *PoolCreateResp
cmpUUID bool
expErr error
}{
"local failure": {
Expand Down Expand Up @@ -687,6 +689,36 @@ func TestControl_PoolCreate(t *testing.T) {
TgtRanks: []uint32{0, 1, 2},
},
},
"custom UUID": {
req: &PoolCreateReq{
UUID: customPoolUUID,
TierRatio: mockTierRatios,
TotalBytes: humanize.GiByte * 20,
Properties: []*daos.PoolProperty{
{
Name: "label",
Number: daos.PoolPropertyLabel,
Value: strVal("foo"),
},
},
},
mic: &MockInvokerConfig{
UnaryResponse: MockMSResponse("host1", nil,
&mgmtpb.PoolCreateResp{
SvcLdr: 1,
SvcReps: []uint32{0, 1, 2},
TgtRanks: []uint32{0, 1, 2},
},
),
},
expResp: &PoolCreateResp{
UUID: customPoolUUID.String(),
Leader: 1,
SvcReps: []uint32{0, 1, 2},
TgtRanks: []uint32{0, 1, 2},
},
cmpUUID: true,
},
} {
t.Run(name, func(t *testing.T) {
log, buf := logging.NewTestLogger(t.Name())
Expand All @@ -706,8 +738,11 @@ func TestControl_PoolCreate(t *testing.T) {
return
}

cmpOpt := cmpopts.IgnoreFields(PoolCreateResp{}, "UUID")
if diff := cmp.Diff(tc.expResp, gotResp, cmpOpt); diff != "" {
var cmpOpts cmp.Options
if !tc.cmpUUID {
cmpOpts = append(cmpOpts, cmpopts.IgnoreFields(PoolCreateResp{}, "UUID"))
}
if diff := cmp.Diff(tc.expResp, gotResp, cmpOpts...); diff != "" {
t.Fatalf("Unexpected response (-want, +got):\n%s\n", diff)
}
})
Expand Down

0 comments on commit 3464753

Please sign in to comment.