types/ptr: deprecate ptr.To, use Go 1.26 new

Updates #18682

Change-Id: I62f6aa0de2a15ef8c1435032c6aa74a181c25f8f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2026-03-05 22:48:46 +00:00
committed by Brad Fitzpatrick
parent 8cfbaa717d
commit 2a64c03c95
96 changed files with 429 additions and 532 deletions
+3 -4
View File
@@ -14,7 +14,6 @@ import (
"tailscale.com/types/opt"
"tailscale.com/types/persist"
"tailscale.com/types/preftype"
"tailscale.com/types/ptr"
)
// Clone makes a deep copy of LoginProfile.
@@ -62,7 +61,7 @@ func (src *Prefs) Clone() *Prefs {
}
}
if dst.RelayServerPort != nil {
dst.RelayServerPort = ptr.To(*src.RelayServerPort)
dst.RelayServerPort = new(*src.RelayServerPort)
}
dst.RelayServerStaticEndpoints = append(src.RelayServerStaticEndpoints[:0:0], src.RelayServerStaticEndpoints...)
dst.Persist = src.Persist.Clone()
@@ -122,7 +121,7 @@ func (src *ServeConfig) Clone() *ServeConfig {
if v == nil {
dst.TCP[k] = nil
} else {
dst.TCP[k] = ptr.To(*v)
dst.TCP[k] = new(*v)
}
}
}
@@ -184,7 +183,7 @@ func (src *ServiceConfig) Clone() *ServiceConfig {
if v == nil {
dst.TCP[k] = nil
} else {
dst.TCP[k] = ptr.To(*v)
dst.TCP[k] = new(*v)
}
}
}
+7 -8
View File
@@ -81,7 +81,6 @@ import (
"tailscale.com/types/opt"
"tailscale.com/types/persist"
"tailscale.com/types/preftype"
"tailscale.com/types/ptr"
"tailscale.com/types/views"
"tailscale.com/util/checkchange"
"tailscale.com/util/clientmetric"
@@ -1738,7 +1737,7 @@ func (b *LocalBackend) setControlClientStatusLocked(c controlclient.Client, st c
b.logf("Failed to save new controlclient state: %v", err)
}
b.sendToLocked(ipn.Notify{Prefs: ptr.To(prefs.View())}, allClients)
b.sendToLocked(ipn.Notify{Prefs: new(prefs.View())}, allClients)
}
// initTKALocked is dependent on CurrentProfile.ID, which is initialized
@@ -3139,13 +3138,13 @@ func (b *LocalBackend) WatchNotificationsAs(ctx context.Context, actor ipnauth.A
ini = &ipn.Notify{Version: version.Long()}
if mask&ipn.NotifyInitialState != 0 {
ini.SessionID = sessionID
ini.State = ptr.To(b.state)
ini.State = new(b.state)
if b.state == ipn.NeedsLogin && b.authURL != "" {
ini.BrowseToURL = ptr.To(b.authURL)
ini.BrowseToURL = new(b.authURL)
}
}
if mask&ipn.NotifyInitialPrefs != 0 {
ini.Prefs = ptr.To(b.sanitizedPrefsLocked())
ini.Prefs = new(b.sanitizedPrefsLocked())
}
if mask&ipn.NotifyInitialNetMap != 0 {
ini.NetMap = cn.NetMap()
@@ -3397,7 +3396,7 @@ func (b *LocalBackend) sendTo(n ipn.Notify, recipient notificationTarget) {
// sendToLocked is like [LocalBackend.sendTo], but assumes b.mu is already held.
func (b *LocalBackend) sendToLocked(n ipn.Notify, recipient notificationTarget) {
if n.Prefs != nil {
n.Prefs = ptr.To(stripKeysFromPrefs(*n.Prefs))
n.Prefs = new(stripKeysFromPrefs(*n.Prefs))
}
if n.Version == "" {
n.Version = version.Long()
@@ -4415,7 +4414,7 @@ func (b *LocalBackend) changeDisablesExitNodeLocked(prefs ipn.PrefsView, change
// First, apply the adjustments to a copy of the changes,
// e.g., clear AutoExitNode if ExitNodeID is set.
tmpChange := ptr.To(*change)
tmpChange := new(*change)
tmpChange.Prefs = *change.Prefs.Clone()
b.adjustEditPrefsLocked(prefs, tmpChange)
@@ -6185,7 +6184,7 @@ func (b *LocalBackend) resolveExitNodeLocked() (changed bool) {
b.goTracker.Go(b.doSetHostinfoFilterServices)
}
b.sendToLocked(ipn.Notify{Prefs: ptr.To(prefs.View())}, allClients)
b.sendToLocked(ipn.Notify{Prefs: new(prefs.View())}, allClients)
return true
}
+41 -42
View File
@@ -61,7 +61,6 @@ import (
"tailscale.com/types/netmap"
"tailscale.com/types/opt"
"tailscale.com/types/persist"
"tailscale.com/types/ptr"
"tailscale.com/types/views"
"tailscale.com/util/dnsname"
"tailscale.com/util/eventbus"
@@ -877,7 +876,7 @@ func TestConfigureExitNode(t *testing.T) {
Prefs: ipn.Prefs{AutoExitNode: "any"},
AutoExitNodeSet: true,
},
useExitNodeEnabled: ptr.To(false),
useExitNodeEnabled: new(false),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: "",
@@ -894,7 +893,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
useExitNodeEnabled: ptr.To(true),
useExitNodeEnabled: new(true),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: exitNode1.StableID(),
@@ -909,7 +908,7 @@ func TestConfigureExitNode(t *testing.T) {
ControlURL: controlURL,
},
netMap: clientNetmap,
exitNodeIDPolicy: ptr.To(exitNode1.StableID()),
exitNodeIDPolicy: new(exitNode1.StableID()),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: exitNode1.StableID(),
@@ -922,7 +921,7 @@ func TestConfigureExitNode(t *testing.T) {
ControlURL: controlURL,
},
netMap: clientNetmap,
exitNodeIDPolicy: ptr.To(exitNode1.StableID()),
exitNodeIDPolicy: new(exitNode1.StableID()),
changePrefs: &ipn.MaskedPrefs{
Prefs: ipn.Prefs{
ExitNodeID: exitNode2.StableID(), // this should be ignored
@@ -942,7 +941,7 @@ func TestConfigureExitNode(t *testing.T) {
ControlURL: controlURL,
},
netMap: clientNetmap,
exitNodeIDPolicy: ptr.To(exitNode1.StableID()),
exitNodeIDPolicy: new(exitNode1.StableID()),
changePrefs: &ipn.MaskedPrefs{
Prefs: ipn.Prefs{
ExitNodeIP: exitNode2.Addresses().At(0).Addr(), // this should be ignored
@@ -962,7 +961,7 @@ func TestConfigureExitNode(t *testing.T) {
ControlURL: controlURL,
},
netMap: clientNetmap,
exitNodeIDPolicy: ptr.To(exitNode1.StableID()),
exitNodeIDPolicy: new(exitNode1.StableID()),
changePrefs: &ipn.MaskedPrefs{
Prefs: ipn.Prefs{
AutoExitNode: "any", // this should be ignored
@@ -982,7 +981,7 @@ func TestConfigureExitNode(t *testing.T) {
ControlURL: controlURL,
},
netMap: clientNetmap,
exitNodeIPPolicy: ptr.To(exitNode2.Addresses().At(0).Addr()),
exitNodeIPPolicy: new(exitNode2.Addresses().At(0).Addr()),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: exitNode2.StableID(),
@@ -996,7 +995,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: exitNode1.StableID(),
@@ -1011,7 +1010,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: nil,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: unresolvedExitNodeID,
@@ -1026,7 +1025,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: nil,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: unresolvedExitNodeID,
@@ -1042,7 +1041,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: nil,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
exitNodeAllowedIDs: nil, // not configured, so all exit node IDs are implicitly allowed
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
@@ -1059,7 +1058,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: nil,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
exitNodeAllowedIDs: []tailcfg.StableNodeID{
exitNode2.StableID(), // the current exit node ID is allowed
},
@@ -1078,7 +1077,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: nil,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
exitNodeAllowedIDs: []tailcfg.StableNodeID{
exitNode1.StableID(), // a different exit node ID; the current one is not allowed
},
@@ -1097,7 +1096,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
exitNodeAllowedIDs: []tailcfg.StableNodeID{
exitNode2.StableID(), // a different exit node ID; the current one is not allowed
},
@@ -1116,7 +1115,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: exitNode1.StableID(), // switch to the best exit node
@@ -1131,7 +1130,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:foo")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:foo")),
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
ExitNodeID: exitNode1.StableID(), // unknown exit node expressions should work as "any"
@@ -1164,8 +1163,8 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
useExitNodeEnabled: ptr.To(false), // should fail with an error
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
useExitNodeEnabled: new(false), // should fail with an error
wantExitNodeToggleErr: errManagedByPolicy,
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
@@ -1182,7 +1181,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
exitNodeAllowOverride: true, // allow changing the exit node
changePrefs: &ipn.MaskedPrefs{
Prefs: ipn.Prefs{
@@ -1204,7 +1203,7 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
exitNodeAllowOverride: true, // allow changing, but not disabling, the exit node
changePrefs: &ipn.MaskedPrefs{
Prefs: ipn.Prefs{
@@ -1228,9 +1227,9 @@ func TestConfigureExitNode(t *testing.T) {
},
netMap: clientNetmap,
report: report,
exitNodeIDPolicy: ptr.To(tailcfg.StableNodeID("auto:any")),
exitNodeAllowOverride: true, // allow changing, but not disabling, the exit node
useExitNodeEnabled: ptr.To(false), // should fail with an error
exitNodeIDPolicy: new(tailcfg.StableNodeID("auto:any")),
exitNodeAllowOverride: true, // allow changing, but not disabling, the exit node
useExitNodeEnabled: new(false), // should fail with an error
wantExitNodeToggleErr: errManagedByPolicy,
wantPrefs: ipn.Prefs{
ControlURL: controlURL,
@@ -1992,15 +1991,15 @@ func TestUpdateNetmapDelta(t *testing.T) {
},
{
NodeID: 2,
Online: ptr.To(true),
Online: new(true),
},
{
NodeID: 3,
Online: ptr.To(false),
Online: new(false),
},
{
NodeID: 4,
LastSeen: ptr.To(someTime),
LastSeen: new(someTime),
},
},
}, someTime)
@@ -2021,17 +2020,17 @@ func TestUpdateNetmapDelta(t *testing.T) {
{
ID: 2,
Key: makeNodeKeyFromID(2),
Online: ptr.To(true),
Online: new(true),
},
{
ID: 3,
Key: makeNodeKeyFromID(3),
Online: ptr.To(false),
Online: new(false),
},
{
ID: 4,
Key: makeNodeKeyFromID(4),
LastSeen: ptr.To(someTime),
LastSeen: new(someTime),
},
}
for _, want := range wants {
@@ -3149,11 +3148,11 @@ func TestUpdateNetmapDeltaAutoExitNode(t *testing.T) {
muts: []*tailcfg.PeerChange{
{
NodeID: 1,
Online: ptr.To(true),
Online: new(true),
},
{
NodeID: 2,
Online: ptr.To(false), // the selected exit node goes offline
Online: new(false), // the selected exit node goes offline
},
},
exitNodeIDWant: peer1.StableID(),
@@ -3173,11 +3172,11 @@ func TestUpdateNetmapDeltaAutoExitNode(t *testing.T) {
muts: []*tailcfg.PeerChange{
{
NodeID: 1,
Online: ptr.To(false), // a different exit node goes offline
Online: new(false), // a different exit node goes offline
},
{
NodeID: 2,
Online: ptr.To(true),
Online: new(true),
},
},
exitNodeIDWant: peer2.StableID(),
@@ -4326,7 +4325,7 @@ func TestDriveManageShares(t *testing.T) {
b.driveSetSharesLocked(tt.existing)
}
if !tt.disabled {
nm := ptr.To(*b.currentNode().NetMap())
nm := new(*b.currentNode().NetMap())
self := nm.SelfNode.AsStruct()
self.CapMap = tailcfg.NodeCapMap{tailcfg.NodeAttrsTaildriveShare: nil}
nm.SelfNode = self.View()
@@ -4476,7 +4475,7 @@ func makePeer(id tailcfg.NodeID, opts ...peerOptFunc) tailcfg.NodeView {
DiscoKey: makeDiscoKeyFromID(id),
StableID: tailcfg.StableNodeID(fmt.Sprintf("stable%d", id)),
Name: fmt.Sprintf("peer%d", id),
Online: ptr.To(true),
Online: new(true),
MachineAuthorized: true,
HomeDERP: int(id),
}
@@ -6399,13 +6398,13 @@ func TestConfigFileReload(t *testing.T) {
initial: &conffile.Config{
Parsed: ipn.ConfigVAlpha{
Version: "alpha0",
Hostname: ptr.To("initial-host"),
Hostname: new("initial-host"),
},
},
updated: &conffile.Config{
Parsed: ipn.ConfigVAlpha{
Version: "alpha0",
Hostname: ptr.To("updated-host"),
Hostname: new("updated-host"),
},
},
checkFn: func(t *testing.T, b *LocalBackend) {
@@ -7362,28 +7361,28 @@ func TestStripKeysFromPrefs(t *testing.T) {
genNotify := map[string]func() ipn.Notify{
"Notify.Prefs.ж.Persist.PrivateNodeKey": func() ipn.Notify {
return ipn.Notify{
Prefs: ptr.To((&ipn.Prefs{
Prefs: new((&ipn.Prefs{
Persist: &persist.Persist{PrivateNodeKey: key.NewNode()},
}).View()),
}
},
"Notify.Prefs.ж.Persist.OldPrivateNodeKey": func() ipn.Notify {
return ipn.Notify{
Prefs: ptr.To((&ipn.Prefs{
Prefs: new((&ipn.Prefs{
Persist: &persist.Persist{OldPrivateNodeKey: key.NewNode()},
}).View()),
}
},
"Notify.Prefs.ж.Persist.NetworkLockKey": func() ipn.Notify {
return ipn.Notify{
Prefs: ptr.To((&ipn.Prefs{
Prefs: new((&ipn.Prefs{
Persist: &persist.Persist{NetworkLockKey: key.NewNLPrivate()},
}).View()),
}
},
"Notify.Prefs.ж.Persist.AttestationKey": func() ipn.Notify {
return ipn.Notify{
Prefs: ptr.To((&ipn.Prefs{
Prefs: new((&ipn.Prefs{
Persist: &persist.Persist{AttestationKey: new(fakeAttestationKey)},
}).View()),
}
+1 -2
View File
@@ -11,7 +11,6 @@ import (
"time"
"gvisor.dev/gvisor/pkg/tcpip"
"tailscale.com/types/ptr"
)
// TCPHandlerForDst returns a TCP handler for connections to dst, or nil if
@@ -52,7 +51,7 @@ func (b *LocalBackend) TCPHandlerForDst(src, dst netip.AddrPort) (handler func(c
// tell the difference between a long lived connection that is idle
// vs a connection that is dead because the peer has gone away.
// We pick 72h as that is typically sufficient for a long weekend.
opts = append(opts, ptr.To(tcpip.KeepaliveIdleOption(72*time.Hour)))
opts = append(opts, new(tcpip.KeepaliveIdleOption(72*time.Hour)))
return b.handleSSHConn, opts
}
// TODO(will,sonia): allow customizing web client port ?
+1 -2
View File
@@ -24,7 +24,6 @@ import (
"tailscale.com/types/key"
"tailscale.com/types/logger"
"tailscale.com/types/netmap"
"tailscale.com/types/ptr"
"tailscale.com/types/views"
"tailscale.com/util/dnsname"
"tailscale.com/util/eventbus"
@@ -414,7 +413,7 @@ func (nb *nodeBackend) netMapWithPeers() *netmap.NetworkMap {
if nb.netMap == nil {
return nil
}
nm := ptr.To(*nb.netMap) // shallow clone
nm := new(*nb.netMap) // shallow clone
nm.Peers = slicesx.MapValues(nb.peers)
slices.SortFunc(nm.Peers, func(a, b tailcfg.NodeView) int {
return cmp.Compare(a.ID(), b.ID())
+4 -5
View File
@@ -12,7 +12,6 @@ import (
"tailscale.com/tailcfg"
"tailscale.com/tstest"
"tailscale.com/types/netmap"
"tailscale.com/types/ptr"
"tailscale.com/util/eventbus"
)
@@ -146,7 +145,7 @@ func TestNodeBackendReachability(t *testing.T) {
name: "disabled/offline",
cap: false,
peer: tailcfg.Node{
Online: ptr.To(false),
Online: new(false),
},
want: false,
},
@@ -154,7 +153,7 @@ func TestNodeBackendReachability(t *testing.T) {
name: "disabled/online",
cap: false,
peer: tailcfg.Node{
Online: ptr.To(true),
Online: new(true),
},
want: true,
},
@@ -162,7 +161,7 @@ func TestNodeBackendReachability(t *testing.T) {
name: "enabled/offline",
cap: true,
peer: tailcfg.Node{
Online: ptr.To(false),
Online: new(false),
},
want: true,
},
@@ -170,7 +169,7 @@ func TestNodeBackendReachability(t *testing.T) {
name: "enabled/online",
cap: true,
peer: tailcfg.Node{
Online: ptr.To(true),
Online: new(true),
},
want: true,
},
+3 -4
View File
@@ -16,7 +16,6 @@ import (
"tailscale.com/ipn"
"tailscale.com/ipn/lapitest"
"tailscale.com/tsd"
"tailscale.com/types/ptr"
"tailscale.com/util/syspolicy/pkey"
"tailscale.com/util/syspolicy/policytest"
)
@@ -49,7 +48,7 @@ func TestUserConnectDisconnectNonWindows(t *testing.T) {
// And if we send a notification, both users should receive it.
wantErrMessage := "test error"
testNotify := ipn.Notify{ErrMessage: ptr.To(wantErrMessage)}
testNotify := ipn.Notify{ErrMessage: new(wantErrMessage)}
server.Backend().DebugNotify(testNotify)
if n, err := watcherA.Next(); err != nil {
@@ -274,12 +273,12 @@ func TestShutdownViaLocalAPI(t *testing.T) {
},
{
name: "AllowTailscaledRestart/False",
allowTailscaledRestart: ptr.To(false),
allowTailscaledRestart: new(false),
wantErr: errAccessDeniedByPolicy,
},
{
name: "AllowTailscaledRestart/True",
allowTailscaledRestart: ptr.To(true),
allowTailscaledRestart: new(true),
wantErr: nil, // shutdown should be allowed
},
}
+1 -2
View File
@@ -20,7 +20,6 @@ import (
"tailscale.com/tailcfg"
"tailscale.com/tka"
"tailscale.com/types/key"
"tailscale.com/types/ptr"
"tailscale.com/types/views"
"tailscale.com/util/dnsname"
"tailscale.com/version"
@@ -535,7 +534,7 @@ func (sb *StatusBuilder) AddPeer(peer key.NodePublic, st *PeerStatus) {
e.Expired = true
}
if t := st.KeyExpiry; t != nil {
e.KeyExpiry = ptr.To(*t)
e.KeyExpiry = new(*t)
}
if v := st.CapMap; v != nil {
e.CapMap = v
+1 -2
View File
@@ -22,7 +22,6 @@ import (
"tailscale.com/ipn/ipnserver"
"tailscale.com/types/logger"
"tailscale.com/types/logid"
"tailscale.com/types/ptr"
"tailscale.com/util/mak"
"tailscale.com/util/rands"
)
@@ -153,7 +152,7 @@ func (s *Server) MakeTestActor(name string, clientID string) *ipnauth.TestActor
}
// Create a shallow copy of the base actor and assign it the new client ID.
actor := ptr.To(*baseActor)
actor := new(*baseActor)
actor.CID = ipnauth.ClientIDFrom(clientID)
return actor
}
+2 -3
View File
@@ -43,7 +43,6 @@ import (
"tailscale.com/types/key"
"tailscale.com/types/logger"
"tailscale.com/types/logid"
"tailscale.com/types/ptr"
"tailscale.com/util/clientmetric"
"tailscale.com/util/eventbus"
"tailscale.com/util/httpm"
@@ -845,8 +844,8 @@ func InUseOtherUserIPNStream(w http.ResponseWriter, r *http.Request, err error)
}
js, err := json.Marshal(&ipn.Notify{
Version: version.Long(),
State: ptr.To(ipn.InUseOtherUser),
ErrMessage: ptr.To(err.Error()),
State: new(ipn.InUseOtherUser),
ErrMessage: new(err.Error()),
})
if err != nil {
return false