@@ -23,32 +23,42 @@ import (
23
23
// It will also append the file extension on Windows, if necessary.
24
24
// This function is different from os.Executable(), which will use /proc/self/exe on Linux
25
25
// and therefore will resolve any symlink used to locate the executable. This function will
26
- // return the symlink instead because we want to locate ../share/lima relative to the location
27
- // of the symlink, and not the actual executable. This is important when using Homebrew.
28
- //
29
- // If os.Args[0] is invalid, this function still falls back on os.Executable().
26
+ // return the symlink instead because we want to be able to locate ../share/lima relative
27
+ // to the location of the symlink, and not the actual executable. This is important when
28
+ // using Homebrew.
30
29
var executableViaArgs0 = sync .OnceValues (func () (string , error ) {
31
30
if os .Args [0 ] == "" {
32
- logrus .Warn ("os.Args[0] has not been set" )
33
- } else {
34
- executable , err := exec .LookPath (os .Args [0 ])
35
- if err == nil {
36
- // LookPath() will add the `.exe` file extension on Windows, but will not return an
37
- // absolute path if the argument contained any of `:/\` (or just `/` on Unix).
38
- return filepath .Abs (executable )
39
- }
40
- logrus .Warnf ("os.Args[0] is invalid: %v" , err )
31
+ return "" , errors .New ("os.Args[0] has not been set" )
32
+ }
33
+ executable , err := exec .LookPath (os .Args [0 ])
34
+ if err == nil {
35
+ executable , err = filepath .Abs (executable )
36
+ }
37
+ if err != nil {
38
+ return "" , fmt .Errorf ("os.Args[0] is invalid: %w" , err )
41
39
}
42
- return os .Executable ()
40
+
41
+ return executable , nil
43
42
})
44
43
45
44
// Dir returns the location of the <PREFIX>/lima/share directory, relative to the location
46
45
// of the current executable. It checks for multiple possible filesystem layouts and returns
47
46
// the first candidate that contains the native guest agent binary.
48
47
func Dir () (string , error ) {
49
- self , err := executableViaArgs0 ()
48
+ selfPaths := []string {}
49
+
50
+ selfViaArgs0 , err := executableViaArgs0 ()
50
51
if err != nil {
51
- return "" , err
52
+ logrus .WithError (err ).Warn ("failed to find executable from os.Args[0]" )
53
+ } else {
54
+ selfPaths = append (selfPaths , selfViaArgs0 )
55
+ }
56
+
57
+ selfViaOS , err := os .Executable ()
58
+ if err != nil {
59
+ logrus .WithError (err ).Warn ("failed to find os.Executable()" )
60
+ } else if len (selfPaths ) == 0 || selfViaOS != selfPaths [0 ] {
61
+ selfPaths = append (selfPaths , selfViaOS )
52
62
}
53
63
54
64
ostype := limayaml .NewOS ("linux" )
@@ -57,31 +67,35 @@ func Dir() (string, error) {
57
67
return "" , fmt .Errorf ("failed to get arch for %q" , runtime .GOARCH )
58
68
}
59
69
60
- // self: /usr/local/bin/limactl
61
- selfDir := filepath .Dir (self )
62
- selfDirDir := filepath .Dir (selfDir )
63
- gaCandidates := []string {
64
- // candidate 0:
65
- // - self: /Applications/Lima.app/Contents/MacOS/limactl
66
- // - agent: /Applications/Lima.app/Contents/MacOS/lima-guestagent.Linux-x86_64
67
- // - dir: /Applications/Lima.app/Contents/MacOS
68
- filepath .Join (selfDir , "lima-guestagent." + ostype + "-" + arch ),
69
- // candidate 1:
70
- // - self: /usr/local/bin/limactl
71
- // - agent: /usr/local/share/lima/lima-guestagent.Linux-x86_64
72
- // - dir: /usr/local/share/lima
73
- filepath .Join (selfDirDir , "share/lima/lima-guestagent." + ostype + "-" + arch ),
74
- // TODO: support custom path
75
- }
76
- if debugutil .Debug {
77
- // candidate 2: launched by `~/go/bin/dlv dap`
78
- // - self: ${workspaceFolder}/cmd/limactl/__debug_bin_XXXXXX
79
- // - agent: ${workspaceFolder}/_output/share/lima/lima-guestagent.Linux-x86_64
80
- // - dir: ${workspaceFolder}/_output/share/lima
81
- candidateForDebugBuild := filepath .Join (filepath .Dir (selfDirDir ), "_output/share/lima/lima-guestagent." + ostype + "-" + arch )
82
- gaCandidates = append (gaCandidates , candidateForDebugBuild )
83
- logrus .Infof ("debug mode detected, adding more guest agent candidates: %v" , candidateForDebugBuild )
70
+ gaCandidates := []string {}
71
+ for _ , self := range selfPaths {
72
+ // self: /usr/local/bin/limactl
73
+ selfDir := filepath .Dir (self )
74
+ selfDirDir := filepath .Dir (selfDir )
75
+ gaCandidates = append (gaCandidates ,
76
+ // candidate 0:
77
+ // - self: /Applications/Lima.app/Contents/MacOS/limactl
78
+ // - agent: /Applications/Lima.app/Contents/MacOS/lima-guestagent.Linux-x86_64
79
+ // - dir: /Applications/Lima.app/Contents/MacOS
80
+ filepath .Join (selfDir , "lima-guestagent." + ostype + "-" + arch ),
81
+ // candidate 1:
82
+ // - self: /usr/local/bin/limactl
83
+ // - agent: /usr/local/share/lima/lima-guestagent.Linux-x86_64
84
+ // - dir: /usr/local/share/lima
85
+ filepath .Join (selfDirDir , "share/lima/lima-guestagent." + ostype + "-" + arch ),
86
+ // TODO: support custom path
87
+ )
88
+ if debugutil .Debug {
89
+ // candidate 2: launched by `~/go/bin/dlv dap`
90
+ // - self: ${workspaceFolder}/cmd/limactl/__debug_bin_XXXXXX
91
+ // - agent: ${workspaceFolder}/_output/share/lima/lima-guestagent.Linux-x86_64
92
+ // - dir: ${workspaceFolder}/_output/share/lima
93
+ candidateForDebugBuild := filepath .Join (filepath .Dir (selfDirDir ), "_output/share/lima/lima-guestagent." + ostype + "-" + arch )
94
+ gaCandidates = append (gaCandidates , candidateForDebugBuild )
95
+ logrus .Infof ("debug mode detected, adding more guest agent candidates: %v" , candidateForDebugBuild )
96
+ }
84
97
}
98
+
85
99
for _ , gaCandidate := range gaCandidates {
86
100
if _ , err := os .Stat (gaCandidate ); err == nil {
87
101
return filepath .Dir (gaCandidate ), nil
@@ -95,8 +109,8 @@ func Dir() (string, error) {
95
109
}
96
110
}
97
111
98
- return "" , fmt .Errorf ("failed to find \" lima-guestagent.%s-%s\" binary for %q , attempted %v" ,
99
- ostype , arch , self , gaCandidates )
112
+ return "" , fmt .Errorf ("failed to find \" lima-guestagent.%s-%s\" binary for %v , attempted %v" ,
113
+ ostype , arch , selfPaths , gaCandidates )
100
114
}
101
115
102
116
// GuestAgentBinary returns the absolute path of the guest agent binary, possibly with ".gz" suffix.
0 commit comments