mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-06 05:25:40 +00:00
use pointer types for metav1.Time fields (#1951)
* use pointer types for metav1.Time fields Signed-off-by: Adnan Abdulhussein <aadnan@vmware.com> * simpler metav1.Time ptrs Signed-off-by: Adnan Abdulhussein <aadnan@vmware.com> * remove test debug println Signed-off-by: Adnan Abdulhussein <aadnan@vmware.com>
This commit is contained in:
committed by
Steve Kriss
parent
3fc4097231
commit
e3d64d9dd9
@@ -219,7 +219,7 @@ type BackupStatus struct {
|
|||||||
// Expiration is when this Backup is eligible for garbage-collection.
|
// Expiration is when this Backup is eligible for garbage-collection.
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
Expiration metav1.Time `json:"expiration,omitempty"`
|
Expiration *metav1.Time `json:"expiration,omitempty"`
|
||||||
|
|
||||||
// Phase is the current state of the Backup.
|
// Phase is the current state of the Backup.
|
||||||
// +optional
|
// +optional
|
||||||
@@ -237,7 +237,7 @@ type BackupStatus struct {
|
|||||||
// The server's time is used for StartTimestamps
|
// The server's time is used for StartTimestamps
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
StartTimestamp metav1.Time `json:"startTimestamp,omitempty"`
|
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||||
|
|
||||||
// CompletionTimestamp records the time a backup was completed.
|
// CompletionTimestamp records the time a backup was completed.
|
||||||
// Completion time is recorded even on failed backups.
|
// Completion time is recorded even on failed backups.
|
||||||
@@ -245,7 +245,7 @@ type BackupStatus struct {
|
|||||||
// The server's time is used for CompletionTimestamps
|
// The server's time is used for CompletionTimestamps
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
CompletionTimestamp metav1.Time `json:"completionTimestamp,omitempty"`
|
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||||
|
|
||||||
// VolumeSnapshotsAttempted is the total number of attempted
|
// VolumeSnapshotsAttempted is the total number of attempted
|
||||||
// volume snapshots for this backup.
|
// volume snapshots for this backup.
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ type BackupStorageLocationStatus struct {
|
|||||||
// the cluster.
|
// the cluster.
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
LastSyncedTime metav1.Time `json:"lastSyncedTime,omitempty"`
|
LastSyncedTime *metav1.Time `json:"lastSyncedTime,omitempty"`
|
||||||
|
|
||||||
// LastSyncedRevision is the value of the `metadata/revision` file in the backup
|
// LastSyncedRevision is the value of the `metadata/revision` file in the backup
|
||||||
// storage location the last time the BSL's contents were synced into the cluster.
|
// storage location the last time the BSL's contents were synced into the cluster.
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ type DownloadRequestStatus struct {
|
|||||||
// Expiration is when this DownloadRequest expires and can be deleted by the system.
|
// Expiration is when this DownloadRequest expires and can be deleted by the system.
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
Expiration metav1.Time `json:"expiration,omitempty"`
|
Expiration *metav1.Time `json:"expiration,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +genclient
|
// +genclient
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ type PodVolumeBackupStatus struct {
|
|||||||
// The server's time is used for StartTimestamps
|
// The server's time is used for StartTimestamps
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
StartTimestamp metav1.Time `json:"startTimestamp,omitempty"`
|
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||||
|
|
||||||
// CompletionTimestamp records the time a backup was completed.
|
// CompletionTimestamp records the time a backup was completed.
|
||||||
// Completion time is recorded even on failed backups.
|
// Completion time is recorded even on failed backups.
|
||||||
@@ -89,7 +89,7 @@ type PodVolumeBackupStatus struct {
|
|||||||
// The server's time is used for CompletionTimestamps
|
// The server's time is used for CompletionTimestamps
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
CompletionTimestamp metav1.Time `json:"completionTimestamp,omitempty"`
|
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||||
|
|
||||||
// Progress holds the total number of bytes of the volume and the current
|
// Progress holds the total number of bytes of the volume and the current
|
||||||
// number of backed up bytes. This can be used to display progress information
|
// number of backed up bytes. This can be used to display progress information
|
||||||
|
|||||||
@@ -65,14 +65,14 @@ type PodVolumeRestoreStatus struct {
|
|||||||
// The server's time is used for StartTimestamps
|
// The server's time is used for StartTimestamps
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
StartTimestamp metav1.Time `json:"startTimestamp,omitempty"`
|
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||||
|
|
||||||
// CompletionTimestamp records the time a restore was completed.
|
// CompletionTimestamp records the time a restore was completed.
|
||||||
// Completion time is recorded even on failed restores.
|
// Completion time is recorded even on failed restores.
|
||||||
// The server's time is used for CompletionTimestamps
|
// The server's time is used for CompletionTimestamps
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
CompletionTimestamp metav1.Time `json:"completionTimestamp,omitempty"`
|
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||||
|
|
||||||
// Progress holds the total number of bytes of the snapshot and the current
|
// Progress holds the total number of bytes of the snapshot and the current
|
||||||
// number of restored bytes. This can be used to display progress information
|
// number of restored bytes. This can be used to display progress information
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ type ResticRepositoryStatus struct {
|
|||||||
// LastMaintenanceTime is the last time maintenance was run.
|
// LastMaintenanceTime is the last time maintenance was run.
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
LastMaintenanceTime metav1.Time `json:"lastMaintenanceTime,omitempty"`
|
LastMaintenanceTime *metav1.Time `json:"lastMaintenanceTime,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +genclient
|
// +genclient
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ type ScheduleStatus struct {
|
|||||||
// Schedule schedule
|
// Schedule schedule
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
LastBackup metav1.Time `json:"lastBackup,omitempty"`
|
LastBackup *metav1.Time `json:"lastBackup,omitempty"`
|
||||||
|
|
||||||
// ValidationErrors is a slice of all validation errors (if
|
// ValidationErrors is a slice of all validation errors (if
|
||||||
// applicable)
|
// applicable)
|
||||||
|
|||||||
@@ -63,22 +63,22 @@ type PluginInfo struct {
|
|||||||
type ServerStatusRequestStatus struct {
|
type ServerStatusRequestStatus struct {
|
||||||
// Phase is the current lifecycle phase of the ServerStatusRequest.
|
// Phase is the current lifecycle phase of the ServerStatusRequest.
|
||||||
// +optional
|
// +optional
|
||||||
Phase ServerStatusRequestPhase `json:"phase"`
|
Phase ServerStatusRequestPhase `json:"phase,omitempty"`
|
||||||
|
|
||||||
// ProcessedTimestamp is when the ServerStatusRequest was processed
|
// ProcessedTimestamp is when the ServerStatusRequest was processed
|
||||||
// by the ServerStatusRequestController.
|
// by the ServerStatusRequestController.
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
ProcessedTimestamp metav1.Time `json:"processedTimestamp"`
|
ProcessedTimestamp *metav1.Time `json:"processedTimestamp,omitempty"`
|
||||||
|
|
||||||
// ServerVersion is the Velero server version.
|
// ServerVersion is the Velero server version.
|
||||||
// +optional
|
// +optional
|
||||||
ServerVersion string `json:"serverVersion"`
|
ServerVersion string `json:"serverVersion,omitempty"`
|
||||||
|
|
||||||
// Plugins list information about the plugins running on the Velero server
|
// Plugins list information about the plugins running on the Velero server
|
||||||
// +optional
|
// +optional
|
||||||
// +nullable
|
// +nullable
|
||||||
Plugins []PluginInfo `json:"plugins"`
|
Plugins []PluginInfo `json:"plugins,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|||||||
@@ -246,14 +246,23 @@ func (in *BackupSpec) DeepCopy() *BackupSpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *BackupStatus) DeepCopyInto(out *BackupStatus) {
|
func (in *BackupStatus) DeepCopyInto(out *BackupStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.Expiration.DeepCopyInto(&out.Expiration)
|
if in.Expiration != nil {
|
||||||
|
in, out := &in.Expiration, &out.Expiration
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
if in.ValidationErrors != nil {
|
if in.ValidationErrors != nil {
|
||||||
in, out := &in.ValidationErrors, &out.ValidationErrors
|
in, out := &in.ValidationErrors, &out.ValidationErrors
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
in.StartTimestamp.DeepCopyInto(&out.StartTimestamp)
|
if in.StartTimestamp != nil {
|
||||||
in.CompletionTimestamp.DeepCopyInto(&out.CompletionTimestamp)
|
in, out := &in.StartTimestamp, &out.StartTimestamp
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
|
if in.CompletionTimestamp != nil {
|
||||||
|
in, out := &in.CompletionTimestamp, &out.CompletionTimestamp
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +364,10 @@ func (in *BackupStorageLocationSpec) DeepCopy() *BackupStorageLocationSpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *BackupStorageLocationStatus) DeepCopyInto(out *BackupStorageLocationStatus) {
|
func (in *BackupStorageLocationStatus) DeepCopyInto(out *BackupStorageLocationStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.LastSyncedTime.DeepCopyInto(&out.LastSyncedTime)
|
if in.LastSyncedTime != nil {
|
||||||
|
in, out := &in.LastSyncedTime, &out.LastSyncedTime
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,7 +560,10 @@ func (in *DownloadRequestSpec) DeepCopy() *DownloadRequestSpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *DownloadRequestStatus) DeepCopyInto(out *DownloadRequestStatus) {
|
func (in *DownloadRequestStatus) DeepCopyInto(out *DownloadRequestStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.Expiration.DeepCopyInto(&out.Expiration)
|
if in.Expiration != nil {
|
||||||
|
in, out := &in.Expiration, &out.Expiration
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,8 +735,14 @@ func (in *PodVolumeBackupSpec) DeepCopy() *PodVolumeBackupSpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *PodVolumeBackupStatus) DeepCopyInto(out *PodVolumeBackupStatus) {
|
func (in *PodVolumeBackupStatus) DeepCopyInto(out *PodVolumeBackupStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.StartTimestamp.DeepCopyInto(&out.StartTimestamp)
|
if in.StartTimestamp != nil {
|
||||||
in.CompletionTimestamp.DeepCopyInto(&out.CompletionTimestamp)
|
in, out := &in.StartTimestamp, &out.StartTimestamp
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
|
if in.CompletionTimestamp != nil {
|
||||||
|
in, out := &in.CompletionTimestamp, &out.CompletionTimestamp
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
out.Progress = in.Progress
|
out.Progress = in.Progress
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -833,8 +854,14 @@ func (in *PodVolumeRestoreSpec) DeepCopy() *PodVolumeRestoreSpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *PodVolumeRestoreStatus) DeepCopyInto(out *PodVolumeRestoreStatus) {
|
func (in *PodVolumeRestoreStatus) DeepCopyInto(out *PodVolumeRestoreStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.StartTimestamp.DeepCopyInto(&out.StartTimestamp)
|
if in.StartTimestamp != nil {
|
||||||
in.CompletionTimestamp.DeepCopyInto(&out.CompletionTimestamp)
|
in, out := &in.StartTimestamp, &out.StartTimestamp
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
|
if in.CompletionTimestamp != nil {
|
||||||
|
in, out := &in.CompletionTimestamp, &out.CompletionTimestamp
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
out.Progress = in.Progress
|
out.Progress = in.Progress
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -930,7 +957,10 @@ func (in *ResticRepositorySpec) DeepCopy() *ResticRepositorySpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ResticRepositoryStatus) DeepCopyInto(out *ResticRepositoryStatus) {
|
func (in *ResticRepositoryStatus) DeepCopyInto(out *ResticRepositoryStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.LastMaintenanceTime.DeepCopyInto(&out.LastMaintenanceTime)
|
if in.LastMaintenanceTime != nil {
|
||||||
|
in, out := &in.LastMaintenanceTime, &out.LastMaintenanceTime
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1165,7 +1195,10 @@ func (in *ScheduleSpec) DeepCopy() *ScheduleSpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ScheduleStatus) DeepCopyInto(out *ScheduleStatus) {
|
func (in *ScheduleStatus) DeepCopyInto(out *ScheduleStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.LastBackup.DeepCopyInto(&out.LastBackup)
|
if in.LastBackup != nil {
|
||||||
|
in, out := &in.LastBackup, &out.LastBackup
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
if in.ValidationErrors != nil {
|
if in.ValidationErrors != nil {
|
||||||
in, out := &in.ValidationErrors, &out.ValidationErrors
|
in, out := &in.ValidationErrors, &out.ValidationErrors
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
@@ -1264,7 +1297,10 @@ func (in *ServerStatusRequestSpec) DeepCopy() *ServerStatusRequestSpec {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ServerStatusRequestStatus) DeepCopyInto(out *ServerStatusRequestStatus) {
|
func (in *ServerStatusRequestStatus) DeepCopyInto(out *ServerStatusRequestStatus) {
|
||||||
*out = *in
|
*out = *in
|
||||||
in.ProcessedTimestamp.DeepCopyInto(&out.ProcessedTimestamp)
|
if in.ProcessedTimestamp != nil {
|
||||||
|
in, out := &in.ProcessedTimestamp, &out.ProcessedTimestamp
|
||||||
|
*out = (*in).DeepCopy()
|
||||||
|
}
|
||||||
if in.Plugins != nil {
|
if in.Plugins != nil {
|
||||||
in, out := &in.Plugins, &out.Plugins
|
in, out := &in.Plugins, &out.Plugins
|
||||||
*out = make([]PluginInfo, len(*in))
|
*out = make([]PluginInfo, len(*in))
|
||||||
|
|||||||
@@ -154,13 +154,13 @@ func (b *BackupBuilder) TTL(ttl time.Duration) *BackupBuilder {
|
|||||||
|
|
||||||
// Expiration sets the Backup's expiration.
|
// Expiration sets the Backup's expiration.
|
||||||
func (b *BackupBuilder) Expiration(val time.Time) *BackupBuilder {
|
func (b *BackupBuilder) Expiration(val time.Time) *BackupBuilder {
|
||||||
b.object.Status.Expiration.Time = val
|
b.object.Status.Expiration = &metav1.Time{Time: val}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartTimestamp sets the Backup's start timestamp.
|
// StartTimestamp sets the Backup's start timestamp.
|
||||||
func (b *BackupBuilder) StartTimestamp(val time.Time) *BackupBuilder {
|
func (b *BackupBuilder) StartTimestamp(val time.Time) *BackupBuilder {
|
||||||
b.object.Status.StartTimestamp.Time = val
|
b.object.Status.StartTimestamp = &metav1.Time{Time: val}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func (b *ScheduleBuilder) CronSchedule(expression string) *ScheduleBuilder {
|
|||||||
// LastBackupTime sets the Schedule's last backup time.
|
// LastBackupTime sets the Schedule's last backup time.
|
||||||
func (b *ScheduleBuilder) LastBackupTime(val string) *ScheduleBuilder {
|
func (b *ScheduleBuilder) LastBackupTime(val string) *ScheduleBuilder {
|
||||||
t, _ := time.Parse("2006-01-02 15:04:05", val)
|
t, _ := time.Parse("2006-01-02 15:04:05", val)
|
||||||
b.object.Status.LastBackup.Time = t
|
b.object.Status.LastBackup = &metav1.Time{Time: t}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func (b *ServerStatusRequestBuilder) Phase(phase velerov1api.ServerStatusRequest
|
|||||||
|
|
||||||
// ProcessedTimestamp sets the ServerStatusRequest's processed timestamp.
|
// ProcessedTimestamp sets the ServerStatusRequest's processed timestamp.
|
||||||
func (b *ServerStatusRequestBuilder) ProcessedTimestamp(time time.Time) *ServerStatusRequestBuilder {
|
func (b *ServerStatusRequestBuilder) ProcessedTimestamp(time time.Time) *ServerStatusRequestBuilder {
|
||||||
b.object.Status.ProcessedTimestamp.Time = time
|
b.object.Status.ProcessedTimestamp = &metav1.Time{Time: time}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -219,19 +219,22 @@ func DescribeBackupStatus(d *Describer, backup *velerov1api.Backup, details bool
|
|||||||
|
|
||||||
d.Println()
|
d.Println()
|
||||||
// "<n/a>" output should only be applicable for backups that failed validation
|
// "<n/a>" output should only be applicable for backups that failed validation
|
||||||
if status.StartTimestamp.Time.IsZero() {
|
if status.StartTimestamp == nil || status.StartTimestamp.Time.IsZero() {
|
||||||
d.Printf("Started:\t%s\n", "<n/a>")
|
d.Printf("Started:\t%s\n", "<n/a>")
|
||||||
} else {
|
} else {
|
||||||
d.Printf("Started:\t%s\n", status.StartTimestamp.Time)
|
d.Printf("Started:\t%s\n", status.StartTimestamp.Time)
|
||||||
}
|
}
|
||||||
if status.CompletionTimestamp.Time.IsZero() {
|
if status.CompletionTimestamp == nil || status.CompletionTimestamp.Time.IsZero() {
|
||||||
d.Printf("Completed:\t%s\n", "<n/a>")
|
d.Printf("Completed:\t%s\n", "<n/a>")
|
||||||
} else {
|
} else {
|
||||||
d.Printf("Completed:\t%s\n", status.CompletionTimestamp.Time)
|
d.Printf("Completed:\t%s\n", status.CompletionTimestamp.Time)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Println()
|
d.Println()
|
||||||
d.Printf("Expiration:\t%s\n", status.Expiration.Time)
|
// Expiration can't be 0, it is always set to a 30-day default. It can be nil
|
||||||
|
// if the controller hasn't processed this Backup yet, in which case this will
|
||||||
|
// just display `<nil>`, though this should be temporary.
|
||||||
|
d.Printf("Expiration:\t%s\n", status.Expiration)
|
||||||
d.Println()
|
d.Println()
|
||||||
|
|
||||||
if details {
|
if details {
|
||||||
|
|||||||
@@ -88,7 +88,10 @@ func printBackup(backup *velerov1api.Backup, options printers.PrintOptions) ([]m
|
|||||||
Object: runtime.RawExtension{Object: backup},
|
Object: runtime.RawExtension{Object: backup},
|
||||||
}
|
}
|
||||||
|
|
||||||
expiration := backup.Status.Expiration.Time
|
var expiration time.Time
|
||||||
|
if backup.Status.Expiration != nil {
|
||||||
|
expiration = backup.Status.Expiration.Time
|
||||||
|
}
|
||||||
if expiration.IsZero() && backup.Spec.TTL.Duration > 0 {
|
if expiration.IsZero() && backup.Spec.TTL.Duration > 0 {
|
||||||
expiration = backup.CreationTimestamp.Add(backup.Spec.TTL.Duration)
|
expiration = backup.CreationTimestamp.Add(backup.Spec.TTL.Duration)
|
||||||
}
|
}
|
||||||
@@ -111,7 +114,7 @@ func printBackup(backup *velerov1api.Backup, options printers.PrintOptions) ([]m
|
|||||||
|
|
||||||
location := backup.Spec.StorageLocation
|
location := backup.Spec.StorageLocation
|
||||||
|
|
||||||
row.Cells = append(row.Cells, backup.Name, status, backup.Status.StartTimestamp.Time, humanReadableTimeFromNow(expiration), location, metav1.FormatLabelSelector(backup.Spec.LabelSelector))
|
row.Cells = append(row.Cells, backup.Name, status, backup.Status.StartTimestamp, humanReadableTimeFromNow(expiration), location, metav1.FormatLabelSelector(backup.Spec.LabelSelector))
|
||||||
|
|
||||||
return []metav1.TableRow{row}, nil
|
return []metav1.TableRow{row}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ func DescribeScheduleSpec(d *Describer, spec v1.ScheduleSpec) {
|
|||||||
|
|
||||||
func DescribeScheduleStatus(d *Describer, status v1.ScheduleStatus) {
|
func DescribeScheduleStatus(d *Describer, status v1.ScheduleStatus) {
|
||||||
lastBackup := "<never>"
|
lastBackup := "<never>"
|
||||||
if !status.LastBackup.Time.IsZero() {
|
if status.LastBackup != nil && !status.LastBackup.Time.IsZero() {
|
||||||
lastBackup = fmt.Sprintf("%v", status.LastBackup.Time)
|
lastBackup = fmt.Sprintf("%v", status.LastBackup.Time)
|
||||||
}
|
}
|
||||||
d.Printf("Last Backup:\t%s\n", lastBackup)
|
d.Printf("Last Backup:\t%s\n", lastBackup)
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ limitations under the License.
|
|||||||
package output
|
package output
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
@@ -61,13 +63,18 @@ func printSchedule(schedule *v1.Schedule, options printers.PrintOptions) ([]meta
|
|||||||
status = v1.SchedulePhaseNew
|
status = v1.SchedulePhaseNew
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lastBackupTime time.Time
|
||||||
|
if schedule.Status.LastBackup != nil {
|
||||||
|
lastBackupTime = schedule.Status.LastBackup.Time
|
||||||
|
}
|
||||||
|
|
||||||
row.Cells = append(row.Cells,
|
row.Cells = append(row.Cells,
|
||||||
schedule.Name,
|
schedule.Name,
|
||||||
status,
|
status,
|
||||||
schedule.CreationTimestamp.Time,
|
schedule.CreationTimestamp.Time,
|
||||||
schedule.Spec.Schedule,
|
schedule.Spec.Schedule,
|
||||||
schedule.Spec.Template.TTL.Duration,
|
schedule.Spec.Template.TTL.Duration,
|
||||||
humanReadableTimeFromNow(schedule.Status.LastBackup.Time),
|
humanReadableTimeFromNow(lastBackupTime),
|
||||||
metav1.FormatLabelSelector(schedule.Spec.Template.LabelSelector),
|
metav1.FormatLabelSelector(schedule.Spec.Template.LabelSelector),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ func (c *backupController) processBackup(key string) error {
|
|||||||
request.Status.Phase = velerov1api.BackupPhaseFailedValidation
|
request.Status.Phase = velerov1api.BackupPhaseFailedValidation
|
||||||
} else {
|
} else {
|
||||||
request.Status.Phase = velerov1api.BackupPhaseInProgress
|
request.Status.Phase = velerov1api.BackupPhaseInProgress
|
||||||
request.Status.StartTimestamp.Time = c.clock.Now()
|
request.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update status
|
// update status
|
||||||
@@ -289,7 +289,7 @@ func (c *backupController) prepareBackupRequest(backup *velerov1api.Backup) *pkg
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calculate expiration
|
// calculate expiration
|
||||||
request.Status.Expiration = metav1.NewTime(c.clock.Now().Add(request.Spec.TTL.Duration))
|
request.Status.Expiration = &metav1.Time{Time: c.clock.Now().Add(request.Spec.TTL.Duration)}
|
||||||
|
|
||||||
// default storage location if not specified
|
// default storage location if not specified
|
||||||
if request.Spec.StorageLocation == "" {
|
if request.Spec.StorageLocation == "" {
|
||||||
@@ -485,7 +485,7 @@ func (c *backupController) runBackup(backup *pkgbackup.Request) error {
|
|||||||
exists, err := backupStore.BackupExists(backup.StorageLocation.Spec.StorageType.ObjectStorage.Bucket, backup.Name)
|
exists, err := backupStore.BackupExists(backup.StorageLocation.Spec.StorageType.ObjectStorage.Bucket, backup.Name)
|
||||||
if exists || err != nil {
|
if exists || err != nil {
|
||||||
backup.Status.Phase = velerov1api.BackupPhaseFailed
|
backup.Status.Phase = velerov1api.BackupPhaseFailed
|
||||||
backup.Status.CompletionTimestamp.Time = c.clock.Now()
|
backup.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error checking if backup already exists in object storage")
|
return errors.Wrapf(err, "error checking if backup already exists in object storage")
|
||||||
}
|
}
|
||||||
@@ -499,7 +499,7 @@ func (c *backupController) runBackup(backup *pkgbackup.Request) error {
|
|||||||
|
|
||||||
// Mark completion timestamp before serializing and uploading.
|
// Mark completion timestamp before serializing and uploading.
|
||||||
// Otherwise, the JSON file in object storage has a CompletionTimestamp of 'null'.
|
// Otherwise, the JSON file in object storage has a CompletionTimestamp of 'null'.
|
||||||
backup.Status.CompletionTimestamp.Time = c.clock.Now()
|
backup.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
|
|
||||||
backup.Status.VolumeSnapshotsAttempted = len(backup.VolumeSnapshots)
|
backup.Status.VolumeSnapshotsAttempted = len(backup.VolumeSnapshots)
|
||||||
for _, snap := range backup.VolumeSnapshots {
|
for _, snap := range backup.VolumeSnapshots {
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ func TestDefaultBackupTTL(t *testing.T) {
|
|||||||
res := c.prepareBackupRequest(test.backup)
|
res := c.prepareBackupRequest(test.backup)
|
||||||
assert.NotNil(t, res)
|
assert.NotNil(t, res)
|
||||||
assert.Equal(t, test.expectedTTL, res.Spec.TTL)
|
assert.Equal(t, test.expectedTTL, res.Spec.TTL)
|
||||||
assert.Equal(t, test.expectedExpiration, res.Status.Expiration)
|
assert.Equal(t, test.expectedExpiration, *res.Status.Expiration)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,6 +316,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
now, err := time.Parse(time.RFC1123Z, time.RFC1123Z)
|
now, err := time.Parse(time.RFC1123Z, time.RFC1123Z)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
now = now.Local()
|
now = now.Local()
|
||||||
|
timestamp := metav1.NewTime(now)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -348,9 +349,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
Status: velerov1api.BackupStatus{
|
Status: velerov1api.BackupStatus{
|
||||||
Phase: velerov1api.BackupPhaseCompleted,
|
Phase: velerov1api.BackupPhaseCompleted,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
StartTimestamp: metav1.NewTime(now),
|
StartTimestamp: ×tamp,
|
||||||
CompletionTimestamp: metav1.NewTime(now),
|
CompletionTimestamp: ×tamp,
|
||||||
Expiration: metav1.NewTime(now),
|
Expiration: ×tamp,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -376,9 +377,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
Status: velerov1api.BackupStatus{
|
Status: velerov1api.BackupStatus{
|
||||||
Phase: velerov1api.BackupPhaseCompleted,
|
Phase: velerov1api.BackupPhaseCompleted,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
StartTimestamp: metav1.NewTime(now),
|
StartTimestamp: ×tamp,
|
||||||
CompletionTimestamp: metav1.NewTime(now),
|
CompletionTimestamp: ×tamp,
|
||||||
Expiration: metav1.NewTime(now),
|
Expiration: ×tamp,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -407,9 +408,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
Status: velerov1api.BackupStatus{
|
Status: velerov1api.BackupStatus{
|
||||||
Phase: velerov1api.BackupPhaseCompleted,
|
Phase: velerov1api.BackupPhaseCompleted,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
StartTimestamp: metav1.NewTime(now),
|
StartTimestamp: ×tamp,
|
||||||
CompletionTimestamp: metav1.NewTime(now),
|
CompletionTimestamp: ×tamp,
|
||||||
Expiration: metav1.NewTime(now),
|
Expiration: ×tamp,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -436,9 +437,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
Status: velerov1api.BackupStatus{
|
Status: velerov1api.BackupStatus{
|
||||||
Phase: velerov1api.BackupPhaseCompleted,
|
Phase: velerov1api.BackupPhaseCompleted,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
Expiration: metav1.NewTime(now.Add(10 * time.Minute)),
|
Expiration: &metav1.Time{now.Add(10 * time.Minute)},
|
||||||
StartTimestamp: metav1.NewTime(now),
|
StartTimestamp: ×tamp,
|
||||||
CompletionTimestamp: metav1.NewTime(now),
|
CompletionTimestamp: ×tamp,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -465,9 +466,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
Status: velerov1api.BackupStatus{
|
Status: velerov1api.BackupStatus{
|
||||||
Phase: velerov1api.BackupPhaseCompleted,
|
Phase: velerov1api.BackupPhaseCompleted,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
StartTimestamp: metav1.NewTime(now),
|
StartTimestamp: ×tamp,
|
||||||
CompletionTimestamp: metav1.NewTime(now),
|
CompletionTimestamp: ×tamp,
|
||||||
Expiration: metav1.NewTime(now),
|
Expiration: ×tamp,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -496,9 +497,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
Status: velerov1api.BackupStatus{
|
Status: velerov1api.BackupStatus{
|
||||||
Phase: velerov1api.BackupPhaseFailed,
|
Phase: velerov1api.BackupPhaseFailed,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
StartTimestamp: metav1.NewTime(now),
|
StartTimestamp: ×tamp,
|
||||||
CompletionTimestamp: metav1.NewTime(now),
|
CompletionTimestamp: ×tamp,
|
||||||
Expiration: metav1.NewTime(now),
|
Expiration: ×tamp,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -525,9 +526,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
|||||||
Status: velerov1api.BackupStatus{
|
Status: velerov1api.BackupStatus{
|
||||||
Phase: velerov1api.BackupPhaseFailed,
|
Phase: velerov1api.BackupPhaseFailed,
|
||||||
Version: 1,
|
Version: 1,
|
||||||
StartTimestamp: metav1.NewTime(now),
|
StartTimestamp: ×tamp,
|
||||||
CompletionTimestamp: metav1.NewTime(now),
|
CompletionTimestamp: ×tamp,
|
||||||
Expiration: metav1.NewTime(now),
|
Expiration: ×tamp,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ func (c *downloadRequestController) generatePreSignedURL(downloadRequest *v1.Dow
|
|||||||
}
|
}
|
||||||
|
|
||||||
update.Status.Phase = v1.DownloadRequestPhaseProcessed
|
update.Status.Phase = v1.DownloadRequestPhaseProcessed
|
||||||
update.Status.Expiration = metav1.NewTime(c.clock.Now().Add(persistence.DownloadURLTTL))
|
update.Status.Expiration = &metav1.Time{Time: c.clock.Now().Add(persistence.DownloadURLTTL)}
|
||||||
|
|
||||||
_, err = patchDownloadRequest(downloadRequest, update, c.downloadRequestClient)
|
_, err = patchDownloadRequest(downloadRequest, update, c.downloadRequestClient)
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
|
|||||||
@@ -252,9 +252,9 @@ func TestProcessDownloadRequest(t *testing.T) {
|
|||||||
// clock time, it's easier to do this here than as part of the test case definitions.
|
// clock time, it's easier to do this here than as part of the test case definitions.
|
||||||
if tc.downloadRequest != nil && tc.downloadRequest.Status.Phase == v1.DownloadRequestPhaseProcessed {
|
if tc.downloadRequest != nil && tc.downloadRequest.Status.Phase == v1.DownloadRequestPhaseProcessed {
|
||||||
if tc.expired {
|
if tc.expired {
|
||||||
tc.downloadRequest.Status.Expiration.Time = harness.controller.clock.Now().Add(-1 * time.Minute)
|
tc.downloadRequest.Status.Expiration = &metav1.Time{Time: harness.controller.clock.Now().Add(-1 * time.Minute)}
|
||||||
} else {
|
} else {
|
||||||
tc.downloadRequest.Status.Expiration.Time = harness.controller.clock.Now().Add(time.Minute)
|
tc.downloadRequest.Status.Expiration = &metav1.Time{Time: harness.controller.clock.Now().Add(time.Minute)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,14 +123,13 @@ func (c *gcController) processQueueItem(key string) error {
|
|||||||
log = c.logger.WithFields(
|
log = c.logger.WithFields(
|
||||||
logrus.Fields{
|
logrus.Fields{
|
||||||
"backup": key,
|
"backup": key,
|
||||||
"expiration": backup.Status.Expiration.Time,
|
"expiration": backup.Status.Expiration,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
now := c.clock.Now()
|
now := c.clock.Now()
|
||||||
|
|
||||||
expiration := backup.Status.Expiration.Time
|
if backup.Status.Expiration == nil || backup.Status.Expiration.After(now) {
|
||||||
if expiration.IsZero() || expiration.After(now) {
|
|
||||||
log.Debug("Backup has not expired yet, skipping")
|
log.Debug("Backup has not expired yet, skipping")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/clock"
|
"k8s.io/apimachinery/pkg/util/clock"
|
||||||
@@ -181,7 +182,7 @@ func (c *podVolumeBackupController) processBackup(req *velerov1api.PodVolumeBack
|
|||||||
// update status to InProgress
|
// update status to InProgress
|
||||||
req, err = c.patchPodVolumeBackup(req, func(r *velerov1api.PodVolumeBackup) {
|
req, err = c.patchPodVolumeBackup(req, func(r *velerov1api.PodVolumeBackup) {
|
||||||
r.Status.Phase = velerov1api.PodVolumeBackupPhaseInProgress
|
r.Status.Phase = velerov1api.PodVolumeBackupPhaseInProgress
|
||||||
r.Status.StartTimestamp.Time = c.clock.Now()
|
r.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("Error setting PodVolumeBackup StartTimestamp and phase to InProgress")
|
log.WithError(err).Error("Error setting PodVolumeBackup StartTimestamp and phase to InProgress")
|
||||||
@@ -277,7 +278,7 @@ func (c *podVolumeBackupController) processBackup(req *velerov1api.PodVolumeBack
|
|||||||
r.Status.Path = path
|
r.Status.Path = path
|
||||||
r.Status.Phase = velerov1api.PodVolumeBackupPhaseCompleted
|
r.Status.Phase = velerov1api.PodVolumeBackupPhaseCompleted
|
||||||
r.Status.SnapshotID = snapshotID
|
r.Status.SnapshotID = snapshotID
|
||||||
r.Status.CompletionTimestamp.Time = c.clock.Now()
|
r.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
if emptySnapshot {
|
if emptySnapshot {
|
||||||
r.Status.Message = "volume was empty so no snapshot was taken"
|
r.Status.Message = "volume was empty so no snapshot was taken"
|
||||||
}
|
}
|
||||||
@@ -376,7 +377,7 @@ func (c *podVolumeBackupController) fail(req *velerov1api.PodVolumeBackup, msg s
|
|||||||
if _, err := c.patchPodVolumeBackup(req, func(r *velerov1api.PodVolumeBackup) {
|
if _, err := c.patchPodVolumeBackup(req, func(r *velerov1api.PodVolumeBackup) {
|
||||||
r.Status.Phase = velerov1api.PodVolumeBackupPhaseFailed
|
r.Status.Phase = velerov1api.PodVolumeBackupPhaseFailed
|
||||||
r.Status.Message = msg
|
r.Status.Message = msg
|
||||||
r.Status.CompletionTimestamp.Time = c.clock.Now()
|
r.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.WithError(err).Error("Error setting PodVolumeBackup phase to Failed")
|
log.WithError(err).Error("Error setting PodVolumeBackup phase to Failed")
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
corev1api "k8s.io/api/core/v1"
|
corev1api "k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/clock"
|
"k8s.io/apimachinery/pkg/util/clock"
|
||||||
@@ -265,7 +266,7 @@ func (c *podVolumeRestoreController) processRestore(req *velerov1api.PodVolumeRe
|
|||||||
// update status to InProgress
|
// update status to InProgress
|
||||||
req, err = c.patchPodVolumeRestore(req, func(r *velerov1api.PodVolumeRestore) {
|
req, err = c.patchPodVolumeRestore(req, func(r *velerov1api.PodVolumeRestore) {
|
||||||
r.Status.Phase = velerov1api.PodVolumeRestorePhaseInProgress
|
r.Status.Phase = velerov1api.PodVolumeRestorePhaseInProgress
|
||||||
r.Status.StartTimestamp.Time = c.clock.Now()
|
r.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("Error setting PodVolumeRestore startTimestamp and phase to InProgress")
|
log.WithError(err).Error("Error setting PodVolumeRestore startTimestamp and phase to InProgress")
|
||||||
@@ -301,7 +302,7 @@ func (c *podVolumeRestoreController) processRestore(req *velerov1api.PodVolumeRe
|
|||||||
// update status to Completed
|
// update status to Completed
|
||||||
if _, err = c.patchPodVolumeRestore(req, func(r *velerov1api.PodVolumeRestore) {
|
if _, err = c.patchPodVolumeRestore(req, func(r *velerov1api.PodVolumeRestore) {
|
||||||
r.Status.Phase = velerov1api.PodVolumeRestorePhaseCompleted
|
r.Status.Phase = velerov1api.PodVolumeRestorePhaseCompleted
|
||||||
r.Status.CompletionTimestamp.Time = c.clock.Now()
|
r.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.WithError(err).Error("Error setting PodVolumeRestore completionTimestamp and phase to Completed")
|
log.WithError(err).Error("Error setting PodVolumeRestore completionTimestamp and phase to Completed")
|
||||||
return err
|
return err
|
||||||
@@ -408,7 +409,7 @@ func (c *podVolumeRestoreController) failRestore(req *velerov1api.PodVolumeResto
|
|||||||
if _, err := c.patchPodVolumeRestore(req, func(pvr *velerov1api.PodVolumeRestore) {
|
if _, err := c.patchPodVolumeRestore(req, func(pvr *velerov1api.PodVolumeRestore) {
|
||||||
pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseFailed
|
pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseFailed
|
||||||
pvr.Status.Message = msg
|
pvr.Status.Message = msg
|
||||||
pvr.Status.CompletionTimestamp.Time = c.clock.Now()
|
pvr.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.WithError(err).Error("Error setting PodVolumeRestore phase to Failed")
|
log.WithError(err).Error("Error setting PodVolumeRestore phase to Failed")
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ func (c *resticRepositoryController) initializeRepo(req *v1.ResticRepository, lo
|
|||||||
|
|
||||||
return c.patchResticRepository(req, func(req *v1.ResticRepository) {
|
return c.patchResticRepository(req, func(req *v1.ResticRepository) {
|
||||||
req.Status.Phase = v1.ResticRepositoryPhaseReady
|
req.Status.Phase = v1.ResticRepositoryPhaseReady
|
||||||
req.Status.LastMaintenanceTime = metav1.Time{Time: time.Now()}
|
req.Status.LastMaintenanceTime = &metav1.Time{Time: time.Now()}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ func (c *resticRepositoryController) runMaintenanceIfDue(req *v1.ResticRepositor
|
|||||||
}
|
}
|
||||||
|
|
||||||
return c.patchResticRepository(req, func(req *v1.ResticRepository) {
|
return c.patchResticRepository(req, func(req *v1.ResticRepository) {
|
||||||
req.Status.LastMaintenanceTime = metav1.Time{Time: now}
|
req.Status.LastMaintenanceTime = &metav1.Time{Time: now}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -373,7 +373,15 @@ func backupXorScheduleProvided(restore *api.Restore) bool {
|
|||||||
func mostRecentCompletedBackup(backups []*api.Backup) *api.Backup {
|
func mostRecentCompletedBackup(backups []*api.Backup) *api.Backup {
|
||||||
sort.Slice(backups, func(i, j int) bool {
|
sort.Slice(backups, func(i, j int) bool {
|
||||||
// Use .After() because we want descending sort.
|
// Use .After() because we want descending sort.
|
||||||
return backups[i].Status.StartTimestamp.After(backups[j].Status.StartTimestamp.Time)
|
|
||||||
|
var iStartTime, jStartTime time.Time
|
||||||
|
if backups[i].Status.StartTimestamp != nil {
|
||||||
|
iStartTime = backups[i].Status.StartTimestamp.Time
|
||||||
|
}
|
||||||
|
if backups[j].Status.StartTimestamp != nil {
|
||||||
|
jStartTime = backups[j].Status.StartTimestamp.Time
|
||||||
|
}
|
||||||
|
return iStartTime.After(jStartTime)
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, backup := range backups {
|
for _, backup := range backups {
|
||||||
|
|||||||
@@ -781,7 +781,7 @@ func TestMostRecentCompletedBackup(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Status: api.BackupStatus{
|
Status: api.BackupStatus{
|
||||||
Phase: api.BackupPhaseCompleted,
|
Phase: api.BackupPhaseCompleted,
|
||||||
StartTimestamp: metav1.Time{Time: now},
|
StartTimestamp: &metav1.Time{Time: now},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -791,7 +791,7 @@ func TestMostRecentCompletedBackup(t *testing.T) {
|
|||||||
},
|
},
|
||||||
Status: api.BackupStatus{
|
Status: api.BackupStatus{
|
||||||
Phase: api.BackupPhaseCompleted,
|
Phase: api.BackupPhaseCompleted,
|
||||||
StartTimestamp: metav1.Time{Time: now.Add(time.Second)},
|
StartTimestamp: &metav1.Time{Time: now.Add(time.Second)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
backups = append(backups, expected)
|
backups = append(backups, expected)
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ func (c *scheduleController) submitBackupIfDue(item *api.Schedule, cronSchedule
|
|||||||
original := item
|
original := item
|
||||||
schedule := item.DeepCopy()
|
schedule := item.DeepCopy()
|
||||||
|
|
||||||
schedule.Status.LastBackup = metav1.NewTime(now)
|
schedule.Status.LastBackup = &metav1.Time{Time: now}
|
||||||
|
|
||||||
if _, err := patchSchedule(original, schedule, c.schedulesClient); err != nil {
|
if _, err := patchSchedule(original, schedule, c.schedulesClient); err != nil {
|
||||||
return errors.Wrapf(err, "error updating Schedule's LastBackup time to %v", schedule.Status.LastBackup)
|
return errors.Wrapf(err, "error updating Schedule's LastBackup time to %v", schedule.Status.LastBackup)
|
||||||
@@ -278,7 +278,10 @@ func (c *scheduleController) submitBackupIfDue(item *api.Schedule, cronSchedule
|
|||||||
func getNextRunTime(schedule *api.Schedule, cronSchedule cron.Schedule, asOf time.Time) (bool, time.Time) {
|
func getNextRunTime(schedule *api.Schedule, cronSchedule cron.Schedule, asOf time.Time) (bool, time.Time) {
|
||||||
// get the latest run time (if the schedule hasn't run yet, this will be the zero value which will trigger
|
// get the latest run time (if the schedule hasn't run yet, this will be the zero value which will trigger
|
||||||
// an immediate backup)
|
// an immediate backup)
|
||||||
lastBackupTime := schedule.Status.LastBackup.Time
|
var lastBackupTime time.Time
|
||||||
|
if schedule.Status.LastBackup != nil {
|
||||||
|
lastBackupTime = schedule.Status.LastBackup.Time
|
||||||
|
}
|
||||||
|
|
||||||
nextRunTime := cronSchedule.Next(lastBackupTime)
|
nextRunTime := cronSchedule.Next(lastBackupTime)
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ func TestProcessSchedule(t *testing.T) {
|
|||||||
t.Logf("error parsing status.lastBackup: %s\n", err)
|
t.Logf("error parsing status.lastBackup: %s\n", err)
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
res.Status.LastBackup = metav1.Time{Time: parsed}
|
res.Status.LastBackup = &metav1.Time{Time: parsed}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, res, nil
|
return true, res, nil
|
||||||
@@ -318,14 +318,21 @@ func TestGetNextRunTime(t *testing.T) {
|
|||||||
offsetDuration, err := time.ParseDuration(test.lastRanOffset)
|
offsetDuration, err := time.ParseDuration(test.lastRanOffset)
|
||||||
require.NoError(t, err, "unable to parse test.lastRanOffset: %v", err)
|
require.NoError(t, err, "unable to parse test.lastRanOffset: %v", err)
|
||||||
|
|
||||||
test.schedule.Status.LastBackup = metav1.Time{Time: testClock.Now().Add(-offsetDuration)}
|
test.schedule.Status.LastBackup = &metav1.Time{Time: testClock.Now().Add(-offsetDuration)}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextRunTimeOffset, err := time.ParseDuration(test.expectedNextRunTimeOffset)
|
nextRunTimeOffset, err := time.ParseDuration(test.expectedNextRunTimeOffset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
expectedNextRunTime := test.schedule.Status.LastBackup.Add(nextRunTimeOffset)
|
|
||||||
|
// calculate expected next run time (if the schedule hasn't run yet, this
|
||||||
|
// will be the zero value which will trigger an immediate backup)
|
||||||
|
var baseTime time.Time
|
||||||
|
if test.lastRanOffset != "" {
|
||||||
|
baseTime = test.schedule.Status.LastBackup.Time
|
||||||
|
}
|
||||||
|
expectedNextRunTime := baseTime.Add(nextRunTimeOffset)
|
||||||
|
|
||||||
due, nextRunTime := getNextRunTime(test.schedule, cronSchedule, testClock.Now())
|
due, nextRunTime := getNextRunTime(test.schedule, cronSchedule, testClock.Now())
|
||||||
|
|
||||||
@@ -371,7 +378,7 @@ func TestParseCronSchedule(t *testing.T) {
|
|||||||
assert.Equal(t, time.Date(2017, 8, 11, 9, 0, 0, 0, time.UTC), next)
|
assert.Equal(t, time.Date(2017, 8, 11, 9, 0, 0, 0, time.UTC), next)
|
||||||
|
|
||||||
// record backup time
|
// record backup time
|
||||||
s.Status.LastBackup = metav1.NewTime(now)
|
s.Status.LastBackup = &metav1.Time{Time: now}
|
||||||
|
|
||||||
// advance clock 1 minute, make sure we're not due and next backup is tomorrow at 9am
|
// advance clock 1 minute, make sure we're not due and next backup is tomorrow at 9am
|
||||||
now = time.Date(2017, 8, 11, 9, 2, 0, 0, time.UTC)
|
now = time.Date(2017, 8, 11, 9, 2, 0, 0, time.UTC)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
jsonpatch "github.com/evanphx/json-patch"
|
jsonpatch "github.com/evanphx/json-patch"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/clock"
|
"k8s.io/apimachinery/pkg/util/clock"
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ func Process(req *velerov1api.ServerStatusRequest, client velerov1client.ServerS
|
|||||||
log.Info("Processing new ServerStatusRequest")
|
log.Info("Processing new ServerStatusRequest")
|
||||||
return errors.WithStack(patch(client, req, func(req *velerov1api.ServerStatusRequest) {
|
return errors.WithStack(patch(client, req, func(req *velerov1api.ServerStatusRequest) {
|
||||||
req.Status.ServerVersion = buildinfo.Version
|
req.Status.ServerVersion = buildinfo.Version
|
||||||
req.Status.ProcessedTimestamp.Time = clock.Now()
|
req.Status.ProcessedTimestamp = &metav1.Time{Time: clock.Now()}
|
||||||
req.Status.Phase = velerov1api.ServerStatusRequestPhaseProcessed
|
req.Status.Phase = velerov1api.ServerStatusRequestPhaseProcessed
|
||||||
req.Status.Plugins = plugins(pluginLister)
|
req.Status.Plugins = plugins(pluginLister)
|
||||||
}))
|
}))
|
||||||
|
|||||||
Reference in New Issue
Block a user