Skip to content

Commit 0124305

Browse files
committed
Handle local self-host MGM version probes
1 parent 071d7c9 commit 0124305

2 files changed

Lines changed: 105 additions & 5 deletions

File tree

eos/client_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,24 @@ func TestSSHTargetForHostLocal(t *testing.T) {
905905
}
906906
}
907907

908+
func TestSSHTargetForHostLocalSameHostUsesLocalShell(t *testing.T) {
909+
prev := hostnameFunc
910+
hostnameFunc = func() (string, error) { return "eospilot-ns-02.cern.ch", nil }
911+
defer func() { hostnameFunc = prev }()
912+
913+
c := &Client{}
914+
915+
target, jump := c.SSHTargetForHost("eospilot-ns-02.cern.ch")
916+
if target != "" || jump != "" {
917+
t.Fatalf("expected local self host to stay local, got target=%q jump=%q", target, jump)
918+
}
919+
920+
target, jump = c.SSHTargetForHost("eospilot-ns-02")
921+
if target != "" || jump != "" {
922+
t.Fatalf("expected short local self host to stay local, got target=%q jump=%q", target, jump)
923+
}
924+
}
925+
908926
func TestSSHTargetForHostRemoteSameHost(t *testing.T) {
909927
// Running via SSH to mgm01.cern.ch; selected host IS the gateway.
910928
c := &Client{resolvedSSHTarget: "root@mgm01.cern.ch"}
@@ -969,6 +987,33 @@ func TestHostOnly(t *testing.T) {
969987
}
970988
}
971989

990+
func TestMatchesLocalHost(t *testing.T) {
991+
prev := hostnameFunc
992+
hostnameFunc = func() (string, error) { return "eospilot-ns-02.cern.ch", nil }
993+
defer func() { hostnameFunc = prev }()
994+
995+
for _, host := range []string{
996+
"eospilot-ns-02.cern.ch",
997+
"eospilot-ns-02",
998+
"localhost",
999+
"127.0.0.1",
1000+
"::1",
1001+
} {
1002+
if !matchesLocalHost(host) {
1003+
t.Fatalf("expected %q to match local host", host)
1004+
}
1005+
}
1006+
1007+
for _, host := range []string{
1008+
"eospilot-ns-01.cern.ch",
1009+
"fst01.cern.ch",
1010+
} {
1011+
if matchesLocalHost(host) {
1012+
t.Fatalf("did not expect %q to match local host", host)
1013+
}
1014+
}
1015+
}
1016+
9721017
func TestIOShapingPolicySetArgsForApp(t *testing.T) {
9731018
got, err := ioShapingPolicySetArgs(IOShapingPolicyUpdate{
9741019
Mode: IOShapingApps,

eos/ssh.go

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package eos
33
import (
44
"context"
55
"fmt"
6+
"os"
67
"os/exec"
78
"strings"
89
)
910

11+
var hostnameFunc = os.Hostname
12+
1013
func (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

5255
func (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.
155157
func (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) {
173174
func (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

Comments
 (0)