mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-03 23:40:03 +00:00 
			
		
		
		
	Add pod registry.
This commit is contained in:
		
							
								
								
									
										121
									
								
								pkg/registry/pod_registry.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								pkg/registry/pod_registry.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 registry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						. "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TaskRegistryStorage implements the RESTStorage interface in terms of a TaskRegistry
 | 
				
			||||||
 | 
					type TaskRegistryStorage struct {
 | 
				
			||||||
 | 
						registry      PodRegistry
 | 
				
			||||||
 | 
						containerInfo client.ContainerInfo
 | 
				
			||||||
 | 
						scheduler     Scheduler
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func MakeTaskRegistryStorage(registry PodRegistry, containerInfo client.ContainerInfo, scheduler Scheduler) apiserver.RESTStorage {
 | 
				
			||||||
 | 
						return &TaskRegistryStorage{
 | 
				
			||||||
 | 
							registry:      registry,
 | 
				
			||||||
 | 
							containerInfo: containerInfo,
 | 
				
			||||||
 | 
							scheduler:     scheduler,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LabelMatch tests to see if a Task's labels map contains 'key' mapping to 'value'
 | 
				
			||||||
 | 
					func LabelMatch(task Pod, queryKey, queryValue string) bool {
 | 
				
			||||||
 | 
						for key, value := range task.Labels {
 | 
				
			||||||
 | 
							if queryKey == key && queryValue == value {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LabelMatch tests to see if a Task's labels map contains all key/value pairs in 'labelQuery'
 | 
				
			||||||
 | 
					func LabelsMatch(task Pod, labelQuery *map[string]string) bool {
 | 
				
			||||||
 | 
						if labelQuery == nil {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for key, value := range *labelQuery {
 | 
				
			||||||
 | 
							if !LabelMatch(task, key, value) {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (storage *TaskRegistryStorage) List(url *url.URL) (interface{}, error) {
 | 
				
			||||||
 | 
						var result PodList
 | 
				
			||||||
 | 
						var query *map[string]string
 | 
				
			||||||
 | 
						if url != nil {
 | 
				
			||||||
 | 
							queryMap := client.DecodeLabelQuery(url.Query().Get("labels"))
 | 
				
			||||||
 | 
							query = &queryMap
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tasks, err := storage.registry.ListTasks(query)
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							result = PodList{
 | 
				
			||||||
 | 
								Items: tasks,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result.Kind = "cluster#taskList"
 | 
				
			||||||
 | 
						return result, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (storage *TaskRegistryStorage) Get(id string) (interface{}, error) {
 | 
				
			||||||
 | 
						task, err := storage.registry.GetTask(id)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return task, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						info, err := storage.containerInfo.GetContainerInfo(task.CurrentState.Host, id)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return task, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						task.CurrentState.Info = info
 | 
				
			||||||
 | 
						task.Kind = "cluster#task"
 | 
				
			||||||
 | 
						return task, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (storage *TaskRegistryStorage) Delete(id string) error {
 | 
				
			||||||
 | 
						return storage.registry.DeleteTask(id)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (storage *TaskRegistryStorage) Extract(body string) (interface{}, error) {
 | 
				
			||||||
 | 
						task := Pod{}
 | 
				
			||||||
 | 
						err := json.Unmarshal([]byte(body), &task)
 | 
				
			||||||
 | 
						return task, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (storage *TaskRegistryStorage) Create(task interface{}) error {
 | 
				
			||||||
 | 
						taskObj := task.(Pod)
 | 
				
			||||||
 | 
						if len(taskObj.ID) == 0 {
 | 
				
			||||||
 | 
							return fmt.Errorf("ID is unspecified: %#v", task)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						machine, err := storage.scheduler.Schedule(taskObj)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return storage.registry.CreateTask(machine, taskObj)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (storage *TaskRegistryStorage) Update(task interface{}) error {
 | 
				
			||||||
 | 
						return storage.registry.UpdateTask(task.(Pod))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										204
									
								
								pkg/registry/pod_registry_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								pkg/registry/pod_registry_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 registry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						. "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type MockPodRegistry struct {
 | 
				
			||||||
 | 
						err   error
 | 
				
			||||||
 | 
						pods []Pod
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func expectNoError(t *testing.T, err error) {
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected error: %#v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (registry *MockPodRegistry) ListTasks(*map[string]string) ([]Pod, error) {
 | 
				
			||||||
 | 
						return registry.pods, registry.err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (registry *MockPodRegistry) GetTask(podId string) (*Pod, error) {
 | 
				
			||||||
 | 
						return &Pod{}, registry.err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (registry *MockPodRegistry) CreateTask(machine string, pod Pod) error {
 | 
				
			||||||
 | 
						return registry.err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (registry *MockPodRegistry) UpdateTask(pod Pod) error {
 | 
				
			||||||
 | 
						return registry.err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (registry *MockPodRegistry) DeleteTask(podId string) error {
 | 
				
			||||||
 | 
						return registry.err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestListTasksError(t *testing.T) {
 | 
				
			||||||
 | 
						mockRegistry := MockPodRegistry{
 | 
				
			||||||
 | 
							err: fmt.Errorf("Test Error"),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						storage := TaskRegistryStorage{
 | 
				
			||||||
 | 
							registry: &mockRegistry,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pods, err := storage.List(nil)
 | 
				
			||||||
 | 
						if err != mockRegistry.err {
 | 
				
			||||||
 | 
							t.Errorf("Expected %#v, Got %#v", mockRegistry.err, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(pods.(PodList).Items) != 0 {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected non-zero pod list: %#v", pods)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestListEmptyTaskList(t *testing.T) {
 | 
				
			||||||
 | 
						mockRegistry := MockPodRegistry{}
 | 
				
			||||||
 | 
						storage := TaskRegistryStorage{
 | 
				
			||||||
 | 
							registry: &mockRegistry,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pods, err := storage.List(nil)
 | 
				
			||||||
 | 
						expectNoError(t, err)
 | 
				
			||||||
 | 
						if len(pods.(PodList).Items) != 0 {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected non-zero pod list: %#v", pods)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestListTaskList(t *testing.T) {
 | 
				
			||||||
 | 
						mockRegistry := MockPodRegistry{
 | 
				
			||||||
 | 
							pods: []Pod{
 | 
				
			||||||
 | 
								Pod{
 | 
				
			||||||
 | 
									JSONBase: JSONBase{
 | 
				
			||||||
 | 
										ID: "foo",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Pod{
 | 
				
			||||||
 | 
									JSONBase: JSONBase{
 | 
				
			||||||
 | 
										ID: "bar",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						storage := TaskRegistryStorage{
 | 
				
			||||||
 | 
							registry: &mockRegistry,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						podsObj, err := storage.List(nil)
 | 
				
			||||||
 | 
						pods := podsObj.(PodList)
 | 
				
			||||||
 | 
						expectNoError(t, err)
 | 
				
			||||||
 | 
						if len(pods.Items) != 2 {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected pod list: %#v", pods)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if pods.Items[0].ID != "foo" {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected pod: %#v", pods.Items[0])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if pods.Items[1].ID != "bar" {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected pod: %#v", pods.Items[1])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestExtractJson(t *testing.T) {
 | 
				
			||||||
 | 
						mockRegistry := MockPodRegistry{}
 | 
				
			||||||
 | 
						storage := TaskRegistryStorage{
 | 
				
			||||||
 | 
							registry: &mockRegistry,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pod := Pod{
 | 
				
			||||||
 | 
							JSONBase: JSONBase{
 | 
				
			||||||
 | 
								ID: "foo",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						body, err := json.Marshal(pod)
 | 
				
			||||||
 | 
						expectNoError(t, err)
 | 
				
			||||||
 | 
						podOut, err := storage.Extract(string(body))
 | 
				
			||||||
 | 
						expectNoError(t, err)
 | 
				
			||||||
 | 
						jsonOut, err := json.Marshal(podOut)
 | 
				
			||||||
 | 
						expectNoError(t, err)
 | 
				
			||||||
 | 
						if string(body) != string(jsonOut) {
 | 
				
			||||||
 | 
							t.Errorf("Expected %#v, found %#v", pod, podOut)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func expectLabelMatch(t *testing.T, pod Pod, key, value string) {
 | 
				
			||||||
 | 
						if !LabelMatch(pod, key, value) {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected match failure: %#v %s %s", pod, key, value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func expectNoLabelMatch(t *testing.T, pod Pod, key, value string) {
 | 
				
			||||||
 | 
						if LabelMatch(pod, key, value) {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected match success: %#v %s %s", pod, key, value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func expectLabelsMatch(t *testing.T, pod Pod, query *map[string]string) {
 | 
				
			||||||
 | 
						if !LabelsMatch(pod, query) {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected match failure: %#v %#v", pod, *query)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func expectNoLabelsMatch(t *testing.T, pod Pod, query *map[string]string) {
 | 
				
			||||||
 | 
						if LabelsMatch(pod, query) {
 | 
				
			||||||
 | 
							t.Errorf("Unexpected match success: %#v %#v", pod, *query)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestLabelMatch(t *testing.T) {
 | 
				
			||||||
 | 
						pod := Pod{
 | 
				
			||||||
 | 
							Labels: map[string]string{
 | 
				
			||||||
 | 
								"foo": "bar",
 | 
				
			||||||
 | 
								"baz": "blah",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						expectLabelMatch(t, pod, "foo", "bar")
 | 
				
			||||||
 | 
						expectLabelMatch(t, pod, "baz", "blah")
 | 
				
			||||||
 | 
						expectNoLabelMatch(t, pod, "foo", "blah")
 | 
				
			||||||
 | 
						expectNoLabelMatch(t, pod, "baz", "bar")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestLabelsMatch(t *testing.T) {
 | 
				
			||||||
 | 
						pod := Pod{
 | 
				
			||||||
 | 
							Labels: map[string]string{
 | 
				
			||||||
 | 
								"foo": "bar",
 | 
				
			||||||
 | 
								"baz": "blah",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						expectLabelsMatch(t, pod, &map[string]string{})
 | 
				
			||||||
 | 
						expectLabelsMatch(t, pod, &map[string]string{
 | 
				
			||||||
 | 
							"foo": "bar",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						expectLabelsMatch(t, pod, &map[string]string{
 | 
				
			||||||
 | 
							"baz": "blah",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						expectLabelsMatch(t, pod, &map[string]string{
 | 
				
			||||||
 | 
							"foo": "bar",
 | 
				
			||||||
 | 
							"baz": "blah",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						expectNoLabelsMatch(t, pod, &map[string]string{
 | 
				
			||||||
 | 
							"foo": "blah",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						expectNoLabelsMatch(t, pod, &map[string]string{
 | 
				
			||||||
 | 
							"baz": "bar",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						expectNoLabelsMatch(t, pod, &map[string]string{
 | 
				
			||||||
 | 
							"foo":    "bar",
 | 
				
			||||||
 | 
							"foobar": "bar",
 | 
				
			||||||
 | 
							"baz":    "blah",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user