@@ -3,10 +3,13 @@ package eos
33import (
44 "context"
55 "fmt"
6+ "os"
67 "os/exec"
78 "strings"
89)
910
11+ var hostnameFunc = os .Hostname
12+
1013func (c * Client ) sshOptions (batchMode bool ) []string {
1114 options := []string {"-o" , "LogLevel=ERROR" }
1215 if batchMode {
@@ -51,7 +54,7 @@ func (c *Client) runCommand(args ...string) ([]byte, error) {
5154
5255func (c * Client ) runCommandOnHost (ctx context.Context , host string , args ... string ) ([]byte , error ) {
5356 host = strings .TrimSpace (host )
54- if host == "" || host == hostOnly ( strings . TrimPrefix ( c .effectiveSSHTarget (), "root@" )) {
57+ if host == "" || isCurrentExecutionHost ( host , c .effectiveSSHTarget ()) {
5558 return c .runCommand (args ... )
5659 }
5760
@@ -113,10 +116,9 @@ func (c *Client) TailLogOnHost(ctx context.Context, host, filePath string, n int
113116 tailArgs := []string {"tail" , fmt .Sprintf ("-n%d" , n ), filePath }
114117
115118 effective := c .effectiveSSHTarget () // e.g. "root@eospilot-ns-02.cern.ch"
116- effectiveHost := hostOnly (strings .TrimPrefix (effective , "root@" ))
117119
118120 // Direct case: no specific host, or the host IS the current target.
119- if host == "" || host == effectiveHost {
121+ if host == "" || isCurrentExecutionHost ( host , effective ) {
120122 out , err := c .runCommand (tailArgs ... )
121123 if err != nil {
122124 return nil , fmt .Errorf ("tail %s: %w (output: %.300s)" , filePath , err , out )
@@ -154,9 +156,8 @@ func (c *Client) TailLogOnHost(ctx context.Context, host, filePath string, n int
154156// Returns (directTarget, jumpProxy) where jumpProxy may be empty.
155157func (c * Client ) SSHTargetForHost (host string ) (target , jump string ) {
156158 effective := c .effectiveSSHTarget ()
157- effectiveHost := hostOnly (strings .TrimPrefix (effective , "root@" ))
158159
159- if host == "" || host == effectiveHost {
160+ if host == "" || isCurrentExecutionHost ( host , effective ) {
160161 if effective != "" {
161162 return effective , ""
162163 }
@@ -173,3 +174,57 @@ func (c *Client) SSHTargetForHost(host string) (target, jump string) {
173174func (c * Client ) AcceptNewHostKeys () bool {
174175 return c .acceptNewHostKeys
175176}
177+
178+ func isCurrentExecutionHost (host , effective string ) bool {
179+ host = canonicalHost (host )
180+ if host == "" {
181+ return true
182+ }
183+
184+ effectiveHost := canonicalHost (strings .TrimPrefix (effective , "root@" ))
185+ if effectiveHost != "" {
186+ return host == effectiveHost
187+ }
188+
189+ return matchesLocalHost (host )
190+ }
191+
192+ func matchesLocalHost (host string ) bool {
193+ host = canonicalHost (host )
194+ if host == "" {
195+ return false
196+ }
197+ if host == "localhost" || host == "127.0.0.1" || host == "::1" {
198+ return true
199+ }
200+
201+ local , err := hostnameFunc ()
202+ if err != nil {
203+ return false
204+ }
205+ local = canonicalHost (local )
206+ if local == "" {
207+ return false
208+ }
209+
210+ return host == local || shortHost (host ) == shortHost (local )
211+ }
212+
213+ func canonicalHost (host string ) string {
214+ host = strings .TrimSpace (host )
215+ host = strings .TrimPrefix (host , "root@" )
216+ if host == "::1" || host == "[::1]" {
217+ return "::1"
218+ }
219+ host = hostOnly (host )
220+ host = strings .TrimSuffix (host , "." )
221+ return strings .ToLower (host )
222+ }
223+
224+ func shortHost (host string ) string {
225+ host = canonicalHost (host )
226+ if idx := strings .Index (host , "." ); idx != - 1 {
227+ return host [:idx ]
228+ }
229+ return host
230+ }
0 commit comments