<p>In Kubernetes, is it possible to display a column using a fraction format (i.e. X/Y) using the &quot;additionalPrinterColumns&quot; field of a CRD?</p>
<p>More precisely, I would like <code>kubectl</code> to display the description of a CR field using the same format than the READY field below:</p>
<pre><code>kubectl get statefulsets.apps &lt;my-statefulset&gt;
NAME              READY   AGE
&lt;my-statefulset&gt;  2/2     18m
</code></pre>
<p>Could you provide the content of the &quot;additionalPrinterColumns&quot; section?</p>

Fabrice Jammes
<p>Unfortunately additionalPrinterColumns only supports Simple JsonPath and so we cannot use .status.readyReplicas/.status.replicas in JsonPath and the GET Operation is handled by kube-apiserver so there is no involvement of Operator in GET Operation. So, easiest way I would recommend is to create a new Field in .status called ready with value &quot;readyReplicas/replicas&quot; and update it every time you update readyReplicas and replicas.</p>
<p>Then put below in additionalPrinterColumns</p>
<pre><code>   additionalPrinterColumns:
    - jsonPath: .status.ready
      name: Ready
      type: string
</code></pre>
<p>For StatefulSet, they are using below code in <a href="https://github.com/kubernetes/kubernetes/blob/master/pkg/printers/internalversion/printers.go" rel="noreferrer">https://github.com/kubernetes/kubernetes/blob/master/pkg/printers/internalversion/printers.go</a> to print value of READY Column</p>
<pre><code>    statefulSetColumnDefinitions := []metav1.TableColumnDefinition{
        {Name: &quot;Name&quot;, Type: &quot;string&quot;, Format: &quot;name&quot;, Description: metav1.ObjectMeta{}.SwaggerDoc()[&quot;name&quot;]},
        {Name: &quot;Ready&quot;, Type: &quot;string&quot;, Description: &quot;Number of the pod with ready state&quot;},
        {Name: &quot;Age&quot;, Type: &quot;string&quot;, Description: metav1.ObjectMeta{}.SwaggerDoc()[&quot;creationTimestamp&quot;]},
        {Name: &quot;Containers&quot;, Type: &quot;string&quot;, Priority: 1, Description: &quot;Names of each container in the template.&quot;},
        {Name: &quot;Images&quot;, Type: &quot;string&quot;, Priority: 1, Description: &quot;Images referenced by each container in the template.&quot;},
    }
    h.TableHandler(statefulSetColumnDefinitions, printStatefulSet)
    h.TableHandler(statefulSetColumnDefinitions, printStatefulSetList)


func printStatefulSet(obj *apps.StatefulSet, options printers.GenerateOptions) ([]metav1.TableRow, error) {
    row := metav1.TableRow{
        Object: runtime.RawExtension{Object: obj},
    }
    desiredReplicas := obj.Spec.Replicas
    readyReplicas := obj.Status.ReadyReplicas
    createTime := translateTimestampSince(obj.CreationTimestamp)
    row.Cells = append(row.Cells, obj.Name, fmt.Sprintf(&quot;%d/%d&quot;, int64(readyReplicas), int64(desiredReplicas)), createTime)
    if options.Wide {
        names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
        row.Cells = append(row.Cells, names, images)
    }
    return []metav1.TableRow{row}, nil
}

func printStatefulSetList(list *apps.StatefulSetList, options printers.GenerateOptions) ([]metav1.TableRow, error) {
    rows := make([]metav1.TableRow, 0, len(list.Items))
    for i := range list.Items {
        r, err := printStatefulSet(&amp;list.Items[i], options)
        if err != nil {
            return nil, err
        }
        rows = append(rows, r...)
    }
    return rows, nil
}
</code></pre>
