Skip to content

Commit 2cee8d2

Browse files
committed
add InspectStatus() to api and refactor wsl2
Signed-off-by: Ansuman Sahoo <[email protected]>
1 parent ecf4026 commit 2cee8d2

File tree

10 files changed

+117
-144
lines changed

10 files changed

+117
-144
lines changed

pkg/driver/driver.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type Lifecycle interface {
3636
Stop(_ context.Context) error
3737

3838
Delete(_ context.Context) error
39+
InspectStatus(_ context.Context, instName string) string
3940
}
4041

4142
// GUI defines GUI-related operations.

pkg/driver/external/client/methods.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,18 @@ func (d *DriverClient) Configure(inst *limatype.Instance) *driver.ConfiguredDriv
308308
}
309309

310310
func (d *DriverClient) Delete(ctx context.Context) error {
311-
return errors.New("AcceptConfig not implemented in DriverClient")
311+
return errors.New("Delete not implemented in DriverClient")
312312
}
313313

314314
func (d *DriverClient) AcceptConfig(cfg *limatype.LimaYAML, filepath string) error {
315315
return errors.New("AcceptConfig not implemented in DriverClient")
316316
}
317317

318318
func (d *DriverClient) FillConfig(cfg *limatype.LimaYAML, filepath string) error {
319-
return errors.New("AcceptConfig not implemented in DriverClient")
319+
return errors.New("FillConfig not implemented in DriverClient")
320+
}
321+
322+
// TODO: Implement InspectStatus in DriverClient
323+
func (d *DriverClient) InspectStatus(_ context.Context, _ string) string {
324+
return ""
320325
}

pkg/driver/qemu/qemu_driver.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,10 @@ func (l *LimaQemuDriver) Info() driver.Info {
641641
return info
642642
}
643643

644+
func (l *LimaQemuDriver) InspectStatus(_ context.Context, instName string) string {
645+
return ""
646+
}
647+
644648
func (l *LimaQemuDriver) Create(_ context.Context) error {
645649
return nil
646650
}

pkg/driver/vz/vz_driver_darwin.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ func (l *LimaVzDriver) Info() driver.Info {
316316
return info
317317
}
318318

319+
func (l *LimaVzDriver) InspectStatus(_ context.Context, instName string) string {
320+
return ""
321+
}
322+
319323
func (l *LimaVzDriver) Delete(ctx context.Context) error {
320324
return nil
321325
}

pkg/driver/wsl2/vm_windows.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os"
1111
"os/exec"
1212
"path/filepath"
13+
"regexp"
1314
"strconv"
1415
"strings"
1516

@@ -18,7 +19,6 @@ import (
1819
"github.com/lima-vm/lima/v2/pkg/executil"
1920
"github.com/lima-vm/lima/v2/pkg/limatype"
2021
"github.com/lima-vm/lima/v2/pkg/limatype/filenames"
21-
"github.com/lima-vm/lima/v2/pkg/store"
2222
"github.com/lima-vm/lima/v2/pkg/textutil"
2323
)
2424

@@ -133,7 +133,7 @@ func provisionVM(ctx context.Context, instanceDir, instanceName, distroName stri
133133
for {
134134
<-ctx.Done()
135135
logrus.Info("Context closed, stopping vm")
136-
if status, err := store.GetWslStatus(instanceName); err == nil &&
136+
if status, err := getWslStatus(instanceName); err == nil &&
137137
status == limatype.StatusRunning {
138138
_ = stopVM(ctx, distroName)
139139
}
@@ -177,3 +177,54 @@ func unregisterVM(ctx context.Context, distroName string) error {
177177
}
178178
return nil
179179
}
180+
181+
func getWslStatus(instName string) (string, error) {
182+
distroName := "lima-" + instName
183+
out, err := executil.RunUTF16leCommand([]string{
184+
"wsl.exe",
185+
"--list",
186+
"--verbose",
187+
})
188+
if err != nil {
189+
return "", fmt.Errorf("failed to run `wsl --list --verbose`, err: %w (out=%q)", err, out)
190+
}
191+
192+
if out == "" {
193+
return limatype.StatusBroken, fmt.Errorf("failed to read instance state for instance %q, try running `wsl --list --verbose` to debug, err: %w", instName, err)
194+
}
195+
196+
// Check for edge cases first
197+
if strings.Contains(out, "Windows Subsystem for Linux has no installed distributions.") {
198+
if strings.Contains(out, "Wsl/WSL_E_DEFAULT_DISTRO_NOT_FOUND") {
199+
return limatype.StatusBroken, fmt.Errorf(
200+
"failed to read instance state for instance %q because no distro is installed,"+
201+
"try running `wsl --install -d Ubuntu` and then re-running Lima", instName)
202+
}
203+
return limatype.StatusBroken, fmt.Errorf(
204+
"failed to read instance state for instance %q because there is no WSL kernel installed,"+
205+
"this usually happens when WSL was installed for another user, but never for your user."+
206+
"Try running `wsl --install -d Ubuntu` and `wsl --update`, and then re-running Lima", instName)
207+
}
208+
209+
var instState string
210+
wslListColsRegex := regexp.MustCompile(`\s+`)
211+
// wsl --list --verbose may have different headers depending on localization, just split by line
212+
for _, rows := range strings.Split(strings.ReplaceAll(out, "\r\n", "\n"), "\n") {
213+
cols := wslListColsRegex.Split(strings.TrimSpace(rows), -1)
214+
nameIdx := 0
215+
// '*' indicates default instance
216+
if cols[0] == "*" {
217+
nameIdx = 1
218+
}
219+
if cols[nameIdx] == distroName {
220+
instState = cols[nameIdx+1]
221+
break
222+
}
223+
}
224+
225+
if instState == "" {
226+
return limatype.StatusUninitialized, nil
227+
}
228+
229+
return instState, nil
230+
}

pkg/driver/wsl2/wsl_driver_windows.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,32 @@ func (l *LimaWslDriver) Validate() error {
158158
return nil
159159
}
160160

161+
func (l *LimaWslDriver) InspectStatus(ctx context.Context, instName string) string {
162+
status, err := getWslStatus(instName)
163+
if err != nil {
164+
l.Instance.Status = limatype.StatusBroken
165+
l.Instance.Errors = append(l.Instance.Errors, err)
166+
} else {
167+
l.Instance.Status = status
168+
}
169+
170+
l.Instance.SSHLocalPort = 22
171+
172+
if l.Instance.Status == limatype.StatusRunning {
173+
sshAddr, err := store.GetSSHAddress(instName)
174+
if err == nil {
175+
l.Instance.SSHAddress = sshAddr
176+
} else {
177+
l.Instance.Errors = append(l.Instance.Errors, err)
178+
}
179+
}
180+
181+
return l.Instance.Status
182+
}
183+
161184
func (l *LimaWslDriver) Delete(ctx context.Context) error {
162185
distroName := "lima-" + l.Instance.Name
163-
status, err := store.GetWslStatus(l.Instance.Name)
186+
status, err := getWslStatus(l.Instance.Name)
164187
if err != nil {
165188
return err
166189
}
@@ -175,7 +198,7 @@ func (l *LimaWslDriver) Delete(ctx context.Context) error {
175198

176199
func (l *LimaWslDriver) Start(ctx context.Context) (chan error, error) {
177200
logrus.Infof("Starting WSL VM")
178-
status, err := store.GetWslStatus(l.Instance.Name)
201+
status, err := getWslStatus(l.Instance.Name)
179202
if err != nil {
180203
return nil, err
181204
}

pkg/registry/registry_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func (m *mockDriver) Info() driver.Info
4848
func (m *mockDriver) Configure(_ *limatype.Instance) *driver.ConfiguredDriver { return nil }
4949
func (m *mockDriver) AcceptConfig(_ *limatype.LimaYAML, _ string) error { return nil }
5050
func (m *mockDriver) FillConfig(_ *limatype.LimaYAML, _ string) error { return nil }
51+
func (m *mockDriver) InspectStatus(_ context.Context, _ string) string { return "" }
5152

5253
func TestRegister(t *testing.T) {
5354
BackupRegistry(t)

pkg/store/instance.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/docker/go-units"
2222
"github.com/sirupsen/logrus"
2323

24+
"github.com/lima-vm/lima/v2/pkg/driverutil"
2425
hostagentclient "github.com/lima-vm/lima/v2/pkg/hostagent/api/client"
2526
"github.com/lima-vm/lima/v2/pkg/instance/hostname"
2627
"github.com/lima-vm/lima/v2/pkg/limatype"
@@ -147,6 +148,27 @@ func Inspect(instName string) (*limatype.Instance, error) {
147148
return inst, nil
148149
}
149150

151+
func inspectStatus(instDir string, inst *limatype.Instance, y *limatype.LimaYAML) {
152+
driver, err := driverutil.CreateConfiguredDriver(inst, inst.SSHLocalPort)
153+
if err != nil {
154+
inst.Errors = append(inst.Errors, fmt.Errorf("failed to create driver instance: %w", err))
155+
inst.Status = limatype.StatusBroken
156+
return
157+
}
158+
159+
status := driver.InspectStatus(context.Background(), inst.Name)
160+
if status == "" {
161+
inspectStatusWithPIDFiles(instDir, inst, y)
162+
return
163+
}
164+
165+
inst.Status = status
166+
}
167+
168+
func GetSSHAddress(_ string) (string, error) {
169+
return "127.0.0.1", nil
170+
}
171+
150172
func inspectStatusWithPIDFiles(instDir string, inst *limatype.Instance, y *limatype.LimaYAML) {
151173
var err error
152174
inst.DriverPID, err = ReadPIDFile(filepath.Join(instDir, filenames.PIDFile(*y.VMType)))

pkg/store/instance_unix.go

Lines changed: 0 additions & 18 deletions
This file was deleted.

pkg/store/instance_windows.go

Lines changed: 0 additions & 120 deletions
This file was deleted.

0 commit comments

Comments
 (0)