From 0e70d96a6813704498a3ce9cc2786648c84daa3a Mon Sep 17 00:00:00 2001 From: Aaron Lehmann Date: Thu, 1 Dec 2016 14:08:06 -0800 Subject: [PATCH] api: Hide UpdateStatus when it is not present When UpdateStatus was not present, the empty values of the timestamps would be present: "UpdateStatus": { "StartedAt": "0001-01-01T00:00:00Z", "CompletedAt": "0001-01-01T00:00:00Z" } To fix this, make the timestamps pointers, so they can be set to nil when they should not be shown. Also make UpdateStatus itself a pointer, so an empty object does not show up when there is no UpdateStatus. Signed-off-by: Aaron Lehmann --- api/types/swarm/service.go | 12 ++++++------ cli/command/formatter/service.go | 14 ++++++++++---- cli/command/service/inspect_test.go | 6 +++--- daemon/cluster/convert/service.go | 14 +++++++++++--- integration-cli/daemon_swarm.go | 3 +++ 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/api/types/swarm/service.go b/api/types/swarm/service.go index 2cf2642c1f..04f59de862 100644 --- a/api/types/swarm/service.go +++ b/api/types/swarm/service.go @@ -6,10 +6,10 @@ import "time" type Service struct { ID string Meta - Spec ServiceSpec `json:",omitempty"` - PreviousSpec *ServiceSpec `json:",omitempty"` - Endpoint Endpoint `json:",omitempty"` - UpdateStatus UpdateStatus `json:",omitempty"` + Spec ServiceSpec `json:",omitempty"` + PreviousSpec *ServiceSpec `json:",omitempty"` + Endpoint Endpoint `json:",omitempty"` + UpdateStatus *UpdateStatus `json:",omitempty"` } // ServiceSpec represents the spec of a service. @@ -50,8 +50,8 @@ const ( // UpdateStatus reports the status of a service update. type UpdateStatus struct { State UpdateState `json:",omitempty"` - StartedAt time.Time `json:",omitempty"` - CompletedAt time.Time `json:",omitempty"` + StartedAt *time.Time `json:",omitempty"` + CompletedAt *time.Time `json:",omitempty"` Message string `json:",omitempty"` } diff --git a/cli/command/formatter/service.go b/cli/command/formatter/service.go index aaa78386cb..2690029ce4 100644 --- a/cli/command/formatter/service.go +++ b/cli/command/formatter/service.go @@ -28,7 +28,9 @@ Service Mode: {{- if .HasUpdateStatus }} UpdateStatus: State: {{ .UpdateStatusState }} +{{- if .HasUpdateStatusStarted }} Started: {{ .UpdateStatusStarted }} +{{- end }} {{- if .UpdateIsCompleted }} Completed: {{ .UpdateStatusCompleted }} {{- end }} @@ -172,23 +174,27 @@ func (ctx *serviceInspectContext) ModeReplicatedReplicas() *uint64 { } func (ctx *serviceInspectContext) HasUpdateStatus() bool { - return ctx.Service.UpdateStatus.State != "" + return ctx.Service.UpdateStatus != nil && ctx.Service.UpdateStatus.State != "" } func (ctx *serviceInspectContext) UpdateStatusState() swarm.UpdateState { return ctx.Service.UpdateStatus.State } +func (ctx *serviceInspectContext) HasUpdateStatusStarted() bool { + return ctx.Service.UpdateStatus.StartedAt != nil +} + func (ctx *serviceInspectContext) UpdateStatusStarted() string { - return units.HumanDuration(time.Since(ctx.Service.UpdateStatus.StartedAt)) + return units.HumanDuration(time.Since(*ctx.Service.UpdateStatus.StartedAt)) } func (ctx *serviceInspectContext) UpdateIsCompleted() bool { - return ctx.Service.UpdateStatus.State == swarm.UpdateStateCompleted + return ctx.Service.UpdateStatus.State == swarm.UpdateStateCompleted && ctx.Service.UpdateStatus.CompletedAt != nil } func (ctx *serviceInspectContext) UpdateStatusCompleted() string { - return units.HumanDuration(time.Since(ctx.Service.UpdateStatus.CompletedAt)) + return units.HumanDuration(time.Since(*ctx.Service.UpdateStatus.CompletedAt)) } func (ctx *serviceInspectContext) UpdateStatusMessage() string { diff --git a/cli/command/service/inspect_test.go b/cli/command/service/inspect_test.go index 04a65080c7..34c41ee78a 100644 --- a/cli/command/service/inspect_test.go +++ b/cli/command/service/inspect_test.go @@ -74,9 +74,9 @@ func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time) }, }, }, - UpdateStatus: swarm.UpdateStatus{ - StartedAt: now, - CompletedAt: now, + UpdateStatus: &swarm.UpdateStatus{ + StartedAt: &now, + CompletedAt: &now, }, } diff --git a/daemon/cluster/convert/service.go b/daemon/cluster/convert/service.go index aa68e01f44..4292844f23 100644 --- a/daemon/cluster/convert/service.go +++ b/daemon/cluster/convert/service.go @@ -26,8 +26,8 @@ func ServiceFromGRPC(s swarmapi.Service) types.Service { service.UpdatedAt, _ = ptypes.Timestamp(s.Meta.UpdatedAt) // UpdateStatus - service.UpdateStatus = types.UpdateStatus{} if s.UpdateStatus != nil { + service.UpdateStatus = &types.UpdateStatus{} switch s.UpdateStatus.State { case swarmapi.UpdateStatus_UPDATING: service.UpdateStatus.State = types.UpdateStateUpdating @@ -37,8 +37,16 @@ func ServiceFromGRPC(s swarmapi.Service) types.Service { service.UpdateStatus.State = types.UpdateStateCompleted } - service.UpdateStatus.StartedAt, _ = ptypes.Timestamp(s.UpdateStatus.StartedAt) - service.UpdateStatus.CompletedAt, _ = ptypes.Timestamp(s.UpdateStatus.CompletedAt) + startedAt, _ := ptypes.Timestamp(s.UpdateStatus.StartedAt) + if !startedAt.IsZero() { + service.UpdateStatus.StartedAt = &startedAt + } + + completedAt, _ := ptypes.Timestamp(s.UpdateStatus.CompletedAt) + if !completedAt.IsZero() { + service.UpdateStatus.CompletedAt = &completedAt + } + service.UpdateStatus.Message = s.UpdateStatus.Message } diff --git a/integration-cli/daemon_swarm.go b/integration-cli/daemon_swarm.go index cb364f0443..537ba3a467 100644 --- a/integration-cli/daemon_swarm.go +++ b/integration-cli/daemon_swarm.go @@ -155,6 +155,9 @@ func (d *SwarmDaemon) checkServiceRunningTasks(service string) func(*check.C) (i func (d *SwarmDaemon) checkServiceUpdateState(service string) func(*check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { service := d.getService(c, service) + if service.UpdateStatus == nil { + return "", nil + } return service.UpdateStatus.State, nil } }