mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +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:
		
							
								
								
									
										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)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user