Browse code

Format times in inspect command with a template as RFC3339Nano

In 1.6.2 we were decoding inspect API response into interface{}.
time.Time fields were JSON encoded as RFC3339Nano in the response
and when decoded into interface{} they were just strings so the inspect
template treated them as just strings.
From 1.7 we are decoding into types.ContainerJSON and when the template
gets executed it now gets a time.Time and it's formatted as
2015-07-22 05:02:38.091530369 +0000 UTC.
This patch brings back the old behavior by typing time.Time fields
as string so they gets formatted as they were encoded in JSON -- RCF3339Nano

Signed-off-by: Antonio Murdaca <runcom@linux.com>

Antonio Murdaca authored on 2015/07/26 22:00:53
Showing 4 changed files
... ...
@@ -86,7 +86,7 @@ type ImageInspect struct {
86 86
 	Id              string
87 87
 	Parent          string
88 88
 	Comment         string
89
-	Created         time.Time
89
+	Created         string
90 90
 	Container       string
91 91
 	ContainerConfig *runconfig.Config
92 92
 	DockerVersion   string
... ...
@@ -215,14 +215,14 @@ type ContainerState struct {
215 215
 	Pid        int
216 216
 	ExitCode   int
217 217
 	Error      string
218
-	StartedAt  time.Time
219
-	FinishedAt time.Time
218
+	StartedAt  string
219
+	FinishedAt string
220 220
 }
221 221
 
222 222
 // GET "/containers/{name:.*}/json"
223 223
 type ContainerJSONBase struct {
224 224
 	Id              string
225
-	Created         time.Time
225
+	Created         string
226 226
 	Path            string
227 227
 	Args            []string
228 228
 	State           *ContainerState
... ...
@@ -2,6 +2,7 @@ package daemon
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"time"
5 6
 
6 7
 	"github.com/docker/docker/api/types"
7 8
 )
... ...
@@ -91,13 +92,13 @@ func (daemon *Daemon) getInspectData(container *Container) (*types.ContainerJSON
91 91
 		Pid:        container.State.Pid,
92 92
 		ExitCode:   container.State.ExitCode,
93 93
 		Error:      container.State.Error,
94
-		StartedAt:  container.State.StartedAt,
95
-		FinishedAt: container.State.FinishedAt,
94
+		StartedAt:  container.State.StartedAt.Format(time.RFC3339Nano),
95
+		FinishedAt: container.State.FinishedAt.Format(time.RFC3339Nano),
96 96
 	}
97 97
 
98 98
 	contJSONBase := &types.ContainerJSONBase{
99 99
 		Id:              container.ID,
100
-		Created:         container.Created,
100
+		Created:         container.Created.Format(time.RFC3339Nano),
101 101
 		Path:            container.Path,
102 102
 		Args:            container.Args,
103 103
 		State:           containerState,
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"io"
6 6
 	"runtime"
7
+	"time"
7 8
 
8 9
 	"github.com/Sirupsen/logrus"
9 10
 	"github.com/docker/docker/api/types"
... ...
@@ -34,7 +35,7 @@ func (s *TagStore) Lookup(name string) (*types.ImageInspect, error) {
34 34
 		Id:              image.ID,
35 35
 		Parent:          image.Parent,
36 36
 		Comment:         image.Comment,
37
-		Created:         image.Created,
37
+		Created:         image.Created.Format(time.RFC3339Nano),
38 38
 		Container:       image.Container,
39 39
 		ContainerConfig: &image.ContainerConfig,
40 40
 		DockerVersion:   image.DockerVersion,
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"os/exec"
6 6
 	"strconv"
7 7
 	"strings"
8
+	"time"
8 9
 
9 10
 	"github.com/docker/docker/api/types"
10 11
 	"github.com/go-check/check"
... ...
@@ -260,3 +261,28 @@ func (s *DockerSuite) TestInspectBindMountPoint(c *check.C) {
260 260
 		c.Fatalf("Expected rw to be false")
261 261
 	}
262 262
 }
263
+
264
+// #14947
265
+func (s *DockerSuite) TestInspectTimesAsRFC3339Nano(c *check.C) {
266
+	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
267
+	id := strings.TrimSpace(out)
268
+	startedAt, err := inspectField(id, "State.StartedAt")
269
+	c.Assert(err, check.IsNil)
270
+	finishedAt, err := inspectField(id, "State.FinishedAt")
271
+	c.Assert(err, check.IsNil)
272
+	created, err := inspectField(id, "Created")
273
+	c.Assert(err, check.IsNil)
274
+
275
+	_, err = time.Parse(time.RFC3339Nano, startedAt)
276
+	c.Assert(err, check.IsNil)
277
+	_, err = time.Parse(time.RFC3339Nano, finishedAt)
278
+	c.Assert(err, check.IsNil)
279
+	_, err = time.Parse(time.RFC3339Nano, created)
280
+	c.Assert(err, check.IsNil)
281
+
282
+	created, err = inspectField("busybox", "Created")
283
+	c.Assert(err, check.IsNil)
284
+
285
+	_, err = time.Parse(time.RFC3339Nano, created)
286
+	c.Assert(err, check.IsNil)
287
+}