Refactor PodStatus to PodCondition in internal API for v1beta3

This commit is contained in:
markturansky 2014-11-05 10:22:54 -05:00
parent 3bd10d4fb4
commit 119f654a13
13 changed files with 139 additions and 46 deletions

View File

@ -26,8 +26,8 @@ import (
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/fsouza/go-dockerclient"
"github.com/google/gofuzz"
docker "github.com/fsouza/go-dockerclient"
fuzz "github.com/google/gofuzz"
)
// apiObjectFuzzer can randomly populate api objects.
@ -71,6 +71,10 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
j.ResourceVersion = strconv.FormatUint(c.RandUint64()>>8, 10)
j.FieldPath = c.RandString()
},
func(j *internal.PodCondition, c fuzz.Continue) {
statuses := []internal.PodCondition{internal.PodPending, internal.PodRunning, internal.PodFailed}
*j = statuses[c.Rand.Intn(len(statuses))]
},
func(intstr *util.IntOrString, c fuzz.Continue) {
// util.IntOrString will panic if its kind is set wrong.
if c.RandBool() {

View File

@ -31,8 +31,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/fsouza/go-dockerclient"
"github.com/google/gofuzz"
docker "github.com/fsouza/go-dockerclient"
fuzz "github.com/google/gofuzz"
)
var fuzzIters = flag.Int("fuzz_iters", 40, "How many fuzzing iterations to do.")
@ -86,6 +86,10 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
j.ResourceVersion = strconv.FormatUint(c.RandUint64()>>8, 10)
j.SelfLink = c.RandString()
},
func(j *api.PodCondition, c fuzz.Continue) {
statuses := []api.PodCondition{api.PodPending, api.PodRunning, api.PodFailed}
*j = statuses[c.Rand.Intn(len(statuses))]
},
func(intstr *util.IntOrString, c fuzz.Continue) {
// util.IntOrString will panic if its kind is set wrong.
if c.RandBool() {

View File

@ -331,17 +331,24 @@ type Lifecycle struct {
// The below types are used by kube_client and api_server.
// PodStatus represents a status of a pod.
type PodStatus string
// PodCondition is a label for the condition of a pod at the current time.
type PodCondition string
// These are the valid statuses of pods.
const (
// PodWaiting means that we're waiting for the pod to begin running.
PodWaiting PodStatus = "Waiting"
// PodRunning means that the pod is up and running.
PodRunning PodStatus = "Running"
// PodTerminated means that the pod has stopped.
PodTerminated PodStatus = "Terminated"
// PodPending means the pod has been accepted by the system, but one or more of the containers
// has not been started. This includes time before being bound to a node, as well as time spent
// pulling images onto the host.
PodPending PodCondition = "Pending"
// PodRunning means the pod has been bound to a node and all of the containers have been started.
// At least one container is still running or is in the process of being restarted.
PodRunning PodCondition = "Running"
// PodSucceeded means that all containers in the pod have voluntarily terminated
// with a container exit code of 0, and the system is not going to restart any of these containers.
PodSucceeded PodCondition = "Succeeded"
// PodFailed means that all containers in the pod have terminated, and at least one container has
// terminated in a failure (exited with a non-zero exit code or was stopped by the system).
PodFailed PodCondition = "Failed"
)
type ContainerStateWaiting struct {
@ -408,7 +415,7 @@ type RestartPolicy struct {
// PodState is the state of a pod, used as either input (desired state) or output (current state).
type PodState struct {
Manifest ContainerManifest `json:"manifest,omitempty" yaml:"manifest,omitempty"`
Status PodStatus `json:"status,omitempty" yaml:"status,omitempty"`
Status PodCondition `json:"status,omitempty" yaml:"status,omitempty"`
Host string `json:"host,omitempty" yaml:"host,omitempty"`
HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
PodIP string `json:"podIP,omitempty" yaml:"podIP,omitempty"`

View File

@ -17,6 +17,7 @@ limitations under the License.
package v1beta1
import (
"errors"
"strconv"
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
@ -159,6 +160,43 @@ func init() {
return nil
},
// Convert all to the new PodCondition constants
func(in *newer.PodCondition, out *PodStatus, s conversion.Scope) error {
switch *in {
case "":
*out = ""
case newer.PodPending:
*out = PodWaiting
case newer.PodRunning:
*out = PodRunning
case newer.PodSucceeded:
*out = PodTerminated
case newer.PodFailed:
*out = PodTerminated
default:
return errors.New("The string provided is not a valid PodCondition constant value")
}
return nil
},
func(in *PodStatus, out *newer.PodCondition, s conversion.Scope) error {
switch *in {
case "":
*out = ""
case PodWaiting:
*out = newer.PodPending
case PodRunning:
*out = newer.PodRunning
case PodTerminated:
// Older API versions did not contain enough info to map to PodFailed
*out = newer.PodFailed
default:
return errors.New("The string provided is not a valid PodCondition constant value")
}
return nil
},
// Convert all the standard objects
func(in *newer.Pod, out *Pod, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {

View File

@ -17,6 +17,7 @@ limitations under the License.
package v1beta2
import (
"errors"
"strconv"
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
@ -89,7 +90,43 @@ func init() {
return s.Convert(&in.Annotations, &out.Annotations, 0)
},
// Convert all the standard objects
// Convert all to the new PodCondition constants
func(in *newer.PodCondition, out *PodStatus, s conversion.Scope) error {
switch *in {
case "":
*out = ""
case newer.PodPending:
*out = PodWaiting
case newer.PodRunning:
*out = PodRunning
case newer.PodSucceeded:
*out = PodTerminated
case newer.PodFailed:
*out = PodTerminated
default:
return errors.New("The string provided is not a valid PodCondition constant value")
}
return nil
},
func(in *PodStatus, out *newer.PodCondition, s conversion.Scope) error {
switch *in {
case "":
*out = ""
case PodWaiting:
*out = newer.PodPending
case PodRunning:
*out = newer.PodRunning
case PodTerminated:
// Older API versions did not contain enough info to map to PodFailed
*out = newer.PodFailed
default:
return errors.New("The string provided is not a valid PodCondition constant value")
}
return nil
},
// Convert all the standard objects
func(in *newer.Pod, out *Pod, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {

View File

@ -374,8 +374,8 @@ const (
// PodRunning means the pod has been bound to a node and all of the containers have been started.
// At least one container is still running or is in the process of being restarted.
PodRunning PodCondition = "Running"
// PodSucceeded means that all containers in the pod have voluntarily terminated with a container
// exit code of 0.
// PodSucceeded means that all containers in the pod have voluntarily terminated
// with a container exit code of 0, and the system is not going to restart any of these containers.
PodSucceeded PodCondition = "Succeeded"
// PodFailed means that all containers in the pod have terminated, and at least one container has
// terminated in a failure (exited with a non-zero exit code or was stopped by the system).

View File

@ -165,7 +165,7 @@ func TestListPods(t *testing.T) {
Items: []api.Pod{
{
CurrentState: api.PodState{
Status: "Foobar",
Status: api.PodRunning,
},
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{
@ -198,7 +198,7 @@ func TestListPodsLabels(t *testing.T) {
Items: []api.Pod{
{
CurrentState: api.PodState{
Status: "Foobar",
Status: api.PodRunning,
},
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{
@ -226,7 +226,7 @@ func TestGetPod(t *testing.T) {
StatusCode: 200,
Body: &api.Pod{
CurrentState: api.PodState{
Status: "Foobar",
Status: api.PodRunning,
},
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{
@ -253,7 +253,7 @@ func TestDeletePod(t *testing.T) {
func TestCreatePod(t *testing.T) {
requestPod := &api.Pod{
CurrentState: api.PodState{
Status: "Foobar",
Status: api.PodRunning,
},
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{
@ -284,7 +284,7 @@ func TestUpdatePod(t *testing.T) {
},
},
CurrentState: api.PodState{
Status: "Foobar",
Status: api.PodRunning,
},
}
c := &testClient{

View File

@ -134,7 +134,8 @@ func (rm *ReplicationManager) watchControllers(resourceVersion *string) {
func (rm *ReplicationManager) filterActivePods(pods []api.Pod) []api.Pod {
var result []api.Pod
for _, value := range pods {
if api.PodTerminated != value.CurrentState.Status {
if api.PodSucceeded != value.CurrentState.Status &&
api.PodFailed != value.CurrentState.Status {
result = append(result, value)
}
}

View File

@ -120,7 +120,7 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string) (strin
return "", err
}
running, waiting, terminated, err := getPodStatusForReplicationController(pc, controller)
running, waiting, succeeded, failed, err := getPodStatusForReplicationController(pc, controller)
if err != nil {
return "", err
}
@ -131,7 +131,7 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string) (strin
fmt.Fprintf(out, "Selector:\t%s\n", formatLabels(controller.DesiredState.ReplicaSelector))
fmt.Fprintf(out, "Labels:\t%s\n", formatLabels(controller.Labels))
fmt.Fprintf(out, "Replicas:\t%d current / %d desired\n", controller.CurrentState.Replicas, controller.DesiredState.Replicas)
fmt.Fprintf(out, "Pods Status:\t%d Running / %d Waiting / %d Terminated\n", running, waiting, terminated)
fmt.Fprintf(out, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed)
return nil
})
}
@ -216,7 +216,7 @@ func getReplicationControllersForLabels(c client.ReplicationControllerInterface,
return list
}
func getPodStatusForReplicationController(c client.PodInterface, controller *api.ReplicationController) (running, waiting, terminated int, err error) {
func getPodStatusForReplicationController(c client.PodInterface, controller *api.ReplicationController) (running, waiting, succeeded, failed int, err error) {
rcPods, err := c.List(labels.SelectorFromSet(controller.DesiredState.ReplicaSelector))
if err != nil {
return
@ -224,10 +224,12 @@ func getPodStatusForReplicationController(c client.PodInterface, controller *api
for _, pod := range rcPods.Items {
if pod.CurrentState.Status == api.PodRunning {
running++
} else if pod.CurrentState.Status == api.PodWaiting {
} else if pod.CurrentState.Status == api.PodPending {
waiting++
} else if pod.CurrentState.Status == api.PodTerminated {
terminated++
} else if pod.CurrentState.Status == api.PodSucceeded {
succeeded++
} else if pod.CurrentState.Status == api.PodFailed {
failed++
}
}
return

View File

@ -183,7 +183,7 @@ func makeContainerKey(machine string) string {
// CreatePod creates a pod based on a specification.
func (r *Registry) CreatePod(ctx api.Context, pod *api.Pod) error {
// Set current status to "Waiting".
pod.CurrentState.Status = api.PodWaiting
pod.CurrentState.Status = api.PodPending
pod.CurrentState.Host = ""
// DesiredState.Host == "" is a signal to the scheduler that this pod needs scheduling.
pod.DesiredState.Status = api.PodRunning

View File

@ -267,9 +267,9 @@ func getInstanceIPFromCloud(cloud cloudprovider.Interface, host string) string {
return addr.String()
}
func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodStatus, error) {
func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodCondition, error) {
if pod.CurrentState.Host == "" {
return api.PodWaiting, nil
return api.PodPending, nil
}
if minions != nil {
res, err := minions.List()
@ -285,13 +285,13 @@ func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodStatus,
}
}
if !found {
return api.PodTerminated, nil
return api.PodFailed, nil
}
} else {
glog.Errorf("Unexpected missing minion interface, status may be in-accurate")
}
if pod.CurrentState.Info == nil {
return api.PodWaiting, nil
return api.PodPending, nil
}
running := 0
stopped := 0
@ -313,10 +313,10 @@ func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodStatus,
case running > 0 && unknown == 0:
return api.PodRunning, nil
case running == 0 && stopped > 0 && unknown == 0:
return api.PodTerminated, nil
return api.PodFailed, nil
case running == 0 && stopped == 0 && unknown > 0:
return api.PodWaiting, nil
return api.PodPending, nil
default:
return api.PodWaiting, nil
return api.PodPending, nil
}
}

View File

@ -418,10 +418,10 @@ func TestMakePodStatus(t *testing.T) {
tests := []struct {
pod *api.Pod
status api.PodStatus
status api.PodCondition
test string
}{
{&api.Pod{DesiredState: desiredState, CurrentState: currentState}, api.PodWaiting, "waiting"},
{&api.Pod{DesiredState: desiredState, CurrentState: currentState}, api.PodPending, "waiting"},
{
&api.Pod{
DesiredState: desiredState,
@ -429,7 +429,7 @@ func TestMakePodStatus(t *testing.T) {
Host: "machine-2",
},
},
api.PodTerminated,
api.PodFailed,
"no info, but bad machine",
},
{
@ -457,7 +457,7 @@ func TestMakePodStatus(t *testing.T) {
Host: "machine-two",
},
},
api.PodTerminated,
api.PodFailed,
"all running but minion is missing",
},
{
@ -471,7 +471,7 @@ func TestMakePodStatus(t *testing.T) {
Host: "machine",
},
},
api.PodTerminated,
api.PodFailed,
"all stopped",
},
{
@ -485,7 +485,7 @@ func TestMakePodStatus(t *testing.T) {
Host: "machine-two",
},
},
api.PodTerminated,
api.PodFailed,
"all stopped but minion missing",
},
{
@ -512,7 +512,7 @@ func TestMakePodStatus(t *testing.T) {
Host: "machine",
},
},
api.PodWaiting,
api.PodPending,
"mixed state #2",
},
}

View File

@ -68,7 +68,7 @@ func (s *Scheduler) scheduleOne() {
pod := s.config.NextPod()
dest, err := s.config.Algorithm.Schedule(*pod, s.config.MinionLister)
if err != nil {
record.Eventf(pod, "", string(api.PodWaiting), "failedScheduling", "Error scheduling: %v", err)
record.Eventf(pod, "", string(api.PodPending), "failedScheduling", "Error scheduling: %v", err)
s.config.Error(pod, err)
return
}
@ -78,9 +78,9 @@ func (s *Scheduler) scheduleOne() {
Host: dest,
}
if err := s.config.Binder.Bind(b); err != nil {
record.Eventf(pod, "", string(api.PodWaiting), "failedScheduling", "Binding rejected: %v", err)
record.Eventf(pod, "", string(api.PodPending), "failedScheduling", "Binding rejected: %v", err)
s.config.Error(pod, err)
return
}
record.Eventf(pod, "", string(api.PodWaiting), "scheduled", "Successfully assigned %v to %v", pod.Name, dest)
record.Eventf(pod, "", string(api.PodPending), "scheduled", "Successfully assigned %v to %v", pod.Name, dest)
}