From b9be140dcccb500d27a4745c40d9bd05c8349c8f Mon Sep 17 00:00:00 2001 From: Artsiom Koltun Date: Fri, 8 Dec 2023 13:49:28 +0100 Subject: [PATCH] fix(storage/backend): adjust nvme to parent member Signed-off-by: Artsiom Koltun --- README.md | 22 +++---- pkg/backend/nvme_controller.go | 6 +- pkg/backend/nvme_controller_test.go | 81 ++++++++++++++----------- pkg/backend/nvme_path.go | 29 +++++---- pkg/backend/nvme_path_test.go | 91 +++++++++++++---------------- pkg/backend/nvme_path_validate.go | 2 +- pkg/utils/resource.go | 30 ++++++++++ scripts/tests.sh | 20 +++---- 8 files changed, 161 insertions(+), 120 deletions(-) diff --git a/README.md b/README.md index 2684c4f2..11ade212 100644 --- a/README.md +++ b/README.md @@ -92,18 +92,18 @@ docker run --network=host --rm -it namely/grpc-cli call --json_input --json_outp docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 GetNvmeNamespace "{name : '//storage.opiproject.org/subsystems/subsystem2/namespaces/namespace1'}" docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 StatsNvmeNamespace "{name : '//storage.opiproject.org/subsystems/subsystem2/namespaces/namespace1'}" docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 CreateNvmeRemoteController "{nvme_remote_controller : {multipath: 'NVME_MULTIPATH_MULTIPATH', tcp: {hdgst: false, ddgst: false}}, nvme_remote_controller_id: 'nvmetcp12'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 ListNvmeRemoteControllers "{parent : 'todo'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 GetNvmeRemoteController "{name: '//storage.opiproject.org/volumes/nvmetcp12'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 CreateNvmePath "{nvme_path : {controller_name_ref: '//storage.opiproject.org/volumes/nvmetcp12', traddr:'11.11.11.2', trtype:'NVME_TRANSPORT_TCP', fabrics:{subnqn:'nqn.2016-06.com.opi.spdk.target0', trsvcid:'4444', adrfam:'NVME_ADRFAM_IPV4', hostnqn:'nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c'}}, nvme_path_id: 'nvmetcp12path0'}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 ListNvmeRemoteControllers "{}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 GetNvmeRemoteController "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12'}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 CreateNvmePath "{parent: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12', nvme_path : {traddr:'11.11.11.2', trtype:'NVME_TRANSPORT_TCP', fabrics:{subnqn:'nqn.2016-06.com.opi.spdk.target0', trsvcid:'4444', adrfam:'NVME_ADRFAM_IPV4', hostnqn:'nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c'}}, nvme_path_id: 'nvmetcp12path0'}" docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 CreateNvmeRemoteController "{nvme_remote_controller : {multipath: 'NVME_MULTIPATH_DISABLE'}, nvme_remote_controller_id: 'nvmepcie13'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 CreateNvmePath "{nvme_path : {controller_name_ref: '//storage.opiproject.org/volumes/nvmepcie13', traddr:'0000:01:00.0', trtype:'NVME_TRANSPORT_PCIE'}, nvme_path_id: 'nvmepcie13path0'}" - -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 ListNvmePaths "{parent : 'todo'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmePath "{name: '//storage.opiproject.org/volumes/nvmepcie13path0'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmeRemoteController "{name: '//storage.opiproject.org/volumes/nvmepcie13'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 GetNvmePath "{name: '//storage.opiproject.org/volumes/nvmetcp12path0'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmePath "{name: '//storage.opiproject.org/volumes/nvmetcp12path0'}" -docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmeRemoteController "{name: '//storage.opiproject.org/volumes/nvmetcp12'}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 CreateNvmePath "{parent: '//storage.opiproject.org/nvmeRemoteControllers/nvmepcie13', nvme_path : {traddr:'0000:01:00.0', trtype:'NVME_TRANSPORT_PCIE'}, nvme_path_id: 'nvmepcie13path0'}" + +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 ListNvmePaths "{parent : '//storage.opiproject.org/nvmeRemoteControllers/nvmepcie13'}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmePath "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmepcie13/nvmePaths/nvmepcie13path0'}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmeRemoteController "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmepcie13'}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 GetNvmePath "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12/nvmePaths/nvmetcp12path0'}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmePath "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12/nvmePaths/nvmetcp12path0'}" +docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmeRemoteController "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12'}" docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmeNamespace "{name : '//storage.opiproject.org/subsystems/subsystem2/namespaces/namespace1'}" docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmeController "{name : '//storage.opiproject.org/subsystems/subsystem2/controllers/controller1'}" docker run --network=host --rm -it namely/grpc-cli call --json_input --json_output 10.10.10.10:50051 DeleteNvmeSubsystem "{name : '//storage.opiproject.org/subsystems/subsystem2'}" diff --git a/pkg/backend/nvme_controller.go b/pkg/backend/nvme_controller.go index 99de643f..413af114 100644 --- a/pkg/backend/nvme_controller.go +++ b/pkg/backend/nvme_controller.go @@ -41,7 +41,7 @@ func (s *Server) CreateNvmeRemoteController(_ context.Context, in *pb.CreateNvme log.Printf("client provided the ID of a resource %v, ignoring the name field %v", in.NvmeRemoteControllerId, in.NvmeRemoteController.Name) resourceID = in.NvmeRemoteControllerId } - in.NvmeRemoteController.Name = utils.ResourceIDToVolumeName(resourceID) + in.NvmeRemoteController.Name = utils.ResourceIDToRemoteControllerName(resourceID) // idempotent API when called with same key, should return same object volume, ok := s.Volumes.NvmeControllers[in.NvmeRemoteController.Name] if ok { @@ -92,7 +92,7 @@ func (s *Server) UpdateNvmeRemoteController(_ context.Context, in *pb.UpdateNvme return nil, err } // fetch object from the database - volume, ok := s.Volumes.NvmeControllers[in.NvmeRemoteController.Name] + controller, ok := s.Volumes.NvmeControllers[in.NvmeRemoteController.Name] if !ok { if in.AllowMissing { log.Printf("TODO: in case of AllowMissing, create a new resource, don;t return error") @@ -100,7 +100,7 @@ func (s *Server) UpdateNvmeRemoteController(_ context.Context, in *pb.UpdateNvme err := status.Errorf(codes.NotFound, "unable to find key %s", in.NvmeRemoteController.Name) return nil, err } - resourceID := path.Base(volume.Name) + resourceID := utils.GetRemoteControllerIDFromNvmeRemoteName(controller.Name) // update_mask = 2 if err := fieldmask.Validate(in.UpdateMask, in.NvmeRemoteController); err != nil { return nil, err diff --git a/pkg/backend/nvme_controller_test.go b/pkg/backend/nvme_controller_test.go index 57ce4f82..2654c134 100644 --- a/pkg/backend/nvme_controller_test.go +++ b/pkg/backend/nvme_controller_test.go @@ -22,7 +22,7 @@ import ( var ( testNvmeCtrlID = "opi-nvme8" - testNvmeCtrlName = utils.ResourceIDToVolumeName(testNvmeCtrlID) + testNvmeCtrlName = utils.ResourceIDToRemoteControllerName(testNvmeCtrlID) testNvmeCtrl = pb.NvmeRemoteController{ Tcp: &pb.TcpController{ Hdgst: false, @@ -178,10 +178,10 @@ func TestBackEnd_ListNvmeRemoteControllers(t *testing.T) { in: testNvmeCtrlID, out: []*pb.NvmeRemoteController{ { - Name: utils.ResourceIDToVolumeName("OpiNvme12"), + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), }, { - Name: utils.ResourceIDToVolumeName("OpiNvme13"), + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), }, }, errCode: codes.OK, @@ -189,18 +189,22 @@ func TestBackEnd_ListNvmeRemoteControllers(t *testing.T) { size: 0, token: "", existingControllers: map[string]*pb.NvmeRemoteController{ - utils.ResourceIDToVolumeName("OpiNvme12"): {Name: utils.ResourceIDToVolumeName("OpiNvme12")}, - utils.ResourceIDToVolumeName("OpiNvme13"): {Name: utils.ResourceIDToVolumeName("OpiNvme13")}, + utils.ResourceIDToRemoteControllerName("OpiNvme12"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), + }, + utils.ResourceIDToRemoteControllerName("OpiNvme13"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), + }, }, }, "pagination overflow": { in: testNvmeCtrlID, out: []*pb.NvmeRemoteController{ { - Name: utils.ResourceIDToVolumeName("OpiNvme12"), + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), }, { - Name: utils.ResourceIDToVolumeName("OpiNvme13"), + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), }, }, errCode: codes.OK, @@ -208,8 +212,12 @@ func TestBackEnd_ListNvmeRemoteControllers(t *testing.T) { size: 1000, token: "", existingControllers: map[string]*pb.NvmeRemoteController{ - utils.ResourceIDToVolumeName("OpiNvme12"): {Name: utils.ResourceIDToVolumeName("OpiNvme12")}, - utils.ResourceIDToVolumeName("OpiNvme13"): {Name: utils.ResourceIDToVolumeName("OpiNvme13")}, + utils.ResourceIDToRemoteControllerName("OpiNvme12"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), + }, + utils.ResourceIDToRemoteControllerName("OpiNvme13"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), + }, }, }, "pagination negative": { @@ -220,8 +228,12 @@ func TestBackEnd_ListNvmeRemoteControllers(t *testing.T) { size: -10, token: "", existingControllers: map[string]*pb.NvmeRemoteController{ - utils.ResourceIDToVolumeName("OpiNvme12"): {Name: utils.ResourceIDToVolumeName("OpiNvme12")}, - utils.ResourceIDToVolumeName("OpiNvme13"): {Name: utils.ResourceIDToVolumeName("OpiNvme13")}, + utils.ResourceIDToRemoteControllerName("OpiNvme12"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), + }, + utils.ResourceIDToRemoteControllerName("OpiNvme13"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), + }, }, }, "pagination error": { @@ -232,15 +244,19 @@ func TestBackEnd_ListNvmeRemoteControllers(t *testing.T) { size: 0, token: "unknown-pagination-token", existingControllers: map[string]*pb.NvmeRemoteController{ - utils.ResourceIDToVolumeName("OpiNvme12"): {Name: utils.ResourceIDToVolumeName("OpiNvme12")}, - utils.ResourceIDToVolumeName("OpiNvme13"): {Name: utils.ResourceIDToVolumeName("OpiNvme13")}, + utils.ResourceIDToRemoteControllerName("OpiNvme12"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), + }, + utils.ResourceIDToRemoteControllerName("OpiNvme13"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), + }, }, }, "pagination": { in: testNvmeCtrlID, out: []*pb.NvmeRemoteController{ { - Name: utils.ResourceIDToVolumeName("OpiNvme12"), + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), }, }, errCode: codes.OK, @@ -248,15 +264,19 @@ func TestBackEnd_ListNvmeRemoteControllers(t *testing.T) { size: 1, token: "", existingControllers: map[string]*pb.NvmeRemoteController{ - utils.ResourceIDToVolumeName("OpiNvme12"): {Name: utils.ResourceIDToVolumeName("OpiNvme12")}, - utils.ResourceIDToVolumeName("OpiNvme13"): {Name: utils.ResourceIDToVolumeName("OpiNvme13")}, + utils.ResourceIDToRemoteControllerName("OpiNvme12"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), + }, + utils.ResourceIDToRemoteControllerName("OpiNvme13"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), + }, }, }, "pagination offset": { in: testNvmeCtrlID, out: []*pb.NvmeRemoteController{ { - Name: utils.ResourceIDToVolumeName("OpiNvme13"), + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), }, }, errCode: codes.OK, @@ -264,19 +284,14 @@ func TestBackEnd_ListNvmeRemoteControllers(t *testing.T) { size: 1, token: "existing-pagination-token", existingControllers: map[string]*pb.NvmeRemoteController{ - utils.ResourceIDToVolumeName("OpiNvme12"): {Name: utils.ResourceIDToVolumeName("OpiNvme12")}, - utils.ResourceIDToVolumeName("OpiNvme13"): {Name: utils.ResourceIDToVolumeName("OpiNvme13")}, + utils.ResourceIDToRemoteControllerName("OpiNvme12"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme12"), + }, + utils.ResourceIDToRemoteControllerName("OpiNvme13"): { + Name: utils.ResourceIDToRemoteControllerName("OpiNvme13"), + }, }, }, - "no required field": { - in: "", - out: []*pb.NvmeRemoteController{}, - errCode: codes.Unknown, - errMsg: "missing required field: parent", - size: 0, - token: "", - existingControllers: map[string]*pb.NvmeRemoteController{}, - }, } // run tests @@ -290,7 +305,7 @@ func TestBackEnd_ListNvmeRemoteControllers(t *testing.T) { testEnv.opiSpdkServer.Volumes.NvmeControllers[k] = utils.ProtoClone(v) } - request := &pb.ListNvmeRemoteControllersRequest{Parent: tt.in, PageSize: tt.size, PageToken: tt.token} + request := &pb.ListNvmeRemoteControllersRequest{PageSize: tt.size, PageToken: tt.token} response, err := testEnv.client.ListNvmeRemoteControllers(testEnv.ctx, request) if !utils.EqualProtoSlices(response.GetNvmeRemoteControllers(), tt.out) { @@ -464,21 +479,21 @@ func TestBackEnd_DeleteNvmeRemoteController(t *testing.T) { missing: false, }, "valid request with unknown key": { - in: utils.ResourceIDToVolumeName("unknown-id"), + in: utils.ResourceIDToRemoteControllerName("unknown-id"), out: nil, errCode: codes.NotFound, - errMsg: fmt.Sprintf("unable to find key %v", utils.ResourceIDToVolumeName("unknown-id")), + errMsg: fmt.Sprintf("unable to find key %v", utils.ResourceIDToRemoteControllerName("unknown-id")), missing: false, }, "unknown key with missing allowed": { - in: utils.ResourceIDToVolumeName("unknown-id"), + in: utils.ResourceIDToRemoteControllerName("unknown-id"), out: &emptypb.Empty{}, errCode: codes.OK, errMsg: "", missing: true, }, "malformed name": { - in: utils.ResourceIDToVolumeName("-ABC-DEF"), + in: utils.ResourceIDToRemoteControllerName("-ABC-DEF"), out: &emptypb.Empty{}, errCode: codes.Unknown, errMsg: fmt.Sprintf("segment '%s': not a valid DNS name", "-ABC-DEF"), diff --git a/pkg/backend/nvme_path.go b/pkg/backend/nvme_path.go index e2bceb8d..6db6e0e5 100644 --- a/pkg/backend/nvme_path.go +++ b/pkg/backend/nvme_path.go @@ -45,7 +45,10 @@ func (s *Server) CreateNvmePath(ctx context.Context, in *pb.CreateNvmePathReques log.Printf("client provided the ID of a resource %v, ignoring the name field %v", in.NvmePathId, in.NvmePath.Name) resourceID = in.NvmePathId } - in.NvmePath.Name = utils.ResourceIDToVolumeName(resourceID) + in.NvmePath.Name = utils.ResourceIDToNvmePathName( + utils.GetRemoteControllerIDFromNvmeRemoteName(in.Parent), + resourceID, + ) nvmePath, ok := s.Volumes.NvmePaths[in.NvmePath.Name] if ok { @@ -53,9 +56,9 @@ func (s *Server) CreateNvmePath(ctx context.Context, in *pb.CreateNvmePathReques return nvmePath, nil } - controller, ok := s.Volumes.NvmeControllers[in.NvmePath.ControllerNameRef] + controller, ok := s.Volumes.NvmeControllers[in.Parent] if !ok { - err := status.Errorf(codes.NotFound, "unable to find NvmeRemoteController by key %s", in.NvmePath.ControllerNameRef) + err := status.Errorf(codes.NotFound, "unable to find NvmeRemoteController by key %s", in.Parent) return nil, err } @@ -85,7 +88,7 @@ func (s *Server) CreateNvmePath(ctx context.Context, in *pb.CreateNvmePathReques psk = keyFile } params := spdk.BdevNvmeAttachControllerParams{ - Name: path.Base(controller.Name), + Name: utils.GetRemoteControllerIDFromNvmeRemoteName(controller.Name), Trtype: s.opiTransportToSpdk(in.NvmePath.GetTrtype()), Traddr: in.NvmePath.GetTraddr(), Adrfam: utils.OpiAdressFamilyToSpdk(in.NvmePath.GetFabrics().GetAdrfam()), @@ -123,14 +126,17 @@ func (s *Server) DeleteNvmePath(ctx context.Context, in *pb.DeleteNvmePathReques err := status.Errorf(codes.NotFound, "unable to find key %s", in.Name) return nil, err } - controller, ok := s.Volumes.NvmeControllers[nvmePath.ControllerNameRef] + controllerName := utils.ResourceIDToRemoteControllerName( + utils.GetRemoteControllerIDFromNvmeRemoteName(in.Name), + ) + controller, ok := s.Volumes.NvmeControllers[controllerName] if !ok { - err := status.Errorf(codes.Internal, "unable to find NvmeRemoteController by key %s", nvmePath.ControllerNameRef) + err := status.Errorf(codes.Internal, "unable to find NvmeRemoteController by key %s", controllerName) return nil, err } params := spdk.BdevNvmeDetachControllerParams{ - Name: path.Base(controller.Name), + Name: utils.GetRemoteControllerIDFromNvmeRemoteName(controller.Name), Trtype: s.opiTransportToSpdk(nvmePath.GetTrtype()), Traddr: nvmePath.GetTraddr(), Adrfam: utils.OpiAdressFamilyToSpdk(nvmePath.GetFabrics().GetAdrfam()), @@ -145,7 +151,7 @@ func (s *Server) DeleteNvmePath(ctx context.Context, in *pb.DeleteNvmePathReques } log.Printf("Received from SPDK: %v", result) if !result { - msg := fmt.Sprintf("Could not delete Nvme Path: %s", path.Base(in.Name)) + msg := fmt.Sprintf("Could not delete Nvme Path: %s", in.Name) return nil, status.Errorf(codes.InvalidArgument, msg) } @@ -161,7 +167,7 @@ func (s *Server) UpdateNvmePath(_ context.Context, in *pb.UpdateNvmePathRequest) return nil, err } // fetch object from the database - volume, ok := s.Volumes.NvmePaths[in.NvmePath.Name] + nvmePath, ok := s.Volumes.NvmePaths[in.NvmePath.Name] if !ok { if in.AllowMissing { log.Printf("TODO: in case of AllowMissing, create a new resource, don;t return error") @@ -169,7 +175,7 @@ func (s *Server) UpdateNvmePath(_ context.Context, in *pb.UpdateNvmePathRequest) err := status.Errorf(codes.NotFound, "unable to find key %s", in.NvmePath.Name) return nil, err } - resourceID := path.Base(volume.Name) + resourceID := path.Base(nvmePath.Name) // update_mask = 2 if err := fieldmask.Validate(in.UpdateMask, in.NvmePath); err != nil { return nil, err @@ -278,8 +284,9 @@ func (s *Server) opiMultipathToSpdk(multipath pb.NvmeMultipath) string { func (s *Server) numberOfPathsForController(controllerName string) int { numberOfPaths := 0 + prefix := controllerName + "/" for _, path := range s.Volumes.NvmePaths { - if path.ControllerNameRef == controllerName { + if strings.HasPrefix(path.Name, prefix) { numberOfPaths++ } } diff --git a/pkg/backend/nvme_path_test.go b/pkg/backend/nvme_path_test.go index 17208667..d5d6181d 100644 --- a/pkg/backend/nvme_path_test.go +++ b/pkg/backend/nvme_path_test.go @@ -26,11 +26,10 @@ import ( var ( testNvmePathID = "mytest" - testNvmePathName = utils.ResourceIDToVolumeName(testNvmePathID) + testNvmePathName = utils.ResourceIDToNvmePathName(testNvmeCtrlID, testNvmePathID) testNvmePath = pb.NvmePath{ - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TCP, - Traddr: "127.0.0.1", - ControllerNameRef: testNvmeCtrlName, + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TCP, + Traddr: "127.0.0.1", Fabrics: &pb.FabricsPath{ Adrfam: pb.NvmeAddressFamily_NVME_ADRFAM_IPV4, Subnqn: "nqn.2016-06.io.spdk:cnode1", @@ -39,11 +38,10 @@ var ( }, } testNvmePathWithName = pb.NvmePath{ - Name: testNvmePathName, - Trtype: testNvmePath.Trtype, - Traddr: testNvmePath.Traddr, - ControllerNameRef: testNvmePath.ControllerNameRef, - Fabrics: testNvmePath.Fabrics, + Name: testNvmePathName, + Trtype: testNvmePath.Trtype, + Traddr: testNvmePath.Traddr, + Fabrics: testNvmePath.Fabrics, } ) @@ -158,15 +156,13 @@ func TestBackEnd_CreateNvmePath(t *testing.T) { "valid request with valid SPDK response for pcie": { id: testNvmePathID, in: &pb.NvmePath{ - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_PCIE, - ControllerNameRef: testNvmePath.ControllerNameRef, - Traddr: "0000:af:00.0", + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_PCIE, + Traddr: "0000:af:00.0", }, out: &pb.NvmePath{ - Name: testNvmePathName, - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_PCIE, - ControllerNameRef: testNvmePath.ControllerNameRef, - Traddr: "0000:af:00.0", + Name: testNvmePathName, + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_PCIE, + Traddr: "0000:af:00.0", }, spdk: []string{`{"id":%d,"error":{"code":0,"message":""},"result":["mytest"]}`}, errCode: codes.OK, @@ -201,10 +197,9 @@ func TestBackEnd_CreateNvmePath(t *testing.T) { "tcp transport type missing fabrics": { id: testAioVolumeID, in: &pb.NvmePath{ - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TCP, - Traddr: "127.0.0.1", - ControllerNameRef: testNvmePath.ControllerNameRef, - Fabrics: nil, + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TCP, + Traddr: "127.0.0.1", + Fabrics: nil, }, out: nil, spdk: []string{}, @@ -216,10 +211,9 @@ func TestBackEnd_CreateNvmePath(t *testing.T) { "pcie transport type with specified fabrics message": { id: testAioVolumeID, in: &pb.NvmePath{ - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_PCIE, - Traddr: "0000:af:00.0", - ControllerNameRef: testNvmePath.ControllerNameRef, - Fabrics: testNvmePath.Fabrics, + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_PCIE, + Traddr: "0000:af:00.0", + Fabrics: testNvmePath.Fabrics, }, out: nil, spdk: []string{}, @@ -231,10 +225,9 @@ func TestBackEnd_CreateNvmePath(t *testing.T) { "pcie transport type with specified tcp controller": { id: testAioVolumeID, in: &pb.NvmePath{ - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_PCIE, - Traddr: "0000:af:00.0", - ControllerNameRef: testNvmePath.ControllerNameRef, - Fabrics: nil, + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_PCIE, + Traddr: "0000:af:00.0", + Fabrics: nil, }, out: nil, spdk: []string{}, @@ -246,9 +239,8 @@ func TestBackEnd_CreateNvmePath(t *testing.T) { "not supported transport type": { id: testNvmePathID, in: &pb.NvmePath{ - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_CUSTOM, - ControllerNameRef: testNvmePath.ControllerNameRef, - Traddr: testNvmePath.Traddr, + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_CUSTOM, + Traddr: testNvmePath.Traddr, }, out: nil, spdk: []string{}, @@ -287,7 +279,7 @@ func TestBackEnd_CreateNvmePath(t *testing.T) { tt.out.Name = testNvmePathName } - request := &pb.CreateNvmePathRequest{NvmePath: tt.in, NvmePathId: tt.id} + request := &pb.CreateNvmePathRequest{Parent: testNvmeCtrlName, NvmePath: tt.in, NvmePathId: tt.id} response, err := testEnv.client.CreateNvmePath(testEnv.ctx, request) if !proto.Equal(response, tt.out) { @@ -331,7 +323,7 @@ func TestBackEnd_DeleteNvmePath(t *testing.T) { out: nil, spdk: []string{`{"id":%d,"error":{"code":0,"message":""},"result":false}`}, errCode: codes.InvalidArgument, - errMsg: fmt.Sprintf("Could not delete Nvme Path: %s", testNvmePathID), + errMsg: fmt.Sprintf("Could not delete Nvme Path: %s", testNvmePathName), missing: false, }, "valid request with invalid marshal SPDK response": { @@ -375,15 +367,15 @@ func TestBackEnd_DeleteNvmePath(t *testing.T) { missing: false, }, "valid request with unknown key": { - in: utils.ResourceIDToVolumeName("unknown-id"), + in: utils.ResourceIDToNvmePathName(testNvmeCtrlID, "unknown-id"), out: nil, spdk: []string{}, errCode: codes.NotFound, - errMsg: fmt.Sprintf("unable to find key %v", utils.ResourceIDToVolumeName("unknown-id")), + errMsg: fmt.Sprintf("unable to find key %v", utils.ResourceIDToNvmePathName(testNvmeCtrlID, "unknown-id")), missing: false, }, "unknown key with missing allowed": { - in: utils.ResourceIDToVolumeName("unknown-id"), + in: utils.ResourceIDToNvmePathName(testNvmeCtrlID, "unknown-id"), out: &emptypb.Empty{}, spdk: []string{}, errCode: codes.OK, @@ -391,7 +383,7 @@ func TestBackEnd_DeleteNvmePath(t *testing.T) { missing: true, }, "malformed name": { - in: utils.ResourceIDToVolumeName("-ABC-DEF"), + in: utils.ResourceIDToNvmePathName(testNvmeCtrlID, "-ABC-DEF"), out: &emptypb.Empty{}, spdk: []string{}, errCode: codes.Unknown, @@ -543,10 +535,9 @@ func TestBackEnd_UpdateNvmePath(t *testing.T) { "valid request with unknown key": { mask: nil, in: &pb.NvmePath{ - Name: utils.ResourceIDToVolumeName("unknown-id"), - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TCP, - Traddr: "127.0.0.1", - ControllerNameRef: "TBD", + Name: utils.ResourceIDToNvmePathName(testNvmeCtrlID, "unknown-id"), + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TCP, + Traddr: "127.0.0.1", Fabrics: &pb.FabricsPath{ Adrfam: pb.NvmeAddressFamily_NVME_ADRFAM_IPV4, Trsvcid: 4444, @@ -556,16 +547,15 @@ func TestBackEnd_UpdateNvmePath(t *testing.T) { out: nil, spdk: []string{}, errCode: codes.NotFound, - errMsg: fmt.Sprintf("unable to find key %v", utils.ResourceIDToVolumeName("unknown-id")), + errMsg: fmt.Sprintf("unable to find key %v", utils.ResourceIDToNvmePathName(testNvmeCtrlID, "unknown-id")), missing: false, }, "unknown key with missing allowed": { mask: nil, in: &pb.NvmePath{ - Name: utils.ResourceIDToVolumeName("unknown-id"), - Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TCP, - Traddr: "127.0.0.1", - ControllerNameRef: "TBD", + Name: utils.ResourceIDToNvmePathName(testNvmeCtrlID, "unknown-id"), + Trtype: pb.NvmeTransportType_NVME_TRANSPORT_TCP, + Traddr: "127.0.0.1", Fabrics: &pb.FabricsPath{ Adrfam: pb.NvmeAddressFamily_NVME_ADRFAM_IPV4, Trsvcid: 4444, @@ -575,16 +565,15 @@ func TestBackEnd_UpdateNvmePath(t *testing.T) { out: nil, spdk: []string{}, errCode: codes.NotFound, - errMsg: fmt.Sprintf("unable to find key %v", utils.ResourceIDToVolumeName("unknown-id")), + errMsg: fmt.Sprintf("unable to find key %v", utils.ResourceIDToNvmePathName(testNvmeCtrlID, "unknown-id")), missing: true, }, "malformed name": { mask: nil, in: &pb.NvmePath{ - Name: "-ABC-DEF", - ControllerNameRef: "TBD", - Trtype: testNvmePath.Trtype, - Traddr: testNvmePath.Traddr, + Name: "-ABC-DEF", + Trtype: testNvmePath.Trtype, + Traddr: testNvmePath.Traddr, }, out: nil, spdk: []string{}, diff --git a/pkg/backend/nvme_path_validate.go b/pkg/backend/nvme_path_validate.go index 95fff8c3..ba71497c 100644 --- a/pkg/backend/nvme_path_validate.go +++ b/pkg/backend/nvme_path_validate.go @@ -27,7 +27,7 @@ func (s *Server) validateCreateNvmePathRequest(in *pb.CreateNvmePathRequest) err } } // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.NvmePath.ControllerNameRef); err != nil { + if err := resourcename.Validate(in.Parent); err != nil { return err } // validate Fabrics and Type coordinated diff --git a/pkg/utils/resource.go b/pkg/utils/resource.go index 24133ed4..d182b686 100644 --- a/pkg/utils/resource.go +++ b/pkg/utils/resource.go @@ -62,3 +62,33 @@ func GetSubsystemIDFromNvmeName(name string) string { return "" } + +// ResourceIDToRemoteControllerName transforms remote controller resource ID to +// remote controller name +func ResourceIDToRemoteControllerName(resourceID string) string { + return resourcename.Join( + "//storage.opiproject.org/", + "nvmeRemoteControllers", resourceID, + ) +} + +// ResourceIDToNvmePathName transforms path resource ID to path name +func ResourceIDToNvmePathName(ctrlrResourceID, pathResourceID string) string { + return resourcename.Join( + "//storage.opiproject.org/", + "nvmeRemoteControllers", ctrlrResourceID, + "nvmePaths", pathResourceID, + ) +} + +// GetRemoteControllerIDFromNvmeRemoteName get parent ID (RemoteController ID) +// from nvme related names +func GetRemoteControllerIDFromNvmeRemoteName(name string) string { + controller := "" + _ = resourcename.Sscan(name, + "nvmeRemoteControllers/{controller}", + &controller, + ) + + return controller +} diff --git a/scripts/tests.sh b/scripts/tests.sh index d6398844..136dcf9f 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -76,11 +76,11 @@ docker run --rm --network=host --privileged -v /dev/hugepages:/dev/hugepages ghc docker run --rm --network=host --privileged -v /dev/hugepages:/dev/hugepages ghcr.io/opiproject/spdk:main spdk_nvme_perf -r 'traddr:127.0.0.1 trtype:TCP adrfam:IPv4 trsvcid:7777 subnqn:nqn.2022-09.io.spdk:opitest1 hostnqn:nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c' -c 0x1 -q 1 -o 4096 -w randread -t 10 | tee log.txt grep "Total" log.txt "${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 CreateNvmeRemoteController "{nvme_remote_controller : {multipath: 'NVME_MULTIPATH_MULTIPATH', tcp: {hdgst: false, ddgst: false}}, nvme_remote_controller_id: 'nvmetcp12'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 CreateNvmePath "{nvme_path : {controller_name_ref: '//storage.opiproject.org/volumes/nvmetcp12', traddr:\"$SPDK_IP\", trtype:'NVME_TRANSPORT_TCP', fabrics: { subnqn:'nqn.2022-09.io.spdk:opitest1', trsvcid:'7777', adrfam:'NVME_ADRFAM_IPV4', hostnqn:'nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c'}}, nvme_path_id: 'nvmetcp12path0'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 GetNvmeRemoteController "{name: '//storage.opiproject.org/volumes/nvmetcp12'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 GetNvmePath "{name: '//storage.opiproject.org/volumes/nvmetcp12path0'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmePath "{name: '//storage.opiproject.org/volumes/nvmetcp12path0'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeRemoteController "{name: '//storage.opiproject.org/volumes/nvmetcp12'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 CreateNvmePath "{parent: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12', nvme_path : {traddr:\"$SPDK_IP\", trtype:'NVME_TRANSPORT_TCP', fabrics: { subnqn:'nqn.2022-09.io.spdk:opitest1', trsvcid:'7777', adrfam:'NVME_ADRFAM_IPV4', hostnqn:'nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c'}}, nvme_path_id: 'nvmetcp12path0'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 GetNvmeRemoteController "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 GetNvmePath "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12/nvmePaths/nvmetcp12path0'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmePath "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12/nvmePaths/nvmetcp12path0'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeRemoteController "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetcp12'}" "${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeNamespace "{name : '//storage.opiproject.org/subsystems/subsystem1/namespaces/namespace1'}" "${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeController "{name : '//storage.opiproject.org/subsystems/subsystem1/controllers/controller1'}" "${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeSubsystem "{name : '//storage.opiproject.org/subsystems/subsystem1'}" @@ -96,11 +96,11 @@ grep "Total" log.txt docker run --rm --network=host --privileged -v /dev/hugepages:/dev/hugepages -v /tmp/opikey.txt:/tmp/opikey.txt ghcr.io/opiproject/spdk:main spdk_nvme_perf -r 'traddr:127.0.0.1 trtype:TCP adrfam:IPv4 trsvcid:8888 subnqn:nqn.2022-09.io.spdk:opitest2 hostnqn:nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c' -c 0x1 -q 1 -o 4096 -w randread -t 10 -S ssl --psk-path /tmp/opikey.txt | tee log.txt grep "Total" log.txt "${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 CreateNvmeRemoteController "{nvme_remote_controller : {multipath: 'NVME_MULTIPATH_MULTIPATH', tcp: {hdgst: false, ddgst: false, psk: 'TlZNZVRMU2tleS0xOjAxOk1EQXhNVEl5TXpNME5EVTFOalkzTnpnNE9UbGhZV0ppWTJOa1pHVmxabVp3SkVpUTo='}}, nvme_remote_controller_id: 'nvmetls17'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 CreateNvmePath "{nvme_path : {controller_name_ref: '//storage.opiproject.org/volumes/nvmetls17', traddr:\"$SPDK_IP\", trtype:'NVME_TRANSPORT_TCP', fabrics: { subnqn:'nqn.2022-09.io.spdk:opitest2', trsvcid:'8888', adrfam:'NVME_ADRFAM_IPV4', hostnqn:'nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c'}}, nvme_path_id: 'nvmetls17path0'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 GetNvmeRemoteController "{name: '//storage.opiproject.org/volumes/nvmetls17'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 GetNvmePath "{name: '//storage.opiproject.org/volumes/nvmetls17path0'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmePath "{name: '//storage.opiproject.org/volumes/nvmetls17path0'}" -"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeRemoteController "{name: '//storage.opiproject.org/volumes/nvmetls17'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 CreateNvmePath "{parent: '//storage.opiproject.org/nvmeRemoteControllers/nvmetls17', nvme_path : {traddr:\"$SPDK_IP\", trtype:'NVME_TRANSPORT_TCP', fabrics: { subnqn:'nqn.2022-09.io.spdk:opitest2', trsvcid:'8888', adrfam:'NVME_ADRFAM_IPV4', hostnqn:'nqn.2014-08.org.nvmexpress:uuid:feb98abe-d51f-40c8-b348-2753f3571d3c'}}, nvme_path_id: 'nvmetls17path0'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 GetNvmeRemoteController "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetls17'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 GetNvmePath "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetls17/nvmePaths/nvmetls17path0'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmePath "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetls17/nvmePaths/nvmetls17path0'}" +"${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeRemoteController "{name: '//storage.opiproject.org/nvmeRemoteControllers/nvmetls17'}" "${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeNamespace "{name : '//storage.opiproject.org/subsystems/subsystem2/namespaces/namespace2'}" "${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeController "{name : '//storage.opiproject.org/subsystems/subsystem2/controllers/controller2'}" "${grpc_cli[@]}" call --json_input --json_output opi-spdk-server:50051 DeleteNvmeSubsystem "{name : '//storage.opiproject.org/subsystems/subsystem2'}"