mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-04-29 11:56:58 +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.
|
||||
// +optional
|
||||
// +nullable
|
||||
Expiration metav1.Time `json:"expiration,omitempty"`
|
||||
Expiration *metav1.Time `json:"expiration,omitempty"`
|
||||
|
||||
// Phase is the current state of the Backup.
|
||||
// +optional
|
||||
@@ -237,7 +237,7 @@ type BackupStatus struct {
|
||||
// The server's time is used for StartTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
StartTimestamp metav1.Time `json:"startTimestamp,omitempty"`
|
||||
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||
|
||||
// CompletionTimestamp records the time a backup was completed.
|
||||
// Completion time is recorded even on failed backups.
|
||||
@@ -245,7 +245,7 @@ type BackupStatus struct {
|
||||
// The server's time is used for CompletionTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
CompletionTimestamp metav1.Time `json:"completionTimestamp,omitempty"`
|
||||
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||
|
||||
// VolumeSnapshotsAttempted is the total number of attempted
|
||||
// volume snapshots for this backup.
|
||||
|
||||
@@ -119,7 +119,7 @@ type BackupStorageLocationStatus struct {
|
||||
// the cluster.
|
||||
// +optional
|
||||
// +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
|
||||
// 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.
|
||||
// +optional
|
||||
// +nullable
|
||||
Expiration metav1.Time `json:"expiration,omitempty"`
|
||||
Expiration *metav1.Time `json:"expiration,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
|
||||
@@ -81,7 +81,7 @@ type PodVolumeBackupStatus struct {
|
||||
// The server's time is used for StartTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
StartTimestamp metav1.Time `json:"startTimestamp,omitempty"`
|
||||
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||
|
||||
// CompletionTimestamp records the time a backup was completed.
|
||||
// Completion time is recorded even on failed backups.
|
||||
@@ -89,7 +89,7 @@ type PodVolumeBackupStatus struct {
|
||||
// The server's time is used for CompletionTimestamps
|
||||
// +optional
|
||||
// +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
|
||||
// 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
|
||||
// +optional
|
||||
// +nullable
|
||||
StartTimestamp metav1.Time `json:"startTimestamp,omitempty"`
|
||||
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||
|
||||
// CompletionTimestamp records the time a restore was completed.
|
||||
// Completion time is recorded even on failed restores.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
// +optional
|
||||
// +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
|
||||
// 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.
|
||||
// +optional
|
||||
// +nullable
|
||||
LastMaintenanceTime metav1.Time `json:"lastMaintenanceTime,omitempty"`
|
||||
LastMaintenanceTime *metav1.Time `json:"lastMaintenanceTime,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
|
||||
@@ -58,7 +58,7 @@ type ScheduleStatus struct {
|
||||
// Schedule schedule
|
||||
// +optional
|
||||
// +nullable
|
||||
LastBackup metav1.Time `json:"lastBackup,omitempty"`
|
||||
LastBackup *metav1.Time `json:"lastBackup,omitempty"`
|
||||
|
||||
// ValidationErrors is a slice of all validation errors (if
|
||||
// applicable)
|
||||
|
||||
@@ -63,22 +63,22 @@ type PluginInfo struct {
|
||||
type ServerStatusRequestStatus struct {
|
||||
// Phase is the current lifecycle phase of the ServerStatusRequest.
|
||||
// +optional
|
||||
Phase ServerStatusRequestPhase `json:"phase"`
|
||||
Phase ServerStatusRequestPhase `json:"phase,omitempty"`
|
||||
|
||||
// ProcessedTimestamp is when the ServerStatusRequest was processed
|
||||
// by the ServerStatusRequestController.
|
||||
// +optional
|
||||
// +nullable
|
||||
ProcessedTimestamp metav1.Time `json:"processedTimestamp"`
|
||||
ProcessedTimestamp *metav1.Time `json:"processedTimestamp,omitempty"`
|
||||
|
||||
// ServerVersion is the Velero server version.
|
||||
// +optional
|
||||
ServerVersion string `json:"serverVersion"`
|
||||
ServerVersion string `json:"serverVersion,omitempty"`
|
||||
|
||||
// Plugins list information about the plugins running on the Velero server
|
||||
// +optional
|
||||
// +nullable
|
||||
Plugins []PluginInfo `json:"plugins"`
|
||||
Plugins []PluginInfo `json:"plugins,omitempty"`
|
||||
}
|
||||
|
||||
// +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.
|
||||
func (in *BackupStatus) DeepCopyInto(out *BackupStatus) {
|
||||
*out = *in
|
||||
in.Expiration.DeepCopyInto(&out.Expiration)
|
||||
if in.Expiration != nil {
|
||||
in, out := &in.Expiration, &out.Expiration
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.ValidationErrors != nil {
|
||||
in, out := &in.ValidationErrors, &out.ValidationErrors
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.StartTimestamp.DeepCopyInto(&out.StartTimestamp)
|
||||
in.CompletionTimestamp.DeepCopyInto(&out.CompletionTimestamp)
|
||||
if in.StartTimestamp != nil {
|
||||
in, out := &in.StartTimestamp, &out.StartTimestamp
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.CompletionTimestamp != nil {
|
||||
in, out := &in.CompletionTimestamp, &out.CompletionTimestamp
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
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.
|
||||
func (in *BackupStorageLocationStatus) DeepCopyInto(out *BackupStorageLocationStatus) {
|
||||
*out = *in
|
||||
in.LastSyncedTime.DeepCopyInto(&out.LastSyncedTime)
|
||||
if in.LastSyncedTime != nil {
|
||||
in, out := &in.LastSyncedTime, &out.LastSyncedTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
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.
|
||||
func (in *DownloadRequestStatus) DeepCopyInto(out *DownloadRequestStatus) {
|
||||
*out = *in
|
||||
in.Expiration.DeepCopyInto(&out.Expiration)
|
||||
if in.Expiration != nil {
|
||||
in, out := &in.Expiration, &out.Expiration
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
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.
|
||||
func (in *PodVolumeBackupStatus) DeepCopyInto(out *PodVolumeBackupStatus) {
|
||||
*out = *in
|
||||
in.StartTimestamp.DeepCopyInto(&out.StartTimestamp)
|
||||
in.CompletionTimestamp.DeepCopyInto(&out.CompletionTimestamp)
|
||||
if in.StartTimestamp != nil {
|
||||
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
|
||||
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.
|
||||
func (in *PodVolumeRestoreStatus) DeepCopyInto(out *PodVolumeRestoreStatus) {
|
||||
*out = *in
|
||||
in.StartTimestamp.DeepCopyInto(&out.StartTimestamp)
|
||||
in.CompletionTimestamp.DeepCopyInto(&out.CompletionTimestamp)
|
||||
if in.StartTimestamp != nil {
|
||||
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
|
||||
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.
|
||||
func (in *ResticRepositoryStatus) DeepCopyInto(out *ResticRepositoryStatus) {
|
||||
*out = *in
|
||||
in.LastMaintenanceTime.DeepCopyInto(&out.LastMaintenanceTime)
|
||||
if in.LastMaintenanceTime != nil {
|
||||
in, out := &in.LastMaintenanceTime, &out.LastMaintenanceTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
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.
|
||||
func (in *ScheduleStatus) DeepCopyInto(out *ScheduleStatus) {
|
||||
*out = *in
|
||||
in.LastBackup.DeepCopyInto(&out.LastBackup)
|
||||
if in.LastBackup != nil {
|
||||
in, out := &in.LastBackup, &out.LastBackup
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.ValidationErrors != nil {
|
||||
in, out := &in.ValidationErrors, &out.ValidationErrors
|
||||
*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.
|
||||
func (in *ServerStatusRequestStatus) DeepCopyInto(out *ServerStatusRequestStatus) {
|
||||
*out = *in
|
||||
in.ProcessedTimestamp.DeepCopyInto(&out.ProcessedTimestamp)
|
||||
if in.ProcessedTimestamp != nil {
|
||||
in, out := &in.ProcessedTimestamp, &out.ProcessedTimestamp
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.Plugins != nil {
|
||||
in, out := &in.Plugins, &out.Plugins
|
||||
*out = make([]PluginInfo, len(*in))
|
||||
|
||||
@@ -154,13 +154,13 @@ func (b *BackupBuilder) TTL(ttl time.Duration) *BackupBuilder {
|
||||
|
||||
// Expiration sets the Backup's expiration.
|
||||
func (b *BackupBuilder) Expiration(val time.Time) *BackupBuilder {
|
||||
b.object.Status.Expiration.Time = val
|
||||
b.object.Status.Expiration = &metav1.Time{Time: val}
|
||||
return b
|
||||
}
|
||||
|
||||
// StartTimestamp sets the Backup's start timestamp.
|
||||
func (b *BackupBuilder) StartTimestamp(val time.Time) *BackupBuilder {
|
||||
b.object.Status.StartTimestamp.Time = val
|
||||
b.object.Status.StartTimestamp = &metav1.Time{Time: val}
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ func (b *ScheduleBuilder) CronSchedule(expression string) *ScheduleBuilder {
|
||||
// LastBackupTime sets the Schedule's last backup time.
|
||||
func (b *ScheduleBuilder) LastBackupTime(val string) *ScheduleBuilder {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ func (b *ServerStatusRequestBuilder) Phase(phase velerov1api.ServerStatusRequest
|
||||
|
||||
// ProcessedTimestamp sets the ServerStatusRequest's processed timestamp.
|
||||
func (b *ServerStatusRequestBuilder) ProcessedTimestamp(time time.Time) *ServerStatusRequestBuilder {
|
||||
b.object.Status.ProcessedTimestamp.Time = time
|
||||
b.object.Status.ProcessedTimestamp = &metav1.Time{Time: time}
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
@@ -219,19 +219,22 @@ func DescribeBackupStatus(d *Describer, backup *velerov1api.Backup, details bool
|
||||
|
||||
d.Println()
|
||||
// "<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>")
|
||||
} else {
|
||||
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>")
|
||||
} else {
|
||||
d.Printf("Completed:\t%s\n", status.CompletionTimestamp.Time)
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
if details {
|
||||
|
||||
@@ -88,7 +88,10 @@ func printBackup(backup *velerov1api.Backup, options printers.PrintOptions) ([]m
|
||||
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 {
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func DescribeScheduleSpec(d *Describer, spec v1.ScheduleSpec) {
|
||||
|
||||
func DescribeScheduleStatus(d *Describer, status v1.ScheduleStatus) {
|
||||
lastBackup := "<never>"
|
||||
if !status.LastBackup.Time.IsZero() {
|
||||
if status.LastBackup != nil && !status.LastBackup.Time.IsZero() {
|
||||
lastBackup = fmt.Sprintf("%v", status.LastBackup.Time)
|
||||
}
|
||||
d.Printf("Last Backup:\t%s\n", lastBackup)
|
||||
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package output
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
@@ -61,13 +63,18 @@ func printSchedule(schedule *v1.Schedule, options printers.PrintOptions) ([]meta
|
||||
status = v1.SchedulePhaseNew
|
||||
}
|
||||
|
||||
var lastBackupTime time.Time
|
||||
if schedule.Status.LastBackup != nil {
|
||||
lastBackupTime = schedule.Status.LastBackup.Time
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells,
|
||||
schedule.Name,
|
||||
status,
|
||||
schedule.CreationTimestamp.Time,
|
||||
schedule.Spec.Schedule,
|
||||
schedule.Spec.Template.TTL.Duration,
|
||||
humanReadableTimeFromNow(schedule.Status.LastBackup.Time),
|
||||
humanReadableTimeFromNow(lastBackupTime),
|
||||
metav1.FormatLabelSelector(schedule.Spec.Template.LabelSelector),
|
||||
)
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ func (c *backupController) processBackup(key string) error {
|
||||
request.Status.Phase = velerov1api.BackupPhaseFailedValidation
|
||||
} else {
|
||||
request.Status.Phase = velerov1api.BackupPhaseInProgress
|
||||
request.Status.StartTimestamp.Time = c.clock.Now()
|
||||
request.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
}
|
||||
|
||||
// update status
|
||||
@@ -289,7 +289,7 @@ func (c *backupController) prepareBackupRequest(backup *velerov1api.Backup) *pkg
|
||||
}
|
||||
|
||||
// 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
|
||||
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)
|
||||
if exists || err != nil {
|
||||
backup.Status.Phase = velerov1api.BackupPhaseFailed
|
||||
backup.Status.CompletionTimestamp.Time = c.clock.Now()
|
||||
backup.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
if err != nil {
|
||||
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.
|
||||
// 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)
|
||||
for _, snap := range backup.VolumeSnapshots {
|
||||
|
||||
@@ -305,7 +305,7 @@ func TestDefaultBackupTTL(t *testing.T) {
|
||||
res := c.prepareBackupRequest(test.backup)
|
||||
assert.NotNil(t, res)
|
||||
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)
|
||||
require.NoError(t, err)
|
||||
now = now.Local()
|
||||
timestamp := metav1.NewTime(now)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -348,9 +349,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseCompleted,
|
||||
Version: 1,
|
||||
StartTimestamp: metav1.NewTime(now),
|
||||
CompletionTimestamp: metav1.NewTime(now),
|
||||
Expiration: metav1.NewTime(now),
|
||||
StartTimestamp: ×tamp,
|
||||
CompletionTimestamp: ×tamp,
|
||||
Expiration: ×tamp,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -376,9 +377,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseCompleted,
|
||||
Version: 1,
|
||||
StartTimestamp: metav1.NewTime(now),
|
||||
CompletionTimestamp: metav1.NewTime(now),
|
||||
Expiration: metav1.NewTime(now),
|
||||
StartTimestamp: ×tamp,
|
||||
CompletionTimestamp: ×tamp,
|
||||
Expiration: ×tamp,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -407,9 +408,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseCompleted,
|
||||
Version: 1,
|
||||
StartTimestamp: metav1.NewTime(now),
|
||||
CompletionTimestamp: metav1.NewTime(now),
|
||||
Expiration: metav1.NewTime(now),
|
||||
StartTimestamp: ×tamp,
|
||||
CompletionTimestamp: ×tamp,
|
||||
Expiration: ×tamp,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -436,9 +437,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseCompleted,
|
||||
Version: 1,
|
||||
Expiration: metav1.NewTime(now.Add(10 * time.Minute)),
|
||||
StartTimestamp: metav1.NewTime(now),
|
||||
CompletionTimestamp: metav1.NewTime(now),
|
||||
Expiration: &metav1.Time{now.Add(10 * time.Minute)},
|
||||
StartTimestamp: ×tamp,
|
||||
CompletionTimestamp: ×tamp,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -465,9 +466,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseCompleted,
|
||||
Version: 1,
|
||||
StartTimestamp: metav1.NewTime(now),
|
||||
CompletionTimestamp: metav1.NewTime(now),
|
||||
Expiration: metav1.NewTime(now),
|
||||
StartTimestamp: ×tamp,
|
||||
CompletionTimestamp: ×tamp,
|
||||
Expiration: ×tamp,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -496,9 +497,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFailed,
|
||||
Version: 1,
|
||||
StartTimestamp: metav1.NewTime(now),
|
||||
CompletionTimestamp: metav1.NewTime(now),
|
||||
Expiration: metav1.NewTime(now),
|
||||
StartTimestamp: ×tamp,
|
||||
CompletionTimestamp: ×tamp,
|
||||
Expiration: ×tamp,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -525,9 +526,9 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
Status: velerov1api.BackupStatus{
|
||||
Phase: velerov1api.BackupPhaseFailed,
|
||||
Version: 1,
|
||||
StartTimestamp: metav1.NewTime(now),
|
||||
CompletionTimestamp: metav1.NewTime(now),
|
||||
Expiration: metav1.NewTime(now),
|
||||
StartTimestamp: ×tamp,
|
||||
CompletionTimestamp: ×tamp,
|
||||
Expiration: ×tamp,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -184,7 +184,7 @@ func (c *downloadRequestController) generatePreSignedURL(downloadRequest *v1.Dow
|
||||
}
|
||||
|
||||
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)
|
||||
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.
|
||||
if tc.downloadRequest != nil && tc.downloadRequest.Status.Phase == v1.DownloadRequestPhaseProcessed {
|
||||
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 {
|
||||
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(
|
||||
logrus.Fields{
|
||||
"backup": key,
|
||||
"expiration": backup.Status.Expiration.Time,
|
||||
"expiration": backup.Status.Expiration,
|
||||
},
|
||||
)
|
||||
|
||||
now := c.clock.Now()
|
||||
|
||||
expiration := backup.Status.Expiration.Time
|
||||
if expiration.IsZero() || expiration.After(now) {
|
||||
if backup.Status.Expiration == nil || backup.Status.Expiration.After(now) {
|
||||
log.Debug("Backup has not expired yet, skipping")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
@@ -181,7 +182,7 @@ func (c *podVolumeBackupController) processBackup(req *velerov1api.PodVolumeBack
|
||||
// update status to InProgress
|
||||
req, err = c.patchPodVolumeBackup(req, func(r *velerov1api.PodVolumeBackup) {
|
||||
r.Status.Phase = velerov1api.PodVolumeBackupPhaseInProgress
|
||||
r.Status.StartTimestamp.Time = c.clock.Now()
|
||||
r.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
})
|
||||
if err != nil {
|
||||
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.Phase = velerov1api.PodVolumeBackupPhaseCompleted
|
||||
r.Status.SnapshotID = snapshotID
|
||||
r.Status.CompletionTimestamp.Time = c.clock.Now()
|
||||
r.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
if emptySnapshot {
|
||||
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) {
|
||||
r.Status.Phase = velerov1api.PodVolumeBackupPhaseFailed
|
||||
r.Status.Message = msg
|
||||
r.Status.CompletionTimestamp.Time = c.clock.Now()
|
||||
r.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
}); err != nil {
|
||||
log.WithError(err).Error("Error setting PodVolumeBackup phase to Failed")
|
||||
return err
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
@@ -265,7 +266,7 @@ func (c *podVolumeRestoreController) processRestore(req *velerov1api.PodVolumeRe
|
||||
// update status to InProgress
|
||||
req, err = c.patchPodVolumeRestore(req, func(r *velerov1api.PodVolumeRestore) {
|
||||
r.Status.Phase = velerov1api.PodVolumeRestorePhaseInProgress
|
||||
r.Status.StartTimestamp.Time = c.clock.Now()
|
||||
r.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
})
|
||||
if err != nil {
|
||||
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
|
||||
if _, err = c.patchPodVolumeRestore(req, func(r *velerov1api.PodVolumeRestore) {
|
||||
r.Status.Phase = velerov1api.PodVolumeRestorePhaseCompleted
|
||||
r.Status.CompletionTimestamp.Time = c.clock.Now()
|
||||
r.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
}); err != nil {
|
||||
log.WithError(err).Error("Error setting PodVolumeRestore completionTimestamp and phase to Completed")
|
||||
return err
|
||||
@@ -408,7 +409,7 @@ func (c *podVolumeRestoreController) failRestore(req *velerov1api.PodVolumeResto
|
||||
if _, err := c.patchPodVolumeRestore(req, func(pvr *velerov1api.PodVolumeRestore) {
|
||||
pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseFailed
|
||||
pvr.Status.Message = msg
|
||||
pvr.Status.CompletionTimestamp.Time = c.clock.Now()
|
||||
pvr.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
}); err != nil {
|
||||
log.WithError(err).Error("Error setting PodVolumeRestore phase to Failed")
|
||||
return err
|
||||
|
||||
@@ -190,7 +190,7 @@ func (c *resticRepositoryController) initializeRepo(req *v1.ResticRepository, lo
|
||||
|
||||
return c.patchResticRepository(req, func(req *v1.ResticRepository) {
|
||||
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) {
|
||||
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 {
|
||||
sort.Slice(backups, func(i, j int) bool {
|
||||
// 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 {
|
||||
|
||||
@@ -781,7 +781,7 @@ func TestMostRecentCompletedBackup(t *testing.T) {
|
||||
},
|
||||
Status: api.BackupStatus{
|
||||
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{
|
||||
Phase: api.BackupPhaseCompleted,
|
||||
StartTimestamp: metav1.Time{Time: now.Add(time.Second)},
|
||||
StartTimestamp: &metav1.Time{Time: now.Add(time.Second)},
|
||||
},
|
||||
}
|
||||
backups = append(backups, expected)
|
||||
|
||||
@@ -266,7 +266,7 @@ func (c *scheduleController) submitBackupIfDue(item *api.Schedule, cronSchedule
|
||||
original := item
|
||||
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 {
|
||||
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) {
|
||||
// get the latest run time (if the schedule hasn't run yet, this will be the zero value which will trigger
|
||||
// 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)
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ func TestProcessSchedule(t *testing.T) {
|
||||
t.Logf("error parsing status.lastBackup: %s\n", err)
|
||||
return false, nil, err
|
||||
}
|
||||
res.Status.LastBackup = metav1.Time{Time: parsed}
|
||||
res.Status.LastBackup = &metav1.Time{Time: parsed}
|
||||
}
|
||||
|
||||
return true, res, nil
|
||||
@@ -318,14 +318,21 @@ func TestGetNextRunTime(t *testing.T) {
|
||||
offsetDuration, err := time.ParseDuration(test.lastRanOffset)
|
||||
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)
|
||||
if err != nil {
|
||||
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())
|
||||
|
||||
@@ -371,7 +378,7 @@ func TestParseCronSchedule(t *testing.T) {
|
||||
assert.Equal(t, time.Date(2017, 8, 11, 9, 0, 0, 0, time.UTC), next)
|
||||
|
||||
// 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
|
||||
now = time.Date(2017, 8, 11, 9, 2, 0, 0, time.UTC)
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
|
||||
@@ -47,7 +48,7 @@ func Process(req *velerov1api.ServerStatusRequest, client velerov1client.ServerS
|
||||
log.Info("Processing new ServerStatusRequest")
|
||||
return errors.WithStack(patch(client, req, func(req *velerov1api.ServerStatusRequest) {
|
||||
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.Plugins = plugins(pluginLister)
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user