Created
March 10, 2023 18:40
-
-
Save josharian/b63397fd86c2df556690468c0ea8eeb0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ... | |
// Start Tailscale. | |
tssrv := &tsnet.Server{ | |
// Silence logs completely. | |
// They're really verbose, and we don't have anywhere good to put them. | |
// This will leave us blind if/when we have Tailscale-specific issues, | |
// but in that case, we'll restore the logs temporarily to debug. | |
Logf: func(string, ...any) {}, | |
Store: &tsDBStateStore{Q: srv.DB.Q}, | |
AuthKey: os.Getenv("TS_AUTHKEY"), | |
} | |
switch fly.AppName() { | |
case "prod-www-rhg": | |
// Prod: give a nice, short, memorable name. | |
tssrv.Hostname = "rhg" + "-" + fly.Region() | |
case "dev-www-rhg": | |
// Dev: almost as nice and short. | |
tssrv.Hostname = "rhg-dev" + "-" + fly.Region() | |
case "": | |
// Running locally, accept the default. | |
default: | |
// Huh? Use as-is so we have a chance of figuring out what happened. | |
tssrv.Hostname = fly.AppName() | |
} | |
// Starting the tsnet server might fail if the other server | |
// we are replacing hasn't gone down yet. | |
// Since we need the tsnet server to have a superuser panel, | |
// keep retrying indefinitely until we succeed. | |
bo := backoff.NewBackoff("start tailscale", log.Printf, 30*time.Second) | |
for { | |
err := tssrv.Start() | |
if err != nil { | |
bo.BackOff(context.Background(), err) | |
continue | |
} | |
break | |
} | |
tscli, err := tssrv.LocalClient() | |
if err != nil { | |
return nil, nil, nil, err | |
} | |
// Block until we get our Tailscale IP address. | |
preferredIP, err := preferredTailscaleIP(tscli) | |
if err != nil { | |
return nil, nil, nil, err | |
} | |
domain := os.Getenv("DNS_DOMAIN") | |
host := &url.URL{Scheme: "https", Host: "sup." + domain} | |
// Best effort: update DNS. | |
go updateSuperUserDNS( | |
"136222", // DNSimple account ID | |
os.Getenv("DNSIMPLE_TOKEN"), | |
domain, | |
preferredIP, | |
) | |
// TODO: make a request to ourselves to trigger the TLS cert process | |
// Set up Tailscale listener. | |
lns, err := tssrv.Listen("tcp", ":443") | |
if err != nil { | |
return nil, nil, nil, err | |
} | |
return nil, lns, srv.getTLSCert, nil | |
} | |
// preferredTailscaleIP returns a Tailscale IP address. | |
// It can block indefinitely; use with care. | |
func preferredTailscaleIP(tscli *tailscale.LocalClient) (netip.Addr, error) { | |
for { | |
status, err := tscli.StatusWithoutPeers(context.Background()) | |
if err != nil { | |
return netip.Addr{}, err | |
} | |
if len(status.Self.TailscaleIPs) == 0 { | |
time.Sleep(100 * time.Millisecond) | |
continue | |
} | |
tsip := status.Self.TailscaleIPs | |
log.Printf("got Tailscale IP addresses: %v", tsip) | |
// Try to pick out an IPv4 address, | |
// for human-readability during debugging. | |
ip, ok := slicez.First(tsip, netip.Addr.Is4) | |
if ok { | |
return ip, nil | |
} | |
// If that failed, take any old IP address. | |
return tsip[0], nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment