Przeglądaj źródła

Fix concurrent map read/write when recreating containers

Signed-off-by: Luis Rascao <[email protected]>
Luis Rascao 2 lat temu
rodzic
commit
bfeb1dc277
2 zmienionych plików z 37 dodań i 18 usunięć
  1. 27 6
      pkg/compose/convergence.go
  2. 10 12
      pkg/compose/create.go

+ 27 - 6
pkg/compose/convergence.go

@@ -399,7 +399,8 @@ func (s *composeService) createContainer(ctx context.Context, project *types.Pro
 	w := progress.ContextWriter(ctx)
 	eventName := "Container " + name
 	w.Event(progress.CreatingEvent(eventName))
-	container, err = s.createMobyContainer(ctx, project, service, name, number, nil, autoRemove, useNetworkAliases, attachStdin, w)
+	container, err = s.createMobyContainer(ctx, project, service, name, number, nil,
+		autoRemove, useNetworkAliases, attachStdin, w, mergeLabels(service.Labels, service.CustomLabels))
 	if err != nil {
 		return
 	}
@@ -424,8 +425,9 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
 	}
 	name := getContainerName(project.Name, service, number)
 	tmpName := fmt.Sprintf("%s_%s", replaced.ID[:12], name)
-	service.CustomLabels[api.ContainerReplaceLabel] = replaced.ID
-	created, err = s.createMobyContainer(ctx, project, service, tmpName, number, inherited, false, true, false, w)
+	created, err = s.createMobyContainer(ctx, project, service, tmpName, number, inherited,
+		false, true, false, w,
+		mergeLabels(service.Labels, service.CustomLabels).Add(api.ContainerReplaceLabel, replaced.ID))
 	if err != nil {
 		return created, err
 	}
@@ -475,10 +477,19 @@ func (s *composeService) startContainer(ctx context.Context, container moby.Cont
 	return nil
 }
 
-func (s *composeService) createMobyContainer(ctx context.Context, project *types.Project, service types.ServiceConfig,
-	name string, number int, inherit *moby.Container, autoRemove bool, useNetworkAliases bool, attachStdin bool, w progress.Writer) (moby.Container, error) {
+func (s *composeService) createMobyContainer(ctx context.Context,
+	project *types.Project,
+	service types.ServiceConfig,
+	name string,
+	number int,
+	inherit *moby.Container,
+	autoRemove, useNetworkAliases, attachStdin bool,
+	w progress.Writer,
+	labels types.Labels,
+) (moby.Container, error) {
 	var created moby.Container
-	containerConfig, hostConfig, networkingConfig, err := s.getCreateOptions(ctx, project, service, number, inherit, autoRemove, attachStdin)
+	containerConfig, hostConfig, networkingConfig, err := s.getCreateOptions(ctx, project, service, number, inherit,
+		autoRemove, attachStdin, labels)
 	if err != nil {
 		return created, err
 	}
@@ -725,3 +736,13 @@ func (s *composeService) startService(ctx context.Context, project *types.Projec
 	}
 	return nil
 }
+
+func mergeLabels(ls ...types.Labels) types.Labels {
+	merged := types.Labels{}
+	for _, l := range ls {
+		for k, v := range l {
+			merged[k] = v
+		}
+	}
+	return merged
+}

+ 10 - 12
pkg/compose/create.go

@@ -236,10 +236,16 @@ func (s *composeService) ensureProjectVolumes(ctx context.Context, project *type
 	return nil
 }
 
-func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, service types.ServiceConfig,
-	number int, inherit *moby.Container, autoRemove bool, attachStdin bool) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) {
+func (s *composeService) getCreateOptions(ctx context.Context,
+	p *types.Project,
+	service types.ServiceConfig,
+	number int,
+	inherit *moby.Container,
+	autoRemove, attachStdin bool,
+	labels types.Labels,
+) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) {
 
-	labels, err := s.prepareLabels(service, number)
+	labels, err := s.prepareLabels(labels, service, number)
 	if err != nil {
 		return nil, nil, nil, err
 	}
@@ -451,15 +457,7 @@ func parseSecurityOpts(p *types.Project, securityOpts []string) ([]string, bool,
 	return parsed, unconfined, nil
 }
 
-func (s *composeService) prepareLabels(service types.ServiceConfig, number int) (map[string]string, error) {
-	labels := map[string]string{}
-	for k, v := range service.Labels {
-		labels[k] = v
-	}
-	for k, v := range service.CustomLabels {
-		labels[k] = v
-	}
-
+func (s *composeService) prepareLabels(labels types.Labels, service types.ServiceConfig, number int) (map[string]string, error) {
 	hash, err := ServiceHash(service)
 	if err != nil {
 		return nil, err