diff --git a/nomad/csi_endpoint.go b/nomad/csi_endpoint.go index 4043955cc2d..0cb45776104 100644 --- a/nomad/csi_endpoint.go +++ b/nomad/csi_endpoint.go @@ -472,15 +472,6 @@ func (v *CSIVolume) Claim(args *structs.CSIVolumeClaimRequest, reply *structs.CS args.NodeID = alloc.NodeID } - if isNewClaim { - // if this is a new claim, add a Volume and PublishContext from the - // controller (if any) to the reply - err = v.controllerPublishVolume(args, reply) - if err != nil { - return fmt.Errorf("controller publish: %v", err) - } - } - resp, index, err := v.srv.raftApply(structs.CSIVolumeClaimRequestType, args) if err != nil { v.logger.Error("csi raft apply failed", "error", err, "method", "claim") @@ -490,6 +481,15 @@ func (v *CSIVolume) Claim(args *structs.CSIVolumeClaimRequest, reply *structs.CS return respErr } + if isNewClaim { + // if this is a new claim, add a Volume and PublishContext from the + // controller (if any) to the reply + err = v.controllerPublishVolume(args, reply) + if err != nil { + return fmt.Errorf("controller publish: %v", err) + } + } + reply.Index = index v.srv.setQueryMeta(&reply.QueryMeta) return nil @@ -570,7 +570,10 @@ func (v *CSIVolume) controllerPublishVolume(req *structs.CSIVolumeClaimRequest, err = v.srv.RPC(method, cReq, cResp) if err != nil { - return fmt.Errorf("attach volume: %v", err) + if strings.Contains(err.Error(), "FailedPrecondition") { + return fmt.Errorf("%v: %v", structs.ErrCSIClientRPCRetryable, err) + } + return err } resp.PublishContext = cResp.PublishContext return nil @@ -725,6 +728,11 @@ func (v *CSIVolume) nodeUnpublishVolume(vol *structs.CSIVolume, claim *structs.C } func (v *CSIVolume) nodeUnpublishVolumeImpl(vol *structs.CSIVolume, claim *structs.CSIVolumeClaim) error { + if claim.AccessMode == structs.CSIVolumeAccessModeUnknown { + // claim has already been released client-side + return nil + } + req := &cstructs.ClientCSINodeDetachVolumeRequest{ PluginID: vol.PluginID, VolumeID: vol.ID, @@ -820,17 +828,17 @@ func (v *CSIVolume) controllerUnpublishVolume(vol *structs.CSIVolume, claim *str // and GC'd by this point, so looking there is the last resort. func (v *CSIVolume) lookupExternalNodeID(vol *structs.CSIVolume, claim *structs.CSIVolumeClaim) (string, error) { for _, rClaim := range vol.ReadClaims { - if rClaim.NodeID == claim.NodeID { + if rClaim.NodeID == claim.NodeID && rClaim.ExternalNodeID != "" { return rClaim.ExternalNodeID, nil } } for _, wClaim := range vol.WriteClaims { - if wClaim.NodeID == claim.NodeID { + if wClaim.NodeID == claim.NodeID && wClaim.ExternalNodeID != "" { return wClaim.ExternalNodeID, nil } } for _, pClaim := range vol.PastClaims { - if pClaim.NodeID == claim.NodeID { + if pClaim.NodeID == claim.NodeID && pClaim.ExternalNodeID != "" { return pClaim.ExternalNodeID, nil } }