mirror of
https://github.com/tailscale/tailscale.git
synced 2025-07-01 12:38:40 +00:00
89 lines
2.7 KiB
Go
89 lines
2.7 KiB
Go
![]() |
// Copyright (c) Tailscale Inc & AUTHORS
|
||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||
|
|
||
|
//go:build !plan9
|
||
|
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
|
||
|
"tailscale.com/ipn"
|
||
|
"tailscale.com/kube/kubetypes"
|
||
|
"tailscale.com/tailcfg"
|
||
|
"tailscale.com/util/deephash"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
keyPodUID = ipn.StateKey(kubetypes.KeyPodUID)
|
||
|
keyCapVer = ipn.StateKey(kubetypes.KeyCapVer)
|
||
|
keyDeviceID = ipn.StateKey(kubetypes.KeyDeviceID)
|
||
|
keyDeviceIPs = ipn.StateKey(kubetypes.KeyDeviceIPs)
|
||
|
keyDeviceFQDN = ipn.StateKey(kubetypes.KeyDeviceFQDN)
|
||
|
)
|
||
|
|
||
|
func setInitialStateKeys(store ipn.StateStore, podUID string) error {
|
||
|
// Clear device state keys first so the operator knows if the pod UID
|
||
|
// matches, the other values are definitely not stale.
|
||
|
for _, key := range []ipn.StateKey{keyDeviceID, keyDeviceFQDN, keyDeviceIPs} {
|
||
|
if _, err := store.ReadState(key); err == nil {
|
||
|
if err := store.WriteState(key, nil); err != nil {
|
||
|
return fmt.Errorf("error writing %q to state store: %w", key, err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if err := store.WriteState(keyPodUID, []byte(podUID)); err != nil {
|
||
|
return fmt.Errorf("error writing pod UID to state store: %w", err)
|
||
|
}
|
||
|
if err := store.WriteState(keyCapVer, fmt.Appendf(nil, "%d", tailcfg.CurrentCapabilityVersion)); err != nil {
|
||
|
return fmt.Errorf("error writing capability version to state store: %w", err)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// keepStateKeysUpdated sets state store keys consistent with containerboot to
|
||
|
// signal proxy readiness to the operator. It runs until its context is
|
||
|
// cancelled or it hits an error
|
||
|
func keepStateKeysUpdated(store ipn.StateStore, next func() (ipn.Notify, error)) error {
|
||
|
var currentDeviceID, currentDeviceIPs, currentDeviceFQDN deephash.Sum
|
||
|
|
||
|
for {
|
||
|
n, err := next() // Blocks on a streaming LocalAPI HTTP call.
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if n.NetMap == nil {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if deviceID := n.NetMap.SelfNode.StableID(); deephash.Update(¤tDeviceID, &deviceID) {
|
||
|
if err := store.WriteState(keyDeviceID, []byte(deviceID)); err != nil {
|
||
|
return fmt.Errorf("failed to store device ID in state: %w", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if fqdn := n.NetMap.SelfNode.Name(); deephash.Update(¤tDeviceFQDN, &fqdn) {
|
||
|
if err := store.WriteState(keyDeviceFQDN, []byte(fqdn)); err != nil {
|
||
|
return fmt.Errorf("failed to store device FQDN in state: %w", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if addrs := n.NetMap.SelfNode.Addresses(); deephash.Update(¤tDeviceIPs, &addrs) {
|
||
|
var deviceIPs []string
|
||
|
for _, addr := range addrs.AsSlice() {
|
||
|
deviceIPs = append(deviceIPs, addr.Addr().String())
|
||
|
}
|
||
|
deviceIPsValue, err := json.Marshal(deviceIPs)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if err := store.WriteState(keyDeviceIPs, deviceIPsValue); err != nil {
|
||
|
return fmt.Errorf("failed to store device IPs in state: %w", err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|