Modify "kubectl get events" to print FieldPath so BoundPod events for the same Pod but different containers can be differentiated

This commit is contained in:
saadali 2014-12-29 17:10:38 -08:00
parent 0155ede0c2
commit e8d30f019d
7 changed files with 33 additions and 22 deletions

View File

@ -975,10 +975,11 @@ type ObjectReference struct {
ResourceVersion string `json:"resourceVersion,omitempty"` ResourceVersion string `json:"resourceVersion,omitempty"`
// Optional. If referring to a piece of an object instead of an entire object, this string // Optional. If referring to a piece of an object instead of an entire object, this string
// should contain a valid field access statement. For example, // should contain information to identify the sub-object. For example, if the object
// if the object reference is to a container within a pod, this would take on a value like: // reference is to a container within a pod, this would take on a value like:
// "desiredState.manifest.containers[2]". Such statements are valid language constructs in // "spec.containers{name}" (where "name" refers to the name of the container that triggered
// both go and JavaScript. This is syntax is chosen only to have some well-defined way of // the event) or if no container name is specified "spec.containers[2]" (container with
// index 2 in this pod). This syntax is chosen only to have some well-defined way of
// referencing a part of an object. // referencing a part of an object.
// TODO: this design is not final and this field is subject to change in the future. // TODO: this design is not final and this field is subject to change in the future.
FieldPath string `json:"fieldPath,omitempty"` FieldPath string `json:"fieldPath,omitempty"`

View File

@ -777,10 +777,11 @@ type ObjectReference struct {
ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any"` ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any"`
// Optional. If referring to a piece of an object instead of an entire object, this string // Optional. If referring to a piece of an object instead of an entire object, this string
// should contain a valid field access statement. For example, // should contain information to identify the sub-object. For example, if the object
// if the object reference is to a container within a pod, this would take on a value like: // reference is to a container within a pod, this would take on a value like:
// "desiredState.manifest.containers[2]". Such statements are valid language constructs in // "spec.containers{name}" (where "name" refers to the name of the container that triggered
// both go and JavaScript. This is syntax is chosen only to have some well-defined way of // the event) or if no container name is specified "spec.containers[2]" (container with
// index 2 in this pod). This syntax is chosen only to have some well-defined way of
// referencing a part of an object. // referencing a part of an object.
// TODO: this design is not final and this field is subject to change in the future. // TODO: this design is not final and this field is subject to change in the future.
FieldPath string `json:"fieldPath,omitempty" description:"if referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]"` FieldPath string `json:"fieldPath,omitempty" description:"if referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]"`

View File

@ -750,10 +750,11 @@ type ObjectReference struct {
ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any"` ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any"`
// Optional. If referring to a piece of an object instead of an entire object, this string // Optional. If referring to a piece of an object instead of an entire object, this string
// should contain a valid field access statement. For example, // should contain information to identify the sub-object. For example, if the object
// if the object reference is to a container within a pod, this would take on a value like: // reference is to a container within a pod, this would take on a value like:
// "desiredState.manifest.containers[2]". Such statements are valid language constructs in // "spec.containers{name}" (where "name" refers to the name of the container that triggered
// both go and JavaScript. This is syntax is chosen only to have some well-defined way of // the event) or if no container name is specified "spec.containers[2]" (container with
// index 2 in this pod). This syntax is chosen only to have some well-defined way of
// referencing a part of an object. // referencing a part of an object.
// TODO: this design is not final and this field is subject to change in the future. // TODO: this design is not final and this field is subject to change in the future.
FieldPath string `json:"fieldPath,omitempty" description:"if referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]"` FieldPath string `json:"fieldPath,omitempty" description:"if referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]"`

View File

@ -993,10 +993,11 @@ type ObjectReference struct {
ResourceVersion string `json:"resourceVersion,omitempty"` ResourceVersion string `json:"resourceVersion,omitempty"`
// Optional. If referring to a piece of an object instead of an entire object, this string // Optional. If referring to a piece of an object instead of an entire object, this string
// should contain a valid field access statement. For example, // should contain information to identify the sub-object. For example, if the object
// if the object reference is to a container within a pod, this would take on a value like: // reference is to a container within a pod, this would take on a value like:
// "spec.containers[2]". Such statements are valid language constructs in // "spec.containers{name}" (where "name" refers to the name of the container that triggered
// both go and JavaScript. This is syntax is chosen only to have some well-defined way of // the event) or if no container name is specified "spec.containers[2]" (container with
// index 2 in this pod). This syntax is chosen only to have some well-defined way of
// referencing a part of an object. // referencing a part of an object.
// TODO: this design is not final and this field is subject to change in the future. // TODO: this design is not final and this field is subject to change in the future.
FieldPath string `json:"fieldPath,omitempty"` FieldPath string `json:"fieldPath,omitempty"`

View File

@ -193,7 +193,7 @@ var replicationControllerColumns = []string{"CONTROLLER", "CONTAINER(S)", "IMAGE
var serviceColumns = []string{"NAME", "LABELS", "SELECTOR", "IP", "PORT"} var serviceColumns = []string{"NAME", "LABELS", "SELECTOR", "IP", "PORT"}
var minionColumns = []string{"NAME", "LABELS"} var minionColumns = []string{"NAME", "LABELS"}
var statusColumns = []string{"STATUS"} var statusColumns = []string{"STATUS"}
var eventColumns = []string{"TIME", "NAME", "KIND", "CONDITION", "REASON", "MESSAGE"} var eventColumns = []string{"TIME", "NAME", "KIND", "SUBOBJECT", "CONDITION", "REASON", "MESSAGE"}
// addDefaultHandlers adds print handlers for default Kubernetes types. // addDefaultHandlers adds print handlers for default Kubernetes types.
func (h *HumanReadablePrinter) addDefaultHandlers() { func (h *HumanReadablePrinter) addDefaultHandlers() {
@ -339,10 +339,11 @@ func printStatus(status *api.Status, w io.Writer) error {
func printEvent(event *api.Event, w io.Writer) error { func printEvent(event *api.Event, w io.Writer) error {
_, err := fmt.Fprintf( _, err := fmt.Fprintf(
w, "%s\t%s\t%s\t%s\t%s\t%s\n", w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
event.Timestamp.Time.Format(time.RFC1123Z), event.Timestamp.Time.Format(time.RFC1123Z),
event.InvolvedObject.Name, event.InvolvedObject.Name,
event.InvolvedObject.Kind, event.InvolvedObject.Kind,
event.InvolvedObject.FieldPath,
event.Condition, event.Condition,
event.Reason, event.Reason,
event.Message, event.Message,

View File

@ -463,7 +463,11 @@ func fieldPath(pod *api.BoundPod, container *api.Container) (string, error) {
for i := range pod.Spec.Containers { for i := range pod.Spec.Containers {
here := &pod.Spec.Containers[i] here := &pod.Spec.Containers[i]
if here.Name == container.Name { if here.Name == container.Name {
if here.Name == "" {
return fmt.Sprintf("spec.containers[%d]", i), nil return fmt.Sprintf("spec.containers[%d]", i), nil
} else {
return fmt.Sprintf("spec.containers{%s}", here.Name), nil
}
} }
} }
return "", fmt.Errorf("container %#v not found in pod %#v", container, pod) return "", fmt.Errorf("container %#v not found in pod %#v", container, pod)

View File

@ -956,6 +956,7 @@ func TestFieldPath(t *testing.T) {
pod := &api.BoundPod{Spec: api.PodSpec{Containers: []api.Container{ pod := &api.BoundPod{Spec: api.PodSpec{Containers: []api.Container{
{Name: "foo"}, {Name: "foo"},
{Name: "bar"}, {Name: "bar"},
{Name: ""},
{Name: "baz"}, {Name: "baz"},
}}} }}}
table := map[string]struct { table := map[string]struct {
@ -964,9 +965,10 @@ func TestFieldPath(t *testing.T) {
path string path string
success bool success bool
}{ }{
"basic": {pod, &api.Container{Name: "foo"}, "spec.containers[0]", true}, "basic": {pod, &api.Container{Name: "foo"}, "spec.containers{foo}", true},
"basic2": {pod, &api.Container{Name: "baz"}, "spec.containers[2]", true}, "basic2": {pod, &api.Container{Name: "baz"}, "spec.containers{baz}", true},
"basicSamePointer": {pod, &pod.Spec.Containers[0], "spec.containers[0]", true}, "emptyName": {pod, &api.Container{Name: ""}, "spec.containers[2]", true},
"basicSamePointer": {pod, &pod.Spec.Containers[0], "spec.containers{foo}", true},
"missing": {pod, &api.Container{Name: "qux"}, "", false}, "missing": {pod, &api.Container{Name: "qux"}, "", false},
} }