mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
This package was originally internal, but was moved out when BuildKit used it for its integration tests. That's no longer the case, so we can make it internal again. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
104 lines
3.6 KiB
Go
104 lines
3.6 KiB
Go
package environment
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"maps"
|
|
"net"
|
|
"testing"
|
|
|
|
"github.com/moby/moby/v2/daemon/libnetwork/drivers/bridge"
|
|
"github.com/moby/moby/v2/daemon/libnetwork/nlwrap"
|
|
"github.com/vishvananda/netlink"
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
type defaultBridgeInfo struct {
|
|
bridge netlink.Link
|
|
addrs map[string]*netlink.Addr
|
|
}
|
|
|
|
var _, llSubnet, _ = net.ParseCIDR("fe80::/64")
|
|
|
|
// ProtectDefaultBridge remembers default bridge settings so that, when a test
|
|
// runs its own daemon and tramples settings of the bridge belonging to the
|
|
// CI-started bridge, the bridge is restored to its old state before the next
|
|
// test.
|
|
//
|
|
// For example, a test may enable IPv6 with a link-local fixed-cidr-v6. That's
|
|
// likely to break later tests, even if they also start their own daemon
|
|
// (because, in the absence of any specific settings, the daemon learns default
|
|
// bridge config from addresses on an existing bridge device).
|
|
func ProtectDefaultBridge(_ context.Context, t testing.TB, testEnv *Execution) {
|
|
t.Helper()
|
|
// Find the bridge - there should always be one, belonging to the daemon started by CI.
|
|
br, err := nlwrap.LinkByName(bridge.DefaultBridgeName)
|
|
if err != nil {
|
|
var lnf netlink.LinkNotFoundError
|
|
if !errors.As(err, &lnf) {
|
|
t.Fatal("Getting default bridge before test:", err)
|
|
}
|
|
return
|
|
}
|
|
testEnv.ProtectDefaultBridge(t, &defaultBridgeInfo{
|
|
bridge: br,
|
|
addrs: getAddrs(t, br),
|
|
})
|
|
}
|
|
|
|
func getAddrs(t testing.TB, br netlink.Link) map[string]*netlink.Addr {
|
|
t.Helper()
|
|
addrs, err := nlwrap.AddrList(br, netlink.FAMILY_ALL)
|
|
assert.NilError(t, err, "Getting default bridge addresses before test")
|
|
addrMap := map[string]*netlink.Addr{}
|
|
for _, addr := range addrs {
|
|
addrMap[addr.IPNet.String()] = &addr
|
|
}
|
|
return addrMap
|
|
}
|
|
|
|
// ProtectDefaultBridge stores default bridge info, to be restored on clean.
|
|
func (e *Execution) ProtectDefaultBridge(t testing.TB, info *defaultBridgeInfo) {
|
|
e.protectedElements.defaultBridgeInfo = info
|
|
}
|
|
|
|
func restoreDefaultBridge(t testing.TB, info *defaultBridgeInfo) {
|
|
t.Helper()
|
|
if info == nil {
|
|
return
|
|
}
|
|
// Re-create the bridge if the test was antisocial enough to delete it.
|
|
// Yes, I'm looking at you TestDockerDaemonSuite/TestBuildOnDisabledBridgeNetworkDaemon.
|
|
br, err := nlwrap.LinkByName(bridge.DefaultBridgeName)
|
|
if err != nil {
|
|
var lnf netlink.LinkNotFoundError
|
|
if !errors.As(err, &lnf) {
|
|
t.Fatal("Failed to find default bridge after test:", err)
|
|
}
|
|
err := netlink.LinkAdd(info.bridge)
|
|
assert.NilError(t, err, "Failed to re-create default bridge after test")
|
|
br, err = nlwrap.LinkByName(bridge.DefaultBridgeName)
|
|
assert.NilError(t, err, "Failed to find re-created default bridge after test")
|
|
}
|
|
addrs, err := nlwrap.AddrList(br, netlink.FAMILY_ALL)
|
|
assert.NilError(t, err, "Failed get default bridge addresses after test")
|
|
// Delete addresses the bridge didn't have before the test, apart from IPv6 LL
|
|
// addresses - because the bridge doesn't get a kernel-assigned LL address until
|
|
// the first veth is hooked up and, once that address is deleted, it's not
|
|
// re-added.
|
|
wantAddrs := maps.Clone(info.addrs)
|
|
for _, addr := range addrs {
|
|
if _, ok := wantAddrs[addr.IPNet.String()]; ok {
|
|
delete(wantAddrs, addr.IPNet.String())
|
|
} else if !llSubnet.Contains(addr.IP) {
|
|
err := netlink.AddrDel(br, &netlink.Addr{IPNet: addr.IPNet})
|
|
assert.NilError(t, err, "Failed to remove default bridge address '%s' after test", addr.IPNet.String())
|
|
}
|
|
}
|
|
// Add missing addresses.
|
|
for _, wantAddr := range wantAddrs {
|
|
err = netlink.AddrAdd(br, wantAddr)
|
|
assert.NilError(t, err, "Failed to add default bridge address '%s' after test", wantAddr.IPNet.String())
|
|
}
|
|
}
|