Skip to content

Commit b8b7ab3

Browse files
authored
Merge pull request kubernetes#76272 from liggitt/cleanup-legacy-printers
Remove legacy table printing and decoding
2 parents db1ab23 + c758f0a commit b8b7ab3

File tree

5 files changed

+35
-225
lines changed

5 files changed

+35
-225
lines changed

pkg/kubectl/cmd/get/humanreadable_flags.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"k8s.io/cli-runtime/pkg/genericclioptions"
2222

2323
"k8s.io/apimachinery/pkg/runtime/schema"
24-
"k8s.io/kubernetes/pkg/kubectl/scheme"
2524
"k8s.io/kubernetes/pkg/printers"
2625
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
2726
)
@@ -73,8 +72,6 @@ func (f *HumanPrintFlags) ToPrinter(outputFormat string) (printers.ResourcePrint
7372
return nil, genericclioptions.NoCompatiblePrinterError{Options: f, AllowedFormats: f.AllowedFormats()}
7473
}
7574

76-
decoder := scheme.Codecs.UniversalDecoder()
77-
7875
showKind := false
7976
if f.ShowKind != nil {
8077
showKind = *f.ShowKind
@@ -90,7 +87,7 @@ func (f *HumanPrintFlags) ToPrinter(outputFormat string) (printers.ResourcePrint
9087
columnLabels = *f.ColumnLabels
9188
}
9289

93-
p := printers.NewHumanReadablePrinter(decoder, printers.PrintOptions{
90+
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
9491
Kind: f.Kind,
9592
WithKind: showKind,
9693
NoHeaders: f.NoHeaders,

pkg/printers/BUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ go_library(
1717
deps = [
1818
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
1919
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
20-
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
2120
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
2221
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
2322
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",

pkg/printers/humanreadable.go

Lines changed: 6 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727

2828
"k8s.io/apimachinery/pkg/api/meta"
2929
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3130
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
3231
"k8s.io/apimachinery/pkg/labels"
3332
"k8s.io/apimachinery/pkg/runtime"
@@ -40,7 +39,6 @@ type TablePrinter interface {
4039
}
4140

4241
type PrintHandler interface {
43-
Handler(columns, columnsWithWide []string, printFunc interface{}) error
4442
TableHandler(columns []metav1beta1.TableColumnDefinition, printFunc interface{}) error
4543
DefaultTableHandler(columns []metav1beta1.TableColumnDefinition, printFunc interface{}) error
4644
}
@@ -49,7 +47,6 @@ var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print
4947

5048
type handlerEntry struct {
5149
columnDefinitions []metav1beta1.TableColumnDefinition
52-
printRows bool
5350
printFunc reflect.Value
5451
args []reflect.Value
5552
}
@@ -65,19 +62,15 @@ type HumanReadablePrinter struct {
6562
lastType interface{}
6663
lastColumns []metav1beta1.TableColumnDefinition
6764
skipTabWriter bool
68-
encoder runtime.Encoder
69-
decoder runtime.Decoder
7065
}
7166

7267
var _ PrintHandler = &HumanReadablePrinter{}
7368

7469
// NewHumanReadablePrinter creates a HumanReadablePrinter.
75-
// If encoder and decoder are provided, an attempt to convert unstructured types to internal types is made.
76-
func NewHumanReadablePrinter(decoder runtime.Decoder, options PrintOptions) *HumanReadablePrinter {
70+
func NewHumanReadablePrinter(options PrintOptions) *HumanReadablePrinter {
7771
printer := &HumanReadablePrinter{
7872
handlerMap: make(map[reflect.Type]*handlerEntry),
7973
options: options,
80-
decoder: decoder,
8174
}
8275
return printer
8376
}
@@ -112,53 +105,6 @@ func (h *HumanReadablePrinter) EnsurePrintHeaders() {
112105
h.lastType = nil
113106
}
114107

115-
// Handler adds a print handler with a given set of columns to HumanReadablePrinter instance.
116-
// See ValidatePrintHandlerFunc for required method signature.
117-
func (h *HumanReadablePrinter) Handler(columns, columnsWithWide []string, printFunc interface{}) error {
118-
var columnDefinitions []metav1beta1.TableColumnDefinition
119-
for i, column := range columns {
120-
format := ""
121-
if i == 0 && strings.EqualFold(column, "name") {
122-
format = "name"
123-
}
124-
125-
columnDefinitions = append(columnDefinitions, metav1beta1.TableColumnDefinition{
126-
Name: column,
127-
Description: column,
128-
Type: "string",
129-
Format: format,
130-
})
131-
}
132-
for _, column := range columnsWithWide {
133-
columnDefinitions = append(columnDefinitions, metav1beta1.TableColumnDefinition{
134-
Name: column,
135-
Description: column,
136-
Type: "string",
137-
Priority: 1,
138-
})
139-
}
140-
141-
printFuncValue := reflect.ValueOf(printFunc)
142-
if err := ValidatePrintHandlerFunc(printFuncValue); err != nil {
143-
utilruntime.HandleError(fmt.Errorf("unable to register print function: %v", err))
144-
return err
145-
}
146-
147-
entry := &handlerEntry{
148-
columnDefinitions: columnDefinitions,
149-
printFunc: printFuncValue,
150-
}
151-
152-
objType := printFuncValue.Type().In(0)
153-
if _, ok := h.handlerMap[objType]; ok {
154-
err := fmt.Errorf("registered duplicate printer for %v", objType)
155-
utilruntime.HandleError(err)
156-
return err
157-
}
158-
h.handlerMap[objType] = entry
159-
return nil
160-
}
161-
162108
// TableHandler adds a print handler with a given set of columns to HumanReadablePrinter instance.
163109
// See ValidateRowPrintHandlerFunc for required method signature.
164110
func (h *HumanReadablePrinter) TableHandler(columnDefinitions []metav1beta1.TableColumnDefinition, printFunc interface{}) error {
@@ -169,7 +115,6 @@ func (h *HumanReadablePrinter) TableHandler(columnDefinitions []metav1beta1.Tabl
169115
}
170116
entry := &handlerEntry{
171117
columnDefinitions: columnDefinitions,
172-
printRows: true,
173118
printFunc: printFuncValue,
174119
}
175120

@@ -194,7 +139,6 @@ func (h *HumanReadablePrinter) DefaultTableHandler(columnDefinitions []metav1bet
194139
}
195140
entry := &handlerEntry{
196141
columnDefinitions: columnDefinitions,
197-
printRows: true,
198142
printFunc: printFuncValue,
199143
}
200144

@@ -312,12 +256,6 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
312256
return PrintTable(table, output, localOptions)
313257
}
314258

315-
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before
316-
// trying to print, since the printers are keyed by type. This is extremely expensive.
317-
if h.decoder != nil {
318-
obj, _ = decodeUnknownObject(obj, h.decoder)
319-
}
320-
321259
// print with a registered handler
322260
t := reflect.TypeOf(obj)
323261
if handler := h.handlerMap[t]; handler != nil {
@@ -516,9 +454,6 @@ func (h *HumanReadablePrinter) PrintTable(obj runtime.Object, options PrintOptio
516454
if !ok {
517455
return nil, fmt.Errorf("no table handler registered for this type %v", t)
518456
}
519-
if !handler.printRows {
520-
return h.legacyPrinterToTable(obj, handler)
521-
}
522457

523458
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(options)}
524459
results := handler.printFunc.Call(args)
@@ -567,12 +502,11 @@ func (h *HumanReadablePrinter) PrintTable(obj runtime.Object, options PrintOptio
567502
// or an error, if any.
568503
func printRowsForHandlerEntry(output io.Writer, handler *handlerEntry, obj runtime.Object, options PrintOptions, includeHeaders bool) error {
569504
var results []reflect.Value
570-
if handler.printRows {
571-
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(options)}
572-
results = handler.printFunc.Call(args)
573-
if !results[1].IsNil() {
574-
return results[1].Interface().(error)
575-
}
505+
506+
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(options)}
507+
results = handler.printFunc.Call(args)
508+
if !results[1].IsNil() {
509+
return results[1].Interface().(error)
576510
}
577511

578512
if includeHeaders {
@@ -592,16 +526,6 @@ func printRowsForHandlerEntry(output io.Writer, handler *handlerEntry, obj runti
592526
printHeader(headers, output)
593527
}
594528

595-
if !handler.printRows {
596-
// TODO: this code path is deprecated and will be removed when all handlers are row printers
597-
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(output), reflect.ValueOf(options)}
598-
resultValue := handler.printFunc.Call(args)[0]
599-
if resultValue.IsNil() {
600-
return nil
601-
}
602-
return resultValue.Interface().(error)
603-
}
604-
605529
if results[1].IsNil() {
606530
rows := results[0].Interface().([]metav1beta1.TableRow)
607531
printRows(output, rows, options)
@@ -649,67 +573,6 @@ func printRows(output io.Writer, rows []metav1beta1.TableRow, options PrintOptio
649573
}
650574
}
651575

652-
// legacyPrinterToTable uses the old printFunc with tabbed writer to generate a table.
653-
// TODO: remove when all legacy printers are removed.
654-
func (h *HumanReadablePrinter) legacyPrinterToTable(obj runtime.Object, handler *handlerEntry) (*metav1beta1.Table, error) {
655-
printFunc := handler.printFunc
656-
table := &metav1beta1.Table{
657-
ColumnDefinitions: handler.columnDefinitions,
658-
}
659-
660-
options := PrintOptions{
661-
NoHeaders: true,
662-
Wide: true,
663-
}
664-
buf := &bytes.Buffer{}
665-
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(buf), reflect.ValueOf(options)}
666-
667-
if meta.IsListType(obj) {
668-
listInterface, ok := obj.(metav1.ListInterface)
669-
if ok {
670-
table.ListMeta.SelfLink = listInterface.GetSelfLink()
671-
table.ListMeta.ResourceVersion = listInterface.GetResourceVersion()
672-
table.ListMeta.Continue = listInterface.GetContinue()
673-
}
674-
675-
// TODO: this uses more memory than it has to, as we refactor printers we should remove the need
676-
// for this.
677-
args[0] = reflect.ValueOf(obj)
678-
resultValue := printFunc.Call(args)[0]
679-
if !resultValue.IsNil() {
680-
return nil, resultValue.Interface().(error)
681-
}
682-
data := buf.Bytes()
683-
i := 0
684-
items, err := meta.ExtractList(obj)
685-
if err != nil {
686-
return nil, err
687-
}
688-
for len(data) > 0 {
689-
cells, remainder := tabbedLineToCells(data, len(table.ColumnDefinitions))
690-
table.Rows = append(table.Rows, metav1beta1.TableRow{
691-
Cells: cells,
692-
Object: runtime.RawExtension{Object: items[i]},
693-
})
694-
data = remainder
695-
i++
696-
}
697-
} else {
698-
args[0] = reflect.ValueOf(obj)
699-
resultValue := printFunc.Call(args)[0]
700-
if !resultValue.IsNil() {
701-
return nil, resultValue.Interface().(error)
702-
}
703-
data := buf.Bytes()
704-
cells, _ := tabbedLineToCells(data, len(table.ColumnDefinitions))
705-
table.Rows = append(table.Rows, metav1beta1.TableRow{
706-
Cells: cells,
707-
Object: runtime.RawExtension{Object: obj},
708-
})
709-
}
710-
return table, nil
711-
}
712-
713576
// TODO: this method assumes the meta/v1 server API, so should be refactored out of this package
714577
func printUnstructured(unstructured runtime.Unstructured, w io.Writer, additionalFields []string, options PrintOptions) error {
715578
metadata, err := meta.Accessor(unstructured)
@@ -848,46 +711,3 @@ func AppendAllLabels(showLabels bool, itemLabels map[string]string) string {
848711

849712
return buffer.String()
850713
}
851-
852-
// check if the object is unstructured. If so, attempt to convert it to a type we can understand.
853-
func decodeUnknownObject(obj runtime.Object, decoder runtime.Decoder) (runtime.Object, error) {
854-
var err error
855-
switch t := obj.(type) {
856-
case runtime.Unstructured:
857-
if objBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj); err == nil {
858-
if decodedObj, err := runtime.Decode(decoder, objBytes); err == nil {
859-
obj = decodedObj
860-
}
861-
}
862-
case *runtime.Unknown:
863-
if decodedObj, err := runtime.Decode(decoder, t.Raw); err == nil {
864-
obj = decodedObj
865-
}
866-
}
867-
868-
return obj, err
869-
}
870-
871-
func tabbedLineToCells(data []byte, expected int) ([]interface{}, []byte) {
872-
var remainder []byte
873-
max := bytes.Index(data, []byte("\n"))
874-
if max != -1 {
875-
remainder = data[max+1:]
876-
data = data[:max]
877-
}
878-
cells := make([]interface{}, expected)
879-
for i := 0; i < expected; i++ {
880-
next := bytes.Index(data, []byte("\t"))
881-
if next == -1 {
882-
cells[i] = string(data)
883-
// fill the remainder with empty strings, this indicates a printer bug
884-
for j := i + 1; j < expected; j++ {
885-
cells[j] = ""
886-
}
887-
break
888-
}
889-
cells[i] = string(data[:next])
890-
data = data[next+1:]
891-
}
892-
return cells, remainder
893-
}

pkg/printers/humanreadable_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ func TestPrintRowsForHandlerEntry(t *testing.T) {
6161
name: "no tablecolumndefinition and includeheader flase",
6262
h: &handlerEntry{
6363
columnDefinitions: []metav1beta1.TableColumnDefinition{},
64-
printRows: true,
6564
printFunc: printFunc,
6665
},
6766
opt: PrintOptions{},
@@ -75,7 +74,6 @@ func TestPrintRowsForHandlerEntry(t *testing.T) {
7574
name: "no tablecolumndefinition and includeheader true",
7675
h: &handlerEntry{
7776
columnDefinitions: []metav1beta1.TableColumnDefinition{},
78-
printRows: true,
7977
printFunc: printFunc,
8078
},
8179
opt: PrintOptions{},
@@ -89,7 +87,6 @@ func TestPrintRowsForHandlerEntry(t *testing.T) {
8987
name: "have tablecolumndefinition and includeheader true",
9088
h: &handlerEntry{
9189
columnDefinitions: testNamespaceColumnDefinitions,
92-
printRows: true,
9390
printFunc: printFunc,
9491
},
9592
opt: PrintOptions{},
@@ -103,7 +100,6 @@ func TestPrintRowsForHandlerEntry(t *testing.T) {
103100
name: "print namespace and withnamespace true, should not print header",
104101
h: &handlerEntry{
105102
columnDefinitions: testNamespaceColumnDefinitions,
106-
printRows: true,
107103
printFunc: printFunc,
108104
},
109105
opt: PrintOptions{

0 commit comments

Comments
 (0)