(ctx context.Context, cmd *cobra.Command, containers []containerd.Container, sn snapshots.Snapshotter, format string)
| 125 | } |
| 126 | |
| 127 | func printComposeImages(ctx context.Context, cmd *cobra.Command, containers []containerd.Container, sn snapshots.Snapshotter, format string) error { |
| 128 | type composeImagePrintable struct { |
| 129 | ContainerName string |
| 130 | Repository string |
| 131 | Tag string |
| 132 | ImageID string |
| 133 | Size string |
| 134 | } |
| 135 | |
| 136 | imagePrintables := make([]composeImagePrintable, len(containers)) |
| 137 | eg, ctx := errgroup.WithContext(ctx) |
| 138 | for i, c := range containers { |
| 139 | i, c := i, c |
| 140 | eg.Go(func() error { |
| 141 | info, err := c.Info(ctx, containerd.WithoutRefreshedMetadata) |
| 142 | if err != nil { |
| 143 | return err |
| 144 | } |
| 145 | containerName := info.Labels[labels.Name] |
| 146 | |
| 147 | image, err := c.Image(ctx) |
| 148 | if err != nil { |
| 149 | return err |
| 150 | } |
| 151 | |
| 152 | size, err := imgutil.UnpackedImageSize(ctx, sn, image) |
| 153 | if err != nil { |
| 154 | return err |
| 155 | } |
| 156 | |
| 157 | metaImage := image.Metadata() |
| 158 | repository, tag := imgutil.ParseRepoTag(metaImage.Name) |
| 159 | imageID := metaImage.Target.Digest.String() |
| 160 | if repository == "" { |
| 161 | repository = "<none>" |
| 162 | } |
| 163 | if tag == "" { |
| 164 | tag = "<none>" |
| 165 | } |
| 166 | if format != "json" { |
| 167 | imageID = strings.Split(imageID, ":")[1][:12] |
| 168 | } |
| 169 | |
| 170 | // no race condition since each goroutine accesses different `i` |
| 171 | imagePrintables[i] = composeImagePrintable{ |
| 172 | ContainerName: containerName, |
| 173 | Repository: repository, |
| 174 | Tag: tag, |
| 175 | ImageID: imageID, |
| 176 | Size: progress.Bytes(size).String(), |
| 177 | } |
| 178 | |
| 179 | return nil |
| 180 | }) |
| 181 | } |
| 182 | |
| 183 | if err := eg.Wait(); err != nil { |
| 184 | return err |
no test coverage detected
searching dependent graphs…