Skip to content

Commit

Permalink
Add image info to the verbose status command
Browse files Browse the repository at this point in the history
Do a combination of the cri-o format (with "labels") and the
containerd format (without "chainID") for the info JSON field.

The info is supposed to include the history, so make a special
call for that in verbose and reverse order to match containerd.
  • Loading branch information
afbjorklund committed Apr 22, 2022
1 parent 0607a1b commit 97ca481
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 1 deletion.
92 changes: 92 additions & 0 deletions src/core/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ limitations under the License.
package core

import (
"encoding/json"
"fmt"
"strings"
"time"

dockertypes "github.com/docker/docker/api/types"
dockercontainer "github.com/docker/docker/api/types/container"
dockerimagetypes "github.com/docker/docker/api/types/image"

runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"

digest "github.com/opencontainers/go-digest"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"

"github.com/Mirantis/cri-dockerd/libdocker"
)

Expand Down Expand Up @@ -66,6 +72,92 @@ func imageInspectToRuntimeAPIImage(image *dockertypes.ImageInspect) (*runtimeapi
return runtimeImage, nil
}

type verboseImageInfo struct {
Labels map[string]string `json:"labels,omitempty"`
ImageSpec imagespec.Image `json:"imageSpec"`
}

func imageInspectToRuntimeAPIImageInfo(image *dockertypes.ImageInspect, history []dockerimagetypes.HistoryResponseItem) (map[string]string, error) {
info := make(map[string]string)

createdAt, err := libdocker.ParseDockerTimestamp(image.Created)
if err != nil {
return nil, err
}

imageSpec := imagespec.Image{
Created: &createdAt,
Author: image.Author,
Architecture: image.Architecture,
OS: image.Os,
Config: toRuntimeAPIConfig(image.Config),
RootFS: toRuntimeAPIRootFS(image.RootFS),
History: toRuntimeAPIHistory(history),
}

imi := &verboseImageInfo{
Labels: image.Config.Labels,
ImageSpec: imageSpec,
}

m, err := json.Marshal(imi)
if err == nil {
info["info"] = string(m)
} else {
return nil, err
}

return info, nil
}

func toRuntimeAPIConfig(config *dockercontainer.Config) imagespec.ImageConfig {
ports := make(map[string]struct{})
for k, v := range config.ExposedPorts {
ports[string(k)] = v
}
return imagespec.ImageConfig{
User: config.User,
ExposedPorts: ports,
Env: config.Env,
Entrypoint: config.Entrypoint,
Cmd: config.Cmd,
Volumes: config.Volumes,
WorkingDir: config.WorkingDir,
Labels: config.Labels,
StopSignal: config.StopSignal,
}
}

func toRuntimeAPIRootFS(rootfs dockertypes.RootFS) imagespec.RootFS {
digests := []digest.Digest{}
for _, l := range rootfs.Layers {
digest, _ := digest.Parse(l)
digests = append(digests, digest)
}
return imagespec.RootFS{
Type: rootfs.Type,
DiffIDs: digests,
}
}

func toRuntimeAPIHistory(history []dockerimagetypes.HistoryResponseItem) []imagespec.History {
result := []imagespec.History{}
for _, h := range history {
created := time.Unix(h.Created, 0).UTC()
result = append(result, imagespec.History{
Created: &created,
CreatedBy: h.CreatedBy,
Comment: h.Comment,
EmptyLayer: h.Size == 0,
})
}
// reverse order
for left, right := 0, len(result)-1; left < right; left, right = left+1, right-1 {
result[left], result[right] = result[right], result[left]
}
return result
}

func toPullableImageID(id string, image *dockertypes.ImageInspect) string {
// Default to the image ID, but if RepoDigests is not empty, use
// the first digest instead.
Expand Down
10 changes: 9 additions & 1 deletion src/core/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,15 @@ func (ds *dockerService) ImageStatus(

res := runtimeapi.ImageStatusResponse{Image: imageStatus}
if r.GetVerbose() {
res.Info = imageInspect.Config.Labels
imageHistory, err := ds.client.ImageHistory(imageInspect.ID)
if err != nil {
return nil, err
}
imageInfo, err := imageInspectToRuntimeAPIImageInfo(imageInspect, imageHistory)
if err != nil {
return nil, err
}
res.Info = imageInfo
}
return &res, nil
}
Expand Down
1 change: 1 addition & 0 deletions src/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/onsi/ginkgo v1.12.0 // indirect
github.com/onsi/gomega v1.8.1 // indirect
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/runc v1.0.0-rc92
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.8.1
Expand Down

0 comments on commit 97ca481

Please sign in to comment.