@@ -156,6 +156,28 @@ func (pw *prefixWriter) Flush() {
156
156
}
157
157
}
158
158
159
+ // nestedPrefixWriter implements PrefixWriter by increasing the level
160
+ // before passing text on to some other writer.
161
+ type nestedPrefixWriter struct {
162
+ PrefixWriter
163
+ indent int
164
+ }
165
+
166
+ var _ PrefixWriter = & prefixWriter {}
167
+
168
+ // NewPrefixWriter creates a new PrefixWriter.
169
+ func NewNestedPrefixWriter (out PrefixWriter , indent int ) PrefixWriter {
170
+ return & nestedPrefixWriter {PrefixWriter : out , indent : indent }
171
+ }
172
+
173
+ func (npw * nestedPrefixWriter ) Write (level int , format string , a ... interface {}) {
174
+ npw .PrefixWriter .Write (level + npw .indent , format , a ... )
175
+ }
176
+
177
+ func (npw * nestedPrefixWriter ) WriteLine (a ... interface {}) {
178
+ npw .PrefixWriter .Write (npw .indent , "%s" , fmt .Sprintln (a ... ))
179
+ }
180
+
159
181
func describerMap (clientConfig * rest.Config ) (map [schema.GroupKind ]ResourceDescriber , error ) {
160
182
c , err := clientset .NewForConfig (clientConfig )
161
183
if err != nil {
@@ -822,6 +844,8 @@ func describeVolumes(volumes []corev1.Volume, w PrefixWriter, space string) {
822
844
printGlusterfsVolumeSource (volume .VolumeSource .Glusterfs , w )
823
845
case volume .VolumeSource .PersistentVolumeClaim != nil :
824
846
printPersistentVolumeClaimVolumeSource (volume .VolumeSource .PersistentVolumeClaim , w )
847
+ case volume .VolumeSource .Ephemeral != nil :
848
+ printEphemeralVolumeSource (volume .VolumeSource .Ephemeral , w )
825
849
case volume .VolumeSource .RBD != nil :
826
850
printRBDVolumeSource (volume .VolumeSource .RBD , w )
827
851
case volume .VolumeSource .Quobyte != nil :
@@ -1037,6 +1061,18 @@ func printPersistentVolumeClaimVolumeSource(claim *corev1.PersistentVolumeClaimV
1037
1061
claim .ClaimName , claim .ReadOnly )
1038
1062
}
1039
1063
1064
+ func printEphemeralVolumeSource (ephemeral * corev1.EphemeralVolumeSource , w PrefixWriter ) {
1065
+ w .Write (LEVEL_2 , "Type:\t EphemeralVolume (an inline specification for a volume that gets created and deleted with the pod)\n " )
1066
+ if ephemeral .VolumeClaimTemplate != nil {
1067
+ printPersistentVolumeClaim (NewNestedPrefixWriter (w , LEVEL_2 ),
1068
+ & corev1.PersistentVolumeClaim {
1069
+ ObjectMeta : ephemeral .VolumeClaimTemplate .ObjectMeta ,
1070
+ Spec : ephemeral .VolumeClaimTemplate .Spec ,
1071
+ }, false /* not a full PVC */ )
1072
+ }
1073
+ w .Write (LEVEL_2 , "ReadOnly:\t %v\n " , ephemeral .ReadOnly )
1074
+ }
1075
+
1040
1076
func printRBDVolumeSource (rbd * corev1.RBDVolumeSource , w PrefixWriter ) {
1041
1077
w .Write (LEVEL_2 , "Type:\t RBD (a Rados Block Device mount on the host that shares a pod's lifetime)\n " +
1042
1078
" CephMonitors:\t %v\n " +
@@ -1535,39 +1571,7 @@ func getPvcs(volumes []corev1.Volume) []corev1.Volume {
1535
1571
func describePersistentVolumeClaim (pvc * corev1.PersistentVolumeClaim , events * corev1.EventList , mountPods []corev1.Pod ) (string , error ) {
1536
1572
return tabbedString (func (out io.Writer ) error {
1537
1573
w := NewPrefixWriter (out )
1538
- w .Write (LEVEL_0 , "Name:\t %s\n " , pvc .Name )
1539
- w .Write (LEVEL_0 , "Namespace:\t %s\n " , pvc .Namespace )
1540
- w .Write (LEVEL_0 , "StorageClass:\t %s\n " , storageutil .GetPersistentVolumeClaimClass (pvc ))
1541
- if pvc .ObjectMeta .DeletionTimestamp != nil {
1542
- w .Write (LEVEL_0 , "Status:\t Terminating (lasts %s)\n " , translateTimestampSince (* pvc .ObjectMeta .DeletionTimestamp ))
1543
- } else {
1544
- w .Write (LEVEL_0 , "Status:\t %v\n " , pvc .Status .Phase )
1545
- }
1546
- w .Write (LEVEL_0 , "Volume:\t %s\n " , pvc .Spec .VolumeName )
1547
- printLabelsMultiline (w , "Labels" , pvc .Labels )
1548
- printAnnotationsMultiline (w , "Annotations" , pvc .Annotations )
1549
- w .Write (LEVEL_0 , "Finalizers:\t %v\n " , pvc .ObjectMeta .Finalizers )
1550
- storage := pvc .Spec .Resources .Requests [corev1 .ResourceStorage ]
1551
- capacity := ""
1552
- accessModes := ""
1553
- if pvc .Spec .VolumeName != "" {
1554
- accessModes = storageutil .GetAccessModesAsString (pvc .Status .AccessModes )
1555
- storage = pvc .Status .Capacity [corev1 .ResourceStorage ]
1556
- capacity = storage .String ()
1557
- }
1558
- w .Write (LEVEL_0 , "Capacity:\t %s\n " , capacity )
1559
- w .Write (LEVEL_0 , "Access Modes:\t %s\n " , accessModes )
1560
- if pvc .Spec .VolumeMode != nil {
1561
- w .Write (LEVEL_0 , "VolumeMode:\t %v\n " , * pvc .Spec .VolumeMode )
1562
- }
1563
- if pvc .Spec .DataSource != nil {
1564
- w .Write (LEVEL_0 , "DataSource:\n " )
1565
- if pvc .Spec .DataSource .APIGroup != nil {
1566
- w .Write (LEVEL_1 , "APIGroup:\t %v\n " , * pvc .Spec .DataSource .APIGroup )
1567
- }
1568
- w .Write (LEVEL_1 , "Kind:\t %v\n " , pvc .Spec .DataSource .Kind )
1569
- w .Write (LEVEL_1 , "Name:\t %v\n " , pvc .Spec .DataSource .Name )
1570
- }
1574
+ printPersistentVolumeClaim (w , pvc , true )
1571
1575
printPodsMultiline (w , "Mounted By" , mountPods )
1572
1576
1573
1577
if len (pvc .Status .Conditions ) > 0 {
@@ -1592,6 +1596,50 @@ func describePersistentVolumeClaim(pvc *corev1.PersistentVolumeClaim, events *co
1592
1596
})
1593
1597
}
1594
1598
1599
+ // printPersistentVolumeClaim is used for both PVCs and PersistentVolumeClaimTemplate. For the latter,
1600
+ // we need to skip some fields which have no meaning.
1601
+ func printPersistentVolumeClaim (w PrefixWriter , pvc * corev1.PersistentVolumeClaim , isFullPVC bool ) {
1602
+ if isFullPVC {
1603
+ w .Write (LEVEL_0 , "Name:\t %s\n " , pvc .Name )
1604
+ w .Write (LEVEL_0 , "Namespace:\t %s\n " , pvc .Namespace )
1605
+ }
1606
+ w .Write (LEVEL_0 , "StorageClass:\t %s\n " , storageutil .GetPersistentVolumeClaimClass (pvc ))
1607
+ if isFullPVC {
1608
+ if pvc .ObjectMeta .DeletionTimestamp != nil {
1609
+ w .Write (LEVEL_0 , "Status:\t Terminating (lasts %s)\n " , translateTimestampSince (* pvc .ObjectMeta .DeletionTimestamp ))
1610
+ } else {
1611
+ w .Write (LEVEL_0 , "Status:\t %v\n " , pvc .Status .Phase )
1612
+ }
1613
+ }
1614
+ w .Write (LEVEL_0 , "Volume:\t %s\n " , pvc .Spec .VolumeName )
1615
+ printLabelsMultiline (w , "Labels" , pvc .Labels )
1616
+ printAnnotationsMultiline (w , "Annotations" , pvc .Annotations )
1617
+ if isFullPVC {
1618
+ w .Write (LEVEL_0 , "Finalizers:\t %v\n " , pvc .ObjectMeta .Finalizers )
1619
+ }
1620
+ storage := pvc .Spec .Resources .Requests [corev1 .ResourceStorage ]
1621
+ capacity := ""
1622
+ accessModes := ""
1623
+ if pvc .Spec .VolumeName != "" {
1624
+ accessModes = storageutil .GetAccessModesAsString (pvc .Status .AccessModes )
1625
+ storage = pvc .Status .Capacity [corev1 .ResourceStorage ]
1626
+ capacity = storage .String ()
1627
+ }
1628
+ w .Write (LEVEL_0 , "Capacity:\t %s\n " , capacity )
1629
+ w .Write (LEVEL_0 , "Access Modes:\t %s\n " , accessModes )
1630
+ if pvc .Spec .VolumeMode != nil {
1631
+ w .Write (LEVEL_0 , "VolumeMode:\t %v\n " , * pvc .Spec .VolumeMode )
1632
+ }
1633
+ if pvc .Spec .DataSource != nil {
1634
+ w .Write (LEVEL_0 , "DataSource:\n " )
1635
+ if pvc .Spec .DataSource .APIGroup != nil {
1636
+ w .Write (LEVEL_1 , "APIGroup:\t %v\n " , * pvc .Spec .DataSource .APIGroup )
1637
+ }
1638
+ w .Write (LEVEL_1 , "Kind:\t %v\n " , pvc .Spec .DataSource .Kind )
1639
+ w .Write (LEVEL_1 , "Name:\t %v\n " , pvc .Spec .DataSource .Name )
1640
+ }
1641
+ }
1642
+
1595
1643
func describeContainers (label string , containers []corev1.Container , containerStatuses []corev1.ContainerStatus ,
1596
1644
resolverFn EnvVarResolverFunc , w PrefixWriter , space string ) {
1597
1645
statuses := map [string ]corev1.ContainerStatus {}
0 commit comments