fix tunnel default name

Kim committed Mar 17, 2026 at 18:22 UTC e21097f68a2303f3887489a0efccba5d4e6106eb
2 files changed +44 -21
cmd/portal-tunnel/README.md
+1 -1
@@ -34,7 +34,7 @@ portal expose --name myapp \
34
35 - `<target>` accepts a bare port like `3000`, a `host:port`, or an `http(s)://host:port` URL.
36 - Bare ports resolve to `127.0.0.1:<port>`.
37 -- `--name` is optional. When omitted, the CLI generates a stable local name suffix from its config.
37 +- `--name` is optional. When omitted, the CLI generates a name derived from its local seed and target port.
38 - `--relays` overrides installed default relays for that run.
39 - `--default-relays=false` disables the public registry list for that run.
40
cmd/portal-tunnel/main.go
+43 -20
@@ -2,6 +2,7 @@ package main
2
3 import (
4 "context"
5 + "crypto/sha256"
6 "errors"
7 "flag"
8 "fmt"
@@ -24,8 +25,6 @@ import (
25 "github.com/gosuda/portal/v2/utils"
26 )
27
27 -const shortClientIDSuffixLen = 6
28 -
28 func main() {
29 zerolog.TimeFieldFormat = time.RFC3339
30 zerolog.SetGlobalLevel(zerolog.InfoLevel)
@@ -290,29 +289,53 @@ func resolveRelayURLs(ctx context.Context, registryURL string, inputs []string,
289 return utils.NormalizeRelayURLs(inputs)
290 }
291
292 +var exposeNameOpeners = []string{
293 + "arcade", "bouncy", "bravo", "bubble", "candy", "cosmic", "dapper", "electric",
294 + "fancy", "fizzy", "flashy", "fuzzy", "gentle", "glitter", "golden", "happy",
295 + "hyper", "jazzy", "jolly", "lively", "lucky", "magic", "mellow", "minty",
296 + "misty", "moonlit", "mystic", "neon", "nova", "peppy", "pixel", "playful",
297 + "poppy", "rapid", "rocket", "rowdy", "snappy", "snazzy", "sparkly", "spicy",
298 + "sprightly", "starry", "sunny", "swift", "tangy", "tidy", "toasty", "turbo",
299 + "velvet", "vivid", "wavy", "whimsy", "wild", "wonky", "zany", "zesty",
300 +}
301 +
302 +var exposeNameCenters = []string{
303 + "alpaca", "badger", "banjo", "beacon", "biscuit", "capybara", "comet", "cricket",
304 + "dragon", "falcon", "feather", "fjord", "fox", "gadget", "gecko", "gizmo",
305 + "harbor", "heron", "iguana", "jelly", "koala", "lemur", "mango", "narwhal",
306 + "nebula", "noodle", "octopus", "otter", "panda", "pepper", "phoenix", "pickle",
307 + "puffin", "quokka", "radar", "ranger", "rocket", "scooter", "seahorse", "skylark",
308 + "sprocket", "starling", "sunbeam", "taco", "thimble", "tiger", "toucan", "triton",
309 + "walrus", "widget", "willow", "wombat", "yeti", "zeppelin", "zigzag", "zinnia",
310 +}
311 +
312 +var exposeNameClosers = []string{
313 + "arcade", "beacon", "boogie", "bounce", "burst", "cascade", "chorus", "dash",
314 + "disco", "drift", "echo", "fiesta", "flare", "flash", "flight", "flip",
315 + "glow", "groove", "jam", "jive", "launch", "loop", "march", "orbit",
316 + "parade", "party", "pulse", "quest", "rally", "riot", "ripple", "rodeo",
317 + "roll", "rush", "serenade", "shuffle", "signal", "sketch", "spark", "sprint",
318 + "starlight", "stride", "sway", "swoop", "twirl", "uplift", "vibe", "voyage",
319 + "whirl", "wink", "zap", "zenith", "zip", "zoom", "zest", "zone",
320 +}
321 +
322 func defaultExposeName(target, clientID string) (string, error) {
294 - trimmed := strings.TrimSpace(clientID)
295 - if trimmed == "" {
296 - trimmed = "relay"
297 - }
298 - if cut, ok := strings.CutPrefix(trimmed, "cli_"); ok {
299 - trimmed = cut
300 - }
301 - if len(trimmed) > shortClientIDSuffixLen {
302 - trimmed = trimmed[:shortClientIDSuffixLen]
323 + seed := strings.TrimSpace(clientID)
324 + if cut, ok := strings.CutPrefix(seed, "cli_"); ok {
325 + seed = cut
326 }
304 - if trimmed == "" {
305 - trimmed = "relay"
327 + if seed == "" {
328 + seed = "portal"
329 }
330
308 - port := "app"
309 - if _, rawPort, err := net.SplitHostPort(target); err == nil {
310 - if rawPort != "" {
311 - port = rawPort
312 - }
313 - }
331 + sum := sha256.Sum256([]byte(seed + "|" + strings.TrimSpace(target)))
332 + label := strings.Join([]string{
333 + exposeNameOpeners[int(sum[0])%len(exposeNameOpeners)],
334 + exposeNameCenters[int(sum[1])%len(exposeNameCenters)],
335 + exposeNameClosers[int(sum[2])%len(exposeNameClosers)],
336 + }, "-")
337
315 - return utils.NormalizeDNSLabel("app-" + port + "-" + trimmed)
338 + return utils.NormalizeDNSLabel(label)
339 }
340
341 func printRootUsage(w io.Writer) {