Skip to content

Commit

Permalink
fingerprint: check if the CNI bridge plugin is available
Browse files Browse the repository at this point in the history
A client should declare the "bridge" network fingerprint only if the
bridge CNI plugin is available.

Currently, Linux clients with the bridge kernel module enabled (pretty
much all Linux boxes with Docker installed) declare "bridge" network,
but allocs requiring it will fail with `failed to find plugin "bridge"
in path [/opt/cni/bin]` error.
  • Loading branch information
Mahmood Ali committed Aug 11, 2021
1 parent eedfa0b commit 551288f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
13 changes: 10 additions & 3 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1236,9 +1236,16 @@ func TestClient_UpdateNodeFromFingerprintKeepsConfig(t *testing.T) {
})
require.Equal(t, int64(123), client.config.Node.NodeResources.Cpu.CpuShares)
// only the configured device is kept
require.Equal(t, 2, len(client.config.Node.NodeResources.Networks))
require.Equal(t, dev, client.config.Node.NodeResources.Networks[0].Device)
require.Equal(t, "bridge", client.config.Node.NodeResources.Networks[1].Mode)
if networks := client.config.Node.NodeResources.Networks; len(networks) == 2 {
// in Linux environments with CNI plugins present, we expect to see bridge network
require.Len(t, 2, networks)
require.Equal(t, dev, networks[0].Device)
require.Equal(t, "bridge", networks[1].Mode)
} else {
// otherwise, should only see the configured device
require.Len(t, 1, networks)
require.Equal(t, dev, networks[0].Device)
}

// Network speed is applied to all NetworkResources
client.config.NetworkInterface = ""
Expand Down
34 changes: 31 additions & 3 deletions client/fingerprint/bridge_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"

"github.com/hashicorp/go-multierror"
Expand All @@ -20,8 +21,8 @@ const (
)

func (f *BridgeFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error {
if err := f.detect(bridgeKernelModuleName); err != nil {
f.logger.Warn("failed to detect bridge kernel module, bridge network mode disabled", "error", err)
if err := f.detect(req); err != nil {
f.logger.Warn("failed to dtect bridge network setup, bridge network mode disabled", "error", err)
return nil
}

Expand All @@ -43,7 +44,34 @@ func (f *BridgeFingerprint) regexp(pattern, module string) *regexp.Regexp {
return regexp.MustCompile(fmt.Sprintf(pattern, module))
}

func (f *BridgeFingerprint) detect(module string) error {
func (f BridgeFingerprint) detect(req *FingerprintRequest) error {
if err := f.detectKernelModule(bridgeKernelModuleName); err != nil {
return fmt.Errorf("failed to detect bridge kernel module: %v", err)
}

return f.detectCNIPluginBinary(req.Config.CNIPath)
}

func (f *BridgeFingerprint) detectCNIPluginBinary(cniPath string) error {
if cniPath == "" {
return fmt.Errorf("cni is not configured")
}

path := filepath.Join(cniPath, "bridge")
fi, err := os.Stat(filepath.Join(cniPath, "bridge"))
if err != nil {
return fmt.Errorf("failed to find the bridge CNI plugin in %v: %v", path, err)
}

if !fi.Mode().IsRegular() {
return fmt.Errorf("the bridge CNI plugin is not a regular file: %v", path)

}

return nil
}

func (f *BridgeFingerprint) detectKernelModule(module string) error {
// accumulate errors from every place we might find the module
var errs error

Expand Down
4 changes: 2 additions & 2 deletions client/fingerprint/bridge_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (

func TestBridgeFingerprint_detect(t *testing.T) {
f := &BridgeFingerprint{logger: testlog.HCLogger(t)}
require.NoError(t, f.detect("ip_tables"))
require.NoError(t, f.detectKernelModule("ip_tables"))

err := f.detect("nonexistentmodule")
err := f.detectKernelModule("nonexistentmodule")
require.Error(t, err)
require.Contains(t, err.Error(), "3 errors occurred")
}
Expand Down

0 comments on commit 551288f

Please sign in to comment.