Browse code

libnetwork/driverapi: make EventNotify optional

Overlay is the only driver which makes use of the EventNotify facility,
yet all other driver implementations are forced to provide a stub
implementation. Move the EventNotify and DecodeTableEntry methods into a
new optional TableWatcher interface and remove the stubs from all the
other drivers.

Signed-off-by: Cory Snider <csnider@mirantis.com>

Cory Snider authored on 2025/07/11 06:51:18
Showing 17 changed files
... ...
@@ -491,17 +491,19 @@ func (n *Network) Services() map[string]ServiceInfo {
491 491
 	// Walk through the driver's tables, have the driver decode the entries
492 492
 	// and return the tuple {ep ID, value}. value is a string that coveys
493 493
 	// relevant info about the endpoint.
494
-	for _, table := range n.driverTables {
495
-		if table.objType != driverapi.EndpointObject {
496
-			continue
497
-		}
498
-		for key, value := range agent.networkDB.GetTableByNetwork(table.name, nwID) {
499
-			epID, info := d.DecodeTableEntry(table.name, key, value.Value)
500
-			if ep, ok := eps[epID]; !ok {
501
-				log.G(context.TODO()).Errorf("Inconsistent driver and libnetwork state for endpoint %s", epID)
502
-			} else {
503
-				ep.info = info
504
-				eps[epID] = ep
494
+	if d, ok := d.(driverapi.TableWatcher); ok {
495
+		for _, table := range n.driverTables {
496
+			if table.objType != driverapi.EndpointObject {
497
+				continue
498
+			}
499
+			for key, value := range agent.networkDB.GetTableByNetwork(table.name, nwID) {
500
+				epID, info := d.DecodeTableEntry(table.name, key, value.Value)
501
+				if ep, ok := eps[epID]; !ok {
502
+					log.G(context.TODO()).Errorf("Inconsistent driver and libnetwork state for endpoint %s", epID)
503
+				} else {
504
+					ep.info = info
505
+					eps[epID] = ep
506
+				}
505 507
 			}
506 508
 		}
507 509
 	}
... ...
@@ -814,6 +816,11 @@ func (n *Network) handleDriverTableEvent(ev events.Event) {
814 814
 		log.G(context.TODO()).Errorf("Could not resolve driver %s while handling driver table event: %v", n.networkType, err)
815 815
 		return
816 816
 	}
817
+	ed, ok := d.(driverapi.TableWatcher)
818
+	if !ok {
819
+		log.G(context.TODO()).Errorf("Could not notify driver %s about table event: driver does not implement TableWatcher interface", n.networkType)
820
+		return
821
+	}
817 822
 
818 823
 	var (
819 824
 		etype driverapi.EventType
... ...
@@ -833,7 +840,7 @@ func (n *Network) handleDriverTableEvent(ev events.Event) {
833 833
 		etype = driverapi.Update
834 834
 	}
835 835
 
836
-	d.EventNotify(etype, n.ID(), event.Table, event.Key, value)
836
+	ed.EventNotify(etype, n.ID(), event.Table, event.Key, value)
837 837
 }
838 838
 
839 839
 func (c *Controller) handleNodeTableEvent(ev events.Event) {
... ...
@@ -32,13 +32,6 @@ func (d *manager) CreateNetwork(ctx context.Context, id string, option map[strin
32 32
 	return types.NotImplementedErrorf("not implemented")
33 33
 }
34 34
 
35
-func (d *manager) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
36
-}
37
-
38
-func (d *manager) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
39
-	return "", nil
40
-}
41
-
42 35
 func (d *manager) DeleteNetwork(nid string) error {
43 36
 	return types.NotImplementedErrorf("not implemented")
44 37
 }
... ...
@@ -56,6 +56,15 @@ type Driver interface {
56 56
 	// Leave method is invoked when a Sandbox detaches from an endpoint.
57 57
 	Leave(nid, eid string) error
58 58
 
59
+	// Type returns the type of this driver, the network type this driver manages
60
+	Type() string
61
+
62
+	// IsBuiltIn returns true if it is a built-in driver
63
+	IsBuiltIn() bool
64
+}
65
+
66
+// TableWatcher is an optional interface for a network driver.
67
+type TableWatcher interface {
59 68
 	// EventNotify notifies the driver when a CRUD operation has
60 69
 	// happened on a table of its interest as soon as this node
61 70
 	// receives such an event in the gossip layer. This method is
... ...
@@ -71,12 +80,6 @@ type Driver interface {
71 71
 	// For example: overlay driver returns the VTEP IP of the host that has the endpoint
72 72
 	// which is shown in 'network inspect --verbose'
73 73
 	DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string)
74
-
75
-	// Type returns the type of this driver, the network type this driver manages
76
-	Type() string
77
-
78
-	// IsBuiltIn returns true if it is a built-in driver
79
-	IsBuiltIn() bool
80 74
 }
81 75
 
82 76
 // ExtConner is an optional interface for a network driver.
... ...
@@ -705,13 +705,6 @@ func (d *driver) NetworkFree(id string) error {
705 705
 	return types.NotImplementedErrorf("not implemented")
706 706
 }
707 707
 
708
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
709
-}
710
-
711
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
712
-	return "", nil
713
-}
714
-
715 708
 func (d *driver) GetSkipGwAlloc(opts options.Generic) (ipv4, ipv6 bool, _ error) {
716 709
 	// The network doesn't exist yet, so use a dummy id that's long enough to be
717 710
 	// truncated to a short-id (12 characters) and used in the bridge device name.
... ...
@@ -32,13 +32,6 @@ func (d *driver) CreateNetwork(ctx context.Context, id string, option map[string
32 32
 	return types.NotImplementedErrorf("not implemented")
33 33
 }
34 34
 
35
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
36
-}
37
-
38
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
39
-	return "", nil
40
-}
41
-
42 35
 func (d *driver) DeleteNetwork(nid string) error {
43 36
 	return types.NotImplementedErrorf("not implemented")
44 37
 }
... ...
@@ -31,13 +31,6 @@ func (d *driver) NetworkFree(id string) error {
31 31
 	return types.NotImplementedErrorf("not implemented")
32 32
 }
33 33
 
34
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
35
-}
36
-
37
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
38
-	return "", nil
39
-}
40
-
41 34
 func (d *driver) CreateNetwork(ctx context.Context, id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
42 35
 	d.Lock()
43 36
 	defer d.Unlock()
... ...
@@ -95,10 +95,3 @@ func (d *driver) Type() string {
95 95
 func (d *driver) IsBuiltIn() bool {
96 96
 	return true
97 97
 }
98
-
99
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
100
-}
101
-
102
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
103
-	return "", nil
104
-}
... ...
@@ -32,13 +32,6 @@ func (d *driver) CreateNetwork(ctx context.Context, id string, option map[string
32 32
 	return types.NotImplementedErrorf("not implemented")
33 33
 }
34 34
 
35
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
36
-}
37
-
38
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
39
-	return "", nil
40
-}
41
-
42 35
 func (d *driver) DeleteNetwork(nid string) error {
43 36
 	return types.NotImplementedErrorf("not implemented")
44 37
 }
... ...
@@ -89,10 +89,3 @@ func (d *driver) Type() string {
89 89
 func (d *driver) IsBuiltIn() bool {
90 90
 	return true
91 91
 }
92
-
93
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
94
-}
95
-
96
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
97
-	return "", nil
98
-}
... ...
@@ -32,13 +32,6 @@ func (d *driver) CreateNetwork(ctx context.Context, id string, option map[string
32 32
 	return types.NotImplementedErrorf("not implemented")
33 33
 }
34 34
 
35
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
36
-}
37
-
38
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
39
-	return "", nil
40
-}
41
-
42 35
 func (d *driver) DeleteNetwork(nid string) error {
43 36
 	return types.NotImplementedErrorf("not implemented")
44 37
 }
... ...
@@ -31,13 +31,6 @@ func (d *driver) NetworkFree(id string) error {
31 31
 	return types.NotImplementedErrorf("not implemented")
32 32
 }
33 33
 
34
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
35
-}
36
-
37
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
38
-	return "", nil
39
-}
40
-
41 34
 func (d *driver) CreateNetwork(ctx context.Context, id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
42 35
 	d.Lock()
43 36
 	defer d.Unlock()
... ...
@@ -25,8 +25,10 @@ const (
25 25
 	secureOption = "encrypted"
26 26
 )
27 27
 
28
-// overlay driver must implement the discover-API.
29
-var _ discoverapi.Discover = (*driver)(nil)
28
+var (
29
+	_ discoverapi.Discover   = (*driver)(nil)
30
+	_ driverapi.TableWatcher = (*driver)(nil)
31
+)
30 32
 
31 33
 type driver struct {
32 34
 	// Immutable; mu does not need to be held when accessing these fields.
... ...
@@ -167,13 +167,6 @@ func (d *driver) CreateNetwork(ctx context.Context, id string, option map[string
167 167
 	return types.NotImplementedErrorf("not implemented")
168 168
 }
169 169
 
170
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
171
-}
172
-
173
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
174
-	return "", nil
175
-}
176
-
177 170
 func (d *driver) DeleteNetwork(nid string) error {
178 171
 	return types.NotImplementedErrorf("not implemented")
179 172
 }
... ...
@@ -174,13 +174,6 @@ func (d *driver) NetworkFree(id string) error {
174 174
 	return d.call("FreeNetwork", fr, &api.FreeNetworkResponse{})
175 175
 }
176 176
 
177
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
178
-}
179
-
180
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
181
-	return "", nil
182
-}
183
-
184 177
 func (d *driver) CreateNetwork(ctx context.Context, id string, options map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
185 178
 	create := &api.CreateNetworkRequest{
186 179
 		NetworkID: id,
... ...
@@ -19,6 +19,8 @@ const (
19 19
 	NetworkType = "overlay"
20 20
 )
21 21
 
22
+var _ driverapi.TableWatcher = (*driver)(nil)
23
+
22 24
 type driver struct {
23 25
 	networks networkTable
24 26
 	sync.Mutex
... ...
@@ -305,13 +305,6 @@ func (ncfg *networkConfiguration) processIPAM(id string, ipamV4Data, ipamV6Data
305 305
 	return nil
306 306
 }
307 307
 
308
-func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
309
-}
310
-
311
-func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
312
-	return "", nil
313
-}
314
-
315 308
 func (d *driver) createNetwork(config *networkConfiguration) *hnsNetwork {
316 309
 	network := &hnsNetwork{
317 310
 		id:         config.ID,
... ...
@@ -831,10 +831,3 @@ func (b *badDriver) NetworkAllocate(id string, option map[string]string, ipV4Dat
831 831
 func (b *badDriver) NetworkFree(id string) error {
832 832
 	return types.NotImplementedErrorf("not implemented")
833 833
 }
834
-
835
-func (b *badDriver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
836
-}
837
-
838
-func (b *badDriver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) {
839
-	return "", nil
840
-}