mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-04 20:09:03 +00:00
ipn/ipnlocal,client/web: add web client to tailscaled
Allows for serving the web interface from tailscaled, with the ability to start and stop the server via localapi endpoints (/web/start and /web/stop). This will be used to run the new full management web client, which will only be accessible over Tailscale (with an extra auth check step over noise) from the daemon. This switch also allows us to run the web interface as a long-lived service in environments where the CLI version is restricted to CGI, allowing us to manage certain auth state in memory. ipn/ipnlocal/web is stubbed out in ipn/ipnlocal/web_stub for ios builds to satisfy ios restriction from adding "text/template" and "html/template" dependencies. Updates tailscale/corp#14335 Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This commit is contained in:
committed by
Sonia Appasamy
parent
93aa8a8cff
commit
89953b015b
@@ -49,8 +49,9 @@ type Server struct {
|
||||
cgiMode bool
|
||||
pathPrefix string
|
||||
|
||||
assetsHandler http.Handler // serves frontend assets
|
||||
apiHandler http.Handler // serves api endpoints; csrf-protected
|
||||
assetsHandler http.Handler // serves frontend assets
|
||||
assetsCleanup func() // called from Server.Shutdown
|
||||
|
||||
// browserSessions is an in-memory cache of browser sessions for the
|
||||
// full management web client, which is only accessible over Tailscale.
|
||||
@@ -143,7 +144,10 @@ type ServerOpts struct {
|
||||
}
|
||||
|
||||
// NewServer constructs a new Tailscale web client server.
|
||||
func NewServer(opts ServerOpts) (s *Server, cleanup func()) {
|
||||
// If err is empty, s is always non-nil.
|
||||
// ctx is only required to live the duration of the NewServer call,
|
||||
// and not the lifespan of the web server.
|
||||
func NewServer(opts ServerOpts) (s *Server, err error) {
|
||||
if opts.LocalClient == nil {
|
||||
opts.LocalClient = &tailscale.LocalClient{}
|
||||
}
|
||||
@@ -162,7 +166,7 @@ func NewServer(opts ServerOpts) (s *Server, cleanup func()) {
|
||||
s.logf = log.Printf
|
||||
}
|
||||
s.tsDebugMode = s.debugMode()
|
||||
s.assetsHandler, cleanup = assetsHandler(opts.DevMode)
|
||||
s.assetsHandler, s.assetsCleanup = assetsHandler(opts.DevMode)
|
||||
|
||||
var metric string // clientmetric to report on startup
|
||||
|
||||
@@ -182,14 +186,21 @@ func NewServer(opts ServerOpts) (s *Server, cleanup func()) {
|
||||
metric = "web_client_initialization"
|
||||
}
|
||||
|
||||
// Report metric in separate go routine with 5 second timeout.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
// Don't block startup on reporting metric.
|
||||
// Report in separate go routine with 5 second timeout.
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
s.lc.IncrementCounter(ctx, metric, 1)
|
||||
}()
|
||||
|
||||
return s, cleanup
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Server) Shutdown() {
|
||||
if s.assetsCleanup != nil {
|
||||
s.assetsCleanup()
|
||||
}
|
||||
}
|
||||
|
||||
// debugMode returns the debug mode the web client is being run in.
|
||||
|
||||
Reference in New Issue
Block a user