Skip to content

Instantly share code, notes, and snippets.

@josharian
Created March 10, 2023 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josharian/b63397fd86c2df556690468c0ea8eeb0 to your computer and use it in GitHub Desktop.
Save josharian/b63397fd86c2df556690468c0ea8eeb0 to your computer and use it in GitHub Desktop.
// ...
// 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