Skip to content

Commit 8b7af1d

Browse files
committed
libnet: update dnsNames on ContainerRename
The `(*Endpoint).rename()` method is changed to only mutate `ep.name` and let a new method `(*Endpoint).UpdateDNSNames()` handle DNS updates. As a consequence, the rollback code that was part of `(*Endpoint).rename()` is now removed, and DNS updates are now rolled back by `ContainerRename`. Signed-off-by: Albin Kerouanton <[email protected]>
1 parent 3bb13c7 commit 8b7af1d

2 files changed

Lines changed: 76 additions & 47 deletions

File tree

daemon/rename.go

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/containerd/log"
88
"github.com/docker/docker/api/types/events"
99
dockercontainer "github.com/docker/docker/container"
10+
"github.com/docker/docker/daemon/network"
1011
"github.com/docker/docker/errdefs"
1112
"github.com/docker/docker/libnetwork"
1213
"github.com/pkg/errors"
@@ -118,10 +119,57 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) (retErr error) {
118119
return err
119120
}
120121

121-
err = sb.Rename(strings.TrimPrefix(container.Name, "/"))
122-
if err != nil {
122+
if err := sb.Rename(newName[1:]); err != nil {
123123
return err
124124
}
125+
defer func() {
126+
if retErr != nil {
127+
if err := sb.Rename(oldName); err != nil {
128+
log.G(context.TODO()).WithFields(log.Fields{
129+
"sandboxID": sid,
130+
"oldName": oldName,
131+
"newName": newName,
132+
"error": err,
133+
}).Errorf("failed to revert sandbox rename")
134+
}
135+
}
136+
}()
137+
138+
for nwName, epConfig := range container.NetworkSettings.Networks {
139+
nw, err := daemon.FindNetwork(nwName)
140+
if err != nil {
141+
return err
142+
}
143+
144+
ep, err := nw.EndpointByID(epConfig.EndpointID)
145+
if err != nil {
146+
return err
147+
}
148+
149+
oldDNSNames := make([]string, len(epConfig.DNSNames))
150+
copy(oldDNSNames, epConfig.DNSNames)
151+
152+
epConfig.DNSNames = buildEndpointDNSNames(container, epConfig.Aliases)
153+
if err := ep.UpdateDNSNames(epConfig.DNSNames); err != nil {
154+
return err
155+
}
156+
157+
defer func(ep *libnetwork.Endpoint, epConfig *network.EndpointSettings, oldDNSNames []string) {
158+
if retErr == nil {
159+
return
160+
}
161+
162+
epConfig.DNSNames = oldDNSNames
163+
if err := ep.UpdateDNSNames(epConfig.DNSNames); err != nil {
164+
log.G(context.TODO()).WithFields(log.Fields{
165+
"sandboxID": sid,
166+
"oldName": oldName,
167+
"newName": newName,
168+
"error": err,
169+
}).Errorf("failed to revert DNSNames update")
170+
}
171+
}(ep, epConfig, oldDNSNames)
172+
}
125173
}
126174

127175
daemon.LogContainerEventWithAttributes(container, events.ActionRename, attributes)

libnetwork/endpoint.go

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -598,71 +598,52 @@ func (ep *Endpoint) sbJoin(sb *Sandbox, options ...EndpointOption) (err error) {
598598
}
599599

600600
func (ep *Endpoint) rename(name string) error {
601-
var (
602-
err error
603-
ok bool
604-
)
601+
ep.mu.Lock()
602+
ep.name = name
603+
ep.mu.Unlock()
605604

606-
n := ep.getNetwork()
607-
if n == nil {
608-
return fmt.Errorf("network not connected for ep %q", ep.name)
605+
// Update the store with the updated name
606+
if err := ep.getNetwork().getController().updateToStore(ep); err != nil {
607+
return err
609608
}
610609

611-
c := n.getController()
610+
return nil
611+
}
612612

613+
func (ep *Endpoint) UpdateDNSNames(dnsNames []string) error {
614+
nw := ep.getNetwork()
615+
c := nw.getController()
613616
sb, ok := ep.getSandbox()
614617
if !ok {
615-
log.G(context.TODO()).Warnf("rename for %s aborted, sandbox %s is not anymore present", ep.ID(), ep.sandboxID)
618+
log.G(context.TODO()).WithFields(log.Fields{
619+
"sandboxID": ep.sandboxID,
620+
"endpointID": ep.ID(),
621+
}).Warn("DNSNames update aborted, sandbox is not present anymore")
616622
return nil
617623
}
618624

619625
if c.isAgent() {
620-
if err = ep.deleteServiceInfoFromCluster(sb, true, "rename"); err != nil {
621-
return types.InternalErrorf("Could not delete service state for endpoint %s from cluster on rename: %v", ep.Name(), err)
626+
if err := ep.deleteServiceInfoFromCluster(sb, true, "UpdateDNSNames"); err != nil {
627+
return types.InternalErrorf("could not delete service state for endpoint %s from cluster on UpdateDNSNames: %v", ep.Name(), err)
622628
}
623-
} else {
624-
n.updateSvcRecord(ep, false)
625-
}
626629

627-
oldName := ep.name
628-
oldAnonymous := ep.anonymous
629-
ep.name = name
630-
ep.anonymous = false
631-
632-
if c.isAgent() {
633-
if err = ep.addServiceInfoToCluster(sb); err != nil {
634-
return types.InternalErrorf("Could not add service state for endpoint %s to cluster on rename: %v", ep.Name(), err)
630+
ep.dnsNames = dnsNames
631+
if err := ep.addServiceInfoToCluster(sb); err != nil {
632+
return types.InternalErrorf("could not add service state for endpoint %s to cluster on UpdateDNSNames: %v", ep.Name(), err)
635633
}
636-
defer func() {
637-
if err != nil {
638-
if err2 := ep.deleteServiceInfoFromCluster(sb, true, "rename"); err2 != nil {
639-
log.G(context.TODO()).WithField("main error", err).WithError(err2).Debug("Error during cleanup due deleting service info from cluster while cleaning up due to other error")
640-
}
641-
ep.name = oldName
642-
ep.anonymous = oldAnonymous
643-
if err2 := ep.addServiceInfoToCluster(sb); err2 != nil {
644-
log.G(context.TODO()).WithField("main error", err).WithError(err2).Debug("Error during cleanup due adding service to from cluster while cleaning up due to other error")
645-
}
646-
}
647-
}()
648634
} else {
649-
n.updateSvcRecord(ep, true)
650-
defer func() {
651-
if err != nil {
652-
n.updateSvcRecord(ep, false)
653-
ep.name = oldName
654-
ep.anonymous = oldAnonymous
655-
n.updateSvcRecord(ep, true)
656-
}
657-
}()
635+
nw.updateSvcRecord(ep, false)
636+
637+
ep.dnsNames = dnsNames
638+
nw.updateSvcRecord(ep, true)
658639
}
659640

660641
// Update the store with the updated name
661-
if err = c.updateToStore(ep); err != nil {
642+
if err := c.updateToStore(ep); err != nil {
662643
return err
663644
}
664645

665-
return err
646+
return nil
666647
}
667648

668649
func (ep *Endpoint) hasInterface(iName string) bool {

0 commit comments

Comments
 (0)