Browse code

Changed all the naked error returns in bridge driver to proper error types, except the naked error returns which were just prefixing strings to previously returned error strings.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>

Jana Radhakrishnan authored on 2015/04/17 11:47:12
Showing 13 changed files
... ...
@@ -1,8 +1,6 @@
1 1
 package bridge
2 2
 
3 3
 import (
4
-	"errors"
5
-	"fmt"
6 4
 	"net"
7 5
 	"strings"
8 6
 	"sync"
... ...
@@ -78,14 +76,14 @@ func (d *driver) Config(option interface{}) error {
78 78
 	defer d.Unlock()
79 79
 
80 80
 	if d.config != nil {
81
-		return fmt.Errorf("configuration already exists, simplebridge configuration can be applied only once")
81
+		return ErrConfigExists
82 82
 	}
83 83
 
84 84
 	switch opt := option.(type) {
85 85
 	case options.Generic:
86 86
 		opaqueConfig, err := options.GenerateFromModel(opt, &Configuration{})
87 87
 		if err != nil {
88
-			return fmt.Errorf("failed to generate driver config: %v", err)
88
+			return err
89 89
 		}
90 90
 		config = opaqueConfig.(*Configuration)
91 91
 	case *Configuration:
... ...
@@ -106,13 +104,13 @@ func (d *driver) CreateNetwork(id driverapi.UUID, option interface{}) error {
106 106
 	d.Lock()
107 107
 	if d.config == nil {
108 108
 		d.Unlock()
109
-		return fmt.Errorf("trying to create a network on a driver without valid config")
109
+		return ErrInvalidConfig
110 110
 	}
111 111
 	config := d.config
112 112
 
113 113
 	if d.network != nil {
114 114
 		d.Unlock()
115
-		return fmt.Errorf("network already exists, simplebridge can only have one network")
115
+		return ErrNetworkExists
116 116
 	}
117 117
 	d.network = &bridgeNetwork{id: id}
118 118
 	d.Unlock()
... ...
@@ -205,7 +203,7 @@ func (d *driver) DeleteNetwork(nid driverapi.UUID) error {
205 205
 	}
206 206
 
207 207
 	if n.endpoint != nil {
208
-		err = fmt.Errorf("Network %s has active endpoint %s", n.id, n.endpoint.id)
208
+		err = &ActiveEndpointsError{nid: string(n.id), eid: string(n.endpoint.id)}
209 209
 		return err
210 210
 	}
211 211
 
... ...
@@ -230,7 +228,7 @@ func (d *driver) CreateEndpoint(nid, eid driverapi.UUID, sboxKey string, epOptio
230 230
 	n.Lock()
231 231
 	if n.id != nid {
232 232
 		n.Unlock()
233
-		return nil, fmt.Errorf("invalid network id %s", nid)
233
+		return nil, InvalidNetworkIDError(nid)
234 234
 	}
235 235
 
236 236
 	if n.endpoint != nil {
... ...
@@ -338,7 +336,7 @@ func (d *driver) DeleteEndpoint(nid, eid driverapi.UUID) error {
338 338
 	n.Lock()
339 339
 	if n.id != nid {
340 340
 		n.Unlock()
341
-		return fmt.Errorf("invalid network id %s", nid)
341
+		return InvalidNetworkIDError(nid)
342 342
 	}
343 343
 
344 344
 	if n.endpoint == nil {
... ...
@@ -349,7 +347,7 @@ func (d *driver) DeleteEndpoint(nid, eid driverapi.UUID) error {
349 349
 	ep := n.endpoint
350 350
 	if ep.id != eid {
351 351
 		n.Unlock()
352
-		return fmt.Errorf("invalid endpoint id %s", eid)
352
+		return InvalidEndpointIDError(eid)
353 353
 	}
354 354
 
355 355
 	n.endpoint = nil
... ...
@@ -398,5 +396,5 @@ func generateIfaceName() (string, error) {
398 398
 			return "", err
399 399
 		}
400 400
 	}
401
-	return "", errors.New("Failed to find name for new interface")
401
+	return "", ErrIfaceName
402 402
 }
403 403
new file mode 100644
... ...
@@ -0,0 +1,138 @@
0
+package bridge
1
+
2
+import (
3
+	"errors"
4
+	"fmt"
5
+	"net"
6
+)
7
+
8
+var (
9
+	// ErrConfigExists error is returned when driver already has a config applied.
10
+	ErrConfigExists = errors.New("configuration already exists, simplebridge configuration can be applied only once")
11
+
12
+	// ErrInvalidConfig error is returned when a network is created on a driver without valid config.
13
+	ErrInvalidConfig = errors.New("trying to create a network on a driver without valid config")
14
+
15
+	// ErrNetworkExists error is returned when a network already exists and another network is created.
16
+	ErrNetworkExists = errors.New("network already exists, simplebridge can only have one network")
17
+
18
+	// ErrIfaceName error is returned when a new name could not be generated.
19
+	ErrIfaceName = errors.New("Failed to find name for new interface")
20
+
21
+	// ErrNoIPAddr error is returned when bridge has no IPv4 addrss configured.
22
+	ErrNoIPAddr = errors.New("Bridge has no IPv4 address configured")
23
+)
24
+
25
+// ActiveEndpointsError is returned when there are
26
+// already active endpoints in the network being deleted.
27
+type ActiveEndpointsError struct {
28
+	nid string
29
+	eid string
30
+}
31
+
32
+func (aee *ActiveEndpointsError) Error() string {
33
+	return fmt.Sprintf("Network %s has active endpoint %s", aee.nid, aee.eid)
34
+}
35
+
36
+// InvalidNetworkIDError is returned when the passed
37
+// network id for an existing network is not a known id.
38
+type InvalidNetworkIDError string
39
+
40
+func (inie InvalidNetworkIDError) Error() string {
41
+	return fmt.Sprintf("invalid network id %s", inie)
42
+}
43
+
44
+// InvalidEndpointIDError is returned when the passed
45
+// endpoint id for an existing endpoint is not a known id.
46
+type InvalidEndpointIDError string
47
+
48
+func (ieie InvalidEndpointIDError) Error() string {
49
+	return fmt.Sprintf("invalid endpoint id %s", ieie)
50
+}
51
+
52
+// NonDefaultBridgeExistError is returned when a non-default
53
+// bridge config is passed but it does not already exist.
54
+type NonDefaultBridgeExistError string
55
+
56
+func (ndbee NonDefaultBridgeExistError) Error() string {
57
+	return fmt.Sprintf("bridge device with non default name %s must be created manually", ndbee)
58
+}
59
+
60
+// FixedCIDRv4Error is returned when fixed-cidrv4 configuration
61
+// failed.
62
+type FixedCIDRv4Error struct {
63
+	net    *net.IPNet
64
+	subnet *net.IPNet
65
+	err    error
66
+}
67
+
68
+func (fcv4 *FixedCIDRv4Error) Error() string {
69
+	return fmt.Sprintf("Setup FixedCIDRv4 failed for subnet %s in %s: %v", fcv4.subnet, fcv4.net, fcv4.err)
70
+}
71
+
72
+// FixedCIDRv6Error is returned when fixed-cidrv6 configuration
73
+// failed.
74
+type FixedCIDRv6Error struct {
75
+	net *net.IPNet
76
+	err error
77
+}
78
+
79
+func (fcv6 *FixedCIDRv6Error) Error() string {
80
+	return fmt.Sprintf("Setup FixedCIDRv6 failed for subnet %s in %s: %v", fcv6.net, fcv6.net, fcv6.err)
81
+}
82
+
83
+type ipForwardCfgError bridgeInterface
84
+
85
+func (i *ipForwardCfgError) Error() string {
86
+	return fmt.Sprintf("Unexpected request to enable IP Forwarding for: %v", *i)
87
+}
88
+
89
+type ipTableCfgError string
90
+
91
+func (name ipTableCfgError) Error() string {
92
+	return fmt.Sprintf("Unexpected request to set IP tables for interface: %s", name)
93
+}
94
+
95
+// IPv4AddrRangeError is returned when a valid IP address range couldn't be found.
96
+type IPv4AddrRangeError string
97
+
98
+func (name IPv4AddrRangeError) Error() string {
99
+	return fmt.Sprintf("can't find an address range for interface %q", name)
100
+}
101
+
102
+// IPv4AddrAddError is returned when IPv4 address could not be added to the bridge.
103
+type IPv4AddrAddError struct {
104
+	ip  *net.IPNet
105
+	err error
106
+}
107
+
108
+func (ipv4 *IPv4AddrAddError) Error() string {
109
+	return fmt.Sprintf("Failed to add IPv4 address %s to bridge: %v", ipv4.ip, ipv4.err)
110
+}
111
+
112
+// IPv6AddrAddError is returned when IPv6 address could not be added to the bridge.
113
+type IPv6AddrAddError struct {
114
+	ip  *net.IPNet
115
+	err error
116
+}
117
+
118
+func (ipv6 *IPv6AddrAddError) Error() string {
119
+	return fmt.Sprintf("Failed to add IPv6 address %s to bridge: %v", ipv6.ip, ipv6.err)
120
+}
121
+
122
+// IPv4AddrNoMatchError is returned when the bridge's IPv4 address does not match configured.
123
+type IPv4AddrNoMatchError struct {
124
+	ip    net.IP
125
+	cfgIP net.IP
126
+}
127
+
128
+func (ipv4 *IPv4AddrNoMatchError) Error() string {
129
+	return fmt.Sprintf("Bridge IPv4 (%s) does not match requested configuration %s", ipv4.ip, ipv4.cfgIP)
130
+}
131
+
132
+// IPv6AddrNoMatchError is returned when the bridge's IPv6 address does not match configured.
133
+type IPv6AddrNoMatchError net.IPNet
134
+
135
+func (ipv6 *IPv6AddrNoMatchError) Error() string {
136
+	return fmt.Sprintf("Bridge IPv6 addresses do not match the expected bridge configuration %s", ipv6)
137
+}
... ...
@@ -1,8 +1,6 @@
1 1
 package bridge
2 2
 
3 3
 import (
4
-	"fmt"
5
-
6 4
 	log "github.com/Sirupsen/logrus"
7 5
 	"github.com/docker/docker/pkg/parsers/kernel"
8 6
 	"github.com/docker/libnetwork/netutils"
... ...
@@ -14,7 +12,7 @@ func setupDevice(config *Configuration, i *bridgeInterface) error {
14 14
 	// We only attempt to create the bridge when the requested device name is
15 15
 	// the default one.
16 16
 	if config.BridgeName != DefaultBridgeName && !config.AllowNonDefaultBridge {
17
-		return fmt.Errorf("bridge device with non default name %q must be created manually", config.BridgeName)
17
+		return NonDefaultBridgeExistError(config.BridgeName)
18 18
 	}
19 19
 
20 20
 	// Set the bridgeInterface netlink.Bridge.
... ...
@@ -3,7 +3,6 @@ package bridge
3 3
 import (
4 4
 	"bytes"
5 5
 	"net"
6
-	"strings"
7 6
 	"testing"
8 7
 
9 8
 	"github.com/docker/libnetwork/netutils"
... ...
@@ -36,8 +35,13 @@ func TestSetupNewNonDefaultBridge(t *testing.T) {
36 36
 	config := &Configuration{BridgeName: "test0"}
37 37
 	br := &bridgeInterface{}
38 38
 
39
-	if err := setupDevice(config, br); err == nil || !strings.Contains(err.Error(), "non default name") {
40
-		t.Fatalf("Expected bridge creation failure with \"non default name\", got: %v", err)
39
+	err := setupDevice(config, br)
40
+	if err == nil {
41
+		t.Fatal("Expected bridge creation failure with \"non default name\", succeeded")
42
+	}
43
+
44
+	if _, ok := err.(NonDefaultBridgeExistError); !ok {
45
+		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
41 46
 	}
42 47
 }
43 48
 
... ...
@@ -1,10 +1,6 @@
1 1
 package bridge
2 2
 
3
-import (
4
-	"fmt"
5
-
6
-	log "github.com/Sirupsen/logrus"
7
-)
3
+import log "github.com/Sirupsen/logrus"
8 4
 
9 5
 func setupFixedCIDRv4(config *Configuration, i *bridgeInterface) error {
10 6
 	addrv4, _, err := i.addresses()
... ...
@@ -14,7 +10,7 @@ func setupFixedCIDRv4(config *Configuration, i *bridgeInterface) error {
14 14
 
15 15
 	log.Debugf("Using IPv4 subnet: %v", config.FixedCIDR)
16 16
 	if err := ipAllocator.RegisterSubnet(addrv4.IPNet, config.FixedCIDR); err != nil {
17
-		return fmt.Errorf("Setup FixedCIDRv4 failed for subnet %s in %s: %v", config.FixedCIDR, addrv4.IPNet, err)
17
+		return &FixedCIDRv4Error{subnet: config.FixedCIDR, net: addrv4.IPNet, err: err}
18 18
 	}
19 19
 
20 20
 	return nil
... ...
@@ -50,7 +50,13 @@ func TestSetupBadFixedCIDRv4(t *testing.T) {
50 50
 		t.Fatalf("Assign IPv4 to bridge failed: %v", err)
51 51
 	}
52 52
 
53
-	if err := setupFixedCIDRv4(config, br); err == nil {
53
+	err := setupFixedCIDRv4(config, br)
54
+	if err == nil {
54 55
 		t.Fatal("Setup bridge FixedCIDRv4 should have failed")
55 56
 	}
57
+
58
+	if _, ok := err.(*FixedCIDRv4Error); !ok {
59
+		t.Fatalf("Did not fail with expected error. Actual error: %v", err)
60
+	}
61
+
56 62
 }
... ...
@@ -1,15 +1,11 @@
1 1
 package bridge
2 2
 
3
-import (
4
-	"fmt"
5
-
6
-	log "github.com/Sirupsen/logrus"
7
-)
3
+import log "github.com/Sirupsen/logrus"
8 4
 
9 5
 func setupFixedCIDRv6(config *Configuration, i *bridgeInterface) error {
10 6
 	log.Debugf("Using IPv6 subnet: %v", config.FixedCIDRv6)
11 7
 	if err := ipAllocator.RegisterSubnet(config.FixedCIDRv6, config.FixedCIDRv6); err != nil {
12
-		return fmt.Errorf("Setup FixedCIDRv6 failed for subnet %s in %s: %v", config.FixedCIDRv6, config.FixedCIDRv6, err)
8
+		return &FixedCIDRv6Error{net: config.FixedCIDRv6, err: err}
13 9
 	}
14 10
 
15 11
 	return nil
... ...
@@ -13,7 +13,7 @@ const (
13 13
 func setupIPForwarding(config *Configuration, i *bridgeInterface) error {
14 14
 	// Sanity Check
15 15
 	if config.EnableIPForwarding == false {
16
-		return fmt.Errorf("Unexpected request to enable IP Forwarding for: %v", *i)
16
+		return (*ipForwardCfgError)(i)
17 17
 	}
18 18
 
19 19
 	// Enable IPv4 forwarding
... ...
@@ -3,7 +3,6 @@ package bridge
3 3
 import (
4 4
 	"bytes"
5 5
 	"io/ioutil"
6
-	"strings"
7 6
 	"testing"
8 7
 )
9 8
 
... ...
@@ -47,9 +46,12 @@ func TestUnexpectedSetupIPForwarding(t *testing.T) {
47 47
 	br := &bridgeInterface{}
48 48
 
49 49
 	// Attempt Set IP Forwarding
50
-	if err := setupIPForwarding(config, br); err == nil {
50
+	err := setupIPForwarding(config, br)
51
+	if err == nil {
51 52
 		t.Fatal("Setup IP forwarding was expected to fail")
52
-	} else if !strings.Contains(err.Error(), "Unexpected request") {
53
+	}
54
+
55
+	if _, ok := err.(*ipForwardCfgError); !ok {
53 56
 		t.Fatalf("Setup IP forwarding failed with unexpected error: %v", err)
54 57
 	}
55 58
 }
... ...
@@ -16,7 +16,7 @@ const (
16 16
 func setupIPTables(config *Configuration, i *bridgeInterface) error {
17 17
 	// Sanity check.
18 18
 	if config.EnableIPTables == false {
19
-		return fmt.Errorf("Unexpected request to set IP tables for interface: %s", config.BridgeName)
19
+		return ipTableCfgError(config.BridgeName)
20 20
 	}
21 21
 
22 22
 	addrv4, _, err := netutils.GetIfaceAddr(config.BridgeName)
... ...
@@ -1,7 +1,6 @@
1 1
 package bridge
2 2
 
3 3
 import (
4
-	"fmt"
5 4
 	"net"
6 5
 
7 6
 	log "github.com/Sirupsen/logrus"
... ...
@@ -49,7 +48,7 @@ func setupBridgeIPv4(config *Configuration, i *bridgeInterface) error {
49 49
 
50 50
 	log.Debugf("Creating bridge interface %q with network %s", config.BridgeName, bridgeIPv4)
51 51
 	if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
52
-		return fmt.Errorf("Failed to add IPv4 address %s to bridge: %v", bridgeIPv4, err)
52
+		return &IPv4AddrAddError{ip: bridgeIPv4, err: err}
53 53
 	}
54 54
 
55 55
 	i.bridgeIPv4 = bridgeIPv4
... ...
@@ -80,5 +79,5 @@ func electBridgeIPv4(config *Configuration) (*net.IPNet, error) {
80 80
 		}
81 81
 	}
82 82
 
83
-	return nil, fmt.Errorf("'t find an address range for interface %q", config.BridgeName)
83
+	return nil, IPv4AddrRangeError(config.BridgeName)
84 84
 }
... ...
@@ -30,7 +30,7 @@ func setupBridgeIPv6(config *Configuration, i *bridgeInterface) error {
30 30
 	}
31 31
 
32 32
 	if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv6}); err != nil {
33
-		return fmt.Errorf("Failed to add IPv6 address %s to bridge: %v", bridgeIPv6, err)
33
+		return &IPv6AddrAddError{ip: bridgeIPv6, err: err}
34 34
 	}
35 35
 
36 36
 	i.bridgeIPv6 = bridgeIPv6
... ...
@@ -1,10 +1,6 @@
1 1
 package bridge
2 2
 
3
-import (
4
-	"fmt"
5
-
6
-	"github.com/vishvananda/netlink"
7
-)
3
+import "github.com/vishvananda/netlink"
8 4
 
9 5
 func setupVerifyAndReconcile(config *Configuration, i *bridgeInterface) error {
10 6
 	// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
... ...
@@ -15,18 +11,18 @@ func setupVerifyAndReconcile(config *Configuration, i *bridgeInterface) error {
15 15
 
16 16
 	// Verify that the bridge does have an IPv4 address.
17 17
 	if addrv4.IPNet == nil {
18
-		return fmt.Errorf("Bridge has no IPv4 address configured")
18
+		return ErrNoIPAddr
19 19
 	}
20 20
 
21 21
 	// Verify that the bridge IPv4 address matches the requested configuration.
22 22
 	if config.AddressIPv4 != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
23
-		return fmt.Errorf("Bridge IPv4 (%s) does not match requested configuration %s", addrv4.IP, config.AddressIPv4.IP)
23
+		return &IPv4AddrNoMatchError{ip: addrv4.IP, cfgIP: config.AddressIPv4.IP}
24 24
 	}
25 25
 
26 26
 	// Verify that one of the bridge IPv6 addresses matches the requested
27 27
 	// configuration.
28 28
 	if config.EnableIPv6 && !findIPv6Address(netlink.Addr{IPNet: bridgeIPv6}, addrsv6) {
29
-		return fmt.Errorf("Bridge IPv6 addresses do not match the expected bridge configuration %s", bridgeIPv6)
29
+		return (*IPv6AddrNoMatchError)(bridgeIPv6)
30 30
 	}
31 31
 
32 32
 	// By this time we have either configured a new bridge with an IP address