Skip to content

Commit 3ca75bd

Browse files
andrii-telesh-readdlendeloof
authored andcommitted
Fix the inability to restart the Compose stack after network configuration change
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent eb3074b commit 3ca75bd

File tree

1 file changed

+58
-7
lines changed

1 file changed

+58
-7
lines changed

pkg/compose/create.go

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ import (
3131
"github.com/compose-spec/compose-go/v2/paths"
3232
"github.com/compose-spec/compose-go/v2/types"
3333
cerrdefs "github.com/containerd/errdefs"
34-
"github.com/docker/compose/v2/pkg/api"
35-
"github.com/docker/compose/v2/pkg/progress"
36-
"github.com/docker/compose/v2/pkg/prompt"
3734
"github.com/docker/docker/api/types/blkiodev"
3835
"github.com/docker/docker/api/types/container"
3936
"github.com/docker/docker/api/types/filters"
@@ -45,6 +42,10 @@ import (
4542
"github.com/docker/go-connections/nat"
4643
"github.com/sirupsen/logrus"
4744
cdi "tags.cncf.io/container-device-interface/pkg/parser"
45+
46+
"github.com/docker/compose/v2/pkg/api"
47+
"github.com/docker/compose/v2/pkg/progress"
48+
"github.com/docker/compose/v2/pkg/prompt"
4849
)
4950

5051
type createOptions struct {
@@ -1262,6 +1263,9 @@ func (s *composeService) ensureNetwork(ctx context.Context, project *types.Proje
12621263
}
12631264

12641265
func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *types.Project, name string, n *types.NetworkConfig) (string, error) { //nolint:gocyclo
1266+
// This is containers that could be left after a diverged network was removed
1267+
var dangledContainers Containers
1268+
12651269
// First, try to find a unique network matching by name or ID
12661270
inspect, err := s.apiClient().NetworkInspect(ctx, n.Name, network.InspectOptions{})
12671271
if err == nil {
@@ -1295,7 +1299,7 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *ty
12951299
return inspect.ID, nil
12961300
}
12971301

1298-
err = s.removeDivergedNetwork(ctx, project, name, n)
1302+
dangledContainers, err = s.removeDivergedNetwork(ctx, project, name, n)
12991303
if err != nil {
13001304
return "", err
13011305
}
@@ -1392,10 +1396,16 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *ty
13921396
return "", fmt.Errorf("failed to create network %s: %w", n.Name, err)
13931397
}
13941398
w.Event(progress.CreatedEvent(networkEventName))
1399+
1400+
err = s.connectNetwork(ctx, n.Name, dangledContainers, nil)
1401+
if err != nil {
1402+
return "", err
1403+
}
1404+
13951405
return resp.ID, nil
13961406
}
13971407

1398-
func (s *composeService) removeDivergedNetwork(ctx context.Context, project *types.Project, name string, n *types.NetworkConfig) error {
1408+
func (s *composeService) removeDivergedNetwork(ctx context.Context, project *types.Project, name string, n *types.NetworkConfig) (Containers, error) {
13991409
// Remove services attached to this network to force recreation
14001410
var services []string
14011411
for _, service := range project.Services.Filter(func(config types.ServiceConfig) bool {
@@ -1412,13 +1422,54 @@ func (s *composeService) removeDivergedNetwork(ctx context.Context, project *typ
14121422
Project: project,
14131423
})
14141424
if err != nil {
1415-
return err
1425+
return nil, err
1426+
}
1427+
1428+
containers, err := s.getContainers(ctx, project.Name, oneOffExclude, true, services...)
1429+
if err != nil {
1430+
return nil, err
1431+
}
1432+
1433+
err = s.disconnectNetwork(ctx, n.Name, containers)
1434+
if err != nil {
1435+
return nil, err
14161436
}
14171437

14181438
err = s.apiClient().NetworkRemove(ctx, n.Name)
14191439
eventName := fmt.Sprintf("Network %s", n.Name)
14201440
progress.ContextWriter(ctx).Event(progress.RemovedEvent(eventName))
1421-
return err
1441+
return containers, err
1442+
}
1443+
1444+
func (s *composeService) disconnectNetwork(
1445+
ctx context.Context,
1446+
network string,
1447+
containers Containers,
1448+
) error {
1449+
for _, c := range containers {
1450+
err := s.apiClient().NetworkDisconnect(ctx, network, c.ID, true)
1451+
if err != nil {
1452+
return err
1453+
}
1454+
}
1455+
1456+
return nil
1457+
}
1458+
1459+
func (s *composeService) connectNetwork(
1460+
ctx context.Context,
1461+
network string,
1462+
containers Containers,
1463+
config *network.EndpointSettings,
1464+
) error {
1465+
for _, c := range containers {
1466+
err := s.apiClient().NetworkConnect(ctx, network, c.ID, config)
1467+
if err != nil {
1468+
return err
1469+
}
1470+
}
1471+
1472+
return nil
14221473
}
14231474

14241475
func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.NetworkConfig) (string, error) {

0 commit comments

Comments
 (0)