Rework map session
This commit restructures the map session in to a struct holding the state of what is needed during its lifetime. For streaming sessions, the event loop is structured a bit differently not hammering the clients with updates but rather batching them over a short, configurable time which should significantly improve cpu usage, and potentially flakyness. The use of Patch updates has been dialed back a little as it does not look like its a 100% ready for prime time. Nodes are now updated with full changes, except for a few things like online status. Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
parent
dd693c444c
commit
58c94d2bd3
35 changed files with 1803 additions and 1716 deletions
|
@ -9,6 +9,7 @@ import (
|
|||
"log"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -503,7 +504,7 @@ func (t *TailscaleInContainer) IPs() ([]netip.Addr, error) {
|
|||
}
|
||||
|
||||
// Status returns the ipnstate.Status of the Tailscale instance.
|
||||
func (t *TailscaleInContainer) Status() (*ipnstate.Status, error) {
|
||||
func (t *TailscaleInContainer) Status(save ...bool) (*ipnstate.Status, error) {
|
||||
command := []string{
|
||||
"tailscale",
|
||||
"status",
|
||||
|
@ -521,60 +522,70 @@ func (t *TailscaleInContainer) Status() (*ipnstate.Status, error) {
|
|||
return nil, fmt.Errorf("failed to unmarshal tailscale status: %w", err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(fmt.Sprintf("/tmp/control/%s_status.json", t.hostname), []byte(result), 0o755)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("status netmap to /tmp/control: %w", err)
|
||||
}
|
||||
|
||||
return &status, err
|
||||
}
|
||||
|
||||
// Netmap returns the current Netmap (netmap.NetworkMap) of the Tailscale instance.
|
||||
// Only works with Tailscale 1.56 and newer.
|
||||
// Panics if version is lower then minimum.
|
||||
// func (t *TailscaleInContainer) Netmap() (*netmap.NetworkMap, error) {
|
||||
// if !util.TailscaleVersionNewerOrEqual("1.56", t.version) {
|
||||
// panic(fmt.Sprintf("tsic.Netmap() called with unsupported version: %s", t.version))
|
||||
// }
|
||||
func (t *TailscaleInContainer) Netmap() (*netmap.NetworkMap, error) {
|
||||
if !util.TailscaleVersionNewerOrEqual("1.56", t.version) {
|
||||
panic(fmt.Sprintf("tsic.Netmap() called with unsupported version: %s", t.version))
|
||||
}
|
||||
|
||||
// command := []string{
|
||||
// "tailscale",
|
||||
// "debug",
|
||||
// "netmap",
|
||||
// }
|
||||
command := []string{
|
||||
"tailscale",
|
||||
"debug",
|
||||
"netmap",
|
||||
}
|
||||
|
||||
// result, stderr, err := t.Execute(command)
|
||||
// if err != nil {
|
||||
// fmt.Printf("stderr: %s\n", stderr)
|
||||
// return nil, fmt.Errorf("failed to execute tailscale debug netmap command: %w", err)
|
||||
// }
|
||||
result, stderr, err := t.Execute(command)
|
||||
if err != nil {
|
||||
fmt.Printf("stderr: %s\n", stderr)
|
||||
return nil, fmt.Errorf("failed to execute tailscale debug netmap command: %w", err)
|
||||
}
|
||||
|
||||
// var nm netmap.NetworkMap
|
||||
// err = json.Unmarshal([]byte(result), &nm)
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("failed to unmarshal tailscale netmap: %w", err)
|
||||
// }
|
||||
var nm netmap.NetworkMap
|
||||
err = json.Unmarshal([]byte(result), &nm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal tailscale netmap: %w", err)
|
||||
}
|
||||
|
||||
// return &nm, err
|
||||
// }
|
||||
err = os.WriteFile(fmt.Sprintf("/tmp/control/%s_netmap.json", t.hostname), []byte(result), 0o755)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("saving netmap to /tmp/control: %w", err)
|
||||
}
|
||||
|
||||
return &nm, err
|
||||
}
|
||||
|
||||
// Netmap returns the current Netmap (netmap.NetworkMap) of the Tailscale instance.
|
||||
// This implementation is based on getting the netmap from `tailscale debug watch-ipn`
|
||||
// as there seem to be some weirdness omitting endpoint and DERP info if we use
|
||||
// Patch updates.
|
||||
// This implementation works on all supported versions.
|
||||
func (t *TailscaleInContainer) Netmap() (*netmap.NetworkMap, error) {
|
||||
// watch-ipn will only give an update if something is happening,
|
||||
// since we send keep alives, the worst case for this should be
|
||||
// 1 minute, but set a slightly more conservative time.
|
||||
ctx, _ := context.WithTimeout(context.Background(), 3*time.Minute)
|
||||
// func (t *TailscaleInContainer) Netmap() (*netmap.NetworkMap, error) {
|
||||
// // watch-ipn will only give an update if something is happening,
|
||||
// // since we send keep alives, the worst case for this should be
|
||||
// // 1 minute, but set a slightly more conservative time.
|
||||
// ctx, _ := context.WithTimeout(context.Background(), 3*time.Minute)
|
||||
|
||||
notify, err := t.watchIPN(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// notify, err := t.watchIPN(ctx)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
if notify.NetMap == nil {
|
||||
return nil, fmt.Errorf("no netmap present in ipn.Notify")
|
||||
}
|
||||
// if notify.NetMap == nil {
|
||||
// return nil, fmt.Errorf("no netmap present in ipn.Notify")
|
||||
// }
|
||||
|
||||
return notify.NetMap, nil
|
||||
}
|
||||
// return notify.NetMap, nil
|
||||
// }
|
||||
|
||||
// watchIPN watches `tailscale debug watch-ipn` for a ipn.Notify object until
|
||||
// it gets one that has a netmap.NetworkMap.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue