Repository: moby/moby
File: daemon/libnetwork/endpoint_info.go (Go)

Code before:
	epi.srcName = epMap["srcName"].(string)
	epi.dstPrefix = epMap["dstPrefix"].(string)

	// TODO(cpuguy83): linter noticed we don't check the error here... no idea why but it seems like it could introduce problems if we start checking
	rb, _ := json.Marshal(epMap["routes"]) //nolint:errchkjson // FIXME: handle json (Un)Marshal errors (see above)
	var routes []string
	_ = json.Unmarshal(rb, &routes) //nolint:errcheck

	epi.routes = make([]*net.IPNet, 0)
	for _, route := range routes {
		ip, ipr, err := net.ParseCIDR(route)
		if err == nil {
			ipr.IP = ip
			epi.routes = append(epi.routes, ipr)
		}
	}
	epi.v4PoolID = epMap["v4PoolID"].(string)
	epi.v6PoolID = epMap["v6PoolID"].(string)

	if v, ok := epMap["createdInContainer"]; ok {
		epi.createdInContainer = v.(bool)
	}
	return nil
}

// Copy returns a deep copy of [EndpointInterface]. If the receiver is nil,
// Copy returns nil.
func (epi *EndpointInterface) Copy() *EndpointInterface {
	if epi == nil {
		return nil
	}

	var routes []*net.IPNet
	for _, route := range epi.routes {
		routes = append(routes, types.GetIPNetCopy(route))
	}

	return &EndpointInterface{
		mac:                slices.Clone(epi.mac),
		addr:               types.GetIPNetCopy(epi.addr),
		addrv6:             types.GetIPNetCopy(epi.addrv6),
		llAddrs:            slices.Clone(epi.llAddrs),
		srcName:            epi.srcName,
		dstPrefix:          epi.dstPrefix,
		routes:             routes,
		dstName:            epi.dstName,
		v4PoolID:           epi.v4PoolID,
		v6PoolID:           epi.v6PoolID,
		createdInContainer: epi.createdInContainer,
	}
}

Review comment (suggestion):
Could mention that it only copies fields that are serialised for the datastore (so, not `netnsPath`).

I wonder if it's worth putting inline in `Endpoint.CopyTo`, the only caller - which is there to satisfy the `datastore.KVObject` interface so maybe slightly clearer it's not a general purpose deep copy? (Or, just copy the whole struct?)

Code after:
	epi.srcName = epMap["srcName"].(string)
	epi.dstPrefix = epMap["dstPrefix"].(string)

	// TODO(cpuguy83): linter noticed we don't check the error here... no idea why but it seems like it could introduce problems if we start checking
	rb, _ := json.Marshal(epMap["routes"]) //nolint:errchkjson // FIXME: handle json (Un)Marshal errors (see above)
	var routes []string
	_ = json.Unmarshal(rb, &routes) //nolint:errcheck

	epi.routes = make([]*net.IPNet, 0)
	for _, route := range routes {
		ip, ipr, err := net.ParseCIDR(route)
		if err == nil {
			ipr.IP = ip
			epi.routes = append(epi.routes, ipr)
		}
	}
	epi.v4PoolID = epMap["v4PoolID"].(string)
	epi.v6PoolID = epMap["v6PoolID"].(string)

	if v, ok := epMap["createdInContainer"]; ok {
		epi.createdInContainer = v.(bool)
	}
	return nil
}

// Copy returns a deep copy of [EndpointInterface]. If the receiver is nil,
// Copy returns nil.
func (epi *EndpointInterface) Copy() *EndpointInterface {
	if epi == nil {
		return nil
	}

	var routes []*net.IPNet
	for _, route := range epi.routes {
		routes = append(routes, types.GetIPNetCopy(route))
	}

	return &EndpointInterface{
		mac:                slices.Clone(epi.mac),
		addr:               types.GetIPNetCopy(epi.addr),
		addrv6:             types.GetIPNetCopy(epi.addrv6),
		llAddrs:            slices.Clone(epi.llAddrs),
		srcName:            epi.srcName,
		dstPrefix:          epi.dstPrefix,
		dstName:            epi.dstName,
		routes:             routes,
		v4PoolID:           epi.v4PoolID,
		v6PoolID:           epi.v6PoolID,
		netnsPath:          epi.netnsPath,
		createdInContainer: epi.createdInContainer,
	}