mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #42285 from liggitt/get-watch
Automatic merge from submit-queue (batch tested with PRs 41919, 41149, 42350, 42351, 42285) Fix error printing objects from kubectl get -w Fixes #42276
This commit is contained in:
commit
f7c07a121d
@ -1160,6 +1160,19 @@ run_kubectl_get_tests() {
|
||||
output_message=$(! kubectl get pod valid-pod --allow-missing-template-keys=false -o go-template='{{.missing}}' "${kube_flags[@]}")
|
||||
kube::test::if_has_string "${output_message}" 'map has no entry for key "missing"'
|
||||
|
||||
### Test kubectl get watch
|
||||
output_message=$(kubectl get pods -w --request-timeout=1 "${kube_flags[@]}")
|
||||
kube::test::if_has_string "${output_message}" 'STATUS' # headers
|
||||
kube::test::if_has_string "${output_message}" 'valid-pod' # pod details
|
||||
output_message=$(kubectl get pods/valid-pod -o name -w --request-timeout=1 "${kube_flags[@]}")
|
||||
kube::test::if_has_not_string "${output_message}" 'STATUS' # no headers
|
||||
kube::test::if_has_string "${output_message}" 'pods/valid-pod' # resource name
|
||||
output_message=$(kubectl get pods/valid-pod -o yaml -w --request-timeout=1 "${kube_flags[@]}")
|
||||
kube::test::if_has_not_string "${output_message}" 'STATUS' # no headers
|
||||
kube::test::if_has_string "${output_message}" 'name: valid-pod' # yaml
|
||||
output_message=$(! kubectl get pods/invalid-pod -w --request-timeout=1 "${kube_flags[@]}" 2>&1)
|
||||
kube::test::if_has_string "${output_message}" '"invalid-pod" not found'
|
||||
|
||||
# cleanup
|
||||
kubectl delete pods valid-pod "${kube_flags[@]}"
|
||||
|
||||
|
@ -147,7 +147,7 @@ func stringBody(body string) io.ReadCloser {
|
||||
|
||||
func Example_printReplicationControllerWithNamespace() {
|
||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
WithNamespace: true,
|
||||
ColumnLabels: []string{},
|
||||
})
|
||||
@ -200,7 +200,7 @@ func Example_printReplicationControllerWithNamespace() {
|
||||
|
||||
func Example_printMultiContainersReplicationControllerWithWide() {
|
||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
Wide: true,
|
||||
ColumnLabels: []string{},
|
||||
})
|
||||
@ -255,7 +255,7 @@ func Example_printMultiContainersReplicationControllerWithWide() {
|
||||
|
||||
func Example_printReplicationController() {
|
||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
ColumnLabels: []string{},
|
||||
})
|
||||
printersinternal.AddHandlers(p)
|
||||
@ -309,7 +309,7 @@ func Example_printReplicationController() {
|
||||
|
||||
func Example_printPodWithWideFormat() {
|
||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
Wide: true,
|
||||
ColumnLabels: []string{},
|
||||
})
|
||||
@ -352,7 +352,7 @@ func Example_printPodWithWideFormat() {
|
||||
|
||||
func Example_printPodWithShowLabels() {
|
||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
ShowLabels: true,
|
||||
ColumnLabels: []string{},
|
||||
})
|
||||
@ -490,7 +490,7 @@ func newAllPhasePodList() *api.PodList {
|
||||
|
||||
func Example_printPodHideTerminated() {
|
||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
ColumnLabels: []string{},
|
||||
})
|
||||
printersinternal.AddHandlers(p)
|
||||
@ -525,7 +525,7 @@ func Example_printPodHideTerminated() {
|
||||
|
||||
func Example_printPodShowAll() {
|
||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
ShowAll: true,
|
||||
ColumnLabels: []string{},
|
||||
})
|
||||
@ -554,7 +554,7 @@ func Example_printPodShowAll() {
|
||||
|
||||
func Example_printServiceWithNamespacesAndLabels() {
|
||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
WithNamespace: true,
|
||||
ColumnLabels: []string{"l1"},
|
||||
})
|
||||
|
@ -251,8 +251,16 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
|
||||
// print the current object
|
||||
filteredResourceCount := 0
|
||||
if !isWatchOnly {
|
||||
if err := printer.PrintObj(obj, out); err != nil {
|
||||
return fmt.Errorf("unable to output the provided object: %v", err)
|
||||
var objsToPrint []runtime.Object
|
||||
if isList {
|
||||
objsToPrint, _ = meta.ExtractList(obj)
|
||||
} else {
|
||||
objsToPrint = append(objsToPrint, obj)
|
||||
}
|
||||
for _, objToPrint := range objsToPrint {
|
||||
if err := printer.PrintObj(objToPrint, out); err != nil {
|
||||
return fmt.Errorf("unable to output the provided object: %v", err)
|
||||
}
|
||||
}
|
||||
filteredResourceCount++
|
||||
cmdutil.PrintFilterCount(filteredResourceCount, mapping.Resource, filterOpts)
|
||||
|
@ -848,7 +848,7 @@ func TestWatchSelector(t *testing.T) {
|
||||
cmd.Flags().Set("selector", "a=b")
|
||||
cmd.Run(cmd, []string{"pods"})
|
||||
|
||||
expected := []runtime.Object{podList, events[2].Object, events[3].Object}
|
||||
expected := []runtime.Object{&pods[0], &pods[1], events[2].Object, events[3].Object}
|
||||
verifyObjects(t, expected, tf.Printer.(*testPrinter).Objects)
|
||||
|
||||
if len(buf.String()) == 0 {
|
||||
|
@ -416,7 +416,7 @@ func (f *ring0Factory) SuggestedPodTemplateResources() []schema.GroupResource {
|
||||
}
|
||||
|
||||
func (f *ring0Factory) Printer(mapping *meta.RESTMapping, options printers.PrintOptions) (printers.ResourcePrinter, error) {
|
||||
p := printers.NewHumanReadablePrinter(options)
|
||||
p := printers.NewHumanReadablePrinter(f.JSONEncoder(), f.Decoder(true), options)
|
||||
printersinternal.AddHandlers(p)
|
||||
return p, nil
|
||||
}
|
||||
|
@ -50,13 +50,18 @@ type HumanReadablePrinter struct {
|
||||
options PrintOptions
|
||||
lastType reflect.Type
|
||||
hiddenObjNum int
|
||||
encoder runtime.Encoder
|
||||
decoder runtime.Decoder
|
||||
}
|
||||
|
||||
// NewHumanReadablePrinter creates a HumanReadablePrinter.
|
||||
func NewHumanReadablePrinter(options PrintOptions) *HumanReadablePrinter {
|
||||
// If encoder and decoder are provided, an attempt to convert unstructured types to internal types is made.
|
||||
func NewHumanReadablePrinter(encoder runtime.Encoder, decoder runtime.Decoder, options PrintOptions) *HumanReadablePrinter {
|
||||
printer := &HumanReadablePrinter{
|
||||
handlerMap: make(map[reflect.Type]*handlerEntry),
|
||||
options: options,
|
||||
encoder: encoder,
|
||||
decoder: decoder,
|
||||
}
|
||||
return printer
|
||||
}
|
||||
@ -167,7 +172,9 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
||||
|
||||
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before
|
||||
// trying to print, since the printers are keyed by type. This is extremely expensive.
|
||||
//obj, _ = DecodeUnknownObject(obj)
|
||||
if h.encoder != nil && h.decoder != nil {
|
||||
obj, _ = decodeUnknownObject(obj, h.encoder, h.decoder)
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(obj)
|
||||
if handler := h.handlerMap[t]; handler != nil {
|
||||
@ -327,3 +334,18 @@ func appendAllLabels(showLabels bool, itemLabels map[string]string) string {
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// check if the object is unstructured. If so, attempt to convert it to a type we can understand.
|
||||
func decodeUnknownObject(obj runtime.Object, encoder runtime.Encoder, decoder runtime.Decoder) (runtime.Object, error) {
|
||||
var err error
|
||||
switch obj.(type) {
|
||||
case runtime.Unstructured, *runtime.Unknown:
|
||||
if objBytes, err := runtime.Encode(encoder, obj); err == nil {
|
||||
if decodedObj, err := runtime.Decode(decoder, objBytes); err == nil {
|
||||
obj = decodedObj
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj, err
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ func ErrorPrintHandler(obj *TestPrintType, w io.Writer, options printers.PrintOp
|
||||
|
||||
func TestCustomTypePrinting(t *testing.T) {
|
||||
columns := []string{"Data"}
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||
printer.Handler(columns, nil, PrintCustomType)
|
||||
|
||||
obj := TestPrintType{"test object"}
|
||||
@ -275,7 +275,7 @@ func TestCustomTypePrinting(t *testing.T) {
|
||||
|
||||
func TestCustomTypePrintingWithKind(t *testing.T) {
|
||||
columns := []string{"Data"}
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||
printer.Handler(columns, nil, PrintCustomType)
|
||||
printer.EnsurePrintWithKind("test")
|
||||
|
||||
@ -293,7 +293,7 @@ func TestCustomTypePrintingWithKind(t *testing.T) {
|
||||
|
||||
func TestPrintHandlerError(t *testing.T) {
|
||||
columns := []string{"Data"}
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||
printer.Handler(columns, nil, ErrorPrintHandler)
|
||||
obj := TestPrintType{"test object"}
|
||||
buffer := &bytes.Buffer{}
|
||||
@ -304,7 +304,7 @@ func TestPrintHandlerError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUnknownTypePrinting(t *testing.T) {
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||
buffer := &bytes.Buffer{}
|
||||
err := printer.PrintObj(&TestUnknownType{}, buffer)
|
||||
if err == nil {
|
||||
@ -522,10 +522,10 @@ func TestPrinters(t *testing.T) {
|
||||
jsonpathPrinter = printers.NewVersionedPrinter(jsonpathPrinter, api.Scheme, v1.SchemeGroupVersion)
|
||||
|
||||
allPrinters := map[string]printers.ResourcePrinter{
|
||||
"humanReadable": printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
"humanReadable": printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
NoHeaders: true,
|
||||
}),
|
||||
"humanReadableHeaders": printers.NewHumanReadablePrinter(printers.PrintOptions{}),
|
||||
"humanReadableHeaders": printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{}),
|
||||
"json": &printers.JSONPrinter{},
|
||||
"yaml": &printers.YAMLPrinter{},
|
||||
"template": templatePrinter,
|
||||
@ -571,7 +571,7 @@ func TestPrinters(t *testing.T) {
|
||||
|
||||
func TestPrintEventsResultSorted(t *testing.T) {
|
||||
// Arrange
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||
AddHandlers(printer)
|
||||
|
||||
obj := api.EventList{
|
||||
@ -616,7 +616,7 @@ func TestPrintEventsResultSorted(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrintNodeStatus(t *testing.T) {
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||
AddHandlers(printer)
|
||||
table := []struct {
|
||||
node api.Node
|
||||
@ -736,7 +736,7 @@ func TestPrintNodeStatus(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrintNodeOSImage(t *testing.T) {
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
ColumnLabels: []string{},
|
||||
Wide: true,
|
||||
})
|
||||
@ -781,7 +781,7 @@ func TestPrintNodeOSImage(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrintNodeKernelVersion(t *testing.T) {
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
ColumnLabels: []string{},
|
||||
Wide: true,
|
||||
})
|
||||
@ -826,7 +826,7 @@ func TestPrintNodeKernelVersion(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrintNodeExternalIP(t *testing.T) {
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
Wide: true,
|
||||
})
|
||||
AddHandlers(printer)
|
||||
@ -1219,7 +1219,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
|
||||
for _, test := range table {
|
||||
if test.isNamespaced {
|
||||
// Expect output to include namespace when requested.
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
WithNamespace: true,
|
||||
})
|
||||
AddHandlers(printer)
|
||||
@ -1234,7 +1234,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
|
||||
}
|
||||
} else {
|
||||
// Expect error when trying to get all namespaces for un-namespaced object.
|
||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
||||
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||
WithNamespace: true,
|
||||
})
|
||||
buffer := &bytes.Buffer{}
|
||||
|
Loading…
Reference in New Issue
Block a user