PV Recycling API

This commit is contained in:
markturansky 2015-05-29 16:12:10 -04:00
parent a7ee5559b1
commit 2829fadfad
21 changed files with 155 additions and 11 deletions

View File

@ -10603,6 +10603,10 @@
"claimRef": { "claimRef": {
"$ref": "v1.ObjectReference", "$ref": "v1.ObjectReference",
"description": "when bound, a reference to the bound claim" "description": "when bound, a reference to the bound claim"
},
"persistentVolumeReclaimPolicy": {
"type": "string",
"description": "persistentVolumeReclaimPolicy is what happens to a volume when released from its claim; Default is Retain."
} }
} }
}, },
@ -10807,6 +10811,14 @@
"phase": { "phase": {
"type": "string", "type": "string",
"description": "the current phase of a persistent volume" "description": "the current phase of a persistent volume"
},
"message": {
"type": "string",
"description": "human-readable message indicating details about why the volume is in this state"
},
"reason": {
"type": "string",
"description": "(brief) reason the volume is not is not available, such as failed recycling"
} }
} }
}, },
@ -12041,4 +12053,4 @@
} }
} }
} }
} }

View File

@ -10600,6 +10600,10 @@
"claimRef": { "claimRef": {
"$ref": "v1beta3.ObjectReference", "$ref": "v1beta3.ObjectReference",
"description": "when bound, a reference to the bound claim" "description": "when bound, a reference to the bound claim"
},
"persistentVolumeReclaimPolicy": {
"type": "string",
"description": "persistentVolumeReclaimPolicy is what happens to a volume when released from its claim; Default is Retain."
} }
} }
}, },
@ -10804,6 +10808,14 @@
"phase": { "phase": {
"type": "string", "type": "string",
"description": "the current phase of a persistent volume" "description": "the current phase of a persistent volume"
},
"message": {
"type": "string",
"description": "human-readable message indicating details about why the volume is in this state"
},
"reason": {
"type": "string",
"description": "(brief) reason the volume is not is not available, such as failed recycling"
} }
} }
}, },
@ -10862,8 +10874,7 @@
"v1beta3.PodSpec": { "v1beta3.PodSpec": {
"id": "v1beta3.PodSpec", "id": "v1beta3.PodSpec",
"required": [ "required": [
"containers", "containers"
"serviceAccount"
], ],
"properties": { "properties": {
"volumes": { "volumes": {
@ -12048,4 +12059,4 @@
} }
} }
} }
} }

View File

@ -6,8 +6,9 @@ metadata:
type: local type: local
spec: spec:
capacity: capacity:
storage: 5Gi storage: 8Gi
accessModes: accessModes:
- ReadWriteOnce - ReadWriteOnce
hostPath: hostPath:
path: "/tmp/data02" path: "/tmp/data02"
persistentVolumeReclaimPolicy: Recycle

View File

@ -1243,11 +1243,14 @@ func deepCopy_api_PersistentVolumeSpec(in PersistentVolumeSpec, out *PersistentV
} else { } else {
out.ClaimRef = nil out.ClaimRef = nil
} }
out.PersistentVolumeReclaimPolicy = in.PersistentVolumeReclaimPolicy
return nil return nil
} }
func deepCopy_api_PersistentVolumeStatus(in PersistentVolumeStatus, out *PersistentVolumeStatus, c *conversion.Cloner) error { func deepCopy_api_PersistentVolumeStatus(in PersistentVolumeStatus, out *PersistentVolumeStatus, c *conversion.Cloner) error {
out.Phase = in.Phase out.Phase = in.Phase
out.Message = in.Message
out.Reason = in.Reason
return nil return nil
} }

View File

@ -234,8 +234,11 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
}, },
func(pv *api.PersistentVolume, c fuzz.Continue) { func(pv *api.PersistentVolume, c fuzz.Continue) {
c.FuzzNoCustom(pv) // fuzz self without calling this function again c.FuzzNoCustom(pv) // fuzz self without calling this function again
types := []api.PersistentVolumePhase{api.VolumePending, api.VolumeBound, api.VolumeReleased, api.VolumeAvailable} types := []api.PersistentVolumePhase{api.VolumeAvailable, api.VolumePending, api.VolumeBound, api.VolumeReleased, api.VolumeFailed}
pv.Status.Phase = types[c.Rand.Intn(len(types))] pv.Status.Phase = types[c.Rand.Intn(len(types))]
pv.Status.Message = c.RandString()
reclamationPolicies := []api.PersistentVolumeReclaimPolicy{api.PersistentVolumeReclaimRecycle, api.PersistentVolumeReclaimRetain}
pv.Spec.PersistentVolumeReclaimPolicy = reclamationPolicies[c.Rand.Intn(len(reclamationPolicies))]
}, },
func(pvc *api.PersistentVolumeClaim, c fuzz.Continue) { func(pvc *api.PersistentVolumeClaim, c fuzz.Continue) {
c.FuzzNoCustom(pvc) // fuzz self without calling this function again c.FuzzNoCustom(pvc) // fuzz self without calling this function again

View File

@ -263,11 +263,33 @@ type PersistentVolumeSpec struct {
// ClaimRef is expected to be non-nil when bound. // ClaimRef is expected to be non-nil when bound.
// claim.VolumeName is the authoritative bind between PV and PVC. // claim.VolumeName is the authoritative bind between PV and PVC.
ClaimRef *ObjectReference `json:"claimRef,omitempty"` ClaimRef *ObjectReference `json:"claimRef,omitempty"`
// Optional: what happens to a persistent volume when released from its claim.
PersistentVolumeReclaimPolicy PersistentVolumeReclaimPolicy `json:"persistentVolumeReclaimPolicy,omitempty" description:"what happens to a volume when released from its claim; Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume."`
} }
// PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes
type PersistentVolumeReclaimPolicy string
const (
// PersistentVolumeReclaimRecycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim.
// The volume plugin must support Recycling.
PersistentVolumeReclaimRecycle PersistentVolumeReclaimPolicy = "Recycle"
// PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim.
// The volume plugin must support Deletion.
// TODO: implement w/ DeletableVolumePlugin
// PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete"
// PersistentVolumeReclaimRetain means the volume will left in its current phase (Released) for manual reclamation by the administrator.
// The default policy is Retain.
PersistentVolumeReclaimRetain PersistentVolumeReclaimPolicy = "Retain"
)
type PersistentVolumeStatus struct { type PersistentVolumeStatus struct {
// Phase indicates if a volume is available, bound to a claim, or released by a claim // Phase indicates if a volume is available, bound to a claim, or released by a claim
Phase PersistentVolumePhase `json:"phase,omitempty"` Phase PersistentVolumePhase `json:"phase,omitempty"`
// A human-readable message indicating details about why the volume is in this state.
Message string `json:"message,omitempty"`
// Reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI
Reason string `json:"reason,omitempty"`
} }
type PersistentVolumeList struct { type PersistentVolumeList struct {
@ -331,12 +353,16 @@ const (
// used for PersistentVolumes that are not available // used for PersistentVolumes that are not available
VolumePending PersistentVolumePhase = "Pending" VolumePending PersistentVolumePhase = "Pending"
// used for PersistentVolumes that are not yet bound // used for PersistentVolumes that are not yet bound
// Available volumes are held by the binder and matched to PersistentVolumeClaims
VolumeAvailable PersistentVolumePhase = "Available" VolumeAvailable PersistentVolumePhase = "Available"
// used for PersistentVolumes that are bound // used for PersistentVolumes that are bound
VolumeBound PersistentVolumePhase = "Bound" VolumeBound PersistentVolumePhase = "Bound"
// used for PersistentVolumes where the bound PersistentVolumeClaim was deleted // used for PersistentVolumes where the bound PersistentVolumeClaim was deleted
// released volumes must be recycled before becoming available again // released volumes must be recycled before becoming available again
// this phase is used by the persistent volume claim binder to signal to another process to reclaim the resource
VolumeReleased PersistentVolumePhase = "Released" VolumeReleased PersistentVolumePhase = "Released"
// used for PersistentVolumes that failed to be correctly recycled or deleted after being released from a claim
VolumeFailed PersistentVolumePhase = "Failed"
) )
type PersistentVolumeClaimPhase string type PersistentVolumeClaimPhase string

View File

@ -1358,6 +1358,7 @@ func convert_api_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in *api.Persist
} else { } else {
out.ClaimRef = nil out.ClaimRef = nil
} }
out.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimPolicy(in.PersistentVolumeReclaimPolicy)
return nil return nil
} }
@ -1366,6 +1367,8 @@ func convert_api_PersistentVolumeStatus_To_v1_PersistentVolumeStatus(in *api.Per
defaulting.(func(*api.PersistentVolumeStatus))(in) defaulting.(func(*api.PersistentVolumeStatus))(in)
} }
out.Phase = PersistentVolumePhase(in.Phase) out.Phase = PersistentVolumePhase(in.Phase)
out.Message = in.Message
out.Reason = in.Reason
return nil return nil
} }
@ -3633,6 +3636,7 @@ func convert_v1_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in *PersistentV
} else { } else {
out.ClaimRef = nil out.ClaimRef = nil
} }
out.PersistentVolumeReclaimPolicy = api.PersistentVolumeReclaimPolicy(in.PersistentVolumeReclaimPolicy)
return nil return nil
} }
@ -3641,6 +3645,8 @@ func convert_v1_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in *Persist
defaulting.(func(*PersistentVolumeStatus))(in) defaulting.(func(*PersistentVolumeStatus))(in)
} }
out.Phase = api.PersistentVolumePhase(in.Phase) out.Phase = api.PersistentVolumePhase(in.Phase)
out.Message = in.Message
out.Reason = in.Reason
return nil return nil
} }

View File

@ -1174,11 +1174,14 @@ func deepCopy_v1_PersistentVolumeSpec(in PersistentVolumeSpec, out *PersistentVo
} else { } else {
out.ClaimRef = nil out.ClaimRef = nil
} }
out.PersistentVolumeReclaimPolicy = in.PersistentVolumeReclaimPolicy
return nil return nil
} }
func deepCopy_v1_PersistentVolumeStatus(in PersistentVolumeStatus, out *PersistentVolumeStatus, c *conversion.Cloner) error { func deepCopy_v1_PersistentVolumeStatus(in PersistentVolumeStatus, out *PersistentVolumeStatus, c *conversion.Cloner) error {
out.Phase = in.Phase out.Phase = in.Phase
out.Message = in.Message
out.Reason = in.Reason
return nil return nil
} }

View File

@ -113,6 +113,9 @@ func addDefaultingFuncs() {
if obj.Status.Phase == "" { if obj.Status.Phase == "" {
obj.Status.Phase = VolumePending obj.Status.Phase = VolumePending
} }
if obj.Spec.PersistentVolumeReclaimPolicy == "" {
obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain
}
}, },
func(obj *PersistentVolumeClaim) { func(obj *PersistentVolumeClaim) {
if obj.Status.Phase == "" { if obj.Status.Phase == "" {

View File

@ -258,6 +258,9 @@ func TestSetDefaultPersistentVolume(t *testing.T) {
if pv2.Status.Phase != versioned.VolumePending { if pv2.Status.Phase != versioned.VolumePending {
t.Errorf("Expected volume phase %v, got %v", versioned.VolumePending, pv2.Status.Phase) t.Errorf("Expected volume phase %v, got %v", versioned.VolumePending, pv2.Status.Phase)
} }
if pv2.Spec.PersistentVolumeReclaimPolicy != versioned.PersistentVolumeReclaimRetain {
t.Errorf("Expected pv reclaim policy %v, got %v", versioned.PersistentVolumeReclaimRetain, pv2.Spec.PersistentVolumeReclaimPolicy)
}
} }
func TestSetDefaultPersistentVolumeClaim(t *testing.T) { func TestSetDefaultPersistentVolumeClaim(t *testing.T) {

View File

@ -280,11 +280,33 @@ type PersistentVolumeSpec struct {
// ClaimRef is expected to be non-nil when bound. // ClaimRef is expected to be non-nil when bound.
// claim.VolumeName is the authoritative bind between PV and PVC. // claim.VolumeName is the authoritative bind between PV and PVC.
ClaimRef *ObjectReference `json:"claimRef,omitempty" description:"when bound, a reference to the bound claim"` ClaimRef *ObjectReference `json:"claimRef,omitempty" description:"when bound, a reference to the bound claim"`
// Optional: what happens to a persistent volume when released from its claim.
PersistentVolumeReclaimPolicy PersistentVolumeReclaimPolicy `json:"persistentVolumeReclaimPolicy,omitempty" description:"what happens to a volume when released from its claim; Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume."`
} }
// PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes
type PersistentVolumeReclaimPolicy string
const (
// PersistentVolumeReclaimRecycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim.
// The volume plugin must support Recycling.
PersistentVolumeReclaimRecycle PersistentVolumeReclaimPolicy = "Recycle"
// PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim.
// The volume plugin must support Deletion.
// TODO: implement w/ DeletableVolumePlugin
// PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete"
// PersistentVolumeReclaimRetain means the volume will left in its current phase (Released) for manual reclamation by the administrator.
// The default policy is Retain.
PersistentVolumeReclaimRetain PersistentVolumeReclaimPolicy = "Retain"
)
type PersistentVolumeStatus struct { type PersistentVolumeStatus struct {
// Phase indicates if a volume is available, bound to a claim, or released by a claim // Phase indicates if a volume is available, bound to a claim, or released by a claim
Phase PersistentVolumePhase `json:"phase,omitempty" description:"the current phase of a persistent volume"` Phase PersistentVolumePhase `json:"phase,omitempty" description:"the current phase of a persistent volume"`
// A human-readable message indicating details about why the volume is in this state.
Message string `json:"message,omitempty" description:"human-readable message indicating details about why the volume is in this state"`
// Reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI
Reason string `json:"reason,omitempty" description:"(brief) reason the volume is not is not available"`
} }
type PersistentVolumeList struct { type PersistentVolumeList struct {
@ -348,12 +370,16 @@ const (
// used for PersistentVolumes that are not available // used for PersistentVolumes that are not available
VolumePending PersistentVolumePhase = "Pending" VolumePending PersistentVolumePhase = "Pending"
// used for PersistentVolumes that are not yet bound // used for PersistentVolumes that are not yet bound
// Available volumes are held by the binder and matched to PersistentVolumeClaims
VolumeAvailable PersistentVolumePhase = "Available" VolumeAvailable PersistentVolumePhase = "Available"
// used for PersistentVolumes that are bound // used for PersistentVolumes that are bound
VolumeBound PersistentVolumePhase = "Bound" VolumeBound PersistentVolumePhase = "Bound"
// used for PersistentVolumes where the bound PersistentVolumeClaim was deleted // used for PersistentVolumes where the bound PersistentVolumeClaim was deleted
// released volumes must be recycled before becoming available again // released volumes must be recycled before becoming available again
// this phase is used by the persistent volume claim binder to signal to another process to reclaim the resource
VolumeReleased PersistentVolumePhase = "Released" VolumeReleased PersistentVolumePhase = "Released"
// used for PersistentVolumes that failed to be correctly recycled or deleted after being released from a claim
VolumeFailed PersistentVolumePhase = "Failed"
) )
type PersistentVolumeClaimPhase string type PersistentVolumeClaimPhase string

View File

@ -1216,6 +1216,7 @@ func convert_api_PersistentVolumeSpec_To_v1beta3_PersistentVolumeSpec(in *api.Pe
} else { } else {
out.ClaimRef = nil out.ClaimRef = nil
} }
out.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimPolicy(in.PersistentVolumeReclaimPolicy)
return nil return nil
} }
@ -1224,6 +1225,8 @@ func convert_api_PersistentVolumeStatus_To_v1beta3_PersistentVolumeStatus(in *ap
defaulting.(func(*api.PersistentVolumeStatus))(in) defaulting.(func(*api.PersistentVolumeStatus))(in)
} }
out.Phase = PersistentVolumePhase(in.Phase) out.Phase = PersistentVolumePhase(in.Phase)
out.Message = in.Message
out.Reason = in.Reason
return nil return nil
} }
@ -3305,6 +3308,7 @@ func convert_v1beta3_PersistentVolumeSpec_To_api_PersistentVolumeSpec(in *Persis
} else { } else {
out.ClaimRef = nil out.ClaimRef = nil
} }
out.PersistentVolumeReclaimPolicy = api.PersistentVolumeReclaimPolicy(in.PersistentVolumeReclaimPolicy)
return nil return nil
} }
@ -3313,6 +3317,8 @@ func convert_v1beta3_PersistentVolumeStatus_To_api_PersistentVolumeStatus(in *Pe
defaulting.(func(*PersistentVolumeStatus))(in) defaulting.(func(*PersistentVolumeStatus))(in)
} }
out.Phase = api.PersistentVolumePhase(in.Phase) out.Phase = api.PersistentVolumePhase(in.Phase)
out.Message = in.Message
out.Reason = in.Reason
return nil return nil
} }

View File

@ -1178,11 +1178,14 @@ func deepCopy_v1beta3_PersistentVolumeSpec(in PersistentVolumeSpec, out *Persist
} else { } else {
out.ClaimRef = nil out.ClaimRef = nil
} }
out.PersistentVolumeReclaimPolicy = in.PersistentVolumeReclaimPolicy
return nil return nil
} }
func deepCopy_v1beta3_PersistentVolumeStatus(in PersistentVolumeStatus, out *PersistentVolumeStatus, c *conversion.Cloner) error { func deepCopy_v1beta3_PersistentVolumeStatus(in PersistentVolumeStatus, out *PersistentVolumeStatus, c *conversion.Cloner) error {
out.Phase = in.Phase out.Phase = in.Phase
out.Message = in.Message
out.Reason = in.Reason
return nil return nil
} }

View File

@ -117,6 +117,9 @@ func addDefaultingFuncs() {
if obj.Status.Phase == "" { if obj.Status.Phase == "" {
obj.Status.Phase = VolumePending obj.Status.Phase = VolumePending
} }
if obj.Spec.PersistentVolumeReclaimPolicy == "" {
obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain
}
}, },
func(obj *PersistentVolumeClaim) { func(obj *PersistentVolumeClaim) {
if obj.Status.Phase == "" { if obj.Status.Phase == "" {

View File

@ -195,6 +195,9 @@ func TestSetDefaultPersistentVolume(t *testing.T) {
if pv2.Status.Phase != versioned.VolumePending { if pv2.Status.Phase != versioned.VolumePending {
t.Errorf("Expected volume phase %v, got %v", versioned.VolumePending, pv2.Status.Phase) t.Errorf("Expected volume phase %v, got %v", versioned.VolumePending, pv2.Status.Phase)
} }
if pv2.Spec.PersistentVolumeReclaimPolicy != versioned.PersistentVolumeReclaimRetain {
t.Errorf("Expected pv reclaim policy %v, got %v", versioned.PersistentVolumeReclaimRetain, pv2.Spec.PersistentVolumeReclaimPolicy)
}
} }
func TestSetDefaultPersistentVolumeClaim(t *testing.T) { func TestSetDefaultPersistentVolumeClaim(t *testing.T) {

View File

@ -280,11 +280,33 @@ type PersistentVolumeSpec struct {
// ClaimRef is expected to be non-nil when bound. // ClaimRef is expected to be non-nil when bound.
// claim.VolumeName is the authoritative bind between PV and PVC. // claim.VolumeName is the authoritative bind between PV and PVC.
ClaimRef *ObjectReference `json:"claimRef,omitempty" description:"when bound, a reference to the bound claim"` ClaimRef *ObjectReference `json:"claimRef,omitempty" description:"when bound, a reference to the bound claim"`
// Optional: what happens to a persistent volume when released from its claim.
PersistentVolumeReclaimPolicy PersistentVolumeReclaimPolicy `json:"persistentVolumeReclaimPolicy,omitempty" description:"what happens to a volume when released from its claim; Valid options are Retain (default) and Recycle. Recyling must be supported by the volume plugin underlying this persistent volume."`
} }
// PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes
type PersistentVolumeReclaimPolicy string
const (
// PersistentVolumeReclaimRecycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim.
// The volume plugin must support Recycling.
PersistentVolumeReclaimRecycle PersistentVolumeReclaimPolicy = "Recycle"
// PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim.
// The volume plugin must support Deletion.
// TODO: implement w/ DeletableVolumePlugin
// PersistentVolumeReclaimDelete PersistentVolumeReclaimPolicy = "Delete"
// PersistentVolumeReclaimRetain means the volume will left in its current phase (Released) for manual reclamation by the administrator.
// The default policy is Retain.
PersistentVolumeReclaimRetain PersistentVolumeReclaimPolicy = "Retain"
)
type PersistentVolumeStatus struct { type PersistentVolumeStatus struct {
// Phase indicates if a volume is available, bound to a claim, or released by a claim // Phase indicates if a volume is available, bound to a claim, or released by a claim
Phase PersistentVolumePhase `json:"phase,omitempty" description:"the current phase of a persistent volume"` Phase PersistentVolumePhase `json:"phase,omitempty" description:"the current phase of a persistent volume"`
// A human-readable message indicating details about why the volume is in this state.
Message string `json:"message,omitempty" description:"human-readable message indicating details about why the volume is in this state"`
// Reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI
Reason string `json:"reason,omitempty" description:"(brief) reason the volume is not is not available"`
} }
type PersistentVolumeList struct { type PersistentVolumeList struct {
@ -348,12 +370,16 @@ const (
// used for PersistentVolumes that are not available // used for PersistentVolumes that are not available
VolumePending PersistentVolumePhase = "Pending" VolumePending PersistentVolumePhase = "Pending"
// used for PersistentVolumes that are not yet bound // used for PersistentVolumes that are not yet bound
// Available volumes are held by the binder and matched to PersistentVolumeClaims
VolumeAvailable PersistentVolumePhase = "Available" VolumeAvailable PersistentVolumePhase = "Available"
// used for PersistentVolumes that are bound // used for PersistentVolumes that are bound
VolumeBound PersistentVolumePhase = "Bound" VolumeBound PersistentVolumePhase = "Bound"
// used for PersistentVolumes where the bound PersistentVolumeClaim was deleted // used for PersistentVolumes where the bound PersistentVolumeClaim was deleted
// released volumes must be recycled before becoming available again // released volumes must be recycled before becoming available again
// this phase is used by the persistent volume claim binder to signal to another process to reclaim the resource
VolumeReleased PersistentVolumePhase = "Released" VolumeReleased PersistentVolumePhase = "Released"
// used for PersistentVolumes that failed to be correctly recycled or deleted after being released from a claim
VolumeFailed PersistentVolumePhase = "Failed"
) )
type PersistentVolumeClaimPhase string type PersistentVolumeClaimPhase string

View File

@ -151,7 +151,8 @@ func TestPersistentVolumeStatusUpdate(t *testing.T) {
}, },
}, },
Status: api.PersistentVolumeStatus{ Status: api.PersistentVolumeStatus{
Phase: api.VolumeBound, Phase: api.VolumeBound,
Message: "foo",
}, },
} }
c := &testClient{ c := &testClient{

View File

@ -311,6 +311,8 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string) (string, er
} else { } else {
fmt.Fprintf(out, "Claim:\t%s\n", "") fmt.Fprintf(out, "Claim:\t%s\n", "")
} }
fmt.Fprintf(out, "Reclaim Policy:\t%d\n", pv.Spec.PersistentVolumeReclaimPolicy)
fmt.Fprintf(out, "Message:\t%d\n", pv.Status.Message)
return nil return nil
}) })
} }

View File

@ -259,7 +259,7 @@ var resourceQuotaColumns = []string{"NAME"}
var namespaceColumns = []string{"NAME", "LABELS", "STATUS"} var namespaceColumns = []string{"NAME", "LABELS", "STATUS"}
var secretColumns = []string{"NAME", "TYPE", "DATA"} var secretColumns = []string{"NAME", "TYPE", "DATA"}
var serviceAccountColumns = []string{"NAME", "SECRETS"} var serviceAccountColumns = []string{"NAME", "SECRETS"}
var persistentVolumeColumns = []string{"NAME", "LABELS", "CAPACITY", "ACCESSMODES", "STATUS", "CLAIM"} var persistentVolumeColumns = []string{"NAME", "LABELS", "CAPACITY", "ACCESSMODES", "STATUS", "CLAIM", "REASON"}
var persistentVolumeClaimColumns = []string{"NAME", "LABELS", "STATUS", "VOLUME"} var persistentVolumeClaimColumns = []string{"NAME", "LABELS", "STATUS", "VOLUME"}
var componentStatusColumns = []string{"NAME", "STATUS", "MESSAGE", "ERROR"} var componentStatusColumns = []string{"NAME", "STATUS", "MESSAGE", "ERROR"}
@ -732,7 +732,7 @@ func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, withNamespace
aQty := pv.Spec.Capacity[api.ResourceStorage] aQty := pv.Spec.Capacity[api.ResourceStorage]
aSize := aQty.Value() aSize := aQty.Value()
_, err := fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\t%s\n", name, formatLabels(pv.Labels), aSize, modesStr, pv.Status.Phase, claimRefUID) _, err := fmt.Fprintf(w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\n", name, formatLabels(pv.Labels), aSize, modesStr, pv.Status.Phase, claimRefUID, pv.Status.Reason)
return err return err
} }

View File

@ -59,9 +59,12 @@ func validNewPersistentVolume(name string) *api.PersistentVolume {
PersistentVolumeSource: api.PersistentVolumeSource{ PersistentVolumeSource: api.PersistentVolumeSource{
HostPath: &api.HostPathVolumeSource{Path: "/foo"}, HostPath: &api.HostPathVolumeSource{Path: "/foo"},
}, },
PersistentVolumeReclaimPolicy: api.PersistentVolumeReclaimRetain,
}, },
Status: api.PersistentVolumeStatus{ Status: api.PersistentVolumeStatus{
Phase: api.VolumePending, Phase: api.VolumePending,
Message: "bar",
Reason: "foo",
}, },
} }
return pv return pv

View File

@ -98,7 +98,7 @@ func TestExampleObjects(t *testing.T) {
Spec: api.PersistentVolumeSpec{ Spec: api.PersistentVolumeSpec{
AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
Capacity: api.ResourceList{ Capacity: api.ResourceList{
api.ResourceName(api.ResourceStorage): resource.MustParse("5Gi"), api.ResourceName(api.ResourceStorage): resource.MustParse("8Gi"),
}, },
PersistentVolumeSource: api.PersistentVolumeSource{ PersistentVolumeSource: api.PersistentVolumeSource{
HostPath: &api.HostPathVolumeSource{ HostPath: &api.HostPathVolumeSource{