Skip to content

Commit

Permalink
feat(storage/nvme): add get backend nvme path cmd
Browse files Browse the repository at this point in the history
Signed-off-by: Artsiom Koltun <[email protected]>
  • Loading branch information
artek-koltun committed Feb 14, 2024
1 parent 5168eb4 commit f2dc44f
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ alias dpu="docker run --rm --network host ghcr.io/opiproject/godpu:main"
nvmf0=$(dpu storage create backend nvme controller --id nvmf0 --multipath disable)
path0=$(dpu storage create backend nvme path tcp --controller "$nvmf0" --id path0 --ip "11.11.11.2" --port 4444 --nqn nqn.2016-06.io.spdk:cnode1 --hostnqn nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c)
dpu storage get backend nvme controller --name $nvmf0
dpu storage get backend nvme path --name $path0

# get remote controller
dpu storage get backend nvme controller --name $nvmf0
Expand All @@ -99,6 +100,7 @@ dpu storage get backend nvme controller --name $nvmf0
nvmf1=$(dpu storage create backend nvme controller --id nvmf1 --multipath disable)
path1=$(dpu storage create backend nvme path pcie --controller "$nvmf1" --id path1 --bdf "0000:40:00.0")
dpu storage get backend nvme controller --name $nvmf1
dpu storage get backend nvme path --name $path1

# expose volume over nvme/tcp controller
ss0=$(dpu storage create frontend nvme subsystem --id subsys0 --nqn "nqn.2022-09.io.spdk:opitest0")
Expand Down
1 change: 1 addition & 0 deletions cmd/storage/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func newGetNvmeCommand() *cobra.Command {
}

cmd.AddCommand(newGetNvmeControllerCommand())
cmd.AddCommand(newGetNvmePathCommand())

return cmd

Check warning on line 114 in cmd/storage/backend/backend.go

View check run for this annotation

Codecov / codecov/patch

cmd/storage/backend/backend.go#L111-L114

Added lines #L111 - L114 were not covered by tests
}
35 changes: 35 additions & 0 deletions cmd/storage/backend/nvme_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/opiproject/godpu/cmd/storage/common"
backendclient "github.com/opiproject/godpu/storage/backend"
"github.com/spf13/cobra"
"google.golang.org/protobuf/encoding/protojson"
)

func newCreateNvmePathCommand() *cobra.Command {
Expand Down Expand Up @@ -150,3 +151,37 @@ func newDeleteNvmePathCommand() *cobra.Command {

return cmd
}

func newGetNvmePathCommand() *cobra.Command {
name := ""
cmd := &cobra.Command{
Use: "path",
Aliases: []string{"p"},
Short: "Gets nvme path to an external nvme device",
Args: cobra.NoArgs,
Run: func(c *cobra.Command, args []string) {

Check warning on line 162 in cmd/storage/backend/nvme_path.go

View workflow job for this annotation

GitHub Actions / call / golangci

unused-parameter: parameter 'args' seems to be unused, consider removing or renaming it as _ (revive)
addr, err := c.Flags().GetString(common.AddrCmdLineArg)
cobra.CheckErr(err)

timeout, err := c.Flags().GetDuration(common.TimeoutCmdLineArg)
cobra.CheckErr(err)

client, err := backendclient.New(addr)
cobra.CheckErr(err)

ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()

ctrl, err := client.GetNvmePath(ctx, name)
cobra.CheckErr(err)

common.PrintResponse(protojson.Format(ctrl))
},

Check warning on line 179 in cmd/storage/backend/nvme_path.go

View check run for this annotation

Codecov / codecov/patch

cmd/storage/backend/nvme_path.go#L155-L179

Added lines #L155 - L179 were not covered by tests
}

cmd.Flags().StringVar(&name, "name", "", "name of path to get")

cobra.CheckErr(cmd.MarkFlagRequired("name"))

return cmd

Check warning on line 186 in cmd/storage/backend/nvme_path.go

View check run for this annotation

Codecov / codecov/patch

cmd/storage/backend/nvme_path.go#L182-L186

Added lines #L182 - L186 were not covered by tests
}
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ services:
nvmf0=$$(/dpu storage create backend nvme controller --addr=opi-spdk-server:50051 --id nvmf0 --multipath failover) && \
/dpu storage get backend nvme controller --addr=opi-spdk-server:50051 --name "$$nvmf0" && \
path0=$$(/dpu storage create backend nvme path tcp --addr=opi-spdk-server:50051 --controller "$$nvmf0" --id path0 --ip $$(getent hosts spdk | cut -d" " -f1) --port 4444 --nqn nqn.2016-06.io.spdk:cnode1 --hostnqn nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c) && \
/dpu storage get backend nvme path --addr=opi-spdk-server:50051 --name "$$path0" && \
ss0=$$(/dpu storage create frontend nvme subsystem --addr=opi-spdk-server:50051 --id subsys0 --nqn "nqn.2022-09.io.spdk:opitest1") && \
ctrl0=$$(/dpu storage create frontend nvme controller tcp --addr=opi-spdk-server:50051 --id ctrl0 --ip "127.0.0.1" --port 4420 --subsystem "$$ss0") && \
ns0=$$(/dpu storage create frontend nvme namespace --addr=opi-spdk-server:50051 --id namespace0 --volume "Malloc0" --subsystem "$$ss0") && \
Expand Down
19 changes: 19 additions & 0 deletions storage/backend/nvme_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,22 @@ func (c *Client) DeleteNvmePath(

return err
}

// GetNvmePath gets an nvme path to an external nvme controller
func (c *Client) GetNvmePath(
ctx context.Context,
name string,
) (*pb.NvmePath, error) {
conn, connClose, err := c.connector.NewConn()
if err != nil {
return nil, err
}
defer connClose()

client := c.createNvmeClient(conn)
return client.GetNvmePath(
ctx,
&pb.GetNvmePathRequest{
Name: name,
})
}
84 changes: 84 additions & 0 deletions storage/backend/nvme_path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,87 @@ func TestDeleteNvmePath(t *testing.T) {
})
}
}

func TestGetNvmePath(t *testing.T) {
testPathName := "pathget"
testRequest := &pb.GetNvmePathRequest{
Name: testPathName,
}
testPath := &pb.NvmePath{
Name: testPathName,
Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TYPE_TCP,
Traddr: "127.0.0.1",
Fabrics: &pb.FabricsPath{
Trsvcid: 4420,
Subnqn: "nqn.2019-06.io.spdk:8",
Adrfam: pb.NvmeAddressFamily_NVME_ADDRESS_FAMILY_IPV4,
},
}
tests := map[string]struct {
giveClientErr error
giveConnectorErr error
wantErr error
wantRequest *pb.GetNvmePathRequest
wantResponse *pb.NvmePath
wantConnClosed bool
}{
"successful call": {
giveConnectorErr: nil,
giveClientErr: nil,
wantErr: nil,
wantRequest: proto.Clone(testRequest).(*pb.GetNvmePathRequest),
wantResponse: proto.Clone(testPath).(*pb.NvmePath),
wantConnClosed: true,
},
"client err": {
giveConnectorErr: nil,
giveClientErr: errors.New("Some client error"),
wantErr: errors.New("Some client error"),
wantRequest: proto.Clone(testRequest).(*pb.GetNvmePathRequest),
wantResponse: nil,
wantConnClosed: true,
},
"connector err": {
giveConnectorErr: errors.New("Some conn error"),
giveClientErr: nil,
wantErr: errors.New("Some conn error"),
wantRequest: nil,
wantResponse: nil,
wantConnClosed: false,
},
}

for testName, tt := range tests {
t.Run(testName, func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

mockClient := mocks.NewNvmeRemoteControllerServiceClient(t)
if tt.wantRequest != nil {
mockClient.EXPECT().GetNvmePath(ctx, tt.wantRequest).
Return(proto.Clone(tt.wantResponse).(*pb.NvmePath), tt.giveClientErr)
}

connClosed := false
mockConn := mocks.NewConnector(t)
mockConn.EXPECT().NewConn().Return(
&grpc.ClientConn{},
func() { connClosed = true },
tt.giveConnectorErr,
)

c, _ := NewWithArgs(
mockConn,
func(grpc.ClientConnInterface) pb.NvmeRemoteControllerServiceClient {
return mockClient
},
)

response, err := c.GetNvmePath(ctx, testPathName)

require.Equal(t, tt.wantErr, err)
require.True(t, proto.Equal(tt.wantResponse, response))
require.Equal(t, tt.wantConnClosed, connClosed)
})
}
}

0 comments on commit f2dc44f

Please sign in to comment.