Skip to content

Commit cabb02f

Browse files
committed
compose: align convergence with Docker Compose
Write com.docker.compose.config-hash label on create/run. Fixes: #4547 Signed-off-by: ChengyuZhu6 <[email protected]>
1 parent 4d28f8b commit cabb02f

File tree

4 files changed

+39
-2
lines changed

4 files changed

+39
-2
lines changed

pkg/composer/create.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,15 @@ func (c *Composer) createServiceContainer(ctx context.Context, service *servicep
188188
cidFilename := filepath.Join(tempDir, "cid")
189189

190190
//add metadata labels to container https://github.com/compose-spec/compose-spec/blob/master/spec.md#labels
191+
currentHash, err := ServiceHash(*service.Unparsed)
192+
if err != nil {
193+
return "", fmt.Errorf("failed computing service hash for %s: %w", container.Name, err)
194+
}
191195
container.RunArgs = append([]string{
192196
"--cidfile=" + cidFilename,
193197
fmt.Sprintf("-l=%s=%s", labels.ComposeProject, c.project.Name),
194198
fmt.Sprintf("-l=%s=%s", labels.ComposeService, service.Unparsed.Name),
199+
fmt.Sprintf("-l=%s=%s", labels.ComposeConfigHash, currentHash),
195200
}, container.RunArgs...)
196201

197202
cmd := c.createNerdctlCmd(ctx, append([]string{"create"}, container.RunArgs...)...)

pkg/composer/up.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (c *Composer) Up(ctx context.Context, uo UpOptions, services []string) erro
8585

8686
var parsedServices []*serviceparser.Service
8787
// use WithServices to sort the services in dependency order
88-
if err := c.project.ForEachService(services, func(name string, svc *types.ServiceConfig) error {
88+
forEachFn := func(name string, svc *types.ServiceConfig) error {
8989
if replicas, ok := uo.Scale[svc.Name]; ok {
9090
if svc.Deploy == nil {
9191
svc.Deploy = &types.DeployConfig{}
@@ -98,7 +98,9 @@ func (c *Composer) Up(ctx context.Context, uo UpOptions, services []string) erro
9898
}
9999
parsedServices = append(parsedServices, ps)
100100
return nil
101-
}); err != nil {
101+
}
102+
err := c.project.ForEachService(services, forEachFn)
103+
if err != nil {
102104
return err
103105
}
104106

pkg/composer/up_service.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,28 @@ func (c *Composer) upServiceContainer(ctx context.Context, service *serviceparse
155155

156156
// delete container if it already exists
157157
if existingCid != "" {
158+
// Default behavior for RecreateDiverged: compare stored hash with current service hash
159+
if recreate == RecreateDiverged {
160+
currentHash, err := ServiceHash(*service.Unparsed)
161+
if err != nil {
162+
return "", fmt.Errorf("failed computing service hash for %s: %w", container.Name, err)
163+
}
164+
con, err := c.client.LoadContainer(ctx, existingCid)
165+
if err != nil {
166+
return "", fmt.Errorf("failed to load container %s: %w", existingCid, err)
167+
}
168+
lbls, err := con.Labels(ctx)
169+
if err != nil {
170+
return "", fmt.Errorf("failed to read labels for %s: %w", existingCid, err)
171+
}
172+
if lbls[labels.ComposeConfigHash] == currentHash {
173+
cmd := c.createNerdctlCmd(ctx, append([]string{"start"}, existingCid)...)
174+
if err := c.executeUpCmd(ctx, cmd, container.Name, runFlagD, service.Unparsed.StdinOpen); err != nil {
175+
return "", fmt.Errorf("error while starting existing container %s: %w", container.Name, err)
176+
}
177+
return existingCid, nil
178+
}
179+
}
158180
log.G(ctx).Debugf("Container %q already exists, deleting", container.Name)
159181
delCmd := c.createNerdctlCmd(ctx, "rm", "-f", container.Name)
160182
if err = delCmd.Run(); err != nil {
@@ -184,10 +206,15 @@ func (c *Composer) upServiceContainer(ctx context.Context, service *serviceparse
184206
}
185207

186208
//add metadata labels to container https://github.com/compose-spec/compose-spec/blob/master/spec.md#labels
209+
currentHash, err := ServiceHash(*service.Unparsed)
210+
if err != nil {
211+
return "", fmt.Errorf("failed computing service hash for %s: %w", container.Name, err)
212+
}
187213
container.RunArgs = append([]string{
188214
"--cidfile=" + cidFilename,
189215
fmt.Sprintf("-l=%s=%s", labels.ComposeProject, c.project.Name),
190216
fmt.Sprintf("-l=%s=%s", labels.ComposeService, service.Unparsed.Name),
217+
fmt.Sprintf("-l=%s=%s", labels.ComposeConfigHash, currentHash),
191218
}, container.RunArgs...)
192219

193220
cmd := c.createNerdctlCmd(ctx, append([]string{"run"}, container.RunArgs...)...)

pkg/labels/labels.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ const (
4141
//Compose Volume Name
4242
ComposeVolume = "com.docker.compose.volume"
4343

44+
// ComposeConfigHash stores the service configuration hash used for convergence decisions
45+
ComposeConfigHash = "com.docker.compose.config-hash"
46+
4447
// Hostname
4548
Hostname = Prefix + "hostname"
4649

0 commit comments

Comments
 (0)