11// SPDX-FileCopyrightText: Copyright The Lima Authors
22// SPDX-License-Identifier: Apache-2.0
33
4- package usrlocalsharelima
4+ package usrlocal
55
66import (
77 "errors"
@@ -10,12 +10,11 @@ import (
1010 "os"
1111 "os/exec"
1212 "path/filepath"
13- "runtime "
13+ "strings "
1414 "sync"
1515
1616 "github.com/sirupsen/logrus"
1717
18- "github.com/lima-vm/lima/v2/pkg/debugutil"
1918 "github.com/lima-vm/lima/v2/pkg/limatype"
2019)
2120
@@ -73,61 +72,54 @@ func SelfDirs() []string {
7372 return selfPaths
7473}
7574
76- // Dir returns the location of the <PREFIX>/lima/share directory, relative to the location
77- // of the current executable. It checks for multiple possible filesystem layouts and returns
78- // the first candidate that contains the native guest agent binary.
79- func Dir () (string , error ) {
80- selfDirs := SelfDirs ()
75+ func delveDebugExe () string {
76+ exe , err := os .Executable ()
77+ if err != nil {
78+ return ""
79+ }
80+ exeBase := filepath .Base (exe )
81+ if strings .HasPrefix (exeBase , "__debug_bin" ) {
82+ return exe
83+ }
84+ return ""
85+ }
8186
82- ostype := limatype . NewOS ( "linux" )
83- arch := limatype . NewArch ( runtime . GOARCH )
84- if arch == "" {
85- return "" , fmt . Errorf ( "failed to get arch for %q" , runtime . GOARCH )
87+ func delveWorkspace () string {
88+ self := delveDebugExe ( )
89+ if self == "" {
90+ return ""
8691 }
92+ // - self: ${workspaceFolder}/cmd/limactl/__debug_bin_XXXXXX
93+ // - agent: ${workspaceFolder}/_output/share/lima/lima-guestagent.Linux-x86_64
94+ return filepath .Dir (filepath .Dir (filepath .Dir (self )))
95+ }
8796
88- gaCandidates := []string {}
97+ // ShareLima returns the <PREFIX>/share/lima directories.
98+ func ShareLima () ([]string , error ) {
99+ var candidates []string
100+ selfDirs := SelfDirs ()
89101 for _ , selfDir := range selfDirs {
90102 // selfDir: /usr/local/bin
91- selfDirDir := filepath .Dir (selfDir )
92- gaCandidates = append (gaCandidates ,
93- // candidate 0:
94- // - self: /Applications/Lima.app/Contents/MacOS/limactl
95- // - agent: /Applications/Lima.app/Contents/MacOS/lima-guestagent.Linux-x86_64
96- // - dir: /Applications/Lima.app/Contents/MacOS
97- filepath .Join (selfDir , "lima-guestagent." + ostype + "-" + arch ),
98- // candidate 1:
99- // - self: /usr/local/bin/limactl
100- // - agent: /usr/local/share/lima/lima-guestagent.Linux-x86_64
101- // - dir: /usr/local/share/lima
102- filepath .Join (selfDirDir , "share/lima/lima-guestagent." + ostype + "-" + arch ),
103- // TODO: support custom path
104- )
105- if debugutil .Debug {
106- // candidate 2: launched by `~/go/bin/dlv dap`
107- // - self: ${workspaceFolder}/cmd/limactl/__debug_bin_XXXXXX
108- // - agent: ${workspaceFolder}/_output/share/lima/lima-guestagent.Linux-x86_64
109- // - dir: ${workspaceFolder}/_output/share/lima
110- candidateForDebugBuild := filepath .Join (filepath .Dir (selfDirDir ), "_output/share/lima/lima-guestagent." + ostype + "-" + arch )
111- gaCandidates = append (gaCandidates , candidateForDebugBuild )
112- logrus .Infof ("debug mode detected, adding more guest agent candidates: %v" , candidateForDebugBuild )
103+ // prefix: /usr/local
104+ // candidate: /usr/local/share/lima
105+ prefix := filepath .Dir (selfDir )
106+ candidate := filepath .Join (prefix , "share" , "lima" )
107+ if ents , err := os .ReadDir (candidate ); err == nil && len (ents ) > 0 {
108+ candidates = append (candidates , candidate )
113109 }
114110 }
115-
116- for _ , gaCandidate := range gaCandidates {
117- if _ , err := os .Stat (gaCandidate ); err == nil {
118- return filepath .Dir (gaCandidate ), nil
119- } else if ! errors .Is (err , os .ErrNotExist ) {
120- return "" , err
121- }
122- if _ , err := os .Stat (gaCandidate + ".gz" ); err == nil {
123- return filepath .Dir (gaCandidate ), nil
124- } else if ! errors .Is (err , os .ErrNotExist ) {
125- return "" , err
111+ if workspace := delveWorkspace (); workspace != "" {
112+ // https://github.com/lima-vm/lima/pull/2651/commits/644c11373cb79aaebd8520706f7d51bd3ee5fbe4
113+ // launched by `~/go/bin/dlv dap`
114+ // - self: ${workspaceFolder}/cmd/limactl/__debug_bin_XXXXXX
115+ // - agent: ${workspaceFolder}/_output/share/lima/lima-guestagent.Linux-x86_64
116+ // - dir: ${workspaceFolder}/_output/share/lima
117+ candidate := filepath .Join (workspace , "_output" , "share" , "lima" )
118+ if ents , err := os .ReadDir (candidate ); err == nil && len (ents ) > 0 {
119+ candidates = append (candidates , candidate )
126120 }
127121 }
128-
129- return "" , fmt .Errorf ("failed to find \" lima-guestagent.%s-%s\" binary for %v, attempted %v" ,
130- ostype , arch , selfDirs , gaCandidates )
122+ return candidates , nil
131123}
132124
133125// GuestAgentBinary returns the absolute path of the guest agent binary, possibly with ".gz" suffix.
@@ -138,18 +130,26 @@ func GuestAgentBinary(ostype limatype.OS, arch limatype.Arch) (string, error) {
138130 if arch == "" {
139131 return "" , errors .New ("arch must be set" )
140132 }
141- dir , err := Dir ()
133+ shareLimaDirs , err := ShareLima ()
142134 if err != nil {
143135 return "" , err
144136 }
145- uncomp := filepath .Join (dir , "lima-guestagent." + ostype + "-" + arch )
146- comp := uncomp + ".gz"
147- res , err := chooseGABinary ([]string {comp , uncomp })
148- if err != nil {
149- logrus .Debug (err )
150- return "" , fmt .Errorf ("guest agent binary could not be found for %s-%s: %w (Hint: try installing `lima-additional-guestagents` package)" , ostype , arch , err )
137+ for _ , dir := range shareLimaDirs {
138+ uncomp := filepath .Join (dir , "lima-guestagent." + ostype + "-" + arch )
139+ comp := uncomp + ".gz"
140+ var res string
141+ res , err = chooseGABinary ([]string {comp , uncomp })
142+ if err != nil {
143+ logrus .Debug (err )
144+ continue
145+ }
146+ return res , nil
147+ }
148+ if err == nil {
149+ // caller expects err to be comparable to fs.ErrNotExist
150+ err = fs .ErrNotExist
151151 }
152- return res , nil
152+ return "" , fmt . Errorf ( "guest agent binary could not be found for %s-%s: %w (Hint: try installing `lima-additional-guestagents` package)" , ostype , arch , err )
153153}
154154
155155func chooseGABinary (candidates []string ) (string , error ) {
@@ -201,5 +201,11 @@ func LibexecLima() ([]string, error) {
201201 candidates = append (candidates , candidate )
202202 }
203203 }
204+ if workspace := delveWorkspace (); workspace != "" {
205+ candidate := filepath .Join (workspace , "_output" , "libexec" , "lima" )
206+ if ents , err := os .ReadDir (candidate ); err == nil && len (ents ) > 0 {
207+ candidates = append (candidates , candidate )
208+ }
209+ }
204210 return candidates , nil
205211}
0 commit comments