Skip to content

Commit 2bee694

Browse files
committed
Restore DynamicSSHAddress functionality for WSL2
Signed-off-by: Anders F Björklund <anders.f.bjorklund@gmail.com>
1 parent 18baab6 commit 2bee694

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

pkg/driver/wsl2/vm_windows.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
_ "embed"
99
"fmt"
10+
"net"
1011
"os"
1112
"os/exec"
1213
"path/filepath"
@@ -179,6 +180,33 @@ func unregisterVM(ctx context.Context, distroName string) error {
179180
return nil
180181
}
181182

183+
// GetWslStatus runs `wsl --list --verbose` and parses its output.
184+
// There are several possible outputs, all listed with their whitespace preserved output below.
185+
//
186+
// (1) Expected output if at least one distro is installed:
187+
// PS > wsl --list --verbose
188+
//
189+
// NAME STATE VERSION
190+
//
191+
// * Ubuntu Stopped 2
192+
//
193+
// (2) Expected output when no distros are installed, but WSL is configured properly:
194+
// PS > wsl --list --verbose
195+
// Windows Subsystem for Linux has no installed distributions.
196+
//
197+
// Use 'wsl.exe --list --online' to list available distributions
198+
// and 'wsl.exe --install <Distro>' to install.
199+
//
200+
// Distributions can also be installed by visiting the Microsoft Store:
201+
// https://aka.ms/wslstore
202+
// Error code: Wsl/WSL_E_DEFAULT_DISTRO_NOT_FOUND
203+
//
204+
// (3) Expected output when no distros are installed, and WSL2 has no kernel installed:
205+
//
206+
// PS > wsl --list --verbose
207+
// Windows Subsystem for Linux has no installed distributions.
208+
// Distributions can be installed by visiting the Microsoft Store:
209+
// https://aka.ms/wslstore
182210
func getWslStatus(instName string) (string, error) {
183211
distroName := "lima-" + instName
184212
out, err := executil.RunUTF16leCommand([]string{
@@ -229,3 +257,34 @@ func getWslStatus(instName string) (string, error) {
229257

230258
return instState, nil
231259
}
260+
261+
// GetSSHAddress runs a hostname command to get the IP from inside of a wsl2 VM.
262+
//
263+
// Expected output (whitespace preserved, [] for optional):
264+
// PS > wsl -d <distroName> bash -c hostname -I | cut -d' ' -f1
265+
// 168.1.1.1 [10.0.0.1]
266+
// But busybox hostname does not implement --all-ip-addresses:
267+
// hostname: unrecognized option: I
268+
func getSSHAddress(ctx context.Context, instName string) (string, error) {
269+
distroName := "lima-" + instName
270+
// Ubuntu
271+
cmd := exec.CommandContext(ctx, "wsl.exe", "-d", distroName, "bash", "-c", `hostname -I | cut -d ' ' -f1`)
272+
out, err := cmd.CombinedOutput()
273+
if err == nil {
274+
return strings.TrimSpace(string(out)), nil
275+
}
276+
// Alpine
277+
cmd = exec.CommandContext(ctx, "wsl.exe", "-d", distroName, "sh", "-c", `ip route get 1 | awk '{gsub("^.*src ",""); print $1; exit}'`)
278+
out, err = cmd.CombinedOutput()
279+
if err == nil {
280+
return strings.TrimSpace(string(out)), nil
281+
}
282+
// fallback
283+
cmd = exec.CommandContext(ctx, "wsl.exe", "-d", distroName, "hostname", "-i")
284+
out, err = cmd.CombinedOutput()
285+
if err != nil || strings.HasPrefix(string(out), "127.") {
286+
return "", fmt.Errorf("failed to get hostname for instance %q, err: %w (out=%q)", instName, err, string(out))
287+
}
288+
289+
return strings.TrimSpace(string(out)), nil
290+
}

pkg/driver/wsl2/wsl_driver_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ func (l *LimaWslDriver) InspectStatus(ctx context.Context, inst *limatype.Instan
193193
inst.SSHLocalPort = 22
194194

195195
if inst.Status == limatype.StatusRunning {
196-
sshAddr, err := l.SSHAddress(ctx)
196+
sshAddr, err := getSSHAddress(ctx, inst.Name)
197197
if err == nil {
198198
inst.SSHAddress = sshAddr
199199
} else {

0 commit comments

Comments
 (0)