Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
with:
repository: kubernetes-sigs/cri-tools
path: src/sigs.k8s.io/cri-tools
ref: 5fd98895f3bbf8a3ba2d25e93fa95ba1e2ae0923
ref: 4dcca56bf75a8d83f9d21de878e5e80088d58239

- name: Build cri-tools
working-directory: src/sigs.k8s.io/cri-tools
Expand Down
13 changes: 4 additions & 9 deletions core/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,12 @@ func (ds *dockerService) PullImage(
return nil, filterHTTPError(err, image.Image)
}

imageRef, err := getImageRef(ds.client, image.Image)
imageID, err := getImageID(ds.client, image.Image)
if err != nil {
return nil, err
}

return &runtimeapi.PullImageResponse{ImageRef: imageRef}, nil
return &runtimeapi.PullImageResponse{ImageRef: imageID}, nil
}

// RemoveImage removes the image.
Expand Down Expand Up @@ -202,8 +202,8 @@ func (ds *dockerService) RemoveImage(
return &runtimeapi.RemoveImageResponse{}, nil
}

// getImageRef returns the image digest if exists, or else returns the image ID.
func getImageRef(client libdocker.DockerClientInterface, image string) (string, error) {
// getImageID returns the image ID.
func getImageID(client libdocker.DockerClientInterface, image string) (string, error) {
img, err := client.InspectImageByRef(image)
if err != nil {
return "", err
Expand All @@ -212,11 +212,6 @@ func getImageRef(client libdocker.DockerClientInterface, image string) (string,
return "", fmt.Errorf("unable to inspect image %s", image)
}

// Returns the digest if it exist.
if len(img.RepoDigests) > 0 {
return img.RepoDigests[0], nil
}

return img.ID, nil
}

Expand Down
40 changes: 35 additions & 5 deletions core/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package core

import (
"fmt"
"reflect"
"testing"

dockertypes "github.com/docker/docker/api/types"
Expand Down Expand Up @@ -138,17 +139,19 @@ func TestRemoveImage(t *testing.T) {
}
}

func TestPullWithJSONError(t *testing.T) {
func TestPullImage(t *testing.T) {
ds, fakeDocker, _ := newTestDockerService()
tests := map[string]struct {
image *runtimeapi.ImageSpec
err error
expectedError string
expectImage bool
}{
"Json error": {
&runtimeapi.ImageSpec{Image: "ubuntu"},
&jsonmessage.JSONError{Code: 50, Message: "Json error"},
"Json error",
false,
},
"Bad gateway": {
&runtimeapi.ImageSpec{Image: "ubuntu"},
Expand All @@ -157,15 +160,42 @@ func TestPullWithJSONError(t *testing.T) {
Message: "<!doctype html>\n<html class=\"no-js\" lang=\"\">\n <head>\n </head>\n <body>\n <h1>Oops, there was an error!</h1>\n <p>We have been contacted of this error, feel free to check out <a href=\"http://status.docker.com/\">status.docker.com</a>\n to see if there is a bigger issue.</p>\n\n </body>\n</html>",
},
"RegistryUnavailable",
false,
},
"Successful Pull": {
&runtimeapi.ImageSpec{Image: "ubuntu"},
nil,
"",
true,
},
}
for key, test := range tests {
fakeDocker.InjectError("pull", test.err)
_, err := ds.PullImage(
if test.err != nil {
fakeDocker.InjectError("pull", test.err)
}

gotResp, gotErr := ds.PullImage(
getTestCTX(),
&runtimeapi.PullImageRequest{Image: test.image, Auth: &runtimeapi.AuthConfig{}},
)
require.Error(t, err, fmt.Sprintf("TestCase [%s]", key))
assert.Contains(t, err.Error(), test.expectedError)
if (len(test.expectedError) > 0) != (gotErr != nil) {
t.Fatalf("expected err %q but got %v", test.expectedError, gotErr)
}

if len(test.expectedError) > 0 {
require.Error(t, gotErr, fmt.Sprintf("TestCase [%s]", key))
assert.Contains(t, gotErr.Error(), test.expectedError)
}

if test.expectImage {
expectedResp := &runtimeapi.PullImageResponse{
ImageRef: libdocker.FakePullImageIDMapping(test.image.Image),
}

if !reflect.DeepEqual(gotResp, expectedResp) {
t.Errorf("expected pull response %v, got %v", expectedResp, gotResp)
}
}

}
}
8 changes: 4 additions & 4 deletions core/stats_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ func (ds *dockerService) getContainerStats(container *runtimeapi.Container) (*ru
// That will typically happen with init-containers in Exited state. Docker still knows about them but the HCS does not.
// As we don't want to block stats retrieval for other containers, we only log errors.
if !hcsshim.IsNotExist(err) && !hcsshim.IsAlreadyStopped(err) {
logrus.Info("Error opening container for ID: %d (stats will be missing): %v", containerID, err)
logrus.Infof("Error opening container for ID: %s (stats will be missing): %v", containerID, err)
}
return nil, nil
}
defer func() {
closeErr := hcsshimContainer.Close()
if closeErr != nil {
logrus.Errorf("Error closing container %d: %v", containerID, err)
logrus.Errorf("Error closing container %s: %v", containerID, err)
}
}()

Expand All @@ -56,8 +56,8 @@ func (ds *dockerService) getContainerStats(container *runtimeapi.Container) (*ru
// These hcs errors do not have helpers exposed in public package so need to query for the known codes
// https://github.com/microsoft/hcsshim/blob/master/internal/hcs/errors.go
// PR to expose helpers in hcsshim: https://github.com/microsoft/hcsshim/pull/933
logrus.Info(
"Container %dis not in a state that stats can be accessed. This occurs when the container is created but not started: %v",
logrus.Infof(
"Container %s is not in a state that stats can be accessed. This occurs when the container is created but not started: %v",
containerID,
err,
)
Expand Down
9 changes: 8 additions & 1 deletion libdocker/fake_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package libdocker

import (
"crypto/sha256"
"encoding/json"
"fmt"
"hash/fnv"
Expand Down Expand Up @@ -842,7 +843,7 @@ func (f *FakeDockerClient) ResizeContainerTTY(id string, height, width uint) err

func createImageInspectFromRef(ref string) *dockertypes.ImageInspect {
return &dockertypes.ImageInspect{
ID: ref,
ID: FakePullImageIDMapping(ref),
RepoTags: []string{ref},
// Image size is required to be non-zero for CRI integration.
VirtualSize: fakeImageSize,
Expand Down Expand Up @@ -927,3 +928,9 @@ func (f *FakeDockerClient) GetContainerStats(id string) (*dockercontainer.StatsR
}
return stats, nil
}

// FakePullImageIDMapping is used by the fake docker client to map an image ref
// to image ID during PullImage operation
func FakePullImageIDMapping(imageRef string) string {
return fmt.Sprintf("sha256:%x", sha256.Sum256([]byte(imageRef)))
}
Loading