From c5c1d133efae537e124a0800a22158dd9b18e97c Mon Sep 17 00:00:00 2001 From: Albin Kerouanton Date: Sat, 11 May 2024 18:20:02 +0200 Subject: [PATCH] libnet/driverapi: Add ctx to Join Signed-off-by: Albin Kerouanton --- builder/builder-next/executor_linux.go | 2 +- daemon/container_operations.go | 2 +- daemon/start_linux.go | 6 ++- libnetwork/cnmallocator/manager.go | 2 +- libnetwork/default_gateway.go | 2 +- libnetwork/driverapi/driverapi.go | 2 +- libnetwork/drivers/bridge/bridge_linux.go | 8 ++- .../drivers/bridge/bridge_linux_test.go | 10 ++-- .../drivers/bridge/brmanager/brmanager.go | 2 +- .../drivers/bridge/network_linux_test.go | 2 +- .../drivers/bridge/port_mapping_linux_test.go | 4 +- libnetwork/drivers/host/host.go | 2 +- libnetwork/drivers/ipvlan/ipvlan_joinleave.go | 23 +++++--- .../drivers/ipvlan/ivmanager/ivmanager.go | 2 +- .../drivers/macvlan/macvlan_joinleave.go | 19 +++++-- .../drivers/macvlan/mvmanager/mvmanager.go | 2 +- libnetwork/drivers/null/null.go | 2 +- libnetwork/drivers/overlay/joinleave.go | 19 +++++-- libnetwork/drivers/overlay/ov_network.go | 4 +- .../drivers/overlay/ovmanager/ovmanager.go | 2 +- libnetwork/drivers/remote/driver.go | 2 +- libnetwork/drivers/remote/driver_test.go | 2 +- .../windows/overlay/joinleave_windows.go | 13 ++++- libnetwork/drivers/windows/windows.go | 8 ++- libnetwork/endpoint.go | 38 +++++++------ libnetwork/endpoint_unix_test.go | 2 +- libnetwork/libnetwork_internal_test.go | 6 +-- libnetwork/libnetwork_linux_test.go | 40 +++++++------- libnetwork/network.go | 13 +++-- libnetwork/osl/interface_linux.go | 53 ++++++++++++++----- libnetwork/osl/sandbox_linux_test.go | 7 +-- libnetwork/resolver_unix_test.go | 2 +- libnetwork/sandbox.go | 2 +- libnetwork/sandbox_dns_unix.go | 10 ++-- libnetwork/sandbox_dns_windows.go | 2 +- libnetwork/sandbox_linux.go | 19 ++++--- libnetwork/sandbox_store.go | 2 +- libnetwork/sandbox_unix_test.go | 16 +++--- libnetwork/sandbox_windows.go | 8 ++- 39 files changed, 233 insertions(+), 129 deletions(-) diff --git a/builder/builder-next/executor_linux.go b/builder/builder-next/executor_linux.go index 48504c92fe..fae862f8b6 100644 --- a/builder/builder-next/executor_linux.go +++ b/builder/builder-next/executor_linux.go @@ -126,7 +126,7 @@ func (iface *lnInterface) init(c *libnetwork.Controller, n *libnetwork.Network) return } - if err := ep.Join(sbx); err != nil { + if err := ep.Join(context.TODO(), sbx); err != nil { iface.err = err return } diff --git a/daemon/container_operations.go b/daemon/container_operations.go index a08e561d81..bce0269119 100644 --- a/daemon/container_operations.go +++ b/daemon/container_operations.go @@ -797,7 +797,7 @@ func (daemon *Daemon) connectToNetwork(ctx context.Context, cfg *config.Config, return err } - if err := ep.Join(sb, joinOptions...); err != nil { + if err := ep.Join(ctx, sb, joinOptions...); err != nil { return err } diff --git a/daemon/start_linux.go b/daemon/start_linux.go index 72e6b2e48a..fa20dca16d 100644 --- a/daemon/start_linux.go +++ b/daemon/start_linux.go @@ -8,11 +8,15 @@ import ( "github.com/docker/docker/libcontainerd/types" "github.com/docker/docker/oci" specs "github.com/opencontainers/runtime-spec/specs-go" + "go.opentelemetry.io/otel" ) // initializeCreatedTask performs any initialization that needs to be done to // prepare a freshly-created task to be started. func (daemon *Daemon) initializeCreatedTask(ctx context.Context, tsk types.Task, container *container.Container, spec *specs.Spec) error { + ctx, span := otel.Tracer("").Start(ctx, "daemon.initializeCreatedTask") + defer span.End() + if !container.Config.NetworkDisabled { nspath, ok := oci.NamespacePath(spec, specs.NetworkNamespace) if ok && nspath == "" { // the runtime has been instructed to create a new network namespace for tsk. @@ -20,7 +24,7 @@ func (daemon *Daemon) initializeCreatedTask(ctx context.Context, tsk types.Task, if err != nil { return errdefs.System(err) } - return sb.FinishConfig() + return sb.FinishConfig(ctx) } } return nil diff --git a/libnetwork/cnmallocator/manager.go b/libnetwork/cnmallocator/manager.go index 821ec6c35d..a549b4bc77 100644 --- a/libnetwork/cnmallocator/manager.go +++ b/libnetwork/cnmallocator/manager.go @@ -55,7 +55,7 @@ func (d *manager) EndpointOperInfo(nid, eid string) (map[string]interface{}, err return nil, types.NotImplementedErrorf("not implemented") } -func (d *manager) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *manager) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { return types.NotImplementedErrorf("not implemented") } diff --git a/libnetwork/default_gateway.go b/libnetwork/default_gateway.go index ead182e0dd..68abd248d4 100644 --- a/libnetwork/default_gateway.go +++ b/libnetwork/default_gateway.go @@ -85,7 +85,7 @@ func (sb *Sandbox) setupDefaultGW() error { } }() - if err = newEp.sbJoin(sb); err != nil { + if err = newEp.sbJoin(context.TODO(), sb); err != nil { return fmt.Errorf("container %s: endpoint join on GW Network failed: %v", sb.containerID, err) } diff --git a/libnetwork/driverapi/driverapi.go b/libnetwork/driverapi/driverapi.go index aae5c11e61..db5551a137 100644 --- a/libnetwork/driverapi/driverapi.go +++ b/libnetwork/driverapi/driverapi.go @@ -49,7 +49,7 @@ type Driver interface { EndpointOperInfo(nid, eid string) (map[string]interface{}, error) // Join method is invoked when a Sandbox is attached to an endpoint. - Join(nid, eid string, sboxKey string, jinfo JoinInfo, options map[string]interface{}) error + Join(ctx context.Context, nid, eid string, sboxKey string, jinfo JoinInfo, options map[string]interface{}) error // Leave method is invoked when a Sandbox detaches from an endpoint. Leave(nid, eid string) error diff --git a/libnetwork/drivers/bridge/bridge_linux.go b/libnetwork/drivers/bridge/bridge_linux.go index 134bd04d70..0c5bc0bad7 100644 --- a/libnetwork/drivers/bridge/bridge_linux.go +++ b/libnetwork/drivers/bridge/bridge_linux.go @@ -1319,7 +1319,13 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro } // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(ctx context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.drivers.bridge.Join", trace.WithAttributes( + attribute.String("nid", nid), + attribute.String("eid", eid), + attribute.String("sboxKey", sboxKey))) + defer span.End() + network, err := d.getNetwork(nid) if err != nil { return err diff --git a/libnetwork/drivers/bridge/bridge_linux_test.go b/libnetwork/drivers/bridge/bridge_linux_test.go index 5edbdb0607..b64a8cbe94 100644 --- a/libnetwork/drivers/bridge/bridge_linux_test.go +++ b/libnetwork/drivers/bridge/bridge_linux_test.go @@ -706,7 +706,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) { t.Fatalf("Failed to create an endpoint : %s", err.Error()) } - err = d.Join("net1", "ep1", "sbox", te, sbOptions) + err = d.Join(context.Background(), "net1", "ep1", "sbox", te, sbOptions) if err != nil { t.Fatalf("Failed to join the endpoint: %v", err) } @@ -809,7 +809,7 @@ func TestLinkContainers(t *testing.T) { sbOptions := make(map[string]interface{}) sbOptions[netlabel.ExposedPorts] = exposedPorts - err = d.Join("net1", "ep1", "sbox", te1, sbOptions) + err = d.Join(context.Background(), "net1", "ep1", "sbox", te1, sbOptions) if err != nil { t.Fatalf("Failed to join the endpoint: %v", err) } @@ -840,7 +840,7 @@ func TestLinkContainers(t *testing.T) { "ChildEndpoints": []string{"ep1"}, } - err = d.Join("net1", "ep2", "", te2, sbOptions) + err = d.Join(context.Background(), "net1", "ep2", "", te2, sbOptions) if err != nil { t.Fatal("Failed to link ep1 and ep2") } @@ -898,7 +898,7 @@ func TestLinkContainers(t *testing.T) { "ChildEndpoints": []string{"ep1", "ep4"}, } - err = d.Join("net1", "ep2", "", te2, sbOptions) + err = d.Join(context.Background(), "net1", "ep2", "", te2, sbOptions) if err != nil { t.Fatal(err) } @@ -1113,7 +1113,7 @@ func TestSetDefaultGw(t *testing.T) { t.Fatalf("Failed to create endpoint: %v", err) } - err = d.Join("dummy", "ep", "sbox", te, nil) + err = d.Join(context.Background(), "dummy", "ep", "sbox", te, nil) if err != nil { t.Fatalf("Failed to join endpoint: %v", err) } diff --git a/libnetwork/drivers/bridge/brmanager/brmanager.go b/libnetwork/drivers/bridge/brmanager/brmanager.go index 9398fbea90..d18040c266 100644 --- a/libnetwork/drivers/bridge/brmanager/brmanager.go +++ b/libnetwork/drivers/bridge/brmanager/brmanager.go @@ -55,7 +55,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro return nil, types.NotImplementedErrorf("not implemented") } -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { return types.NotImplementedErrorf("not implemented") } diff --git a/libnetwork/drivers/bridge/network_linux_test.go b/libnetwork/drivers/bridge/network_linux_test.go index 17adddf183..e5827ebb81 100644 --- a/libnetwork/drivers/bridge/network_linux_test.go +++ b/libnetwork/drivers/bridge/network_linux_test.go @@ -49,7 +49,7 @@ func TestLinkCreate(t *testing.T) { t.Fatalf("Failed to create a link: %s", err.Error()) } - err = d.Join("dummy", "ep", "sbox", te, nil) + err = d.Join(context.Background(), "dummy", "ep", "sbox", te, nil) if err != nil { t.Fatalf("Failed to create a link: %s", err.Error()) } diff --git a/libnetwork/drivers/bridge/port_mapping_linux_test.go b/libnetwork/drivers/bridge/port_mapping_linux_test.go index 82b1b8cb52..534c8cdeb2 100644 --- a/libnetwork/drivers/bridge/port_mapping_linux_test.go +++ b/libnetwork/drivers/bridge/port_mapping_linux_test.go @@ -58,7 +58,7 @@ func TestPortMappingConfig(t *testing.T) { t.Fatalf("Failed to create the endpoint: %s", err.Error()) } - if err = d.Join("dummy", "ep1", "sbox", te, sbOptions); err != nil { + if err = d.Join(context.Background(), "dummy", "ep1", "sbox", te, sbOptions); err != nil { t.Fatalf("Failed to join the endpoint: %v", err) } @@ -143,7 +143,7 @@ func TestPortMappingV6Config(t *testing.T) { t.Fatalf("Failed to create the endpoint: %s", err.Error()) } - if err = d.Join("dummy", "ep1", "sbox", te, sbOptions); err != nil { + if err = d.Join(context.Background(), "dummy", "ep1", "sbox", te, sbOptions); err != nil { t.Fatalf("Failed to join the endpoint: %v", err) } diff --git a/libnetwork/drivers/host/host.go b/libnetwork/drivers/host/host.go index 8fabc95e52..7433a61260 100644 --- a/libnetwork/drivers/host/host.go +++ b/libnetwork/drivers/host/host.go @@ -68,7 +68,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro } // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { return nil } diff --git a/libnetwork/drivers/ipvlan/ipvlan_joinleave.go b/libnetwork/drivers/ipvlan/ipvlan_joinleave.go index 59e27bbbf5..4414d99626 100644 --- a/libnetwork/drivers/ipvlan/ipvlan_joinleave.go +++ b/libnetwork/drivers/ipvlan/ipvlan_joinleave.go @@ -12,6 +12,9 @@ import ( "github.com/docker/docker/libnetwork/netutils" "github.com/docker/docker/libnetwork/ns" "github.com/docker/docker/libnetwork/types" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type staticRoute struct { @@ -26,7 +29,13 @@ const ( ) // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(ctx context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.drivers.ipvlan.Join", trace.WithAttributes( + attribute.String("nid", nid), + attribute.String("eid", eid), + attribute.String("sboxKey", sboxKey))) + defer span.End() + n, err := d.getNetwork(nid) if err != nil { return err @@ -63,7 +72,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, if err := jinfo.AddStaticRoute(defaultRoute.Destination, defaultRoute.RouteType, defaultRoute.NextHop); err != nil { return fmt.Errorf("failed to set an ipvlan l3/l3s mode ipv4 default gateway: %v", err) } - log.G(context.TODO()).Debugf("Ipvlan Endpoint Joined with IPv4_Addr: %s, Ipvlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Ipvlan Endpoint Joined with IPv4_Addr: %s, Ipvlan_Mode: %s, Parent: %s", ep.addr.IP.String(), n.config.IpvlanMode, n.config.Parent) // If the endpoint has a v6 address, set a v6 default route if ep.addrv6 != nil { @@ -74,7 +83,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, if err = jinfo.AddStaticRoute(default6Route.Destination, default6Route.RouteType, default6Route.NextHop); err != nil { return fmt.Errorf("failed to set an ipvlan l3/l3s mode ipv6 default gateway: %v", err) } - log.G(context.TODO()).Debugf("Ipvlan Endpoint Joined with IPv6_Addr: %s, Ipvlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Ipvlan Endpoint Joined with IPv6_Addr: %s, Ipvlan_Mode: %s, Parent: %s", ep.addrv6.IP.String(), n.config.IpvlanMode, n.config.Parent) } case modeL2: @@ -92,7 +101,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, if err != nil { return err } - log.G(context.TODO()).Debugf("Ipvlan Endpoint Joined with IPv4_Addr: %s, Gateway: %s, Ipvlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Ipvlan Endpoint Joined with IPv4_Addr: %s, Gateway: %s, Ipvlan_Mode: %s, Parent: %s", ep.addr.IP.String(), v4gw.String(), n.config.IpvlanMode, n.config.Parent) } // parse and correlate the endpoint v6 address with the available v6 subnets @@ -109,17 +118,17 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, if err != nil { return err } - log.G(context.TODO()).Debugf("Ipvlan Endpoint Joined with IPv6_Addr: %s, Gateway: %s, Ipvlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Ipvlan Endpoint Joined with IPv6_Addr: %s, Gateway: %s, Ipvlan_Mode: %s, Parent: %s", ep.addrv6.IP.String(), v6gw.String(), n.config.IpvlanMode, n.config.Parent) } } } else { if len(n.config.Ipv4Subnets) > 0 { - log.G(context.TODO()).Debugf("Ipvlan Endpoint Joined with IPv4_Addr: %s, IpVlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Ipvlan Endpoint Joined with IPv4_Addr: %s, IpVlan_Mode: %s, Parent: %s", ep.addr.IP.String(), n.config.IpvlanMode, n.config.Parent) } if len(n.config.Ipv6Subnets) > 0 { - log.G(context.TODO()).Debugf("Ipvlan Endpoint Joined with IPv6_Addr: %s IpVlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Ipvlan Endpoint Joined with IPv6_Addr: %s IpVlan_Mode: %s, Parent: %s", ep.addrv6.IP.String(), n.config.IpvlanMode, n.config.Parent) } // If n.config.Internal was set locally by the driver because there's no parent diff --git a/libnetwork/drivers/ipvlan/ivmanager/ivmanager.go b/libnetwork/drivers/ipvlan/ivmanager/ivmanager.go index dbdafeb40a..19796c38bf 100644 --- a/libnetwork/drivers/ipvlan/ivmanager/ivmanager.go +++ b/libnetwork/drivers/ipvlan/ivmanager/ivmanager.go @@ -55,7 +55,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro return nil, types.NotImplementedErrorf("not implemented") } -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { return types.NotImplementedErrorf("not implemented") } diff --git a/libnetwork/drivers/macvlan/macvlan_joinleave.go b/libnetwork/drivers/macvlan/macvlan_joinleave.go index 95a35bbe03..8f60133914 100644 --- a/libnetwork/drivers/macvlan/macvlan_joinleave.go +++ b/libnetwork/drivers/macvlan/macvlan_joinleave.go @@ -11,10 +11,19 @@ import ( "github.com/docker/docker/libnetwork/driverapi" "github.com/docker/docker/libnetwork/netutils" "github.com/docker/docker/libnetwork/ns" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(ctx context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.drivers.macvlan.Join", trace.WithAttributes( + attribute.String("nid", nid), + attribute.String("eid", eid), + attribute.String("sboxKey", sboxKey))) + defer span.End() + n, err := d.getNetwork(nid) if err != nil { return err @@ -54,7 +63,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, if err != nil { return err } - log.G(context.TODO()).Debugf("Macvlan Endpoint Joined with IPv4_Addr: %s, Gateway: %s, MacVlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Macvlan Endpoint Joined with IPv4_Addr: %s, Gateway: %s, MacVlan_Mode: %s, Parent: %s", ep.addr.IP.String(), v4gw.String(), n.config.MacvlanMode, n.config.Parent) } // parse and match the endpoint address with the available v6 subnets @@ -71,16 +80,16 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, if err != nil { return err } - log.G(context.TODO()).Debugf("Macvlan Endpoint Joined with IPv6_Addr: %s Gateway: %s MacVlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Macvlan Endpoint Joined with IPv6_Addr: %s Gateway: %s MacVlan_Mode: %s, Parent: %s", ep.addrv6.IP.String(), v6gw.String(), n.config.MacvlanMode, n.config.Parent) } } else { if len(n.config.Ipv4Subnets) > 0 { - log.G(context.TODO()).Debugf("Macvlan Endpoint Joined with IPv4_Addr: %s, MacVlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Macvlan Endpoint Joined with IPv4_Addr: %s, MacVlan_Mode: %s, Parent: %s", ep.addr.IP.String(), n.config.MacvlanMode, n.config.Parent) } if len(n.config.Ipv6Subnets) > 0 { - log.G(context.TODO()).Debugf("Macvlan Endpoint Joined with IPv6_Addr: %s MacVlan_Mode: %s, Parent: %s", + log.G(ctx).Debugf("Macvlan Endpoint Joined with IPv6_Addr: %s MacVlan_Mode: %s, Parent: %s", ep.addrv6.IP.String(), n.config.MacvlanMode, n.config.Parent) } // If n.config.Internal was set locally by the driver because there's no parent diff --git a/libnetwork/drivers/macvlan/mvmanager/mvmanager.go b/libnetwork/drivers/macvlan/mvmanager/mvmanager.go index 2b7ee8f043..3fbf0e92ca 100644 --- a/libnetwork/drivers/macvlan/mvmanager/mvmanager.go +++ b/libnetwork/drivers/macvlan/mvmanager/mvmanager.go @@ -55,7 +55,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro return nil, types.NotImplementedErrorf("not implemented") } -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { return types.NotImplementedErrorf("not implemented") } diff --git a/libnetwork/drivers/null/null.go b/libnetwork/drivers/null/null.go index 9f2e53d577..f4563d4a68 100644 --- a/libnetwork/drivers/null/null.go +++ b/libnetwork/drivers/null/null.go @@ -68,7 +68,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro } // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { return nil } diff --git a/libnetwork/drivers/overlay/joinleave.go b/libnetwork/drivers/overlay/joinleave.go index 3f56918f1e..8ac77f351f 100644 --- a/libnetwork/drivers/overlay/joinleave.go +++ b/libnetwork/drivers/overlay/joinleave.go @@ -14,10 +14,19 @@ import ( "github.com/docker/docker/libnetwork/osl" "github.com/docker/docker/libnetwork/types" "github.com/gogo/protobuf/proto" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(ctx context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.drivers.overlay.Join", trace.WithAttributes( + attribute.String("nid", nid), + attribute.String("eid", eid), + attribute.String("sboxKey", sboxKey))) + defer span.End() + if err := validateID(nid, eid); err != nil { return err } @@ -74,7 +83,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, return err } - if err = sbox.AddInterface(overlayIfName, "veth", osl.WithMaster(s.brName)); err != nil { + if err = sbox.AddInterface(ctx, overlayIfName, "veth", osl.WithMaster(s.brName)); err != nil { return fmt.Errorf("could not add veth pair inside the network sandbox: %v", err) } @@ -96,7 +105,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, continue } if err = jinfo.AddStaticRoute(sub.subnetIP, types.NEXTHOP, s.gwIP.IP); err != nil { - log.G(context.TODO()).Errorf("Adding subnet %s static route in network %q failed\n", s.subnetIP, n.id) + log.G(ctx).Errorf("Adding subnet %s static route in network %q failed\n", s.subnetIP, n.id) } } @@ -110,7 +119,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, d.peerAdd(nid, eid, ep.addr.IP, ep.addr.Mask, ep.mac, d.advertiseAddress, true) if err = d.checkEncryption(nid, nil, true, true); err != nil { - log.G(context.TODO()).Warn(err) + log.G(ctx).Warn(err) } buf, err := proto.Marshal(&PeerRecord{ @@ -123,7 +132,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, } if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil { - log.G(context.TODO()).Errorf("overlay: Failed adding table entry to joininfo: %v", err) + log.G(ctx).Errorf("overlay: Failed adding table entry to joininfo: %v", err) } return nil diff --git a/libnetwork/drivers/overlay/ov_network.go b/libnetwork/drivers/overlay/ov_network.go index 6dcf3ec37c..9ba9f62510 100644 --- a/libnetwork/drivers/overlay/ov_network.go +++ b/libnetwork/drivers/overlay/ov_network.go @@ -426,7 +426,7 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error // create a bridge and vxlan device for this subnet and move it to the sandbox sbox := n.sbox - if err := sbox.AddInterface(brName, "br", osl.WithIPv4Address(s.gwIP), osl.WithIsBridge(true)); err != nil { + if err := sbox.AddInterface(context.TODO(), brName, "br", osl.WithIPv4Address(s.gwIP), osl.WithIsBridge(true)); err != nil { return fmt.Errorf("bridge creation in sandbox failed for subnet %q: %v", s.subnetIP.String(), err) } @@ -438,7 +438,7 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error return err } - if err := sbox.AddInterface(vxlanName, "vxlan", osl.WithMaster(brName)); err != nil { + if err := sbox.AddInterface(context.TODO(), vxlanName, "vxlan", osl.WithMaster(brName)); err != nil { // If adding vxlan device to the overlay namespace fails, remove the bridge interface we // already added to the namespace. This allows the caller to try the setup again. for _, iface := range sbox.Interfaces() { diff --git a/libnetwork/drivers/overlay/ovmanager/ovmanager.go b/libnetwork/drivers/overlay/ovmanager/ovmanager.go index 4e3682d9d2..ddb6366adb 100644 --- a/libnetwork/drivers/overlay/ovmanager/ovmanager.go +++ b/libnetwork/drivers/overlay/ovmanager/ovmanager.go @@ -190,7 +190,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro } // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { return types.NotImplementedErrorf("not implemented") } diff --git a/libnetwork/drivers/remote/driver.go b/libnetwork/drivers/remote/driver.go index 91003e018b..6a4ff96255 100644 --- a/libnetwork/drivers/remote/driver.go +++ b/libnetwork/drivers/remote/driver.go @@ -258,7 +258,7 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro } // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) (retErr error) { +func (d *driver) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) (retErr error) { join := &api.JoinRequest{ NetworkID: nid, EndpointID: eid, diff --git a/libnetwork/drivers/remote/driver_test.go b/libnetwork/drivers/remote/driver_test.go index 1e4bf26434..e822734770 100644 --- a/libnetwork/drivers/remote/driver_test.go +++ b/libnetwork/drivers/remote/driver_test.go @@ -452,7 +452,7 @@ func TestRemoteDriver(t *testing.T) { } joinOpts := map[string]interface{}{"foo": "fooValue"} - err = d.Join(netID, endID, "sandbox-key", ep, joinOpts) + err = d.Join(context.Background(), netID, endID, "sandbox-key", ep, joinOpts) if err != nil { t.Fatal(err) } diff --git a/libnetwork/drivers/windows/overlay/joinleave_windows.go b/libnetwork/drivers/windows/overlay/joinleave_windows.go index 406824a46e..e378bc8406 100644 --- a/libnetwork/drivers/windows/overlay/joinleave_windows.go +++ b/libnetwork/drivers/windows/overlay/joinleave_windows.go @@ -9,10 +9,19 @@ import ( "github.com/docker/docker/libnetwork/driverapi" "github.com/docker/docker/libnetwork/types" "github.com/gogo/protobuf/proto" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(ctx context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.drivers.windows_overlay.Join", trace.WithAttributes( + attribute.String("nid", nid), + attribute.String("eid", eid), + attribute.String("sboxKey", sboxKey))) + defer span.End() + if err := validateID(nid, eid); err != nil { return err } @@ -37,7 +46,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, } if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil { - log.G(context.TODO()).Errorf("overlay: Failed adding table entry to joininfo: %v", err) + log.G(ctx).Errorf("overlay: Failed adding table entry to joininfo: %v", err) } if ep.disablegateway { diff --git a/libnetwork/drivers/windows/windows.go b/libnetwork/drivers/windows/windows.go index e2a94c3a3b..6dff5e983b 100644 --- a/libnetwork/drivers/windows/windows.go +++ b/libnetwork/drivers/windows/windows.go @@ -835,7 +835,13 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro } // Join method is invoked when a Sandbox is attached to an endpoint. -func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (d *driver) Join(ctx context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { + ctx, span := otel.Tracer("").Start(ctx, fmt.Sprintf("libnetwork.drivers.windows_%s.Join", d.name), trace.WithAttributes( + attribute.String("nid", nid), + attribute.String("eid", eid), + attribute.String("sboxKey", sboxKey))) + defer span.End() + network, err := d.getNetwork(nid) if err != nil { return err diff --git a/libnetwork/endpoint.go b/libnetwork/endpoint.go index 35bfa3e2d2..20e08cfe8d 100644 --- a/libnetwork/endpoint.go +++ b/libnetwork/endpoint.go @@ -20,6 +20,7 @@ import ( "github.com/docker/docker/libnetwork/options" "github.com/docker/docker/libnetwork/scope" "github.com/docker/docker/libnetwork/types" + "go.opentelemetry.io/otel" ) // ByNetworkType sorts a [Endpoint] slice based on the network-type @@ -469,7 +470,7 @@ func (ep *Endpoint) getNetworkFromStore() (*Network, error) { // Join joins the sandbox to the endpoint and populates into the sandbox // the network resources allocated for the endpoint. -func (ep *Endpoint) Join(sb *Sandbox, options ...EndpointOption) error { +func (ep *Endpoint) Join(ctx context.Context, sb *Sandbox, options ...EndpointOption) error { if sb == nil || sb.ID() == "" || sb.Key() == "" { return types.InvalidParameterErrorf("invalid Sandbox passed to endpoint join: %v", sb) } @@ -477,10 +478,13 @@ func (ep *Endpoint) Join(sb *Sandbox, options ...EndpointOption) error { sb.joinLeaveStart() defer sb.joinLeaveEnd() - return ep.sbJoin(sb, options...) + return ep.sbJoin(ctx, sb, options...) } -func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) { +func (ep *Endpoint) sbJoin(ctx context.Context, sb *Sandbox, options ...EndpointOption) (err error) { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.sbJoin") + defer span.End() + n, err := ep.getNetworkFromStore() if err != nil { return fmt.Errorf("failed to get network from store during join: %v", err) @@ -518,25 +522,25 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) { return fmt.Errorf("failed to get driver during join: %v", err) } - err = d.Join(nid, epid, sb.Key(), ep, sb.Labels()) + err = d.Join(ctx, nid, epid, sb.Key(), ep, sb.Labels()) if err != nil { return err } defer func() { if err != nil { if e := d.Leave(nid, epid); e != nil { - log.G(context.TODO()).Warnf("driver leave failed while rolling back join: %v", e) + log.G(ctx).Warnf("driver leave failed while rolling back join: %v", e) } } }() if !n.getController().isAgent() { if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() { - n.updateSvcRecord(ep, true) + n.updateSvcRecord(context.WithoutCancel(ctx), ep, true) } } - if err := sb.updateHostsFile(ep.getEtcHostsAddrs()); err != nil { + if err := sb.updateHostsFile(ctx, ep.getEtcHostsAddrs()); err != nil { return err } @@ -550,11 +554,11 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) { } }() - if err = sb.populateNetworkResources(ep); err != nil { + if err = sb.populateNetworkResources(ctx, ep); err != nil { return err } - if err = addEpToResolver(context.TODO(), n.Name(), ep.Name(), &sb.config, ep.iface, n.Resolvers()); err != nil { + if err = addEpToResolver(ctx, n.Name(), ep.Name(), &sb.config, ep.iface, n.Resolvers()); err != nil { return errdefs.System(err) } @@ -569,7 +573,7 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) { defer func() { if err != nil { if e := ep.deleteDriverInfoFromCluster(); e != nil { - log.G(context.TODO()).Errorf("Could not delete endpoint state for endpoint %s from cluster on join failure: %v", ep.Name(), e) + log.G(ctx).Errorf("Could not delete endpoint state for endpoint %s from cluster on join failure: %v", ep.Name(), e) } } }() @@ -593,7 +597,7 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) { moveExtConn := currentExtEp != extEp if moveExtConn { if extEp != nil { - log.G(context.TODO()).Debugf("Revoking external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID()) + log.G(ctx).Debugf("Revoking external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID()) extN, err := extEp.getNetworkFromStore() if err != nil { return fmt.Errorf("failed to get network from store for revoking external connectivity during join: %v", err) @@ -610,14 +614,14 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) { defer func() { if err != nil { if e := extD.ProgramExternalConnectivity(extEp.network.ID(), extEp.ID(), sb.Labels()); e != nil { - log.G(context.TODO()).Warnf("Failed to roll-back external connectivity on endpoint %s (%s): %v", + log.G(ctx).Warnf("Failed to roll-back external connectivity on endpoint %s (%s): %v", extEp.Name(), extEp.ID(), e) } } }() } if !n.internal { - log.G(context.TODO()).Debugf("Programming external connectivity on endpoint %s (%s)", ep.Name(), ep.ID()) + log.G(ctx).Debugf("Programming external connectivity on endpoint %s (%s)", ep.Name(), ep.ID()) if err = d.ProgramExternalConnectivity(n.ID(), ep.ID(), sb.Labels()); err != nil { return types.InternalErrorf( "driver failed programming external connectivity on endpoint %s (%s): %v", @@ -628,7 +632,7 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) { if !sb.needDefaultGW() { if e := sb.clearDefaultGW(); e != nil { - log.G(context.TODO()).Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v", + log.G(ctx).Warnf("Failure while disconnecting sandbox %s (%s) from gateway network: %v", sb.ID(), sb.ContainerID(), e) } } @@ -671,10 +675,10 @@ func (ep *Endpoint) UpdateDNSNames(dnsNames []string) error { return types.InternalErrorf("could not add service state for endpoint %s to cluster on UpdateDNSNames: %v", ep.Name(), err) } } else { - nw.updateSvcRecord(ep, false) + nw.updateSvcRecord(context.WithoutCancel(context.TODO()), ep, false) ep.dnsNames = dnsNames - nw.updateSvcRecord(ep, true) + nw.updateSvcRecord(context.WithoutCancel(context.TODO()), ep, true) } // Update the store with the updated name @@ -863,7 +867,7 @@ func (ep *Endpoint) Delete(force bool) error { }() if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() { - n.updateSvcRecord(ep, false) + n.updateSvcRecord(context.WithoutCancel(context.TODO()), ep, false) } if err = ep.deleteEndpoint(force); err != nil && !force { diff --git a/libnetwork/endpoint_unix_test.go b/libnetwork/endpoint_unix_test.go index 5f19b77f2b..1017d3977d 100644 --- a/libnetwork/endpoint_unix_test.go +++ b/libnetwork/endpoint_unix_test.go @@ -48,7 +48,7 @@ fe90::2 somehost.example.com somehost t.Fatal(err) } - if err := ep1.Join(sbx, JoinOptionPriority(1)); err != nil { + if err := ep1.Join(context.Background(), sbx, JoinOptionPriority(1)); err != nil { t.Fatal(err) } diff --git a/libnetwork/libnetwork_internal_test.go b/libnetwork/libnetwork_internal_test.go index be07e6dd3a..67f8374f9d 100644 --- a/libnetwork/libnetwork_internal_test.go +++ b/libnetwork/libnetwork_internal_test.go @@ -387,7 +387,7 @@ func TestSRVServiceQuery(t *testing.T) { } }() - err = ep.Join(sb) + err = ep.Join(context.Background(), sb) if err != nil { t.Fatal(err) } @@ -486,7 +486,7 @@ func TestServiceVIPReuse(t *testing.T) { } }() - err = ep.Join(sb) + err = ep.Join(context.Background(), sb) if err != nil { t.Fatal(err) } @@ -673,7 +673,7 @@ func (b *badDriver) EndpointOperInfo(nid, eid string) (map[string]interface{}, e return nil, nil } -func (b *badDriver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { +func (b *badDriver) Join(_ context.Context, nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { return fmt.Errorf("I will not allow any join") } diff --git a/libnetwork/libnetwork_linux_test.go b/libnetwork/libnetwork_linux_test.go index 31bbaafc8d..aaf09e5e5a 100644 --- a/libnetwork/libnetwork_linux_test.go +++ b/libnetwork/libnetwork_linux_test.go @@ -115,7 +115,7 @@ func TestNull(t *testing.T) { t.Fatal(err) } - err = ep.Join(cnt) + err = ep.Join(context.Background(), cnt) if err != nil { t.Fatal(err) } @@ -888,7 +888,7 @@ func TestEndpointDeleteWithActiveContainer(t *testing.T) { } }() - err = ep.Join(cnt) + err = ep.Join(context.Background(), cnt) if err != nil { t.Fatal(err) } @@ -961,7 +961,7 @@ func TestEndpointMultipleJoins(t *testing.T) { } }() - err = ep.Join(sbx1) + err = ep.Join(context.Background(), sbx1) if err != nil { t.Fatal(err) } @@ -972,7 +972,7 @@ func TestEndpointMultipleJoins(t *testing.T) { } }() - err = ep.Join(sbx2) + err = ep.Join(context.Background(), sbx2) if err == nil { t.Fatal("Expected to fail multiple joins for the same endpoint") } @@ -1030,12 +1030,12 @@ func TestLeaveAll(t *testing.T) { t.Fatal(err) } - err = ep1.Join(cnt) + err = ep1.Join(context.Background(), cnt) if err != nil { t.Fatalf("Failed to join ep1: %v", err) } - err = ep2.Join(cnt) + err = ep2.Join(context.Background(), cnt) if err != nil { t.Fatalf("Failed to join ep2: %v", err) } @@ -1166,12 +1166,12 @@ func TestEndpointUpdateParent(t *testing.T) { } }() - err = ep1.Join(sbx1) + err = ep1.Join(context.Background(), sbx1) if err != nil { t.Fatal(err) } - err = ep2.Join(sbx2) + err = ep2.Join(context.Background(), sbx2) if err != nil { t.Fatal(err) } @@ -1344,7 +1344,7 @@ func TestHost(t *testing.T) { t.Fatal(err) } - if err := ep1.Join(sbx1); err != nil { + if err := ep1.Join(context.Background(), sbx1); err != nil { t.Fatal(err) } @@ -1353,7 +1353,7 @@ func TestHost(t *testing.T) { t.Fatal(err) } - if err := ep2.Join(sbx2); err != nil { + if err := ep2.Join(context.Background(), sbx2); err != nil { t.Fatal(err) } @@ -1393,7 +1393,7 @@ func TestHost(t *testing.T) { t.Fatal(err) } - if err := ep3.Join(sbx2); err != nil { + if err := ep3.Join(context.Background(), sbx2); err != nil { t.Fatal(err) } @@ -1541,7 +1541,7 @@ func TestEndpointJoin(t *testing.T) { } // test invalid joins - err = ep1.Join(nil) + err = ep1.Join(context.Background(), nil) if err == nil { t.Fatalf("Expected to fail join with nil Sandbox") } @@ -1550,7 +1550,7 @@ func TestEndpointJoin(t *testing.T) { } fsbx := &libnetwork.Sandbox{} - if err = ep1.Join(fsbx); err == nil { + if err = ep1.Join(context.Background(), fsbx); err == nil { t.Fatalf("Expected to fail join with invalid Sandbox") } if _, ok := err.(types.InvalidParameterError); !ok { @@ -1571,7 +1571,7 @@ func TestEndpointJoin(t *testing.T) { } }() - err = ep1.Join(sb) + err = ep1.Join(context.Background(), sb) if err != nil { t.Fatal(err) } @@ -1635,7 +1635,7 @@ func TestEndpointJoin(t *testing.T) { } }() - err = ep2.Join(sb) + err = ep2.Join(context.Background(), sb) if err != nil { t.Fatal(err) } @@ -1724,7 +1724,7 @@ func externalKeyTest(t *testing.T, reexec bool) { }() // Join endpoint to sandbox before SetKey - err = ep.Join(cnt) + err = ep.Join(context.Background(), cnt) if err != nil { t.Fatal(err) } @@ -1775,7 +1775,7 @@ func externalKeyTest(t *testing.T, reexec bool) { } // Join endpoint to sandbox after SetKey - err = ep2.Join(sbox) + err = ep2.Join(context.Background(), sbox) if err != nil { t.Fatal(err) } @@ -1887,7 +1887,7 @@ func TestResolvConf(t *testing.T) { assert.Check(t, err) }() - err = ep.Join(sb) + err = ep.Join(context.Background(), sb) assert.NilError(t, err) defer func() { err := ep.Leave(sb) @@ -1942,7 +1942,7 @@ func (pt parallelTester) Do(t *testing.T, thrNumber int) error { } for i := 0; i < pt.iterCnt; i++ { - if err := ep.Join(sb); err != nil { + if err := ep.Join(context.Background(), sb); err != nil { if _, ok := err.(types.ForbiddenError); !ok { return errors.Wrapf(err, "thread %d", thrNumber) } @@ -2069,7 +2069,7 @@ func TestBridge(t *testing.T) { } }() - err = ep.Join(sb) + err = ep.Join(context.Background(), sb) if err != nil { t.Fatal(err) } diff --git a/libnetwork/network.go b/libnetwork/network.go index a0acab2850..36a71ce53b 100644 --- a/libnetwork/network.go +++ b/libnetwork/network.go @@ -1227,10 +1227,10 @@ func (n *Network) createEndpoint(ctx context.Context, name string, options ...En } if !n.getController().isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() { - n.updateSvcRecord(ep, true) + n.updateSvcRecord(context.WithoutCancel(ctx), ep, true) defer func() { if err != nil { - n.updateSvcRecord(ep, false) + n.updateSvcRecord(context.WithoutCancel(ctx), ep, false) } }() } @@ -1302,7 +1302,12 @@ func (n *Network) EndpointByID(id string) (*Endpoint, error) { } // updateSvcRecord adds or deletes local DNS records for a given Endpoint. -func (n *Network) updateSvcRecord(ep *Endpoint, isAdd bool) { +func (n *Network) updateSvcRecord(ctx context.Context, ep *Endpoint, isAdd bool) { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.updateSvcRecord", trace.WithAttributes( + attribute.String("ep.name", ep.name), + attribute.Bool("isAdd", isAdd))) + defer span.End() + iface := ep.Iface() if iface == nil || iface.Address() == nil { return @@ -2140,7 +2145,7 @@ func (n *Network) createLoadBalancerSandbox() (retErr error) { } }() - if err := ep.Join(sb, nil); err != nil { + if err := ep.Join(context.TODO(), sb, nil); err != nil { return err } diff --git a/libnetwork/osl/interface_linux.go b/libnetwork/osl/interface_linux.go index 1dec44dfd4..dac3b84053 100644 --- a/libnetwork/osl/interface_linux.go +++ b/libnetwork/osl/interface_linux.go @@ -16,6 +16,9 @@ import ( "github.com/pkg/errors" "github.com/vishvananda/netlink" "github.com/vishvananda/netns" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) // newInterface creates a new interface in the given namespace using the @@ -159,12 +162,33 @@ func (n *Namespace) findDst(srcName string, isBridge bool) string { return "" } +func moveLink(ctx context.Context, nlhHost *netlink.Handle, iface netlink.Link, i *Interface, path string) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.osl.moveLink", trace.WithAttributes( + attribute.String("ifaceName", i.DstName()))) + defer span.End() + + newNs, err := netns.GetFromPath(path) + if err != nil { + return fmt.Errorf("failed get network namespace %q: %v", path, err) + } + defer newNs.Close() + if err := nlhHost.LinkSetNsFd(iface, int(newNs)); err != nil { + return fmt.Errorf("failed to set namespace on link %q: %v", i.srcName, err) + } + return nil +} + // AddInterface adds an existing Interface to the sandbox. The operation will rename // from the Interface SrcName to DstName as it moves, and reconfigure the // interface according to the specified settings. The caller is expected // to only provide a prefix for DstName. The AddInterface api will auto-generate // an appropriate suffix for the DstName to disambiguate. -func (n *Namespace) AddInterface(srcName, dstPrefix string, options ...IfaceOption) error { +func (n *Namespace) AddInterface(ctx context.Context, srcName, dstPrefix string, options ...IfaceOption) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.osl.AddInterface", trace.WithAttributes( + attribute.String("srcName", srcName), + attribute.String("dstPrefix", dstPrefix))) + defer span.End() + i, err := newInterface(n, srcName, dstPrefix, options...) if err != nil { return err @@ -205,13 +229,8 @@ func (n *Namespace) AddInterface(srcName, dstPrefix string, options ...IfaceOpti // namespace only if the namespace is not a default // type if !isDefault { - newNs, err := netns.GetFromPath(path) - if err != nil { - return fmt.Errorf("failed get network namespace %q: %v", path, err) - } - defer newNs.Close() - if err := nlhHost.LinkSetNsFd(iface, int(newNs)); err != nil { - return fmt.Errorf("failed to set namespace on link %q: %v", i.srcName, err) + if err := moveLink(ctx, nlhHost, iface, i, path); err != nil { + return err } } } @@ -228,16 +247,16 @@ func (n *Namespace) AddInterface(srcName, dstPrefix string, options ...IfaceOpti } // Configure the interface now this is moved in the proper namespace. - if err := n.configureInterface(nlh, iface, i); err != nil { + if err := n.configureInterface(ctx, nlh, iface, i); err != nil { // If configuring the device fails move it back to the host namespace // and change the name back to the source name. This allows the caller // to properly cleanup the interface. Its important especially for // interfaces with global attributes, ex: vni id for vxlan interfaces. if nerr := nlh.LinkSetName(iface, i.SrcName()); nerr != nil { - log.G(context.TODO()).Errorf("renaming interface (%s->%s) failed, %v after config error %v", i.DstName(), i.SrcName(), nerr, err) + log.G(ctx).Errorf("renaming interface (%s->%s) failed, %v after config error %v", i.DstName(), i.SrcName(), nerr, err) } if nerr := nlh.LinkSetNsFd(iface, ns.ParseHandlerInt()); nerr != nil { - log.G(context.TODO()).Errorf("moving interface %s to host ns failed, %v, after config error %v", i.SrcName(), nerr, err) + log.G(ctx).Errorf("moving interface %s to host ns failed, %v, after config error %v", i.SrcName(), nerr, err) } return err } @@ -245,7 +264,11 @@ func (n *Namespace) AddInterface(srcName, dstPrefix string, options ...IfaceOpti // Up the interface. cnt := 0 for err = nlh.LinkSetUp(iface); err != nil && cnt < 3; cnt++ { - log.G(context.TODO()).Debugf("retrying link setup because of: %v", err) + ctx, span2 := otel.Tracer("").Start(ctx, "libnetwork.osl.retryingLinkUp", trace.WithAttributes( + attribute.String("srcName", srcName), + attribute.String("dstPrefix", dstPrefix))) + defer span2.End() + log.G(ctx).Debugf("retrying link setup because of: %v", err) time.Sleep(10 * time.Millisecond) err = nlh.LinkSetUp(iface) } @@ -317,7 +340,11 @@ func (n *Namespace) RemoveInterface(i *Interface) error { return nil } -func (n *Namespace) configureInterface(nlh *netlink.Handle, iface netlink.Link, i *Interface) error { +func (n *Namespace) configureInterface(ctx context.Context, nlh *netlink.Handle, iface netlink.Link, i *Interface) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.osl.configureInterface", trace.WithAttributes( + attribute.String("ifaceName", iface.Attrs().Name))) + defer span.End() + ifaceName := iface.Attrs().Name ifaceConfigurators := []struct { Fn func(*netlink.Handle, netlink.Link, *Interface) error diff --git a/libnetwork/osl/sandbox_linux_test.go b/libnetwork/osl/sandbox_linux_test.go index 171f6b5295..35aa9c69ca 100644 --- a/libnetwork/osl/sandbox_linux_test.go +++ b/libnetwork/osl/sandbox_linux_test.go @@ -1,6 +1,7 @@ package osl import ( + "context" "crypto/rand" "encoding/hex" "io" @@ -393,7 +394,7 @@ func TestSandboxCreate(t *testing.T) { } for _, i := range tbox.Interfaces() { - err = s.AddInterface(i.SrcName(), i.DstName(), + err = s.AddInterface(context.Background(), i.SrcName(), i.DstName(), WithIsBridge(i.Bridge()), WithIPv4Address(i.Address()), WithIPv6Address(i.AddressIPv6())) @@ -492,7 +493,7 @@ func TestAddRemoveInterface(t *testing.T) { } for _, i := range tbox.Interfaces() { - err = s.AddInterface(i.SrcName(), i.DstName(), + err = s.AddInterface(context.Background(), i.SrcName(), i.DstName(), WithIsBridge(i.Bridge()), WithIPv4Address(i.Address()), WithIPv6Address(i.AddressIPv6()), @@ -512,7 +513,7 @@ func TestAddRemoveInterface(t *testing.T) { verifySandbox(t, s, []string{"1", "2"}) i := tbox.Interfaces()[0] - err = s.AddInterface(i.SrcName(), i.DstName(), + err = s.AddInterface(context.Background(), i.SrcName(), i.DstName(), WithIsBridge(i.Bridge()), WithIPv4Address(i.Address()), WithIPv6Address(i.AddressIPv6()), diff --git a/libnetwork/resolver_unix_test.go b/libnetwork/resolver_unix_test.go index a7b38d4ccb..d80a1e8edb 100644 --- a/libnetwork/resolver_unix_test.go +++ b/libnetwork/resolver_unix_test.go @@ -51,7 +51,7 @@ func TestDNSIPQuery(t *testing.T) { // we need the endpoint only to populate ep_list for the sandbox as part of resolve_name // it is not set as a target for name resolution and does not serve any other purpose - err = ep.Join(sb) + err = ep.Join(context.Background(), sb) if err != nil { t.Fatal(err) } diff --git a/libnetwork/sandbox.go b/libnetwork/sandbox.go index e1138da5c4..3a3c274d2f 100644 --- a/libnetwork/sandbox.go +++ b/libnetwork/sandbox.go @@ -266,7 +266,7 @@ func (sb *Sandbox) Refresh(options ...SandboxOption) error { // Re-connect to all endpoints for _, ep := range epList { - if err := ep.Join(sb); err != nil { + if err := ep.Join(context.WithoutCancel(context.TODO()), sb); err != nil { log.G(context.TODO()).Warnf("Failed attach sandbox %s to endpoint %s: %v\n", sb.ID(), ep.ID(), err) } } diff --git a/libnetwork/sandbox_dns_unix.go b/libnetwork/sandbox_dns_unix.go index d43f3f6844..29831e8dbb 100644 --- a/libnetwork/sandbox_dns_unix.go +++ b/libnetwork/sandbox_dns_unix.go @@ -17,6 +17,7 @@ import ( "github.com/docker/docker/libnetwork/internal/resolvconf" "github.com/docker/docker/libnetwork/types" "github.com/pkg/errors" + "go.opentelemetry.io/otel" ) const ( @@ -30,12 +31,12 @@ const ( // finishInitDNS is to be called after the container namespace has been created, // before it the user process is started. The container's support for IPv6 can be // determined at this point. -func (sb *Sandbox) finishInitDNS() error { +func (sb *Sandbox) finishInitDNS(ctx context.Context) error { if err := sb.buildHostsFile(); err != nil { return errdefs.System(err) } for _, ep := range sb.Endpoints() { - if err := sb.updateHostsFile(ep.getEtcHostsAddrs()); err != nil { + if err := sb.updateHostsFile(ctx, ep.getEtcHostsAddrs()); err != nil { return errdefs.System(err) } } @@ -133,7 +134,10 @@ func (sb *Sandbox) buildHostsFile() error { return sb.updateParentHosts() } -func (sb *Sandbox) updateHostsFile(ifaceIPs []string) error { +func (sb *Sandbox) updateHostsFile(ctx context.Context, ifaceIPs []string) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.updateHostsFile") + defer span.End() + if len(ifaceIPs) == 0 { return nil } diff --git a/libnetwork/sandbox_dns_windows.go b/libnetwork/sandbox_dns_windows.go index 6a8c9beef5..32876e3f39 100644 --- a/libnetwork/sandbox_dns_windows.go +++ b/libnetwork/sandbox_dns_windows.go @@ -16,7 +16,7 @@ func (sb *Sandbox) restoreHostsPath() {} func (sb *Sandbox) restoreResolvConfPath() {} -func (sb *Sandbox) updateHostsFile(ifaceIP []string) error { +func (sb *Sandbox) updateHostsFile(_ context.Context, ifaceIP []string) error { return nil } diff --git a/libnetwork/sandbox_linux.go b/libnetwork/sandbox_linux.go index 3cae9b9904..7ac25d09d0 100644 --- a/libnetwork/sandbox_linux.go +++ b/libnetwork/sandbox_linux.go @@ -10,6 +10,9 @@ import ( "github.com/docker/docker/libnetwork/netutils" "github.com/docker/docker/libnetwork/osl" "github.com/docker/docker/libnetwork/types" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) // Linux-specific container configuration flags. @@ -165,12 +168,12 @@ func (sb *Sandbox) SetKey(basePath string) error { // determined yet, as sysctls haven't been applied by the runtime. Calling // FinishInit after the container task has been created, when sysctls have been // applied will regenerate these files. - if err := sb.finishInitDNS(); err != nil { + if err := sb.finishInitDNS(context.TODO()); err != nil { return err } for _, ep := range sb.Endpoints() { - if err = sb.populateNetworkResources(ep); err != nil { + if err = sb.populateNetworkResources(context.TODO(), ep); err != nil { return err } } @@ -181,7 +184,7 @@ func (sb *Sandbox) SetKey(basePath string) error { // FinishConfig completes Sandbox configuration. If called after the container task has been // created, and sysctl settings applied, the configuration will be based on the container's // IPv6 support. -func (sb *Sandbox) FinishConfig() error { +func (sb *Sandbox) FinishConfig(ctx context.Context) error { if sb.config.useDefaultSandBox { return nil } @@ -196,7 +199,7 @@ func (sb *Sandbox) FinishConfig() error { // If sysctl changes have been made, IPv6 may have been enabled/disabled since last checked. osSbox.RefreshIPv6LoEnabled() - return sb.finishInitDNS() + return sb.finishInitDNS(ctx) } // IPv6 support can always be determined for host networking. For other network @@ -283,7 +286,11 @@ func (sb *Sandbox) restoreOslSandbox() error { return sb.osSbox.Restore(interfaces, routes, gwep.joinInfo.gw, gwep.joinInfo.gw6) } -func (sb *Sandbox) populateNetworkResources(ep *Endpoint) error { +func (sb *Sandbox) populateNetworkResources(ctx context.Context, ep *Endpoint) error { + ctx, span := otel.Tracer("").Start(ctx, "libnetwork.Sandbox.populateNetworkResources", trace.WithAttributes( + attribute.String("endpoint.Name", ep.Name()))) + defer span.End() + sb.mu.Lock() if sb.osSbox == nil { sb.mu.Unlock() @@ -319,7 +326,7 @@ func (sb *Sandbox) populateNetworkResources(ep *Endpoint) error { ifaceOptions = append(ifaceOptions, osl.WithSysctls(sysctls)) } - if err := sb.osSbox.AddInterface(i.srcName, i.dstPrefix, ifaceOptions...); err != nil { + if err := sb.osSbox.AddInterface(ctx, i.srcName, i.dstPrefix, ifaceOptions...); err != nil { return fmt.Errorf("failed to add interface %s to sandbox: %v", i.srcName, err) } diff --git a/libnetwork/sandbox_store.go b/libnetwork/sandbox_store.go index da099a6b47..aebf1735dc 100644 --- a/libnetwork/sandbox_store.go +++ b/libnetwork/sandbox_store.go @@ -272,7 +272,7 @@ func (c *Controller) sandboxCleanup(activeSandboxes map[string]interface{}) erro if !c.isAgent() { n := ep.getNetwork() if !c.isSwarmNode() || n.Scope() != scope.Swarm || !n.driverIsMultihost() { - n.updateSvcRecord(ep, true) + n.updateSvcRecord(context.WithoutCancel(context.TODO()), ep, true) } } } diff --git a/libnetwork/sandbox_unix_test.go b/libnetwork/sandbox_unix_test.go index 2213004d2b..5af1487c92 100644 --- a/libnetwork/sandbox_unix_test.go +++ b/libnetwork/sandbox_unix_test.go @@ -143,15 +143,15 @@ func TestSandboxAddMultiPrio(t *testing.T) { t.Fatal(err) } - if err := ep1.Join(sbx, JoinOptionPriority(1)); err != nil { + if err := ep1.Join(context.Background(), sbx, JoinOptionPriority(1)); err != nil { t.Fatal(err) } - if err := ep2.Join(sbx, JoinOptionPriority(2)); err != nil { + if err := ep2.Join(context.Background(), sbx, JoinOptionPriority(2)); err != nil { t.Fatal(err) } - if err := ep3.Join(sbx, JoinOptionPriority(3)); err != nil { + if err := ep3.Join(context.Background(), sbx, JoinOptionPriority(3)); err != nil { t.Fatal(err) } @@ -178,7 +178,7 @@ func TestSandboxAddMultiPrio(t *testing.T) { } // Re-add ep3 back - if err := ep3.Join(sbx, JoinOptionPriority(3)); err != nil { + if err := ep3.Join(context.Background(), sbx, JoinOptionPriority(3)); err != nil { t.Fatal(err) } @@ -234,19 +234,19 @@ func TestSandboxAddSamePrio(t *testing.T) { t.Fatal(err) } - if err := epNw1.Join(sbx); err != nil { + if err := epNw1.Join(context.Background(), sbx); err != nil { t.Fatal(err) } - if err := epIPv6.Join(sbx); err != nil { + if err := epIPv6.Join(context.Background(), sbx); err != nil { t.Fatal(err) } - if err := epInternal.Join(sbx); err != nil { + if err := epInternal.Join(context.Background(), sbx); err != nil { t.Fatal(err) } - if err := epNw0.Join(sbx); err != nil { + if err := epNw0.Join(context.Background(), sbx); err != nil { t.Fatal(err) } diff --git a/libnetwork/sandbox_windows.go b/libnetwork/sandbox_windows.go index d9d9ce735b..7b57971254 100644 --- a/libnetwork/sandbox_windows.go +++ b/libnetwork/sandbox_windows.go @@ -1,6 +1,10 @@ package libnetwork -import "github.com/docker/docker/libnetwork/osl" +import ( + "context" + + "github.com/docker/docker/libnetwork/osl" +) // Windows-specific container configuration flags. type containerConfigOS struct { @@ -29,7 +33,7 @@ func (sb *Sandbox) restoreOslSandbox() error { return nil } -func (sb *Sandbox) populateNetworkResources(*Endpoint) error { +func (sb *Sandbox) populateNetworkResources(context.Context, *Endpoint) error { // not implemented on Windows (Sandbox.osSbox is always nil) return nil }