(ctx context.Context, client *containerd.Client, containers []containerd.Container, statusPerContainer map[string]string, options types.ContainerListOptions)
| 136 | } |
| 137 | |
| 138 | func prepareContainers(ctx context.Context, client *containerd.Client, containers []containerd.Container, statusPerContainer map[string]string, options types.ContainerListOptions) ([]ListItem, error) { |
| 139 | listItems := make([]ListItem, len(containers)) |
| 140 | snapshottersCache := map[string]snapshots.Snapshotter{} |
| 141 | for i, c := range containers { |
| 142 | info, err := c.Info(ctx, containerd.WithoutRefreshedMetadata) |
| 143 | if err != nil { |
| 144 | if errdefs.IsNotFound(err) { |
| 145 | log.G(ctx).Warn(err) |
| 146 | continue |
| 147 | } |
| 148 | return nil, err |
| 149 | } |
| 150 | spec, err := c.Spec(ctx) |
| 151 | if err != nil { |
| 152 | if errdefs.IsNotFound(err) { |
| 153 | log.G(ctx).Warn(err) |
| 154 | continue |
| 155 | } |
| 156 | return nil, err |
| 157 | } |
| 158 | id := c.ID() |
| 159 | if options.Truncate && len(id) > 12 { |
| 160 | id = id[:12] |
| 161 | } |
| 162 | var status string |
| 163 | if s, ok := statusPerContainer[c.ID()]; ok { |
| 164 | status = s |
| 165 | if strings.HasPrefix(status, "Up") && info.Labels[labels.HealthState] != "" { |
| 166 | healthState, err := healthcheck.HealthStateFromJSON(info.Labels[labels.HealthState]) |
| 167 | if err != nil { |
| 168 | log.G(ctx).WithError(err).Debugf("failed to parse health state for container %s", c.ID()) |
| 169 | } else { |
| 170 | switch healthState.Status { |
| 171 | case healthcheck.Healthy, healthcheck.Unhealthy: |
| 172 | status = fmt.Sprintf("%s (%s)", status, healthState.Status) |
| 173 | case healthcheck.Starting: |
| 174 | status = fmt.Sprintf("%s (health: %s)", status, healthState.Status) |
| 175 | } |
| 176 | } |
| 177 | } |
| 178 | } else { |
| 179 | return nil, fmt.Errorf("can't get container %s status", c.ID()) |
| 180 | } |
| 181 | dataStore, err := clientutil.DataStore(options.GOptions.DataRoot, options.GOptions.Address) |
| 182 | if err != nil { |
| 183 | return nil, err |
| 184 | } |
| 185 | containerLabels, err := c.Labels(ctx) |
| 186 | if err != nil { |
| 187 | return nil, err |
| 188 | } |
| 189 | ports, err := portutil.LoadPortMappings(dataStore, options.GOptions.Namespace, c.ID(), containerLabels) |
| 190 | if err != nil { |
| 191 | return nil, err |
| 192 | } |
| 193 | li := ListItem{ |
| 194 | Command: formatter.InspectContainerCommand(spec, options.Truncate, true), |
| 195 | CreatedAt: info.CreatedAt, |
no test coverage detected
searching dependent graphs…