Bläddra i källkod

libnetwork/osl: make constructing Interfaces more atomic

It's still not "great", but implement a `newInterface()` constructor
to create a new Interface instance, instead of creating a partial
instance and applying "options" after the fact.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 1 år sedan
förälder
incheckning
9d3b1f9419
3 ändrade filer med 29 tillägg och 38 borttagningar
  1. 27 14
      libnetwork/osl/interface_linux.go
  2. 2 12
      libnetwork/osl/namespace_linux.go
  3. 0 12
      libnetwork/osl/options_linux.go

+ 27 - 14
libnetwork/osl/interface_linux.go

@@ -14,6 +14,31 @@ import (
 	"github.com/vishvananda/netns"
 )
 
+// newInterface creates a new interface in the given namespace using the
+// provided options.
+func newInterface(ns *Namespace, srcName, dstPrefix string, options ...IfaceOption) (*Interface, error) {
+	i := &Interface{
+		srcName: srcName,
+		dstName: dstPrefix,
+		ns:      ns,
+	}
+	for _, opt := range options {
+		if opt != nil {
+			// TODO(thaJeztah): use multi-error instead of returning early.
+			if err := opt(i); err != nil {
+				return nil, err
+			}
+		}
+	}
+	if i.master != "" {
+		i.dstMaster = ns.findDst(i.master, true)
+		if i.dstMaster == "" {
+			return nil, fmt.Errorf("could not find an appropriate master %q for %q", i.master, i.srcName)
+		}
+	}
+	return i, nil
+}
+
 // Interface represents the settings and identity of a network device.
 // It is used as a return type for Network.Link, and it is common practice
 // for the caller to use this information when moving interface SrcName from
@@ -135,23 +160,11 @@ func (n *Namespace) findDst(srcName string, isBridge bool) string {
 // 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 {
-	i := &Interface{
-		srcName: srcName,
-		dstName: dstPrefix,
-		ns:      n,
-	}
-	if err := i.processInterfaceOptions(options...); err != nil {
+	i, err := newInterface(n, srcName, dstPrefix, options...)
+	if err != nil {
 		return err
 	}
 
-	if i.master != "" {
-		i.dstMaster = n.findDst(i.master, true)
-		if i.dstMaster == "" {
-			return fmt.Errorf("could not find an appropriate master %q for %q",
-				i.master, i.srcName)
-		}
-	}
-
 	n.mu.Lock()
 	if n.isDefault {
 		i.dstName = i.srcName

+ 2 - 12
libnetwork/osl/namespace_linux.go

@@ -482,20 +482,10 @@ func (n *Namespace) Destroy() error {
 func (n *Namespace) Restore(interfaces map[Iface][]IfaceOption, routes []*types.StaticRoute, gw net.IP, gw6 net.IP) error {
 	// restore interfaces
 	for iface, opts := range interfaces {
-		i := &Interface{
-			srcName: iface.SrcName,
-			dstName: iface.DstPrefix,
-			ns:      n,
-		}
-		if err := i.processInterfaceOptions(opts...); err != nil {
+		i, err := newInterface(n, iface.SrcName, iface.DstPrefix, opts...)
+		if err != nil {
 			return err
 		}
-		if i.master != "" {
-			i.dstMaster = n.findDst(i.master, true)
-			if i.dstMaster == "" {
-				return fmt.Errorf("could not find an appropriate master %q for %q", i.master, i.srcName)
-			}
-		}
 		if n.isDefault {
 			i.dstName = i.srcName
 		} else {

+ 0 - 12
libnetwork/osl/options_linux.go

@@ -24,18 +24,6 @@ func WithFamily(family int) NeighOption {
 	}
 }
 
-func (i *Interface) processInterfaceOptions(options ...IfaceOption) error {
-	for _, opt := range options {
-		if opt != nil {
-			// TODO(thaJeztah): use multi-error instead of returning early.
-			if err := opt(i); err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
-
 // WithIsBridge sets whether the interface is a bridge.
 func WithIsBridge(isBridge bool) IfaceOption {
 	return func(i *Interface) error {