diff --git a/cmd/sic/addr.go b/cmd/sic/addr.go index 0336be1..dd65d98 100644 --- a/cmd/sic/addr.go +++ b/cmd/sic/addr.go @@ -1,5 +1,7 @@ package main +import "fmt" + func parseTarget(s string) (host string, hops []string) { for i := 0; i < len(s); i++ { if s[i] == '/' { @@ -28,3 +30,16 @@ func splitHops(s string) []string { hops = append(hops, s[start:]) return hops } + +func verbFor(runtime, name string) (string, error) { + switch runtime { + case "incus": + return "incus exec " + name + " --", nil + case "docker": + return "docker exec " + name, nil + case "pct": + return "pct exec " + name + " --", nil + default: + return "", fmt.Errorf("unknown runtime: %s", runtime) + } +} diff --git a/cmd/sic/verbfor_test.go b/cmd/sic/verbfor_test.go new file mode 100644 index 0000000..194a773 --- /dev/null +++ b/cmd/sic/verbfor_test.go @@ -0,0 +1,29 @@ +package main + +import "testing" + +// WP5: verbFor maps a hop's runtime TYPE + container name to the runtime verb that enters it. +// The inner-hop command is this verb with " sicd" appended (wrapHop does the append), so the +// verb must end right where "sicd" should follow: incus/pct need the "--" argv separator, +// docker exec does not. Unknown runtime is a hard error (fail-loud, never guess a verb). +func TestVerbFor(t *testing.T) { + cases := []struct { + runtime, name, want string + }{ + {"incus", "memory", "incus exec memory --"}, + {"docker", "stash-stash-1", "docker exec stash-stash-1"}, + {"pct", "107", "pct exec 107 --"}, + } + for _, tc := range cases { + got, err := verbFor(tc.runtime, tc.name) + if err != nil { + t.Fatalf("verbFor(%q,%q) unexpected err: %v", tc.runtime, tc.name, err) + } + if got != tc.want { + t.Fatalf("verbFor(%q,%q) = %q, want %q", tc.runtime, tc.name, got, tc.want) + } + } + if _, err := verbFor("bogus", "x"); err == nil { + t.Fatal("verbFor with an unknown runtime must return an error, not guess a verb") + } +}