mirror of https://github.com/k3s-io/k3s
Merge pull request #30737 from saad-ali/fix29358Round2
Automatic merge from submit-queue Skip safe to detach check if node API object no longer exists Fixes #29358pull/6/head
commit
9696a27aa0
|
@ -67,7 +67,7 @@ func (nsu *nodeStatusUpdater) UpdateNodeStatuses() error {
|
||||||
"Could not update node status. Failed to find node %q in NodeInformer cache. %v",
|
"Could not update node status. Failed to find node %q in NodeInformer cache. %v",
|
||||||
nodeName,
|
nodeName,
|
||||||
err)
|
err)
|
||||||
return nil
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
node, ok := nodeObj.(*api.Node)
|
node, ok := nodeObj.(*api.Node)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
"k8s.io/kubernetes/pkg/types"
|
"k8s.io/kubernetes/pkg/types"
|
||||||
"k8s.io/kubernetes/pkg/util/mount"
|
"k8s.io/kubernetes/pkg/util/mount"
|
||||||
|
@ -544,41 +545,11 @@ func (oe *operationExecutor) generateDetachVolumeFunc(
|
||||||
|
|
||||||
return func() error {
|
return func() error {
|
||||||
if verifySafeToDetach {
|
if verifySafeToDetach {
|
||||||
// Fetch current node object
|
safeToDetachErr := oe.verifyVolumeIsSafeToDetach(volumeToDetach)
|
||||||
node, fetchErr := oe.kubeClient.Core().Nodes().Get(volumeToDetach.NodeName)
|
if safeToDetachErr != nil {
|
||||||
if fetchErr != nil {
|
|
||||||
// On failure, return error. Caller will log and retry.
|
// On failure, return error. Caller will log and retry.
|
||||||
return fmt.Errorf(
|
return err
|
||||||
"DetachVolume failed fetching node from API server for volume %q (spec.Name: %q) from node %q with: %v",
|
|
||||||
volumeToDetach.VolumeName,
|
|
||||||
volumeToDetach.VolumeSpec.Name(),
|
|
||||||
volumeToDetach.NodeName,
|
|
||||||
fetchErr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if node == nil {
|
|
||||||
// On failure, return error. Caller will log and retry.
|
|
||||||
return fmt.Errorf(
|
|
||||||
"DetachVolume failed fetching node from API server for volume %q (spec.Name: %q) from node %q. Error: node object retrieved from API server is nil.",
|
|
||||||
volumeToDetach.VolumeName,
|
|
||||||
volumeToDetach.VolumeSpec.Name(),
|
|
||||||
volumeToDetach.NodeName)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, inUseVolume := range node.Status.VolumesInUse {
|
|
||||||
if inUseVolume == volumeToDetach.VolumeName {
|
|
||||||
return fmt.Errorf("DetachVolume failed for volume %q (spec.Name: %q) from node %q. Error: volume is still in use by node, according to Node status.",
|
|
||||||
volumeToDetach.VolumeName,
|
|
||||||
volumeToDetach.VolumeSpec.Name(),
|
|
||||||
volumeToDetach.NodeName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Volume not attached, return error. Caller will log and retry.
|
|
||||||
glog.Infof("Verified volume is safe to detach for volume %q (spec.Name: %q) from node %q.",
|
|
||||||
volumeToDetach.VolumeName,
|
|
||||||
volumeToDetach.VolumeSpec.Name(),
|
|
||||||
volumeToDetach.NodeName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute detach
|
// Execute detach
|
||||||
|
@ -607,6 +578,54 @@ func (oe *operationExecutor) generateDetachVolumeFunc(
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (oe *operationExecutor) verifyVolumeIsSafeToDetach(
|
||||||
|
volumeToDetach AttachedVolume) error {
|
||||||
|
// Fetch current node object
|
||||||
|
node, fetchErr := oe.kubeClient.Core().Nodes().Get(volumeToDetach.NodeName)
|
||||||
|
if fetchErr != nil {
|
||||||
|
if errors.IsNotFound(fetchErr) {
|
||||||
|
glog.Warningf("Node %q not found on API server. DetachVolume will skip safe to detach check.",
|
||||||
|
volumeToDetach.NodeName,
|
||||||
|
volumeToDetach.VolumeName,
|
||||||
|
volumeToDetach.VolumeSpec.Name())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// On failure, return error. Caller will log and retry.
|
||||||
|
return fmt.Errorf(
|
||||||
|
"DetachVolume failed fetching node from API server for volume %q (spec.Name: %q) from node %q with: %v",
|
||||||
|
volumeToDetach.VolumeName,
|
||||||
|
volumeToDetach.VolumeSpec.Name(),
|
||||||
|
volumeToDetach.NodeName,
|
||||||
|
fetchErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if node == nil {
|
||||||
|
// On failure, return error. Caller will log and retry.
|
||||||
|
return fmt.Errorf(
|
||||||
|
"DetachVolume failed fetching node from API server for volume %q (spec.Name: %q) from node %q. Error: node object retrieved from API server is nil.",
|
||||||
|
volumeToDetach.VolumeName,
|
||||||
|
volumeToDetach.VolumeSpec.Name(),
|
||||||
|
volumeToDetach.NodeName)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, inUseVolume := range node.Status.VolumesInUse {
|
||||||
|
if inUseVolume == volumeToDetach.VolumeName {
|
||||||
|
return fmt.Errorf("DetachVolume failed for volume %q (spec.Name: %q) from node %q. Error: volume is still in use by node, according to Node status.",
|
||||||
|
volumeToDetach.VolumeName,
|
||||||
|
volumeToDetach.VolumeSpec.Name(),
|
||||||
|
volumeToDetach.NodeName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Volume is not marked as in use by node
|
||||||
|
glog.Infof("Verified volume is safe to detach for volume %q (spec.Name: %q) from node %q.",
|
||||||
|
volumeToDetach.VolumeName,
|
||||||
|
volumeToDetach.VolumeSpec.Name(),
|
||||||
|
volumeToDetach.NodeName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (oe *operationExecutor) generateMountVolumeFunc(
|
func (oe *operationExecutor) generateMountVolumeFunc(
|
||||||
waitForAttachTimeout time.Duration,
|
waitForAttachTimeout time.Duration,
|
||||||
volumeToMount VolumeToMount,
|
volumeToMount VolumeToMount,
|
||||||
|
|
Loading…
Reference in New Issue