Repository: docker/compose
File: pkg/compose/plugins.go (Go)

Code before:
	}
	cmd.Env = env.Values()

	// Use docker/cli mechanism to propagate termination signal to child process
	server, err := socket.NewPluginServer(nil)
	if err == nil {
		defer server.Close() //nolint:errcheck
		cmd.Cancel = server.Close
		cmd.Env = replace(cmd.Env, socket.EnvKey, server.Addr().String())
	}

	cmd.Env = append(cmd.Env, fmt.Sprintf("DOCKER_CONTEXT=%s", s.dockerCli.CurrentContext()))

	// propagate opentelemetry context to child process, see https://github.com/open-telemetry/oteps/blob/main/text/0258-env-context-baggage-carriers.md
	carrier := propagation.MapCarrier{}
	otel.GetTextMapPropagator().Inject(ctx, &carrier)
	cmd.Env = append(cmd.Env, types.Mapping(carrier).Values()...)
	return cmd
}

func (s *composeService) getPluginMetadata(path string) map[string]CommandMetadata {
	cmd := exec.Command(path, "compose", "metadata")
	stdout := &bytes.Buffer{}
	cmd.Stdout = stdout

	if err := cmd.Start(); err != nil {
		logrus.Debugf("failed to start plugin metadata command: %v", err)
		return nil
	}
	if err := cmd.Wait(); err != nil {
		var exiterr *exec.ExitError
		if errors.As(err, &exiterr) {
			logrus.Debugf("plugin metadata command failed with exit code: %d\n", exiterr.ExitCode())
		}
		return nil
	}

	decoder := json.NewDecoder(stdout)
	var metadata map[string]CommandMetadata
	if err := decoder.Decode(&metadata); err != nil {
		output, _ := io.ReadAll(stdout)
		logrus.Debugf("failed to decode plugin metadata: %v - %s", err, output)
		return nil
	}
	return metadata
}

type CommandMetadata struct {
	Parameters []ParametersMetadata `json:"parameters"`
}


Review comment (suggestion):
can just call `cmd.Run()` as we don't try to decode a long running json stream here

Code after:
			if _, ok := currentCommandMetadata.GetParameter(k); commandMetadataIsEmpty || ok {
				args = append(args, fmt.Sprintf("--%s=%s", k, value))
			}
		}
	}
	args = append(args, service.Name)

	cmd := exec.CommandContext(ctx, path, args...)
	// exec provider command with same environment Compose is running
	env := types.NewMapping(os.Environ())
	// but remove DOCKER_CLI_PLUGIN... variable so plugin can detect it run standalone
	delete(env, manager.ReexecEnvvar)
	// and add the explicit environment variables set for service
	for key, val := range service.Environment.RemoveEmpty().ToMapping() {
		env[key] = val
	}
	cmd.Env = env.Values()

	// Use docker/cli mechanism to propagate termination signal to child process
	server, err := socket.NewPluginServer(nil)
	if err == nil {
		defer server.Close() //nolint:errcheck
		cmd.Cancel = server.Close
		cmd.Env = replace(cmd.Env, socket.EnvKey, server.Addr().String())
	}

	cmd.Env = append(cmd.Env, fmt.Sprintf("DOCKER_CONTEXT=%s", s.dockerCli.CurrentContext()))

	// propagate opentelemetry context to child process, see https://github.com/open-telemetry/oteps/blob/main/text/0258-env-context-baggage-carriers.md
	carrier := propagation.MapCarrier{}
	otel.GetTextMapPropagator().Inject(ctx, &carrier)
	cmd.Env = append(cmd.Env, types.Mapping(carrier).Values()...)
	return cmd, nil
}

func (s *composeService) getPluginMetadata(path, command string) ProviderMetadata {
	cmd := exec.Command(path, "compose", "metadata")
	stdout := &bytes.Buffer{}
	cmd.Stdout = stdout

	if err := cmd.Run(); err != nil {
		logrus.Debugf("failed to start plugin metadata command: %v", err)
		return ProviderMetadata{}
	}

	var metadata ProviderMetadata
	if err := json.Unmarshal(stdout.Bytes(), &metadata); err != nil {
		output, _ := io.ReadAll(stdout)
		logrus.Debugf("failed to decode plugin metadata: %v - %s", err, output)
		return ProviderMetadata{}
	}