|
7 | 7 | package vm
|
8 | 8 |
|
9 | 9 | import (
|
| 10 | + "context" |
| 11 | + "fmt" |
10 | 12 | "os"
|
| 13 | + "os/exec" |
11 | 14 | "path/filepath"
|
12 | 15 | "testing"
|
| 16 | + "time" |
13 | 17 |
|
14 | 18 | "github.com/onsi/ginkgo/v2"
|
15 | 19 | "github.com/onsi/gomega"
|
@@ -60,3 +64,40 @@ var resetDisks = func(_ *option.Option, _ bool) {
|
60 | 64 | dataDiskDir := filepath.Join(finchRootDir, ".finch", ".disks")
|
61 | 65 | gomega.Expect(os.RemoveAll(dataDiskDir)).ShouldNot(gomega.HaveOccurred())
|
62 | 66 | }
|
| 67 | + |
| 68 | +// shutdownWSL is a wrapper function for "wsl --shutdown". |
| 69 | +// |
| 70 | +// This is a workaround for https://github.com/microsoft/WSL/issues/8529 |
| 71 | +// |
| 72 | +// If WSL is suspected of hanging for longer than 180 seconds, then |
| 73 | +// kill the WSL service and retry the shutdown command. |
| 74 | +// |
| 75 | +// This function will at maximum run for 300 seconds before returning |
| 76 | +// context.DeadlineExceeded error. |
| 77 | +var shutdownWSL = func() error { |
| 78 | + ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second) |
| 79 | + defer cancel() |
| 80 | + |
| 81 | + if err := exec.CommandContext(ctx, "wsl", "--shutdown").Run(); err != nil { |
| 82 | + ginkgo.GinkgoLogr.Error(err, "WSL shutdown failed", "time", time.Now().Format(time.RFC3339)) |
| 83 | + |
| 84 | + // wsl might be hung, kill the wsl service and try again. |
| 85 | + // https://github.com/microsoft/WSL/issues/8529 |
| 86 | + killCtx, cancel := context.WithTimeout(context.Background(), 60*time.Second) |
| 87 | + defer cancel() |
| 88 | + |
| 89 | + if err := exec.CommandContext(killCtx, "taskkill", "/f", "/im", "wslservice.exe").Run(); err != nil { |
| 90 | + ginkgo.GinkgoLogr.Error(err, "WSL task kill failed", "time", time.Now().Format(time.RFC3339)) |
| 91 | + return fmt.Errorf("unable to kill wsl service: %w", err) |
| 92 | + } |
| 93 | + |
| 94 | + retryCtx, cancel := context.WithTimeout(context.Background(), 60*time.Second) |
| 95 | + defer cancel() |
| 96 | + |
| 97 | + if err := exec.CommandContext(retryCtx, "wsl", "--shutdown").Run(); err != nil { |
| 98 | + return fmt.Errorf("unable to shutdown wsl: %w", err) |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | + return nil |
| 103 | +} |
0 commit comments