k8s.io/kubernetes@v1.29.3/pkg/kubelet/cm/dra/plugin/client.go (about) 1 /* 2 Copyright 2022 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package plugin 18 19 import ( 20 "context" 21 "fmt" 22 "time" 23 24 "google.golang.org/grpc" 25 grpccodes "google.golang.org/grpc/codes" 26 grpcstatus "google.golang.org/grpc/status" 27 28 "k8s.io/klog/v2" 29 drapbv1alpha2 "k8s.io/kubelet/pkg/apis/dra/v1alpha2" 30 drapb "k8s.io/kubelet/pkg/apis/dra/v1alpha3" 31 ) 32 33 const PluginClientTimeout = 45 * time.Second 34 35 type ( 36 nodeResourceManager interface { 37 Prepare(context.Context, *grpc.ClientConn, *plugin, *drapb.NodePrepareResourcesRequest) (*drapb.NodePrepareResourcesResponse, error) 38 Unprepare(context.Context, *grpc.ClientConn, *plugin, *drapb.NodeUnprepareResourcesRequest) (*drapb.NodeUnprepareResourcesResponse, error) 39 } 40 41 v1alpha2NodeResourceManager struct{} 42 v1alpha3NodeResourceManager struct{} 43 ) 44 45 var nodeResourceManagers = map[string]nodeResourceManager{ 46 v1alpha2Version: v1alpha2NodeResourceManager{}, 47 v1alpha3Version: v1alpha3NodeResourceManager{}, 48 } 49 50 func (v1alpha2rm v1alpha2NodeResourceManager) Prepare(ctx context.Context, conn *grpc.ClientConn, _ *plugin, req *drapb.NodePrepareResourcesRequest) (*drapb.NodePrepareResourcesResponse, error) { 51 nodeClient := drapbv1alpha2.NewNodeClient(conn) 52 response := &drapb.NodePrepareResourcesResponse{ 53 Claims: make(map[string]*drapb.NodePrepareResourceResponse), 54 } 55 56 for _, claim := range req.Claims { 57 res, err := nodeClient.NodePrepareResource(ctx, 58 &drapbv1alpha2.NodePrepareResourceRequest{ 59 Namespace: claim.Namespace, 60 ClaimUid: claim.Uid, 61 ClaimName: claim.Name, 62 ResourceHandle: claim.ResourceHandle, 63 }) 64 result := &drapb.NodePrepareResourceResponse{} 65 if err != nil { 66 result.Error = err.Error() 67 } else { 68 result.CDIDevices = res.CdiDevices 69 } 70 response.Claims[claim.Uid] = result 71 } 72 73 return response, nil 74 } 75 76 func (v1alpha2rm v1alpha2NodeResourceManager) Unprepare(ctx context.Context, conn *grpc.ClientConn, _ *plugin, req *drapb.NodeUnprepareResourcesRequest) (*drapb.NodeUnprepareResourcesResponse, error) { 77 nodeClient := drapbv1alpha2.NewNodeClient(conn) 78 response := &drapb.NodeUnprepareResourcesResponse{ 79 Claims: make(map[string]*drapb.NodeUnprepareResourceResponse), 80 } 81 82 for _, claim := range req.Claims { 83 _, err := nodeClient.NodeUnprepareResource(ctx, 84 &drapbv1alpha2.NodeUnprepareResourceRequest{ 85 Namespace: claim.Namespace, 86 ClaimUid: claim.Uid, 87 ClaimName: claim.Name, 88 ResourceHandle: claim.ResourceHandle, 89 }) 90 result := &drapb.NodeUnprepareResourceResponse{} 91 if err != nil { 92 result.Error = err.Error() 93 } 94 response.Claims[claim.Uid] = result 95 } 96 97 return response, nil 98 } 99 100 func (v1alpha3rm v1alpha3NodeResourceManager) Prepare(ctx context.Context, conn *grpc.ClientConn, p *plugin, req *drapb.NodePrepareResourcesRequest) (*drapb.NodePrepareResourcesResponse, error) { 101 nodeClient := drapb.NewNodeClient(conn) 102 response, err := nodeClient.NodePrepareResources(ctx, req) 103 if err != nil { 104 status, _ := grpcstatus.FromError(err) 105 if status.Code() == grpccodes.Unimplemented { 106 p.setVersion(v1alpha2Version) 107 return nodeResourceManagers[v1alpha2Version].Prepare(ctx, conn, p, req) 108 } 109 return nil, err 110 } 111 112 return response, nil 113 } 114 115 func (v1alpha3rm v1alpha3NodeResourceManager) Unprepare(ctx context.Context, conn *grpc.ClientConn, p *plugin, req *drapb.NodeUnprepareResourcesRequest) (*drapb.NodeUnprepareResourcesResponse, error) { 116 nodeClient := drapb.NewNodeClient(conn) 117 response, err := nodeClient.NodeUnprepareResources(ctx, req) 118 if err != nil { 119 status, _ := grpcstatus.FromError(err) 120 if status.Code() == grpccodes.Unimplemented { 121 p.setVersion(v1alpha2Version) 122 return nodeResourceManagers[v1alpha2Version].Unprepare(ctx, conn, p, req) 123 } 124 return nil, err 125 } 126 127 return response, nil 128 } 129 130 func NewDRAPluginClient(pluginName string) (drapb.NodeClient, error) { 131 if pluginName == "" { 132 return nil, fmt.Errorf("plugin name is empty") 133 } 134 135 existingPlugin := draPlugins.get(pluginName) 136 if existingPlugin == nil { 137 return nil, fmt.Errorf("plugin name %s not found in the list of registered DRA plugins", pluginName) 138 } 139 140 return existingPlugin, nil 141 } 142 143 func (p *plugin) NodePrepareResources( 144 ctx context.Context, 145 req *drapb.NodePrepareResourcesRequest, 146 opts ...grpc.CallOption, 147 ) (*drapb.NodePrepareResourcesResponse, error) { 148 logger := klog.FromContext(ctx) 149 logger.V(4).Info(log("calling NodePrepareResources rpc"), "request", req) 150 151 conn, err := p.getOrCreateGRPCConn() 152 if err != nil { 153 return nil, err 154 } 155 156 ctx, cancel := context.WithTimeout(ctx, PluginClientTimeout) 157 defer cancel() 158 159 version := p.getVersion() 160 resourceManager, exists := nodeResourceManagers[version] 161 if !exists { 162 err := fmt.Errorf("unsupported plugin version: %s", version) 163 logger.V(4).Info(log("done calling NodePrepareResources rpc"), "response", nil, "err", err) 164 return nil, err 165 } 166 167 response, err := resourceManager.Prepare(ctx, conn, p, req) 168 logger.V(4).Info(log("done calling NodePrepareResources rpc"), "response", response, "err", err) 169 return response, err 170 } 171 172 func (p *plugin) NodeUnprepareResources( 173 ctx context.Context, 174 req *drapb.NodeUnprepareResourcesRequest, 175 opts ...grpc.CallOption, 176 ) (*drapb.NodeUnprepareResourcesResponse, error) { 177 logger := klog.FromContext(ctx) 178 logger.V(4).Info(log("calling NodeUnprepareResource rpc"), "request", req) 179 180 conn, err := p.getOrCreateGRPCConn() 181 if err != nil { 182 return nil, err 183 } 184 185 ctx, cancel := context.WithTimeout(ctx, PluginClientTimeout) 186 defer cancel() 187 188 version := p.getVersion() 189 resourceManager, exists := nodeResourceManagers[version] 190 if !exists { 191 err := fmt.Errorf("unsupported plugin version: %s", version) 192 logger.V(4).Info(log("done calling NodeUnprepareResources rpc"), "response", nil, "err", err) 193 return nil, err 194 } 195 196 response, err := resourceManager.Unprepare(ctx, conn, p, req) 197 logger.V(4).Info(log("done calling NodeUnprepareResources rpc"), "response", response, "err", err) 198 return response, err 199 }