From f20faa8ec34a20401334dc377f87b3b015b8886c Mon Sep 17 00:00:00 2001 From: Manuel Buil Date: Mon, 27 May 2024 07:29:52 +0200 Subject: [PATCH] Improve rke2-uninstall.ps1 script (#5961) Signed-off-by: Manuel Buil --- bundle/bin/rke2-uninstall.ps1 | 42 +++++++++++++++++++++++++++++--- pkg/pebinaryexecutor/pebinary.go | 15 ++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/bundle/bin/rke2-uninstall.ps1 b/bundle/bin/rke2-uninstall.ps1 index 50b8b83818..4134e42871 100644 --- a/bundle/bin/rke2-uninstall.ps1 +++ b/bundle/bin/rke2-uninstall.ps1 @@ -272,6 +272,13 @@ function Remove-Containerd () { } if (ctr) { + # We create a lockfile to prevent rke2 service from starting kubelet again + Create-Lockfile + Stop-Process -Name "kubelet" + while (-Not(Get-Process -Name "kubelet").HasExited) { + Write-LogInfo "Waiting for kubelet process to stop" + Start-Sleep -s 5 + } $namespaces = $(Find-Namespaces) if (-Not($namespaces)) { $ErrorActionPreference = 'SilentlyContinue' @@ -292,10 +299,23 @@ function Remove-Containerd () { foreach ($image in $images) { Remove-Image $ns $image } - Remove-Namespace $ns - # TODO - # clean pods with crictl - # $CONTAINER_RUNTIME_ENDPOINT = "npipe:\\.\\pipe\\containerd-containerd" + } + + # Some resources in the namespace take a while to disappear. Try several times to remove the namespace and give up after 30s + $endTime = (Get-Date).AddSeconds(30) + while ((Get-Date) -lt $endTime) { + $namespaces = $(Find-Namespaces) + if ($namespaces) { + foreach ($ns in $namespaces) { + Remove-Namespace $ns + } + } else { + break + } + Start-Sleep -Seconds 5 + if ((Get-Date) -ge $endTime) { + Write-Output "Unable to remove all namespaces" + } } } else { @@ -345,6 +365,20 @@ function Remove-Namespace() { Invoke-Ctr -cmd "namespace remove $namespace" } +function Create-Lockfile() { + # We fetch ctr.exe path and place the lock there + $command = Get-Command ctr -ErrorAction SilentlyContinue + if ($command) { + $executablePath = $command.Source + $dataBinDirDirectory = Split-Path -Parent $executablePath + $lockFilePath = Join-Path -Path $dataBinDirDirectory -ChildPath "rke2-uninstall.lock" + New-Item -ItemType File -Path $lockFilePath -Force + } else { + # ctr should exist at this point but just in case we add this log + Write-Host "ctr.exe not found, container cleanup and RKE2 uninstallation is unlikely to succeed." + } +} + function Invoke-Rke2Uninstall () { $env:PATH += ";$env:CATTLE_AGENT_BIN_PREFIX/bin/;c:\var\lib\rancher\rke2\bin" Remove-Containerd diff --git a/pkg/pebinaryexecutor/pebinary.go b/pkg/pebinaryexecutor/pebinary.go index d45ed81a46..ab1e9683b4 100644 --- a/pkg/pebinaryexecutor/pebinary.go +++ b/pkg/pebinaryexecutor/pebinary.go @@ -165,6 +165,15 @@ func (p *PEBinaryConfig) Kubelet(ctx context.Context, args []string) error { cleanArgs = append(cleanArgs, arg) } + // It should never happen but just in case, we make sure the rke2-uninstall.lock does not exist before starting kubelet + lockFile := filepath.Join(p.DataDir, "bin", "rke2-uninstall.lock") + if _, err := os.Stat(lockFile); err == nil { + // If the file exists, delete it + if err := os.Remove(lockFile); err != nil { + logrus.Errorf("Failed to remove the %s file: %v", lockFile, err) + } + } + win.ProcessWaitGroup.StartWithContext(ctx, func(ctx context.Context) { for { logrus.Infof("Running RKE2 kubelet %v", cleanArgs) @@ -185,6 +194,12 @@ func (p *PEBinaryConfig) Kubelet(ctx context.Context, args []string) error { } cancel() + // If the rke2-uninstall.ps1 script created the lock file, we are removing rke2 and thus we don't restart kubelet + if _, err := os.Stat(lockFile); err == nil { + logrus.Infof("rke2-uninstall.lock exists. kubelet is not restarted") + return + } + select { case <-ctx.Done(): return