Rename minioncontroller to nodecontroller

This commit is contained in:
Deyuan Deng 2014-12-19 17:27:01 +08:00
parent 7bff03fb41
commit a2651bfcc7
6 changed files with 254 additions and 253 deletions

View File

@ -37,7 +37,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
minionControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
nodeControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
replicationControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
"github.com/GoogleCloudPlatform/kubernetes/pkg/health"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
@ -188,8 +188,8 @@ func startComponents(manifestURL string) (apiServerURL string) {
controllerManager.Run(10 * time.Minute)
nodeResources := &api.NodeResources{}
minionController := minionControllerPkg.NewMinionController(nil, "", machineList, nodeResources, cl)
minionController.Run(10 * time.Second)
nodeController := nodeControllerPkg.NewNodeController(nil, "", machineList, nodeResources, cl)
nodeController.Run(10 * time.Second)
// Kubelet (localhost)
standalone.SimpleRunKubelet(cl, etcdClient, &fakeDocker1, machineList[0], testRootDir, manifestURL, "127.0.0.1", 10250)

View File

@ -31,7 +31,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
minionControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
nodeControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
replicationControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
@ -105,8 +105,8 @@ func main() {
api.ResourceMemory: *nodeMemory,
},
}
minionController := minionControllerPkg.NewMinionController(cloud, *minionRegexp, machineList, nodeResources, kubeClient)
minionController.Run(10 * time.Second)
nodeController := nodeControllerPkg.NewNodeController(cloud, *minionRegexp, machineList, nodeResources, kubeClient)
nodeController.Run(10 * time.Second)
select {}
}

View File

@ -1,209 +0,0 @@
/*
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 controller
import (
"fmt"
"testing"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
fake_cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake"
)
func newNode(name string) *api.Node {
return &api.Node{ObjectMeta: api.ObjectMeta{Name: name}}
}
type FakeMinionHandler struct {
client.Fake
client.FakeNodes
// Input: Hooks determine if request is valid or not
CreateHook func(*FakeMinionHandler, *api.Node) bool
Existing []*api.Node
// Output
CreatedMinions []*api.Node
DeletedMinions []*api.Node
RequestCount int
}
func (c *FakeMinionHandler) Nodes() client.NodeInterface {
return c
}
func (m *FakeMinionHandler) Create(minion *api.Node) (*api.Node, error) {
defer func() { m.RequestCount++ }()
if m.CreateHook == nil || m.CreateHook(m, minion) {
m.CreatedMinions = append(m.CreatedMinions, minion)
return minion, nil
} else {
return nil, fmt.Errorf("Create error.")
}
}
func (m *FakeMinionHandler) List() (*api.NodeList, error) {
defer func() { m.RequestCount++ }()
minions := []api.Node{}
for i := 0; i < len(m.Existing); i++ {
if !contains(m.Existing[i], m.DeletedMinions) {
minions = append(minions, *m.Existing[i])
}
}
for i := 0; i < len(m.CreatedMinions); i++ {
if !contains(m.Existing[i], m.DeletedMinions) {
minions = append(minions, *m.CreatedMinions[i])
}
}
return &api.NodeList{Items: minions}, nil
}
func (m *FakeMinionHandler) Delete(id string) error {
m.DeletedMinions = append(m.DeletedMinions, newNode(id))
m.RequestCount++
return nil
}
func TestSyncStaticCreateMinion(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
CreateHook: func(fake *FakeMinionHandler, minion *api.Node) bool {
return true
},
}
minionController := NewMinionController(nil, ".*", []string{"minion0"}, &api.NodeResources{}, fakeMinionHandler)
if err := minionController.SyncStatic(time.Millisecond); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeMinionHandler.RequestCount != 1 {
t.Errorf("Expected 1 call, but got %v.", fakeMinionHandler.RequestCount)
}
if len(fakeMinionHandler.CreatedMinions) != 1 {
t.Errorf("expect only 1 minion created, got %v", len(fakeMinionHandler.CreatedMinions))
}
if fakeMinionHandler.CreatedMinions[0].Name != "minion0" {
t.Errorf("unexpect minion %v created", fakeMinionHandler.CreatedMinions[0].Name)
}
}
func TestSyncStaticCreateMinionWithError(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
CreateHook: func(fake *FakeMinionHandler, minion *api.Node) bool {
if fake.RequestCount == 0 {
return false
}
return true
},
}
minionController := NewMinionController(nil, ".*", []string{"minion0"}, &api.NodeResources{}, fakeMinionHandler)
if err := minionController.SyncStatic(time.Millisecond); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeMinionHandler.RequestCount != 2 {
t.Errorf("Expected 2 call, but got %v.", fakeMinionHandler.RequestCount)
}
if len(fakeMinionHandler.CreatedMinions) != 1 {
t.Errorf("expect only 1 minion created, got %v", len(fakeMinionHandler.CreatedMinions))
}
if fakeMinionHandler.CreatedMinions[0].Name != "minion0" {
t.Errorf("unexpect minion %v created", fakeMinionHandler.CreatedMinions[0].Name)
}
}
func TestSyncCloudCreateMinion(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Node{newNode("minion0")},
}
instances := []string{"minion0", "minion1"}
fakeCloud := fake_cloud.FakeCloud{
Machines: instances,
}
minionController := NewMinionController(&fakeCloud, ".*", nil, nil, fakeMinionHandler)
if err := minionController.SyncCloud(); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeMinionHandler.RequestCount != 2 {
t.Errorf("Expected 2 call, but got %v.", fakeMinionHandler.RequestCount)
}
if len(fakeMinionHandler.CreatedMinions) != 1 {
t.Errorf("expect only 1 minion created, got %v", len(fakeMinionHandler.CreatedMinions))
}
if fakeMinionHandler.CreatedMinions[0].Name != "minion1" {
t.Errorf("unexpect minion %v created", fakeMinionHandler.CreatedMinions[0].Name)
}
}
func TestSyncCloudDeleteMinion(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Node{newNode("minion0"), newNode("minion1")},
}
instances := []string{"minion0"}
fakeCloud := fake_cloud.FakeCloud{
Machines: instances,
}
minionController := NewMinionController(&fakeCloud, ".*", nil, nil, fakeMinionHandler)
if err := minionController.SyncCloud(); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeMinionHandler.RequestCount != 2 {
t.Errorf("Expected 2 call, but got %v.", fakeMinionHandler.RequestCount)
}
if len(fakeMinionHandler.DeletedMinions) != 1 {
t.Errorf("expect only 1 minion deleted, got %v", len(fakeMinionHandler.DeletedMinions))
}
if fakeMinionHandler.DeletedMinions[0].Name != "minion1" {
t.Errorf("unexpect minion %v created", fakeMinionHandler.DeletedMinions[0].Name)
}
}
func TestSyncCloudRegexp(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Node{newNode("minion0")},
}
instances := []string{"minion0", "minion1", "node0"}
fakeCloud := fake_cloud.FakeCloud{
Machines: instances,
}
minionController := NewMinionController(&fakeCloud, "minion[0-9]+", nil, nil, fakeMinionHandler)
if err := minionController.SyncCloud(); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeMinionHandler.RequestCount != 2 {
t.Errorf("Expected 2 call, but got %v.", fakeMinionHandler.RequestCount)
}
if len(fakeMinionHandler.CreatedMinions) != 1 {
t.Errorf("expect only 1 minion created, got %v", len(fakeMinionHandler.CreatedMinions))
}
if fakeMinionHandler.CreatedMinions[0].Name != "minion1" {
t.Errorf("unexpect minion %v created", fakeMinionHandler.CreatedMinions[0].Name)
}
}
func contains(minion *api.Node, minions []*api.Node) bool {
for i := 0; i < len(minions); i++ {
if minion.Name == minions[i].Name {
return true
}
}
return false
}

View File

@ -27,32 +27,32 @@ import (
"github.com/golang/glog"
)
type MinionController struct {
type NodeController struct {
cloud cloudprovider.Interface
matchRE string
staticResources *api.NodeResources
minions []string
nodes []string
kubeClient client.Interface
}
// NewMinionController returns a new minion controller to sync instances from cloudprovider.
func NewMinionController(
// NewNodeController returns a new node controller to sync instances from cloudprovider.
func NewNodeController(
cloud cloudprovider.Interface,
matchRE string,
minions []string,
nodes []string,
staticResources *api.NodeResources,
kubeClient client.Interface) *MinionController {
return &MinionController{
kubeClient client.Interface) *NodeController {
return &NodeController{
cloud: cloud,
matchRE: matchRE,
minions: minions,
nodes: nodes,
staticResources: staticResources,
kubeClient: kubeClient,
}
}
// Run starts syncing instances from cloudprovider periodically, or create initial minion list.
func (s *MinionController) Run(period time.Duration) {
// Run starts syncing instances from cloudprovider periodically, or create initial node list.
func (s *NodeController) Run(period time.Duration) {
if s.cloud != nil && len(s.matchRE) > 0 {
go util.Forever(func() {
if err := s.SyncCloud(); err != nil {
@ -66,24 +66,24 @@ func (s *MinionController) Run(period time.Duration) {
// SyncStatic registers list of machines from command line flag. It returns after successful
// registration of all machines.
func (s *MinionController) SyncStatic(period time.Duration) error {
func (s *NodeController) SyncStatic(period time.Duration) error {
registered := util.NewStringSet()
for {
for _, minionID := range s.minions {
if registered.Has(minionID) {
for _, nodeID := range s.nodes {
if registered.Has(nodeID) {
continue
}
_, err := s.kubeClient.Nodes().Create(&api.Node{
ObjectMeta: api.ObjectMeta{Name: minionID},
ObjectMeta: api.ObjectMeta{Name: nodeID},
Spec: api.NodeSpec{
Capacity: s.staticResources.Capacity,
},
})
if err == nil {
registered.Insert(minionID)
registered.Insert(nodeID)
}
}
if registered.Len() == len(s.minions) {
if registered.Len() == len(s.nodes) {
return nil
}
time.Sleep(period)
@ -91,44 +91,44 @@ func (s *MinionController) SyncStatic(period time.Duration) error {
}
// SyncCloud syncs list of instances from cloudprovider to master etcd registry.
func (s *MinionController) SyncCloud() error {
matches, err := s.cloudMinions()
func (s *NodeController) SyncCloud() error {
matches, err := s.cloudNodes()
if err != nil {
return err
}
minions, err := s.kubeClient.Nodes().List()
nodes, err := s.kubeClient.Nodes().List()
if err != nil {
return err
}
minionMap := make(map[string]*api.Node)
for _, minion := range minions.Items {
minionMap[minion.Name] = &minion
nodeMap := make(map[string]*api.Node)
for _, node := range nodes.Items {
nodeMap[node.Name] = &node
}
// Create or delete minions from registry.
for _, minion := range matches.Items {
if _, ok := minionMap[minion.Name]; !ok {
glog.Infof("Create minion in registry: %s", minion.Name)
_, err = s.kubeClient.Nodes().Create(&minion)
// Create or delete nodes from registry.
for _, node := range matches.Items {
if _, ok := nodeMap[node.Name]; !ok {
glog.Infof("Create node in registry: %s", node.Name)
_, err = s.kubeClient.Nodes().Create(&node)
if err != nil {
glog.Errorf("Create minion error: %s", minion.Name)
glog.Errorf("Create node error: %s", node.Name)
}
}
delete(minionMap, minion.Name)
delete(nodeMap, node.Name)
}
for minionID := range minionMap {
glog.Infof("Delete minion from registry: %s", minionID)
err = s.kubeClient.Nodes().Delete(minionID)
for nodeID := range nodeMap {
glog.Infof("Delete node from registry: %s", nodeID)
err = s.kubeClient.Nodes().Delete(nodeID)
if err != nil {
glog.Errorf("Delete minion error: %s", minionID)
glog.Errorf("Delete node error: %s", nodeID)
}
}
return nil
}
// cloudMinions constructs and returns api.NodeList from cloudprovider.
func (s *MinionController) cloudMinions() (*api.NodeList, error) {
// cloudNodes constructs and returns api.NodeList from cloudprovider.
func (s *NodeController) cloudNodes() (*api.NodeList, error) {
instances, ok := s.cloud.Instances()
if !ok {
return nil, fmt.Errorf("cloud doesn't support instances")

View File

@ -0,0 +1,209 @@
/*
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 controller
import (
"fmt"
"testing"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
fake_cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake"
)
func newNode(name string) *api.Node {
return &api.Node{ObjectMeta: api.ObjectMeta{Name: name}}
}
type FakeNodeHandler struct {
client.Fake
client.FakeNodes
// Input: Hooks determine if request is valid or not
CreateHook func(*FakeNodeHandler, *api.Node) bool
Existing []*api.Node
// Output
CreatedNodes []*api.Node
DeletedNodes []*api.Node
RequestCount int
}
func (c *FakeNodeHandler) Nodes() client.NodeInterface {
return c
}
func (m *FakeNodeHandler) Create(node *api.Node) (*api.Node, error) {
defer func() { m.RequestCount++ }()
if m.CreateHook == nil || m.CreateHook(m, node) {
m.CreatedNodes = append(m.CreatedNodes, node)
return node, nil
} else {
return nil, fmt.Errorf("Create error.")
}
}
func (m *FakeNodeHandler) List() (*api.NodeList, error) {
defer func() { m.RequestCount++ }()
nodes := []api.Node{}
for i := 0; i < len(m.Existing); i++ {
if !contains(m.Existing[i], m.DeletedNodes) {
nodes = append(nodes, *m.Existing[i])
}
}
for i := 0; i < len(m.CreatedNodes); i++ {
if !contains(m.Existing[i], m.DeletedNodes) {
nodes = append(nodes, *m.CreatedNodes[i])
}
}
return &api.NodeList{Items: nodes}, nil
}
func (m *FakeNodeHandler) Delete(id string) error {
m.DeletedNodes = append(m.DeletedNodes, newNode(id))
m.RequestCount++
return nil
}
func TestSyncStaticCreateNode(t *testing.T) {
fakeNodeHandler := &FakeNodeHandler{
CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool {
return true
},
}
nodeController := NewNodeController(nil, ".*", []string{"node0"}, &api.NodeResources{}, fakeNodeHandler)
if err := nodeController.SyncStatic(time.Millisecond); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeNodeHandler.RequestCount != 1 {
t.Errorf("Expected 1 call, but got %v.", fakeNodeHandler.RequestCount)
}
if len(fakeNodeHandler.CreatedNodes) != 1 {
t.Errorf("expect only 1 node created, got %v", len(fakeNodeHandler.CreatedNodes))
}
if fakeNodeHandler.CreatedNodes[0].Name != "node0" {
t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name)
}
}
func TestSyncStaticCreateNodeWithError(t *testing.T) {
fakeNodeHandler := &FakeNodeHandler{
CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool {
if fake.RequestCount == 0 {
return false
}
return true
},
}
nodeController := NewNodeController(nil, ".*", []string{"node0"}, &api.NodeResources{}, fakeNodeHandler)
if err := nodeController.SyncStatic(time.Millisecond); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeNodeHandler.RequestCount != 2 {
t.Errorf("Expected 2 call, but got %v.", fakeNodeHandler.RequestCount)
}
if len(fakeNodeHandler.CreatedNodes) != 1 {
t.Errorf("expect only 1 node created, got %v", len(fakeNodeHandler.CreatedNodes))
}
if fakeNodeHandler.CreatedNodes[0].Name != "node0" {
t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name)
}
}
func TestSyncCloudCreateNode(t *testing.T) {
fakeNodeHandler := &FakeNodeHandler{
Existing: []*api.Node{newNode("node0")},
}
instances := []string{"node0", "node1"}
fakeCloud := fake_cloud.FakeCloud{
Machines: instances,
}
nodeController := NewNodeController(&fakeCloud, ".*", nil, nil, fakeNodeHandler)
if err := nodeController.SyncCloud(); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeNodeHandler.RequestCount != 2 {
t.Errorf("Expected 2 call, but got %v.", fakeNodeHandler.RequestCount)
}
if len(fakeNodeHandler.CreatedNodes) != 1 {
t.Errorf("expect only 1 node created, got %v", len(fakeNodeHandler.CreatedNodes))
}
if fakeNodeHandler.CreatedNodes[0].Name != "node1" {
t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name)
}
}
func TestSyncCloudDeleteNode(t *testing.T) {
fakeNodeHandler := &FakeNodeHandler{
Existing: []*api.Node{newNode("node0"), newNode("node1")},
}
instances := []string{"node0"}
fakeCloud := fake_cloud.FakeCloud{
Machines: instances,
}
nodeController := NewNodeController(&fakeCloud, ".*", nil, nil, fakeNodeHandler)
if err := nodeController.SyncCloud(); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeNodeHandler.RequestCount != 2 {
t.Errorf("Expected 2 call, but got %v.", fakeNodeHandler.RequestCount)
}
if len(fakeNodeHandler.DeletedNodes) != 1 {
t.Errorf("expect only 1 node deleted, got %v", len(fakeNodeHandler.DeletedNodes))
}
if fakeNodeHandler.DeletedNodes[0].Name != "node1" {
t.Errorf("unexpect node %v created", fakeNodeHandler.DeletedNodes[0].Name)
}
}
func TestSyncCloudRegexp(t *testing.T) {
fakeNodeHandler := &FakeNodeHandler{
Existing: []*api.Node{newNode("node0")},
}
instances := []string{"node0", "node1", "fake"}
fakeCloud := fake_cloud.FakeCloud{
Machines: instances,
}
nodeController := NewNodeController(&fakeCloud, "node[0-9]+", nil, nil, fakeNodeHandler)
if err := nodeController.SyncCloud(); err != nil {
t.Errorf("unexpected error: %v", err)
}
if fakeNodeHandler.RequestCount != 2 {
t.Errorf("Expected 2 call, but got %v.", fakeNodeHandler.RequestCount)
}
if len(fakeNodeHandler.CreatedNodes) != 1 {
t.Errorf("expect only 1 node created, got %v", len(fakeNodeHandler.CreatedNodes))
}
if fakeNodeHandler.CreatedNodes[0].Name != "node1" {
t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name)
}
}
func contains(node *api.Node, nodes []*api.Node) bool {
for i := 0; i < len(nodes); i++ {
if node.Name == nodes[i].Name {
return true
}
}
return false
}

View File

@ -26,8 +26,9 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
minionControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
nodeControllerPkg "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
"github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config"
@ -130,8 +131,8 @@ func RunControllerManager(machineList []string, cl *client.Client, nodeMilliCPU,
api.ResourceMemory: *resource.NewQuantity(nodeMemory, resource.BinarySI),
},
}
minionController := minionControllerPkg.NewMinionController(nil, "", machineList, nodeResources, cl)
minionController.Run(10 * time.Second)
nodeController := nodeControllerPkg.NewNodeController(nil, "", machineList, nodeResources, cl)
nodeController.Run(10 * time.Second)
endpoints := service.NewEndpointController(cl)
go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10)