Exec executes a given command on a running container specified by `ServiceName` (and `Index` if it has multiple instances).
(ctx context.Context, eo ExecOptions)
| 49 | // Exec executes a given command on a running container specified by |
| 50 | // `ServiceName` (and `Index` if it has multiple instances). |
| 51 | func (c *Composer) Exec(ctx context.Context, eo ExecOptions) error { |
| 52 | // Exec does not need to lock and should allow concurrency. |
| 53 | if err := Unlock(); err != nil { |
| 54 | return err |
| 55 | } |
| 56 | |
| 57 | containers, err := c.Containers(ctx, eo.ServiceName) |
| 58 | if err != nil { |
| 59 | return fmt.Errorf("fail to get containers for service %s: %w", eo.ServiceName, err) |
| 60 | } |
| 61 | if len(containers) == 0 { |
| 62 | return fmt.Errorf("no running containers from service %s", eo.ServiceName) |
| 63 | } |
| 64 | if eo.Index > len(containers) { |
| 65 | return fmt.Errorf("index (%d) out of range: only %d running instances from service %s", |
| 66 | eo.Index, len(containers), eo.ServiceName) |
| 67 | } |
| 68 | if len(containers) == 1 { |
| 69 | return c.exec(ctx, containers[0], eo) |
| 70 | } |
| 71 | // The order of the containers is not consistently ascending |
| 72 | // we need to re-sort them. |
| 73 | sort.SliceStable(containers, func(i, j int) bool { |
| 74 | infoI, _ := containers[i].Info(ctx, containerd.WithoutRefreshedMetadata) |
| 75 | infoJ, _ := containers[j].Info(ctx, containerd.WithoutRefreshedMetadata) |
| 76 | segsI := strings.Split(infoI.Labels[labels.Name], serviceparser.Separator) |
| 77 | segsJ := strings.Split(infoJ.Labels[labels.Name], serviceparser.Separator) |
| 78 | indexI, _ := strconv.Atoi(segsI[len(segsI)-1]) |
| 79 | indexJ, _ := strconv.Atoi(segsJ[len(segsJ)-1]) |
| 80 | return indexI < indexJ |
| 81 | }) |
| 82 | return c.exec(ctx, containers[eo.Index-1], eo) |
| 83 | } |
| 84 | |
| 85 | // exec constructs/executes the `nerdctl exec` command to be executed on the given container. |
| 86 | func (c *Composer) exec(ctx context.Context, container containerd.Container, eo ExecOptions) error { |
no test coverage detected