|
|
|
@ -28,6 +28,7 @@ import (
|
|
|
|
|
"tailscale.com/hostinfo"
|
|
|
|
|
"tailscale.com/ipn"
|
|
|
|
|
"tailscale.com/ipn/ipnlocal"
|
|
|
|
|
"tailscale.com/ipn/ipnstate"
|
|
|
|
|
"tailscale.com/ipn/localapi"
|
|
|
|
|
"tailscale.com/ipn/store"
|
|
|
|
|
"tailscale.com/ipn/store/mem"
|
|
|
|
@ -146,6 +147,52 @@ func (s *Server) Start() error {
|
|
|
|
|
return s.initErr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Up connects the server to the tailnet and waits until it is running.
|
|
|
|
|
// On success it returns the current status, including a Tailscale IP address.
|
|
|
|
|
func (s *Server) Up(ctx context.Context) (*ipnstate.Status, error) {
|
|
|
|
|
lc, err := s.LocalClient() // calls Start
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("tsnet.Up: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
watcher, err := lc.WatchIPNBus(ctx, ipn.NotifyInitialState|ipn.NotifyNoPrivateKeys)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("tsnet.Up: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer watcher.Close()
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
n, err := watcher.Next()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("tsnet.Up: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if n.ErrMessage != nil {
|
|
|
|
|
return nil, fmt.Errorf("tsnet.Up: backend: %s", *n.ErrMessage)
|
|
|
|
|
}
|
|
|
|
|
if s := n.State; s != nil {
|
|
|
|
|
switch *s {
|
|
|
|
|
case ipn.Running:
|
|
|
|
|
status, err := lc.Status(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("tsnet.Up: %w", err)
|
|
|
|
|
}
|
|
|
|
|
if len(status.TailscaleIPs) == 0 {
|
|
|
|
|
return nil, errors.New("tsnet.Up: running, but no ip")
|
|
|
|
|
}
|
|
|
|
|
return status, nil
|
|
|
|
|
case ipn.NeedsMachineAuth:
|
|
|
|
|
return nil, errors.New("tsnet.Up: tailnet requested machine auth")
|
|
|
|
|
}
|
|
|
|
|
// TODO: in the future, return an error on NeedsLogin
|
|
|
|
|
// to improve the UX of trying out the tsnet package.
|
|
|
|
|
//
|
|
|
|
|
// Unfortunately today, even when using an AuthKey we
|
|
|
|
|
// briefly see a NeedsLogin state. It would be nice
|
|
|
|
|
// to fix that.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close stops the server.
|
|
|
|
|
//
|
|
|
|
|
// It must not be called before or concurrently with Start.
|
|
|
|
|