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,55 @@ 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+ // https://github.com/lima-vm/lima/pull/2651/commits/644c11373cb79aaebd8520706f7d51bd3ee5fbe4
93+ // launched by `~/go/bin/dlv dap`
94+ // - self: ${workspaceFolder}/cmd/limactl/__debug_bin_XXXXXX
95+ return filepath .Dir (filepath .Dir (filepath .Dir (self )))
96+ }
8797
88- gaCandidates := []string {}
98+ // ShareLima returns the <PREFIX>/share/lima directories.
99+ func ShareLima () ([]string , error ) {
100+ var candidates []string
101+ selfDirs := SelfDirs ()
89102 for _ , selfDir := range selfDirs {
90103 // 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 )
104+ // prefix: /usr/local
105+ // candidate: /usr/local/share/lima
106+ prefix := filepath .Dir (selfDir )
107+ candidate := filepath .Join (prefix , "share" , "lima" )
108+ if ents , err := os .ReadDir (candidate ); err == nil && len (ents ) > 0 {
109+ candidates = append (candidates , candidate )
113110 }
114111 }
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
112+ if workspace := delveWorkspace (); workspace != "" {
113+ // https://github.com/lima-vm/lima/pull/2651/commits/644c11373cb79aaebd8520706f7d51bd3ee5fbe4
114+ // launched by `~/go/bin/dlv dap`
115+ // - self: ${workspaceFolder}/cmd/limactl/__debug_bin_XXXXXX
116+ // - agent: ${workspaceFolder}/_output/share/lima/lima-guestagent.Linux-x86_64
117+ // - dir: ${workspaceFolder}/_output/share/lima
118+ candidate := filepath .Join (workspace , "_output" , "share" , "lima" )
119+ if ents , err := os .ReadDir (candidate ); err == nil && len (ents ) > 0 {
120+ candidates = append (candidates , candidate )
126121 }
127122 }
128-
129- return "" , fmt .Errorf ("failed to find \" lima-guestagent.%s-%s\" binary for %v, attempted %v" ,
130- ostype , arch , selfDirs , gaCandidates )
123+ return candidates , nil
131124}
132125
133126// GuestAgentBinary returns the absolute path of the guest agent binary, possibly with ".gz" suffix.
@@ -138,18 +131,26 @@ func GuestAgentBinary(ostype limatype.OS, arch limatype.Arch) (string, error) {
138131 if arch == "" {
139132 return "" , errors .New ("arch must be set" )
140133 }
141- dir , err := Dir ()
134+ shareLimaDirs , err := ShareLima ()
142135 if err != nil {
143136 return "" , err
144137 }
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 )
138+ for _ , dir := range shareLimaDirs {
139+ uncomp := filepath .Join (dir , "lima-guestagent." + ostype + "-" + arch )
140+ comp := uncomp + ".gz"
141+ var res string
142+ res , err = chooseGABinary ([]string {comp , uncomp })
143+ if err != nil {
144+ logrus .Debug (err )
145+ continue
146+ }
147+ return res , nil
148+ }
149+ if err == nil {
150+ // caller expects err to be comparable to fs.ErrNotExist
151+ err = fs .ErrNotExist
151152 }
152- return res , nil
153+ return "" , fmt . Errorf ( "guest agent binary could not be found for %s-%s: %w (Hint: try installing `lima-additional-guestagents` package)" , ostype , arch , err )
153154}
154155
155156func chooseGABinary (candidates []string ) (string , error ) {
@@ -201,5 +202,11 @@ func LibexecLima() ([]string, error) {
201202 candidates = append (candidates , candidate )
202203 }
203204 }
205+ if workspace := delveWorkspace (); workspace != "" {
206+ candidate := filepath .Join (workspace , "_output" , "libexec" , "lima" )
207+ if ents , err := os .ReadDir (candidate ); err == nil && len (ents ) > 0 {
208+ candidates = append (candidates , candidate )
209+ }
210+ }
204211 return candidates , nil
205212}
0 commit comments