(ctx context.Context, client *containerd.Client, containers []containerd.Container, globalOptions *types.GlobalCommandOptions, nerdctlCmd string, nerdctlArgs []string)
| 99 | } |
| 100 | |
| 101 | func startContainers(ctx context.Context, client *containerd.Client, containers []containerd.Container, globalOptions *types.GlobalCommandOptions, nerdctlCmd string, nerdctlArgs []string) error { |
| 102 | eg, ctx := errgroup.WithContext(ctx) |
| 103 | for _, c := range containers { |
| 104 | c := c |
| 105 | eg.Go(func() error { |
| 106 | if cStatus, err := containerutil.ContainerStatus(ctx, c); err != nil { |
| 107 | // NOTE: NotFound doesn't mean that container hasn't started. |
| 108 | // In docker/CRI-containerd plugin, the task will be deleted |
| 109 | // when it exits. So, the status will be "created" for this |
| 110 | // case. |
| 111 | if !errdefs.IsNotFound(err) { |
| 112 | return err |
| 113 | } |
| 114 | } else if cStatus.Status == containerd.Running { |
| 115 | return nil |
| 116 | } |
| 117 | |
| 118 | // in compose, always disable attach |
| 119 | if err := containerutil.Start(ctx, c, false, false, client, "", "", (*config.Config)(globalOptions), nerdctlCmd, nerdctlArgs); err != nil { |
| 120 | return err |
| 121 | } |
| 122 | info, err := c.Info(ctx, containerd.WithoutRefreshedMetadata) |
| 123 | if err != nil { |
| 124 | return err |
| 125 | } |
| 126 | |
| 127 | _, err = fmt.Fprintf(os.Stdout, "Container %s started\n", info.Labels[labels.Name]) |
| 128 | return err |
| 129 | }) |
| 130 | } |
| 131 | |
| 132 | return eg.Wait() |
| 133 | } |
no test coverage detected
searching dependent graphs…