cmd/cloner: support maps with clone ptrs

In order to clone DERPMaps, it was necessary to extend the cloner so that it supports
nested pointers inside of maps which are also cloneable. This also adds cloning for DERPRegions
and DERPNodes because they are on DERPMap's maps.

Signed-off-by: julianknodt <julianknodt@gmail.com>
This commit is contained in:
julianknodt 2021-06-22 22:01:11 -07:00
parent ece138ffc3
commit 0f18801716
3 changed files with 115 additions and 12 deletions

View File

@ -246,7 +246,9 @@ func gen(buf *bytes.Buffer, imports map[string]struct{}, name string, typ *types
writef("\t\tdst.%s[k] = append([]%s{}, src.%s[k]...)", fname, n, fname)
writef("\t}")
} else if containsPointers(ft.Elem()) {
writef("\t\t" + `panic("TODO map value pointers")`)
writef("\tfor k, v := range src.%s {", fname)
writef("\t\tdst.%s[k] = v.Clone()", fname)
writef("\t}")
} else {
writef("\tfor k, v := range src.%s {", fname)
writef("\t\tdst.%s[k] = v", fname)

View File

@ -4,7 +4,7 @@
package tailcfg
//go:generate go run tailscale.com/cmd/cloner --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse --clonefunc=true --output=tailcfg_clone.go
//go:generate go run tailscale.com/cmd/cloner --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode --clonefunc=true --output=tailcfg_clone.go
import (
"encoding/hex"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse; DO NOT EDIT.
// Code generated by tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode; DO NOT EDIT.
package tailcfg
@ -26,7 +26,7 @@ func (src *User) Clone() *User {
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _UserNeedsRegeneration = User(struct {
ID UserID
LoginName string
@ -62,7 +62,7 @@ func (src *Node) Clone() *Node {
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _NodeNeedsRegeneration = Node(struct {
ID NodeID
StableID StableNodeID
@ -105,7 +105,7 @@ func (src *Hostinfo) Clone() *Hostinfo {
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _HostinfoNeedsRegeneration = Hostinfo(struct {
IPNVersion string
FrontendLogID string
@ -142,7 +142,7 @@ func (src *NetInfo) Clone() *NetInfo {
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _NetInfoNeedsRegeneration = NetInfo(struct {
MappingVariesByDestIP opt.Bool
HairPinning opt.Bool
@ -169,7 +169,7 @@ func (src *Login) Clone() *Login {
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _LoginNeedsRegeneration = Login(struct {
_ structs.Incomparable
ID LoginID
@ -210,7 +210,7 @@ func (src *DNSConfig) Clone() *DNSConfig {
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _DNSConfigNeedsRegeneration = DNSConfig(struct {
Resolvers []DNSResolver
Routes map[string][]DNSResolver
@ -236,7 +236,7 @@ func (src *DNSResolver) Clone() *DNSResolver {
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _DNSResolverNeedsRegeneration = DNSResolver(struct {
Addr string
BootstrapResolution []netaddr.IP
@ -255,7 +255,7 @@ func (src *RegisterResponse) Clone() *RegisterResponse {
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _RegisterResponseNeedsRegeneration = RegisterResponse(struct {
User User
Login Login
@ -264,9 +264,83 @@ func (src *RegisterResponse) Clone() *RegisterResponse {
AuthURL string
}{})
// Clone makes a deep copy of DERPRegion.
// The result aliases no memory with the original.
func (src *DERPRegion) Clone() *DERPRegion {
if src == nil {
return nil
}
dst := new(DERPRegion)
*dst = *src
dst.Nodes = make([]*DERPNode, len(src.Nodes))
for i := range dst.Nodes {
dst.Nodes[i] = src.Nodes[i].Clone()
}
return dst
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _DERPRegionNeedsRegeneration = DERPRegion(struct {
RegionID int
RegionCode string
RegionName string
Avoid bool
Nodes []*DERPNode
}{})
// Clone makes a deep copy of DERPMap.
// The result aliases no memory with the original.
func (src *DERPMap) Clone() *DERPMap {
if src == nil {
return nil
}
dst := new(DERPMap)
*dst = *src
if dst.Regions != nil {
dst.Regions = map[int]*DERPRegion{}
for k, v := range src.Regions {
dst.Regions[k] = v.Clone()
}
}
return dst
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _DERPMapNeedsRegeneration = DERPMap(struct {
Regions map[int]*DERPRegion
}{})
// Clone makes a deep copy of DERPNode.
// The result aliases no memory with the original.
func (src *DERPNode) Clone() *DERPNode {
if src == nil {
return nil
}
dst := new(DERPNode)
*dst = *src
return dst
}
// A compilation failure here means this code must be regenerated, with command:
// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode
var _DERPNodeNeedsRegeneration = DERPNode(struct {
Name string
RegionID int
HostName string
CertName string
IPv4 string
IPv6 string
STUNPort int
STUNOnly bool
DERPTestPort int
STUNTestIP string
}{})
// Clone duplicates src into dst and reports whether it succeeded.
// To succeed, <src, dst> must be of types <*T, *T> or <*T, **T>,
// where T is one of User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse.
// where T is one of User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode.
func Clone(dst, src interface{}) bool {
switch src := src.(type) {
case *User:
@ -341,6 +415,33 @@ func Clone(dst, src interface{}) bool {
*dst = src.Clone()
return true
}
case *DERPRegion:
switch dst := dst.(type) {
case *DERPRegion:
*dst = *src.Clone()
return true
case **DERPRegion:
*dst = src.Clone()
return true
}
case *DERPMap:
switch dst := dst.(type) {
case *DERPMap:
*dst = *src.Clone()
return true
case **DERPMap:
*dst = src.Clone()
return true
}
case *DERPNode:
switch dst := dst.(type) {
case *DERPNode:
*dst = *src.Clone()
return true
case **DERPNode:
*dst = src.Clone()
return true
}
}
return false
}