Sfoglia il codice sorgente

Merge pull request #10763 from ndeloof/exec_index

when --index is not set select first service container
Guillaume Lours 2 anni fa
parent
commit
e90df62bb0

+ 3 - 3
cmd/compose/cp.go

@@ -64,10 +64,10 @@ func copyCommand(p *ProjectOptions, backend api.Service) *cobra.Command {
 	}
 
 	flags := copyCmd.Flags()
-	flags.IntVar(&opts.index, "index", 0, "Index of the container if there are multiple instances of a service .")
-	flags.BoolVar(&opts.all, "all", false, "Copy to all the containers of the service.")
+	flags.IntVar(&opts.index, "index", 0, "index of the container if service has multiple replicas")
+	flags.BoolVar(&opts.all, "all", false, "copy to all the containers of the service.")
 	flags.MarkHidden("all")                                                                                                      //nolint:errcheck
-	flags.MarkDeprecated("all", "By default all the containers of the service will get the source file/directory to be copied.") //nolint:errcheck
+	flags.MarkDeprecated("all", "by default all the containers of the service will get the source file/directory to be copied.") //nolint:errcheck
 	flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")
 	flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")
 

+ 1 - 1
cmd/compose/exec.go

@@ -65,7 +65,7 @@ func execCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *c
 
 	runCmd.Flags().BoolVarP(&opts.detach, "detach", "d", false, "Detached mode: Run command in the background.")
 	runCmd.Flags().StringArrayVarP(&opts.environment, "env", "e", []string{}, "Set environment variables")
-	runCmd.Flags().IntVar(&opts.index, "index", 1, "index of the container if there are multiple instances of a service [default: 1].")
+	runCmd.Flags().IntVar(&opts.index, "index", 0, "index of the container if service has multiple replicas")
 	runCmd.Flags().BoolVarP(&opts.privileged, "privileged", "", false, "Give extended privileges to the process.")
 	runCmd.Flags().StringVarP(&opts.user, "user", "u", "", "Run the command as this user.")
 	runCmd.Flags().BoolVarP(&opts.noTty, "no-TTY", "T", !streams.Out().IsTerminal(), "Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY.")

+ 1 - 1
cmd/compose/port.go

@@ -57,7 +57,7 @@ func portCommand(p *ProjectOptions, streams api.Streams, backend api.Service) *c
 		ValidArgsFunction: completeServiceNames(p),
 	}
 	cmd.Flags().StringVar(&opts.protocol, "protocol", "tcp", "tcp or udp")
-	cmd.Flags().IntVar(&opts.index, "index", 1, "index of the container if service has multiple replicas")
+	cmd.Flags().IntVar(&opts.index, "index", 0, "index of the container if service has multiple replicas")
 	return cmd
 }
 

+ 6 - 6
docs/reference/compose_cp.md

@@ -5,12 +5,12 @@ Copy files/folders between a service container and the local filesystem
 
 ### Options
 
-| Name                  | Type  | Default | Description                                                           |
-|:----------------------|:------|:--------|:----------------------------------------------------------------------|
-| `-a`, `--archive`     |       |         | Archive mode (copy all uid/gid information)                           |
-| `--dry-run`           |       |         | Execute command in dry run mode                                       |
-| `-L`, `--follow-link` |       |         | Always follow symbol link in SRC_PATH                                 |
-| `--index`             | `int` | `0`     | Index of the container if there are multiple instances of a service . |
+| Name                  | Type  | Default | Description                                             |
+|:----------------------|:------|:--------|:--------------------------------------------------------|
+| `-a`, `--archive`     |       |         | Archive mode (copy all uid/gid information)             |
+| `--dry-run`           |       |         | Execute command in dry run mode                         |
+| `-L`, `--follow-link` |       |         | Always follow symbol link in SRC_PATH                   |
+| `--index`             | `int` | `0`     | index of the container if service has multiple replicas |
 
 
 <!---MARKER_GEN_END-->

+ 10 - 10
docs/reference/compose_exec.md

@@ -5,16 +5,16 @@ Execute a command in a running container.
 
 ### Options
 
-| Name              | Type          | Default | Description                                                                       |
-|:------------------|:--------------|:--------|:----------------------------------------------------------------------------------|
-| `-d`, `--detach`  |               |         | Detached mode: Run command in the background.                                     |
-| `--dry-run`       |               |         | Execute command in dry run mode                                                   |
-| `-e`, `--env`     | `stringArray` |         | Set environment variables                                                         |
-| `--index`         | `int`         | `1`     | index of the container if there are multiple instances of a service [default: 1]. |
-| `-T`, `--no-TTY`  |               |         | Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY.  |
-| `--privileged`    |               |         | Give extended privileges to the process.                                          |
-| `-u`, `--user`    | `string`      |         | Run the command as this user.                                                     |
-| `-w`, `--workdir` | `string`      |         | Path to workdir directory for this command.                                       |
+| Name              | Type          | Default | Description                                                                      |
+|:------------------|:--------------|:--------|:---------------------------------------------------------------------------------|
+| `-d`, `--detach`  |               |         | Detached mode: Run command in the background.                                    |
+| `--dry-run`       |               |         | Execute command in dry run mode                                                  |
+| `-e`, `--env`     | `stringArray` |         | Set environment variables                                                        |
+| `--index`         | `int`         | `0`     | index of the container if service has multiple replicas                          |
+| `-T`, `--no-TTY`  |               |         | Disable pseudo-TTY allocation. By default `docker compose exec` allocates a TTY. |
+| `--privileged`    |               |         | Give extended privileges to the process.                                         |
+| `-u`, `--user`    | `string`      |         | Run the command as this user.                                                    |
+| `-w`, `--workdir` | `string`      |         | Path to workdir directory for this command.                                      |
 
 
 <!---MARKER_GEN_END-->

+ 1 - 1
docs/reference/compose_port.md

@@ -8,7 +8,7 @@ Print the public port for a port binding.
 | Name         | Type     | Default | Description                                             |
 |:-------------|:---------|:--------|:--------------------------------------------------------|
 | `--dry-run`  |          |         | Execute command in dry run mode                         |
-| `--index`    | `int`    | `1`     | index of the container if service has multiple replicas |
+| `--index`    | `int`    | `0`     | index of the container if service has multiple replicas |
 | `--protocol` | `string` | `tcp`   | tcp or udp                                              |
 
 

+ 2 - 3
docs/reference/docker_compose_cp.yaml

@@ -10,7 +10,7 @@ options:
     - option: all
       value_type: bool
       default_value: "false"
-      description: Copy to all the containers of the service.
+      description: copy to all the containers of the service.
       deprecated: true
       hidden: true
       experimental: false
@@ -42,8 +42,7 @@ options:
     - option: index
       value_type: int
       default_value: "0"
-      description: |
-        Index of the container if there are multiple instances of a service .
+      description: index of the container if service has multiple replicas
       deprecated: false
       hidden: false
       experimental: false

+ 2 - 3
docs/reference/docker_compose_exec.yaml

@@ -33,9 +33,8 @@ options:
       swarm: false
     - option: index
       value_type: int
-      default_value: "1"
-      description: |
-        index of the container if there are multiple instances of a service [default: 1].
+      default_value: "0"
+      description: index of the container if service has multiple replicas
       deprecated: false
       hidden: false
       experimental: false

+ 1 - 1
docs/reference/docker_compose_port.yaml

@@ -7,7 +7,7 @@ plink: docker_compose.yaml
 options:
     - option: index
       value_type: int
-      default_value: "1"
+      default_value: "0"
       description: index of the container if service has multiple replicas
       deprecated: false
       hidden: false

+ 13 - 2
pkg/compose/containers.go

@@ -20,6 +20,7 @@ import (
 	"context"
 	"fmt"
 	"sort"
+	"strconv"
 
 	"github.com/docker/compose/v2/pkg/api"
 	"github.com/docker/compose/v2/pkg/utils"
@@ -72,7 +73,9 @@ func getDefaultFilters(projectName string, oneOff oneOff, selectedServices ...st
 
 func (s *composeService) getSpecifiedContainer(ctx context.Context, projectName string, oneOff oneOff, stopped bool, serviceName string, containerIndex int) (moby.Container, error) {
 	defaultFilters := getDefaultFilters(projectName, oneOff, serviceName)
-	defaultFilters = append(defaultFilters, containerNumberFilter(containerIndex))
+	if containerIndex > 0 {
+		defaultFilters = append(defaultFilters, containerNumberFilter(containerIndex))
+	}
 	containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
 		Filters: filters.NewArgs(
 			defaultFilters...,
@@ -83,8 +86,16 @@ func (s *composeService) getSpecifiedContainer(ctx context.Context, projectName
 		return moby.Container{}, err
 	}
 	if len(containers) < 1 {
-		return moby.Container{}, fmt.Errorf("service %q is not running container #%d", serviceName, containerIndex)
+		if containerIndex > 0 {
+			return moby.Container{}, fmt.Errorf("service %q is not running container #%d", serviceName, containerIndex)
+		}
+		return moby.Container{}, fmt.Errorf("service %q is not running", serviceName)
 	}
+	sort.Slice(containers, func(i, j int) bool {
+		x, _ := strconv.Atoi(containers[i].Labels[api.ContainerNumberLabel])
+		y, _ := strconv.Atoi(containers[j].Labels[api.ContainerNumberLabel])
+		return x < y
+	})
 	container := containers[0]
 	return container, nil
 }

+ 1 - 12
pkg/compose/port.go

@@ -24,25 +24,14 @@ import (
 	"github.com/docker/compose/v2/pkg/api"
 
 	moby "github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/filters"
 )
 
 func (s *composeService) Port(ctx context.Context, projectName string, service string, port uint16, options api.PortOptions) (string, int, error) {
 	projectName = strings.ToLower(projectName)
-	list, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(projectName),
-			serviceFilter(service),
-			containerNumberFilter(options.Index),
-		),
-	})
+	container, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, service, options.Index)
 	if err != nil {
 		return "", 0, err
 	}
-	if len(list) == 0 {
-		return "", 0, fmt.Errorf("no container found for %s%s%d", service, api.Separator, options.Index)
-	}
-	container := list[0]
 	for _, p := range container.Ports {
 		if p.PrivatePort == port && p.Type == options.Protocol {
 			return p.IP, int(p.PublicPort), nil