Merge pull request #470 from mikebrow/debug-image

adding info map for verbose image status
This commit is contained in:
Lantao Liu 2017-12-12 15:09:57 -08:00 committed by GitHub
commit a9c7237e67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 103 additions and 49 deletions

View File

@ -139,12 +139,12 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
// Create container volumes mounts. // Create container volumes mounts.
// TODO(random-liu): Add cri-containerd integration test for image volume. // TODO(random-liu): Add cri-containerd integration test for image volume.
volumeMounts := c.generateVolumeMounts(containerRootDir, config.GetMounts(), image.Config) volumeMounts := c.generateVolumeMounts(containerRootDir, config.GetMounts(), &image.ImageSpec.Config)
// Generate container runtime spec. // Generate container runtime spec.
mounts := c.generateContainerMounts(getSandboxRootDir(c.config.RootDir, sandboxID), config) mounts := c.generateContainerMounts(getSandboxRootDir(c.config.RootDir, sandboxID), config)
spec, err := c.generateContainerSpec(id, sandboxPid, config, sandboxConfig, image.Config, append(mounts, volumeMounts...)) spec, err := c.generateContainerSpec(id, sandboxPid, config, sandboxConfig, &image.ImageSpec.Config, append(mounts, volumeMounts...))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to generate container %q spec: %v", id, err) return nil, fmt.Errorf("failed to generate container %q spec: %v", id, err)
} }

View File

@ -80,11 +80,11 @@ func (c *criContainerdService) stopContainer(ctx context.Context, container cont
// an error here. // an error here.
return fmt.Errorf("failed to get image metadata %q: %v", container.ImageRef, err) return fmt.Errorf("failed to get image metadata %q: %v", container.ImageRef, err)
} }
if image.Config.StopSignal != "" { if image.ImageSpec.Config.StopSignal != "" {
stopSignal, err = signal.ParseSignal(image.Config.StopSignal) stopSignal, err = signal.ParseSignal(image.ImageSpec.Config.StopSignal)
if err != nil { if err != nil {
return fmt.Errorf("failed to parse stop signal %q: %v", return fmt.Errorf("failed to parse stop signal %q: %v",
image.Config.StopSignal, err) image.ImageSpec.Config.StopSignal, err)
} }
} }
glog.V(2).Infof("Stop container %q with signal %v", id, stopSignal) glog.V(2).Infof("Stop container %q with signal %v", id, stopSignal)

View File

@ -308,10 +308,10 @@ func loadCgroup(cgroupPath string) (cgroups.Cgroup, error) {
// imageInfo is the information about the image got from containerd. // imageInfo is the information about the image got from containerd.
type imageInfo struct { type imageInfo struct {
id string id string
chainID imagedigest.Digest chainID imagedigest.Digest
size int64 size int64
config imagespec.ImageConfig imagespec imagespec.Image
} }
// getImageInfo gets image info from containerd. // getImageInfo gets image info from containerd.
@ -344,10 +344,10 @@ func getImageInfo(ctx context.Context, image containerd.Image) (*imageInfo, erro
} }
return &imageInfo{ return &imageInfo{
id: id, id: id,
chainID: chainID, chainID: chainID,
size: size, size: size,
config: ociimage.Config, imagespec: ociimage,
}, nil }, nil
} }

View File

@ -47,7 +47,7 @@ func toCRIImage(image imagestore.Image) *runtime.Image {
RepoDigests: image.RepoDigests, RepoDigests: image.RepoDigests,
Size_: uint64(image.Size), Size_: uint64(image.Size),
} }
uid, username := getUserFromImage(image.Config.User) uid, username := getUserFromImage(image.ImageSpec.Config.User)
if uid != nil { if uid != nil {
runtimeImage.Uid = &runtime.Int64Value{Value: *uid} runtimeImage.Uid = &runtime.Int64Value{Value: *uid}
} }

View File

@ -37,8 +37,10 @@ func TestListImages(t *testing.T) {
RepoTags: []string{"tag-a-1", "tag-b-1"}, RepoTags: []string{"tag-a-1", "tag-b-1"},
RepoDigests: []string{"digest-a-1", "digest-b-1"}, RepoDigests: []string{"digest-a-1", "digest-b-1"},
Size: 1000, Size: 1000,
Config: &imagespec.ImageConfig{ ImageSpec: imagespec.Image{
User: "root", Config: imagespec.ImageConfig{
User: "root",
},
}, },
}, },
{ {
@ -47,8 +49,10 @@ func TestListImages(t *testing.T) {
RepoTags: []string{"tag-a-2", "tag-b-2"}, RepoTags: []string{"tag-a-2", "tag-b-2"},
RepoDigests: []string{"digest-a-2", "digest-b-2"}, RepoDigests: []string{"digest-a-2", "digest-b-2"},
Size: 2000, Size: 2000,
Config: &imagespec.ImageConfig{ ImageSpec: imagespec.Image{
User: "1234:1234", Config: imagespec.ImageConfig{
User: "1234:1234",
},
}, },
}, },
{ {
@ -57,8 +61,10 @@ func TestListImages(t *testing.T) {
RepoTags: []string{"tag-a-3", "tag-b-3"}, RepoTags: []string{"tag-a-3", "tag-b-3"},
RepoDigests: []string{"digest-a-3", "digest-b-3"}, RepoDigests: []string{"digest-a-3", "digest-b-3"},
Size: 3000, Size: 3000,
Config: &imagespec.ImageConfig{ ImageSpec: imagespec.Image{
User: "nobody", Config: imagespec.ImageConfig{
User: "nobody",
},
}, },
}, },
} }

View File

@ -61,13 +61,14 @@ func (c *criContainerdService) LoadImage(ctx context.Context, r *api.LoadImageRe
if err := c.createImageReference(ctx, id, image.Target()); err != nil { if err := c.createImageReference(ctx, id, image.Target()); err != nil {
return nil, fmt.Errorf("failed to create image reference %q: %v", id, err) return nil, fmt.Errorf("failed to create image reference %q: %v", id, err)
} }
img := imagestore.Image{ img := imagestore.Image{
ID: id, ID: id,
RepoTags: []string{repoTag}, RepoTags: []string{repoTag},
ChainID: info.chainID.String(), ChainID: info.chainID.String(),
Size: info.size, Size: info.size,
Config: &info.config, ImageSpec: info.imagespec,
Image: image, Image: image,
} }
if err := c.imageStore.Add(img); err != nil { if err := c.imageStore.Add(img); err != nil {

View File

@ -137,11 +137,11 @@ func (c *criContainerdService) PullImage(ctx context.Context, r *runtime.PullIma
glog.V(4).Infof("Pulled image %q with image id %q, repo tag %q, repo digest %q", imageRef, imageID, glog.V(4).Infof("Pulled image %q with image id %q, repo tag %q, repo digest %q", imageRef, imageID,
repoTag, repoDigest) repoTag, repoDigest)
img := imagestore.Image{ img := imagestore.Image{
ID: imageID, ID: imageID,
ChainID: info.chainID.String(), ChainID: info.chainID.String(),
Size: info.size, Size: info.size,
Config: &info.config, ImageSpec: info.imagespec,
Image: image, Image: image,
} }
if repoDigest != "" { if repoDigest != "" {
img.RepoDigests = []string{repoDigest} img.RepoDigests = []string{repoDigest}

View File

@ -17,10 +17,15 @@ limitations under the License.
package server package server
import ( import (
"encoding/json"
"fmt" "fmt"
"github.com/golang/glog"
"golang.org/x/net/context" "golang.org/x/net/context"
"k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
imagestore "github.com/kubernetes-incubator/cri-containerd/pkg/store/image"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
) )
// ImageStatus returns the status of the image, returns nil if the image isn't present. // ImageStatus returns the status of the image, returns nil if the image isn't present.
@ -37,18 +42,62 @@ func (c *criContainerdService) ImageStatus(ctx context.Context, r *runtime.Image
} }
// TODO(random-liu): [P0] Make sure corresponding snapshot exists. What if snapshot // TODO(random-liu): [P0] Make sure corresponding snapshot exists. What if snapshot
// doesn't exist? // doesn't exist?
runtimeImage := toCRIRuntimeImage(image)
info, err := c.toCRIImageInfo(ctx, image, r.GetVerbose())
if err != nil {
return nil, fmt.Errorf("failed to generate image info: %v", err)
}
return &runtime.ImageStatusResponse{
Image: runtimeImage,
Info: info,
}, nil
}
// toCRIRuntimeImage converts internal image object to CRI runtime.Image.
func toCRIRuntimeImage(image *imagestore.Image) *runtime.Image {
runtimeImage := &runtime.Image{ runtimeImage := &runtime.Image{
Id: image.ID, Id: image.ID,
RepoTags: image.RepoTags, RepoTags: image.RepoTags,
RepoDigests: image.RepoDigests, RepoDigests: image.RepoDigests,
Size_: uint64(image.Size), Size_: uint64(image.Size),
} }
uid, username := getUserFromImage(image.Config.User) uid, username := getUserFromImage(image.ImageSpec.Config.User)
if uid != nil { if uid != nil {
runtimeImage.Uid = &runtime.Int64Value{Value: *uid} runtimeImage.Uid = &runtime.Int64Value{Value: *uid}
} }
runtimeImage.Username = username runtimeImage.Username = username
// TODO(mikebrow): write a ImageMetadata to runtime.Image converter return runtimeImage
return &runtime.ImageStatusResponse{Image: runtimeImage}, nil }
// TODO (mikebrow): discuss moving this struct and / or constants for info map for some or all of these fields to CRI
type verboseImageInfo struct {
ChainID string `json:"chainID"`
ImageSpec imagespec.Image `json:"imageSpec"`
}
// toCRIImageInfo converts internal image object information to CRI image status response info map.
func (c *criContainerdService) toCRIImageInfo(ctx context.Context, image *imagestore.Image, verbose bool) (map[string]string, error) {
if !verbose {
return nil, nil
}
info := make(map[string]string)
imi := &verboseImageInfo{
ChainID: image.ChainID,
ImageSpec: image.ImageSpec,
}
m, err := json.Marshal(imi)
if err == nil {
info["info"] = string(m)
} else {
glog.Errorf("failed to marshal info %v: %v", imi, err)
info["info"] = err.Error()
}
return info, nil
} }

View File

@ -36,8 +36,10 @@ func TestImageStatus(t *testing.T) {
RepoTags: []string{"a", "b"}, RepoTags: []string{"a", "b"},
RepoDigests: []string{"c", "d"}, RepoDigests: []string{"c", "d"},
Size: 1234, Size: 1234,
Config: &imagespec.ImageConfig{ ImageSpec: imagespec.Image{
User: "user:group", Config: imagespec.ImageConfig{
User: "user:group",
},
}, },
} }
expected := &runtime.Image{ expected := &runtime.Image{

View File

@ -365,11 +365,11 @@ func loadImages(ctx context.Context, cImages []containerd.Image,
continue continue
} }
image := imagestore.Image{ image := imagestore.Image{
ID: id, ID: id,
ChainID: info.chainID.String(), ChainID: info.chainID.String(),
Size: info.size, Size: info.size,
Config: &info.config, ImageSpec: info.imagespec,
Image: i, Image: i,
} }
// Recover repo digests and repo tags. // Recover repo digests and repo tags.
for _, i := range imgs { for _, i := range imgs {

View File

@ -123,7 +123,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
} }
// Create sandbox container. // Create sandbox container.
spec, err := c.generateSandboxContainerSpec(id, config, image.Config, sandbox.NetNSPath) spec, err := c.generateSandboxContainerSpec(id, config, &image.ImageSpec.Config, sandbox.NetNSPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to generate sandbox container spec: %v", err) return nil, fmt.Errorf("failed to generate sandbox container spec: %v", err)
} }

View File

@ -40,8 +40,9 @@ type Image struct {
ChainID string ChainID string
// Size is the compressed size of the image. // Size is the compressed size of the image.
Size int64 Size int64
// Config is the oci image config of the image. // ImageSpec is the oci image structure which describes basic information about the image.
Config *imagespec.ImageConfig ImageSpec imagespec.Image
// Containerd image reference // Containerd image reference
Image containerd.Image Image containerd.Image
} }

View File

@ -20,7 +20,6 @@ import (
"strings" "strings"
"testing" "testing"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
assertlib "github.com/stretchr/testify/assert" assertlib "github.com/stretchr/testify/assert"
"github.com/kubernetes-incubator/cri-containerd/pkg/store" "github.com/kubernetes-incubator/cri-containerd/pkg/store"
@ -34,7 +33,6 @@ func TestImageStore(t *testing.T) {
RepoTags: []string{"tag-1"}, RepoTags: []string{"tag-1"},
RepoDigests: []string{"digest-1"}, RepoDigests: []string{"digest-1"},
Size: 10, Size: 10,
Config: &imagespec.ImageConfig{},
}, },
{ {
ID: "sha256:2123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", ID: "sha256:2123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
@ -42,7 +40,6 @@ func TestImageStore(t *testing.T) {
RepoTags: []string{"tag-2abcd"}, RepoTags: []string{"tag-2abcd"},
RepoDigests: []string{"digest-2abcd"}, RepoDigests: []string{"digest-2abcd"},
Size: 20, Size: 20,
Config: &imagespec.ImageConfig{},
}, },
{ {
ID: "sha256:3123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", ID: "sha256:3123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
@ -50,7 +47,6 @@ func TestImageStore(t *testing.T) {
RepoDigests: []string{"digest-4a333"}, RepoDigests: []string{"digest-4a333"},
ChainID: "test-chain-id-4a333", ChainID: "test-chain-id-4a333",
Size: 30, Size: 30,
Config: &imagespec.ImageConfig{},
}, },
{ {
ID: "sha256:4123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", ID: "sha256:4123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
@ -58,7 +54,6 @@ func TestImageStore(t *testing.T) {
RepoDigests: []string{"digest-4abcd"}, RepoDigests: []string{"digest-4abcd"},
ChainID: "test-chain-id-4abcd", ChainID: "test-chain-id-4abcd",
Size: 40, Size: 40,
Config: &imagespec.ImageConfig{},
}, },
} }
assert := assertlib.New(t) assert := assertlib.New(t)