kubeadm: throw errors on unmount instead of warnings

Instead of warnings when syscall.Unmount() causes errors,
store all the errors in an aggregate. Abort the reset operation if
at least one unmount error was encountered.
This commit is contained in:
Lubomir I. Ivanov 2023-12-30 10:49:18 +02:00
parent 63eb5028ba
commit d6bfd7daeb
3 changed files with 23 additions and 18 deletions

View File

@ -84,11 +84,15 @@ func runCleanupNode(c workflow.RunData) error {
// Try to unmount mounted directories under kubeadmconstants.KubeletRunDirectory in order to be able to remove the kubeadmconstants.KubeletRunDirectory directory later // Try to unmount mounted directories under kubeadmconstants.KubeletRunDirectory in order to be able to remove the kubeadmconstants.KubeletRunDirectory directory later
fmt.Printf("[reset] Unmounting mounted directories in %q\n", kubeadmconstants.KubeletRunDirectory) fmt.Printf("[reset] Unmounting mounted directories in %q\n", kubeadmconstants.KubeletRunDirectory)
// In case KubeletRunDirectory holds a symbolic link, evaluate it // In case KubeletRunDirectory holds a symbolic link, evaluate it
kubeletRunDir, err := absoluteKubeletRunDirectory() kubeletRunDirectory, err := absoluteKubeletRunDirectory()
if err == nil { if err != nil {
// Only clean absoluteKubeletRunDirectory if umountDirsCmd passed without error return err
dirsToClean = append(dirsToClean, kubeletRunDir)
} }
// Unmount all mount paths under kubeletRunDirectory
if err := unmountKubeletDirectory(kubeletRunDirectory); err != nil {
return err
}
dirsToClean = append(dirsToClean, kubeletRunDirectory)
} else { } else {
fmt.Printf("[reset] Would unmount mounted directories in %q\n", kubeadmconstants.KubeletRunDirectory) fmt.Printf("[reset] Would unmount mounted directories in %q\n", kubeadmconstants.KubeletRunDirectory)
} }
@ -131,13 +135,7 @@ func runCleanupNode(c workflow.RunData) error {
func absoluteKubeletRunDirectory() (string, error) { func absoluteKubeletRunDirectory() (string, error) {
absoluteKubeletRunDirectory, err := filepath.EvalSymlinks(kubeadmconstants.KubeletRunDirectory) absoluteKubeletRunDirectory, err := filepath.EvalSymlinks(kubeadmconstants.KubeletRunDirectory)
if err != nil { if err != nil {
klog.Warningf("[reset] Failed to evaluate the %q directory. Skipping its unmount and cleanup: %v\n", kubeadmconstants.KubeletRunDirectory, err) return "", errors.Wrapf(err, "failed to evaluate the %q directory", kubeadmconstants.KubeletRunDirectory)
return "", err
}
err = unmountKubeletDirectory(absoluteKubeletRunDirectory)
if err != nil {
klog.Warningf("[reset] Failed to unmount mounted directories in %s \n", kubeadmconstants.KubeletRunDirectory)
return "", err
} }
return absoluteKubeletRunDirectory, nil return absoluteKubeletRunDirectory, nil
} }

View File

@ -24,7 +24,7 @@ import (
) )
// unmountKubeletDirectory is a NOOP on all but linux. // unmountKubeletDirectory is a NOOP on all but linux.
func unmountKubeletDirectory(absoluteKubeletRunDirectory string) error { func unmountKubeletDirectory(kubeletRunDirectory string) error {
klog.Warning("Cannot unmount filesystems on current OS, all mounted file systems will need to be manually unmounted") klog.Warning("Cannot unmount filesystems on current OS, all mounted file systems will need to be manually unmounted")
return nil return nil
} }

View File

@ -24,30 +24,37 @@ import (
"strings" "strings"
"syscall" "syscall"
"github.com/pkg/errors"
"k8s.io/klog/v2" "k8s.io/klog/v2"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
) )
// unmountKubeletDirectory unmounts all paths that contain KubeletRunDirectory // unmountKubeletDirectory unmounts all paths that contain KubeletRunDirectory
func unmountKubeletDirectory(absoluteKubeletRunDirectory string) error { func unmountKubeletDirectory(kubeletRunDirectory string) error {
raw, err := os.ReadFile("/proc/mounts") raw, err := os.ReadFile("/proc/mounts")
if err != nil { if err != nil {
return err return err
} }
if !strings.HasSuffix(absoluteKubeletRunDirectory, "/") { if !strings.HasSuffix(kubeletRunDirectory, "/") {
// trailing "/" is needed to ensure that possibly mounted /var/lib/kubelet is skipped // trailing "/" is needed to ensure that possibly mounted /var/lib/kubelet is skipped
absoluteKubeletRunDirectory += "/" kubeletRunDirectory += "/"
} }
var errList []error
mounts := strings.Split(string(raw), "\n") mounts := strings.Split(string(raw), "\n")
for _, mount := range mounts { for _, mount := range mounts {
m := strings.Split(mount, " ") m := strings.Split(mount, " ")
if len(m) < 2 || !strings.HasPrefix(m[1], absoluteKubeletRunDirectory) { if len(m) < 2 || !strings.HasPrefix(m[1], kubeletRunDirectory) {
continue continue
} }
klog.V(5).Infof("[reset] Unmounting %q", m[1])
if err := syscall.Unmount(m[1], 0); err != nil { if err := syscall.Unmount(m[1], 0); err != nil {
klog.Warningf("[reset] Failed to unmount mounted directory in %s: %s", absoluteKubeletRunDirectory, m[1]) errList = append(errList, errors.WithMessagef(err, "failed to unmount %q", m[1]))
} }
} }
return nil return errors.Wrapf(utilerrors.NewAggregate(errList),
"encountered the following errors while unmounting directories in %q", kubeletRunDirectory)
} }