mirror of
https://github.com/devplayer0/docker-net-dhcp
synced 2024-10-30 09:20:28 +00:00
Prevent container veth name race condition
This commit is contained in:
parent
0cc1fb82ec
commit
126dd55069
@ -17,6 +17,8 @@ import (
|
||||
"github.com/devplayer0/docker-net-dhcp/pkg/util"
|
||||
)
|
||||
|
||||
const pollTime = 100 * time.Millisecond
|
||||
|
||||
type dhcpManager struct {
|
||||
docker *docker.Client
|
||||
joinReq JoinRequest
|
||||
@ -197,7 +199,7 @@ func (m *dhcpManager) setupClient(v6 bool) (chan error, error) {
|
||||
|
||||
func (m *dhcpManager) Start(ctx context.Context) error {
|
||||
var err error
|
||||
m.nsHandle, err = util.AwaitNetNS(ctx, m.joinReq.SandboxKey, 100*time.Millisecond)
|
||||
m.nsHandle, err = util.AwaitNetNS(ctx, m.joinReq.SandboxKey, pollTime)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get sandbox network namespace: %w", err)
|
||||
}
|
||||
@ -209,7 +211,7 @@ func (m *dhcpManager) Start(ctx context.Context) error {
|
||||
}
|
||||
|
||||
if err := func() error {
|
||||
hostName, _ := vethPairNames(m.joinReq.EndpointID)
|
||||
hostName, oldCtrName := vethPairNames(m.joinReq.EndpointID)
|
||||
hostLink, err := netlink.LinkByName(hostName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find host side of veth pair: %w", err)
|
||||
@ -224,9 +226,15 @@ func (m *dhcpManager) Start(ctx context.Context) error {
|
||||
return fmt.Errorf("failed to get container side of veth's index: %w", err)
|
||||
}
|
||||
|
||||
m.ctrLink, err = util.AwaitLinkByIndex(ctx, m.netHandle, ctrIndex, 100*time.Millisecond)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get link for container side of veth pair: %w", err)
|
||||
if err := util.AwaitCondition(ctx, func() (bool, error) {
|
||||
m.ctrLink, err = util.AwaitLinkByIndex(ctx, m.netHandle, ctrIndex, pollTime)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to get link for container side of veth pair: %w", err)
|
||||
}
|
||||
|
||||
return m.ctrLink.Attrs().Name != oldCtrName, nil
|
||||
}, pollTime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dockerNet, err := m.docker.NetworkInspect(ctx, m.joinReq.NetworkID, dTypes.NetworkInspectOptions{})
|
||||
|
33
pkg/util/general.go
Normal file
33
pkg/util/general.go
Normal file
@ -0,0 +1,33 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
func AwaitCondition(ctx context.Context, cond func() (bool, error), interval time.Duration) error {
|
||||
errChan := make(chan error)
|
||||
go func() {
|
||||
for {
|
||||
ok, err := cond()
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
if ok {
|
||||
errChan <- nil
|
||||
return
|
||||
}
|
||||
|
||||
time.Sleep(interval)
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-errChan:
|
||||
return err
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/vishvananda/netlink"
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
@ -31,7 +31,7 @@ func AwaitNetNS(ctx context.Context, path string, interval time.Duration) (netns
|
||||
return ns, nil
|
||||
case <-ctx.Done():
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("path", path).Error("Failed to await network namespace")
|
||||
log.WithError(err).WithField("path", path).Error("Failed to await network namespace")
|
||||
}
|
||||
return dummy, ctx.Err()
|
||||
}
|
||||
@ -59,7 +59,7 @@ func AwaitLinkByIndex(ctx context.Context, handle *netlink.Handle, index int, in
|
||||
return link, nil
|
||||
case <-ctx.Done():
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("index", index).Error("Failed to await link by index")
|
||||
log.WithError(err).WithField("index", index).Error("Failed to await link by index")
|
||||
}
|
||||
return dummy, ctx.Err()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user