mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #29914 from tmrts/kubelet-rkt-cri/image-store
Automatic merge from submit-queue Kubelet rkt CRI ImageService Contains the ImageService stub and the basic tests for the implementation. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.kubernetes.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.kubernetes.io/reviews/kubernetes/kubernetes/29914) <!-- Reviewable:end -->
This commit is contained in:
commit
19a8f0f902
20
pkg/kubelet/rktshim/doc.go
Normal file
20
pkg/kubelet/rktshim/doc.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package rktshim is the package that contains the shim code for rkt to be used
|
||||||
|
// as the kubelet container runtime implementation that is integrated using the
|
||||||
|
// Container Runtime Interface.
|
||||||
|
package rktshim
|
61
pkg/kubelet/rktshim/imagestore.go
Normal file
61
pkg/kubelet/rktshim/imagestore.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rktshim
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO(tmrts): Move these errors to the container API for code re-use.
|
||||||
|
var (
|
||||||
|
ErrImageNotFound = errors.New("rktshim: image not found")
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ container.ImageService = (*ImageStore)(nil)
|
||||||
|
|
||||||
|
// ImageStore supports CRUD operations for images.
|
||||||
|
type ImageStore struct{}
|
||||||
|
|
||||||
|
// TODO(tmrts): fill the image store configuration fields.
|
||||||
|
type ImageStoreConfig struct{}
|
||||||
|
|
||||||
|
// NewImageStore creates an image storage that allows CRUD operations for images.
|
||||||
|
func NewImageStore(ImageStoreConfig) (container.ImageService, error) {
|
||||||
|
return &ImageStore{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// List lists the images residing in the image store.
|
||||||
|
func (*ImageStore) List() ([]container.Image, error) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull pulls an image into the image store and uses the given authentication method.
|
||||||
|
func (*ImageStore) Pull(container.ImageSpec, container.AuthConfig, *container.PodSandboxConfig) error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove removes the image from the image store.
|
||||||
|
func (*ImageStore) Remove(container.ImageSpec) error {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status returns the status of the image.
|
||||||
|
func (*ImageStore) Status(container.ImageSpec) (container.Image, error) {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
205
pkg/kubelet/rktshim/imagestore_test.go
Normal file
205
pkg/kubelet/rktshim/imagestore_test.go
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rktshim
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
emptyImgStoreConfig = ImageStoreConfig{}
|
||||||
|
// TODO(tmrts): fill the pod configuration
|
||||||
|
testPodConfig *container.PodSandboxConfig = nil
|
||||||
|
)
|
||||||
|
|
||||||
|
type imageTestCase struct {
|
||||||
|
Spec *container.ImageSpec
|
||||||
|
ExpectedStatus *container.Image
|
||||||
|
}
|
||||||
|
|
||||||
|
func compareContainerImages(got, expected container.Image) error {
|
||||||
|
if got.ID != expected.ID {
|
||||||
|
return fmt.Errorf("mismatching IDs -> expected %q, got %q", got.ID, expected.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got.RepoTags, expected.RepoTags) {
|
||||||
|
return fmt.Errorf("mismatching RepoTags -> expected %q, got %q", got.ID, expected.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got.RepoDigests, expected.RepoDigests) {
|
||||||
|
return fmt.Errorf("mismatching RepoDigests -> expected %q, got %q", got.ID, expected.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got.Size != expected.Size {
|
||||||
|
return fmt.Errorf("mismatching Sizes -> expected %q, got %q", got.ID, expected.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var testImgSpecs = map[string]imageTestCase{
|
||||||
|
"non-existent-image": {
|
||||||
|
&container.ImageSpec{
|
||||||
|
Image: "XXXX_GIBBERISH_XXXX",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
"busybox": {
|
||||||
|
&container.ImageSpec{
|
||||||
|
Image: "busybox",
|
||||||
|
},
|
||||||
|
&container.Image{
|
||||||
|
ID: "",
|
||||||
|
RepoTags: []string{},
|
||||||
|
RepoDigests: []string{},
|
||||||
|
Size: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var testAuthConfig = map[string]container.AuthConfig{
|
||||||
|
"no-auth": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
func testNewImageStore(t *testing.T, cfg ImageStoreConfig) container.ImageService {
|
||||||
|
imgStore, err := NewImageStore(cfg)
|
||||||
|
if err != nil {
|
||||||
|
// TODO(tmrts): Implement stringer for rktshim.ImageStoreConfig for test readability.
|
||||||
|
t.Fatalf("rktshim.NewImageStore(%s) got error %q", cfg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return imgStore
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPullsImageWithoutAuthentication(t *testing.T) {
|
||||||
|
t.SkipNow()
|
||||||
|
|
||||||
|
imgStore := testNewImageStore(t, emptyImgStoreConfig)
|
||||||
|
|
||||||
|
testImg := "busybox"
|
||||||
|
testImgSpec := *testImgSpecs[testImg].Spec
|
||||||
|
|
||||||
|
if err := imgStore.Pull(testImgSpec, testAuthConfig["no-auth"], testPodConfig); err != nil {
|
||||||
|
t.Fatalf("rktshim.ImageStore.PullImage(%q) got error %q", testImg, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQueriesNonExistentImage(t *testing.T) {
|
||||||
|
t.SkipNow()
|
||||||
|
|
||||||
|
imgStore := testNewImageStore(t, emptyImgStoreConfig)
|
||||||
|
|
||||||
|
// New store shouldn't contain this image
|
||||||
|
testImg := "non-existent-image"
|
||||||
|
testImgSpec := *testImgSpecs[testImg].Spec
|
||||||
|
|
||||||
|
if _, err := imgStore.Status(testImgSpec); err != ErrImageNotFound {
|
||||||
|
t.Errorf("rktshim.ImageStore.Status(%q) expected error %q, got %q", testImg, ErrImageNotFound, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQueriesExistentImage(t *testing.T) {
|
||||||
|
t.SkipNow()
|
||||||
|
|
||||||
|
imgStore := testNewImageStore(t, emptyImgStoreConfig)
|
||||||
|
|
||||||
|
testImg := "busybox"
|
||||||
|
testImgSpec := *testImgSpecs[testImg].Spec
|
||||||
|
expectedStatus := *testImgSpecs[testImg].ExpectedStatus
|
||||||
|
|
||||||
|
imgStatus, err := imgStore.Status(testImgSpec)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("rktshim.ImageStore.Status(%q) got error %q", testImg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := compareContainerImages(imgStatus, expectedStatus); err != nil {
|
||||||
|
t.Errorf("rktshim.ImageStore.Status(%q) %v", testImg, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemovesImage(t *testing.T) {
|
||||||
|
t.SkipNow()
|
||||||
|
|
||||||
|
imgStore := testNewImageStore(t, emptyImgStoreConfig)
|
||||||
|
|
||||||
|
testImg := "busybox"
|
||||||
|
testImgSpec := *testImgSpecs[testImg].Spec
|
||||||
|
|
||||||
|
if err := imgStore.Pull(testImgSpec, testAuthConfig["no-auth"], testPodConfig); err != nil {
|
||||||
|
t.Fatalf("rktshim.ImageStore.Pull(%q) got error %q", testImg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := imgStore.Status(testImgSpec); err != nil {
|
||||||
|
t.Fatalf("rktshim.ImageStore.Status(%q) got error %q", testImg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := imgStore.Remove(testImgSpec); err != nil {
|
||||||
|
t.Fatalf("rktshim.ImageStore.Remove(%q) got error %q", testImg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := imgStore.Status(testImgSpec); err != ErrImageNotFound {
|
||||||
|
t.Fatalf("rktshim.ImageStore.Status(%q) expected error %q, got error %q", testImg, ErrImageNotFound, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemovesNonExistentImage(t *testing.T) {
|
||||||
|
t.SkipNow()
|
||||||
|
|
||||||
|
imgStore := testNewImageStore(t, emptyImgStoreConfig)
|
||||||
|
|
||||||
|
testImg := "non-existent-image"
|
||||||
|
testImgSpec := *testImgSpecs[testImg].Spec
|
||||||
|
|
||||||
|
if err := imgStore.Remove(testImgSpec); err != ErrImageNotFound {
|
||||||
|
t.Fatalf("rktshim.ImageStore.Remove(%q) expected error %q, got error %q", testImg, ErrImageNotFound, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListsImages(t *testing.T) {
|
||||||
|
t.SkipNow()
|
||||||
|
|
||||||
|
imgStore := testNewImageStore(t, emptyImgStoreConfig)
|
||||||
|
|
||||||
|
busyboxImg := "busybox"
|
||||||
|
busyboxImgSpec := *testImgSpecs[busyboxImg].Spec
|
||||||
|
if err := imgStore.Pull(busyboxImgSpec, testAuthConfig["no-auth"], testPodConfig); err != nil {
|
||||||
|
t.Fatalf("rktshim.ImageStore.Pull(%q) got error %q", busyboxImg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
alpineImg := "alpine"
|
||||||
|
alpineImgSpec := *testImgSpecs[alpineImg].Spec
|
||||||
|
if err := imgStore.Pull(alpineImgSpec, testAuthConfig["no-auth"], testPodConfig); err != nil {
|
||||||
|
t.Fatalf("rktshim.ImageStore.Pull(%q) got error %q", alpineImg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
imgs, err := imgStore.List()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("rktshim.ImageStore.List() got error %q", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, img := range imgs {
|
||||||
|
expectedImg := *testImgSpecs[img.ID].ExpectedStatus
|
||||||
|
|
||||||
|
if err := compareContainerImages(img, expectedImg); err != nil {
|
||||||
|
t.Errorf("rktshim.ImageStore.List() for %q, %v", img.ID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user