Browse code

Merge pull request #24648 from mlaventure/fix-kill-test

Fix TestDaemonRestartWithKilledRunningContainer failures on RHEL systems

Arnaud Porterie authored on 2016/07/20 03:24:34
Showing 27 changed files
... ...
@@ -244,7 +244,7 @@ RUN set -x \
244 244
 	&& rm -rf "$GOPATH"
245 245
 
246 246
 # Install containerd
247
-ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
247
+ENV CONTAINERD_COMMIT 0ac3cd1be170d180b2baed755e8f0da547ceb267
248 248
 RUN set -x \
249 249
 	&& export GOPATH="$(mktemp -d)" \
250 250
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -195,7 +195,7 @@ RUN set -x \
195 195
 	&& rm -rf "$GOPATH"
196 196
 
197 197
 # Install containerd
198
-ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
198
+ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
199 199
 RUN set -x \
200 200
 	&& export GOPATH="$(mktemp -d)" \
201 201
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -200,7 +200,7 @@ RUN set -x \
200 200
 	&& rm -rf "$GOPATH"
201 201
 
202 202
 # Install containerd
203
-ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
203
+ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
204 204
 RUN set -x \
205 205
 	&& export GOPATH="$(mktemp -d)" \
206 206
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -85,7 +85,7 @@ RUN set -x \
85 85
 	&& rm -rf "$GOPATH"
86 86
 
87 87
 # Install containerd
88
-ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
88
+ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
89 89
 RUN set -x \
90 90
 	&& export GOPATH="$(mktemp -d)" \
91 91
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -213,7 +213,7 @@ RUN set -x \
213 213
 	&& rm -rf "$GOPATH"
214 214
 
215 215
 # Install containerd
216
-ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
216
+ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
217 217
 RUN set -x \
218 218
 	&& export GOPATH="$(mktemp -d)" \
219 219
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -208,7 +208,7 @@ RUN set -x \
208 208
 	&& rm -rf "$GOPATH"
209 209
 
210 210
 # Install containerd
211
-ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
211
+ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
212 212
 RUN set -x \
213 213
 	&& export GOPATH="$(mktemp -d)" \
214 214
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -68,7 +68,7 @@ RUN set -x \
68 68
 	&& rm -rf "$GOPATH"
69 69
 
70 70
 # Install containerd
71
-ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
71
+ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
72 72
 RUN set -x \
73 73
 	&& export GOPATH="$(mktemp -d)" \
74 74
 	&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \
... ...
@@ -178,7 +178,7 @@ func (daemon *Daemon) restore() error {
178 178
 			rm := c.RestartManager(false)
179 179
 			if c.IsRunning() || c.IsPaused() {
180 180
 				if err := daemon.containerd.Restore(c.ID, libcontainerd.WithRestartManager(rm)); err != nil {
181
-					logrus.Errorf("Failed to restore with containerd: %q", err)
181
+					logrus.Errorf("Failed to restore %s with containerd: %s", c.ID, err)
182 182
 					return
183 183
 				}
184 184
 				if !c.HostConfig.NetworkMode.IsContainer() && c.IsRunning() {
... ...
@@ -14,7 +14,6 @@ import (
14 14
 	"strconv"
15 15
 	"strings"
16 16
 	"syscall"
17
-	"time"
18 17
 
19 18
 	"github.com/Sirupsen/logrus"
20 19
 	"github.com/docker/docker/container"
... ...
@@ -36,6 +35,7 @@ import (
36 36
 	"github.com/docker/libnetwork/netutils"
37 37
 	"github.com/docker/libnetwork/options"
38 38
 	lntypes "github.com/docker/libnetwork/types"
39
+	"github.com/golang/protobuf/ptypes"
39 40
 	"github.com/opencontainers/runc/libcontainer/label"
40 41
 	"github.com/opencontainers/runc/libcontainer/user"
41 42
 	"github.com/opencontainers/specs/specs-go"
... ...
@@ -1119,7 +1119,10 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
1119 1119
 			}
1120 1120
 		}
1121 1121
 	}
1122
-	s.Read = time.Unix(int64(stats.Timestamp), 0)
1122
+	s.Read, err = ptypes.Timestamp(stats.Timestamp)
1123
+	if err != nil {
1124
+		return nil, err
1125
+	}
1123 1126
 	return s, nil
1124 1127
 }
1125 1128
 
... ...
@@ -199,12 +199,12 @@ func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.R
199 199
 	}
200 200
 
201 201
 	if err := execSetPlatformOpt(c, ec, &p); err != nil {
202
-		return nil
202
+		return err
203 203
 	}
204 204
 
205 205
 	attachErr := container.AttachStreams(ctx, ec.StreamConfig, ec.OpenStdin, true, ec.Tty, cStdin, cStdout, cStderr, ec.DetachKeys)
206 206
 
207
-	if err := d.containerd.AddProcess(c.ID, name, p); err != nil {
207
+	if err := d.containerd.AddProcess(ctx, c.ID, name, p); err != nil {
208 208
 		return err
209 209
 	}
210 210
 
... ...
@@ -136,7 +136,7 @@ clone git google.golang.org/cloud dae7e3d993bc3812a2185af60552bb6b847e52a0 https
136 136
 clone git github.com/docker/docker-credential-helpers v0.3.0
137 137
 
138 138
 # containerd
139
-clone git github.com/docker/containerd 1b3a81545ca79456086dc2aa424357be98b962ee
139
+clone git github.com/docker/containerd 0ac3cd1be170d180b2baed755e8f0da547ceb267
140 140
 
141 141
 # cluster
142 142
 clone git github.com/docker/swarmkit 6478bc19cf4bc1d7ba2d6f04ccaacf099508f4a0
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"os/exec"
8 8
 	"path/filepath"
9 9
 	"strings"
10
-	"time"
10
+	"syscall"
11 11
 
12 12
 	"github.com/docker/docker/pkg/integration/checker"
13 13
 	"github.com/go-check/check"
... ...
@@ -129,7 +129,11 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
129 129
 		c.Fatalf("Could not kill daemon: %v", err)
130 130
 	}
131 131
 
132
-	time.Sleep(5 * time.Second)
132
+	for {
133
+		if err := syscall.Kill(s.d.cmd.Process.Pid, 0); err == syscall.ESRCH {
134
+			break
135
+		}
136
+	}
133 137
 
134 138
 	cmd := exec.Command("pgrep", "-f", "plugin-no-remove")
135 139
 	if out, ec, err := runCommandWithOutput(cmd); ec != 1 {
... ...
@@ -28,7 +28,7 @@ type client struct {
28 28
 	liveRestore   bool
29 29
 }
30 30
 
31
-func (clnt *client) AddProcess(containerID, processFriendlyName string, specp Process) error {
31
+func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendlyName string, specp Process) error {
32 32
 	clnt.lock(containerID)
33 33
 	defer clnt.unlock(containerID)
34 34
 	container, err := clnt.getContainer(containerID)
... ...
@@ -89,7 +89,7 @@ func (clnt *client) AddProcess(containerID, processFriendlyName string, specp Pr
89 89
 		return err
90 90
 	}
91 91
 
92
-	if _, err := clnt.remote.apiClient.AddProcess(context.Background(), r); err != nil {
92
+	if _, err := clnt.remote.apiClient.AddProcess(ctx, r); err != nil {
93 93
 		p.closeFifos(iopipe)
94 94
 		return err
95 95
 	}
... ...
@@ -281,16 +281,10 @@ func (clnt *client) cleanupOldRootfs(containerID string) {
281 281
 	}
282 282
 }
283 283
 
284
-func (clnt *client) setExited(containerID string) error {
284
+func (clnt *client) setExited(containerID string, exitCode uint32) error {
285 285
 	clnt.lock(containerID)
286 286
 	defer clnt.unlock(containerID)
287 287
 
288
-	var exitCode uint32
289
-	if event, ok := clnt.remote.pastEvents[containerID]; ok {
290
-		exitCode = event.Status
291
-		delete(clnt.remote.pastEvents, containerID)
292
-	}
293
-
294 288
 	err := clnt.backend.StateChanged(containerID, StateInfo{
295 289
 		CommonStateInfo: CommonStateInfo{
296 290
 			State:    StateExit,
... ...
@@ -393,7 +387,7 @@ func (clnt *client) getOrCreateExitNotifier(containerID string) *exitNotifier {
393 393
 	return w
394 394
 }
395 395
 
396
-func (clnt *client) restore(cont *containerd.Container, options ...CreateOption) (err error) {
396
+func (clnt *client) restore(cont *containerd.Container, lastEvent *containerd.Event, options ...CreateOption) (err error) {
397 397
 	clnt.lock(cont.Id)
398 398
 	defer clnt.unlock(cont.Id)
399 399
 
... ...
@@ -441,66 +435,132 @@ func (clnt *client) restore(cont *containerd.Container, options ...CreateOption)
441 441
 		return err
442 442
 	}
443 443
 
444
-	if event, ok := clnt.remote.pastEvents[containerID]; ok {
444
+	if lastEvent != nil {
445 445
 		// This should only be a pause or resume event
446
-		if event.Type == StatePause || event.Type == StateResume {
446
+		if lastEvent.Type == StatePause || lastEvent.Type == StateResume {
447 447
 			return clnt.backend.StateChanged(containerID, StateInfo{
448 448
 				CommonStateInfo: CommonStateInfo{
449
-					State: event.Type,
449
+					State: lastEvent.Type,
450 450
 					Pid:   container.systemPid,
451 451
 				}})
452 452
 		}
453 453
 
454
-		logrus.Warnf("unexpected backlog event: %#v", event)
454
+		logrus.Warnf("unexpected backlog event: %#v", lastEvent)
455 455
 	}
456 456
 
457 457
 	return nil
458 458
 }
459 459
 
460
-func (clnt *client) Restore(containerID string, options ...CreateOption) error {
461
-	if clnt.liveRestore {
462
-		cont, err := clnt.getContainerdContainer(containerID)
463
-		if err == nil && cont.Status != "stopped" {
464
-			if err := clnt.restore(cont, options...); err != nil {
465
-				logrus.Errorf("error restoring %s: %v", containerID, err)
460
+func (clnt *client) getContainerLastEvent(containerID string) (*containerd.Event, error) {
461
+	er := &containerd.EventsRequest{
462
+		Timestamp:  clnt.remote.restoreFromTimestamp,
463
+		StoredOnly: true,
464
+		Id:         containerID,
465
+	}
466
+	events, err := clnt.remote.apiClient.Events(context.Background(), er)
467
+	if err != nil {
468
+		logrus.Errorf("libcontainerd: failed to get container events stream for %s: %q", er.Id, err)
469
+		return nil, err
470
+	}
471
+
472
+	var ev *containerd.Event
473
+	for {
474
+		e, err := events.Recv()
475
+		if err != nil {
476
+			if err.Error() == "EOF" {
477
+				break
466 478
 			}
467
-			return nil
479
+			logrus.Errorf("libcontainerd: failed to get container event for %s: %q", containerID, err)
480
+			return nil, err
481
+		}
482
+
483
+		logrus.Debugf("libcontainerd: received past event %#v", e)
484
+
485
+		switch e.Type {
486
+		case StateExit, StatePause, StateResume:
487
+			ev = e
468 488
 		}
469
-		return clnt.setExited(containerID)
470 489
 	}
471 490
 
491
+	return ev, nil
492
+}
493
+
494
+func (clnt *client) Restore(containerID string, options ...CreateOption) error {
495
+	// Synchronize with live events
496
+	clnt.remote.Lock()
497
+	defer clnt.remote.Unlock()
498
+	// Check that containerd still knows this container.
499
+	//
500
+	// In the unlikely event that Restore for this container process
501
+	// the its past event before the main loop, the event will be
502
+	// processed twice. However, this is not an issue as all those
503
+	// events will do is change the state of the container to be
504
+	// exactly the same.
472 505
 	cont, err := clnt.getContainerdContainer(containerID)
473
-	if err == nil && cont.Status != "stopped" {
474
-		w := clnt.getOrCreateExitNotifier(containerID)
475
-		clnt.lock(cont.Id)
476
-		container := clnt.newContainer(cont.BundlePath)
477
-		container.systemPid = systemPid(cont)
478
-		clnt.appendContainer(container)
479
-		clnt.unlock(cont.Id)
480
-
481
-		container.discardFifos()
482
-
483
-		if err := clnt.Signal(containerID, int(syscall.SIGTERM)); err != nil {
484
-			logrus.Errorf("error sending sigterm to %v: %v", containerID, err)
506
+	// Get its last event
507
+	ev, eerr := clnt.getContainerLastEvent(containerID)
508
+	if err != nil || cont.Status == "Stopped" {
509
+		if err != nil && !strings.Contains(err.Error(), "container not found") {
510
+			// Legitimate error
511
+			return err
512
+		}
513
+
514
+		// If ev is nil, then we already consumed all the event of the
515
+		// container, included the "exit" one.
516
+		// Thus we return to avoid overriding the Exit Code.
517
+		if ev == nil {
518
+			logrus.Warnf("libcontainerd: restore was called on a fully synced container (%s)", containerID)
519
+			return nil
520
+		}
521
+
522
+		// get the exit status for this container
523
+		ec := uint32(0)
524
+		if eerr == nil && ev.Type == StateExit {
525
+			ec = ev.Status
526
+		}
527
+		clnt.setExited(containerID, ec)
528
+
529
+		return nil
530
+	}
531
+
532
+	// container is still alive
533
+	if clnt.liveRestore {
534
+		if err := clnt.restore(cont, ev, options...); err != nil {
535
+			logrus.Errorf("error restoring %s: %v", containerID, err)
536
+		}
537
+		return nil
538
+	}
539
+
540
+	// Kill the container if liveRestore == false
541
+	w := clnt.getOrCreateExitNotifier(containerID)
542
+	clnt.lock(cont.Id)
543
+	container := clnt.newContainer(cont.BundlePath)
544
+	container.systemPid = systemPid(cont)
545
+	clnt.appendContainer(container)
546
+	clnt.unlock(cont.Id)
547
+
548
+	container.discardFifos()
549
+
550
+	if err := clnt.Signal(containerID, int(syscall.SIGTERM)); err != nil {
551
+		logrus.Errorf("error sending sigterm to %v: %v", containerID, err)
552
+	}
553
+	select {
554
+	case <-time.After(10 * time.Second):
555
+		if err := clnt.Signal(containerID, int(syscall.SIGKILL)); err != nil {
556
+			logrus.Errorf("error sending sigkill to %v: %v", containerID, err)
485 557
 		}
486 558
 		select {
487
-		case <-time.After(10 * time.Second):
488
-			if err := clnt.Signal(containerID, int(syscall.SIGKILL)); err != nil {
489
-				logrus.Errorf("error sending sigkill to %v: %v", containerID, err)
490
-			}
491
-			select {
492
-			case <-time.After(2 * time.Second):
493
-			case <-w.wait():
494
-				return nil
495
-			}
559
+		case <-time.After(2 * time.Second):
496 560
 		case <-w.wait():
497 561
 			return nil
498 562
 		}
563
+	case <-w.wait():
564
+		return nil
499 565
 	}
500 566
 
501 567
 	clnt.deleteContainer(containerID)
502 568
 
503
-	return clnt.setExited(containerID)
569
+	return clnt.setExited(containerID, uint32(255))
504 570
 }
505 571
 
506 572
 type exitNotifier struct {
... ...
@@ -1,12 +1,14 @@
1 1
 package libcontainerd
2 2
 
3
+import "golang.org/x/net/context"
4
+
3 5
 type client struct {
4 6
 	clientCommon
5 7
 
6 8
 	// Platform specific properties below here.
7 9
 }
8 10
 
9
-func (clnt *client) AddProcess(containerID, processFriendlyName string, specp Process) error {
11
+func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendlyName string, specp Process) error {
10 12
 	return nil
11 13
 }
12 14
 
... ...
@@ -8,6 +8,8 @@ import (
8 8
 	"strings"
9 9
 	"syscall"
10 10
 
11
+	"golang.org/x/net/context"
12
+
11 13
 	"github.com/Microsoft/hcsshim"
12 14
 	"github.com/Sirupsen/logrus"
13 15
 )
... ...
@@ -176,8 +178,7 @@ func (clnt *client) Create(containerID string, spec Spec, options ...CreateOptio
176 176
 
177 177
 // AddProcess is the handler for adding a process to an already running
178 178
 // container. It's called through docker exec.
179
-func (clnt *client) AddProcess(containerID, processFriendlyName string, procToAdd Process) error {
180
-
179
+func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendlyName string, procToAdd Process) error {
181 180
 	clnt.lock(containerID)
182 181
 	defer clnt.unlock(containerID)
183 182
 	container, err := clnt.getContainer(containerID)
... ...
@@ -20,6 +20,8 @@ import (
20 20
 	"github.com/docker/docker/pkg/locker"
21 21
 	sysinfo "github.com/docker/docker/pkg/system"
22 22
 	"github.com/docker/docker/utils"
23
+	"github.com/golang/protobuf/ptypes"
24
+	"github.com/golang/protobuf/ptypes/timestamp"
23 25
 	"golang.org/x/net/context"
24 26
 	"google.golang.org/grpc"
25 27
 	"google.golang.org/grpc/grpclog"
... ...
@@ -39,22 +41,22 @@ const (
39 39
 
40 40
 type remote struct {
41 41
 	sync.RWMutex
42
-	apiClient     containerd.APIClient
43
-	daemonPid     int
44
-	stateDir      string
45
-	rpcAddr       string
46
-	startDaemon   bool
47
-	closeManually bool
48
-	debugLog      bool
49
-	rpcConn       *grpc.ClientConn
50
-	clients       []*client
51
-	eventTsPath   string
52
-	pastEvents    map[string]*containerd.Event
53
-	runtime       string
54
-	runtimeArgs   []string
55
-	daemonWaitCh  chan struct{}
56
-	liveRestore   bool
57
-	oomScore      int
42
+	apiClient            containerd.APIClient
43
+	daemonPid            int
44
+	stateDir             string
45
+	rpcAddr              string
46
+	startDaemon          bool
47
+	closeManually        bool
48
+	debugLog             bool
49
+	rpcConn              *grpc.ClientConn
50
+	clients              []*client
51
+	eventTsPath          string
52
+	runtime              string
53
+	runtimeArgs          []string
54
+	daemonWaitCh         chan struct{}
55
+	liveRestore          bool
56
+	oomScore             int
57
+	restoreFromTimestamp *timestamp.Timestamp
58 58
 }
59 59
 
60 60
 // New creates a fresh instance of libcontainerd remote.
... ...
@@ -68,7 +70,6 @@ func New(stateDir string, options ...RemoteOption) (_ Remote, err error) {
68 68
 		stateDir:    stateDir,
69 69
 		daemonPid:   -1,
70 70
 		eventTsPath: filepath.Join(stateDir, eventTimestampFilename),
71
-		pastEvents:  make(map[string]*containerd.Event),
72 71
 	}
73 72
 	for _, option := range options {
74 73
 		if err := option.Apply(r); err != nil {
... ...
@@ -105,6 +106,14 @@ func New(stateDir string, options ...RemoteOption) (_ Remote, err error) {
105 105
 	r.rpcConn = conn
106 106
 	r.apiClient = containerd.NewAPIClient(conn)
107 107
 
108
+	// Get the timestamp to restore from
109
+	t := r.getLastEventTimestamp()
110
+	tsp, err := ptypes.TimestampProto(t)
111
+	if err != nil {
112
+		logrus.Errorf("libcontainerd: failed to convert timestamp: %q", err)
113
+	}
114
+	r.restoreFromTimestamp = tsp
115
+
108 116
 	go r.handleConnectionChange()
109 117
 
110 118
 	if err := r.startEventsMonitor(); err != nil {
... ...
@@ -225,40 +234,44 @@ func (r *remote) updateEventTimestamp(t time.Time) {
225 225
 		f.Truncate(0)
226 226
 		return
227 227
 	}
228
-
229 228
 }
230 229
 
231
-func (r *remote) getLastEventTimestamp() int64 {
230
+func (r *remote) getLastEventTimestamp() time.Time {
232 231
 	t := time.Now()
233 232
 
234 233
 	fi, err := os.Stat(r.eventTsPath)
235 234
 	if os.IsNotExist(err) || fi.Size() == 0 {
236
-		return t.Unix()
235
+		return t
237 236
 	}
238 237
 
239 238
 	f, err := os.Open(r.eventTsPath)
240 239
 	defer f.Close()
241 240
 	if err != nil {
242 241
 		logrus.Warnf("libcontainerd: Unable to access last event ts: %v", err)
243
-		return t.Unix()
242
+		return t
244 243
 	}
245 244
 
246 245
 	b := make([]byte, fi.Size())
247 246
 	n, err := f.Read(b)
248 247
 	if err != nil || n != len(b) {
249 248
 		logrus.Warnf("libcontainerd: Unable to read last event ts: %v", err)
250
-		return t.Unix()
249
+		return t
251 250
 	}
252 251
 
253 252
 	t.UnmarshalText(b)
254 253
 
255
-	return t.Unix()
254
+	return t
256 255
 }
257 256
 
258 257
 func (r *remote) startEventsMonitor() error {
259 258
 	// First, get past events
259
+	t := r.getLastEventTimestamp()
260
+	tsp, err := ptypes.TimestampProto(t)
261
+	if err != nil {
262
+		logrus.Errorf("libcontainerd: failed to convert timestamp: %q", err)
263
+	}
260 264
 	er := &containerd.EventsRequest{
261
-		Timestamp: uint64(r.getLastEventTimestamp()),
265
+		Timestamp: tsp,
262 266
 	}
263 267
 	events, err := r.apiClient.Events(context.Background(), er)
264 268
 	if err != nil {
... ...
@@ -269,7 +282,6 @@ func (r *remote) startEventsMonitor() error {
269 269
 }
270 270
 
271 271
 func (r *remote) handleEventStream(events containerd.API_EventsClient) {
272
-	live := false
273 272
 	for {
274 273
 		e, err := events.Recv()
275 274
 		if err != nil {
... ...
@@ -283,45 +295,34 @@ func (r *remote) handleEventStream(events containerd.API_EventsClient) {
283 283
 			return
284 284
 		}
285 285
 
286
-		if live == false {
287
-			logrus.Debugf("received past containerd event: %#v", e)
288
-
289
-			// Pause/Resume events should never happens after exit one
290
-			switch e.Type {
291
-			case StateExit:
292
-				r.pastEvents[e.Id] = e
293
-			case StatePause:
294
-				r.pastEvents[e.Id] = e
295
-			case StateResume:
296
-				r.pastEvents[e.Id] = e
297
-			case stateLive:
298
-				live = true
299
-				r.updateEventTimestamp(time.Unix(int64(e.Timestamp), 0))
300
-			}
301
-		} else {
302
-			logrus.Debugf("received containerd event: %#v", e)
303
-
304
-			var container *container
305
-			var c *client
306
-			r.RLock()
307
-			for _, c = range r.clients {
308
-				container, err = c.getContainer(e.Id)
309
-				if err == nil {
310
-					break
311
-				}
312
-			}
313
-			r.RUnlock()
314
-			if container == nil {
315
-				logrus.Errorf("no state for container: %q", err)
316
-				continue
317
-			}
286
+		logrus.Debugf("received containerd event: %#v", e)
318 287
 
319
-			if err := container.handleEvent(e); err != nil {
320
-				logrus.Errorf("error processing state change for %s: %v", e.Id, err)
288
+		var container *container
289
+		var c *client
290
+		r.RLock()
291
+		for _, c = range r.clients {
292
+			container, err = c.getContainer(e.Id)
293
+			if err == nil {
294
+				break
321 295
 			}
296
+		}
297
+		r.RUnlock()
298
+		if container == nil {
299
+			logrus.Warnf("libcontainerd: unknown container %s", e.Id)
300
+			continue
301
+		}
322 302
 
323
-			r.updateEventTimestamp(time.Unix(int64(e.Timestamp), 0))
303
+		if err := container.handleEvent(e); err != nil {
304
+			logrus.Errorf("libcontainerd: error processing state change for %s: %v", e.Id, err)
324 305
 		}
306
+
307
+		tsp, err := ptypes.Timestamp(e.Timestamp)
308
+		if err != nil {
309
+			logrus.Errorf("libcontainerd: failed to convert event timestamp: %q", err)
310
+			continue
311
+		}
312
+
313
+		r.updateEventTimestamp(tsp)
325 314
 	}
326 315
 }
327 316
 
... ...
@@ -1,6 +1,10 @@
1 1
 package libcontainerd
2 2
 
3
-import "io"
3
+import (
4
+	"io"
5
+
6
+	"golang.org/x/net/context"
7
+)
4 8
 
5 9
 // State constants used in state change reporting.
6 10
 const (
... ...
@@ -35,7 +39,7 @@ type Client interface {
35 35
 	Create(containerID string, spec Spec, options ...CreateOption) error
36 36
 	Signal(containerID string, sig int) error
37 37
 	SignalProcess(containerID string, processFriendlyName string, sig int) error
38
-	AddProcess(containerID, processFriendlyName string, process Process) error
38
+	AddProcess(ctx context.Context, containerID, processFriendlyName string, process Process) error
39 39
 	Resize(containerID, processFriendlyName string, width, height int) error
40 40
 	Pause(containerID string) error
41 41
 	Resume(containerID string) error
... ...
@@ -58,6 +58,7 @@ package types
58 58
 import proto "github.com/golang/protobuf/proto"
59 59
 import fmt "fmt"
60 60
 import math "math"
61
+import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
61 62
 
62 63
 import (
63 64
 	context "golang.org/x/net/context"
... ...
@@ -480,7 +481,10 @@ func (*UpdateContainerResponse) ProtoMessage()               {}
480 480
 func (*UpdateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} }
481 481
 
482 482
 type EventsRequest struct {
483
-	Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"`
483
+	// Tag 1 is deprecated (old uint64 timestamp)
484
+	Timestamp  *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=timestamp" json:"timestamp,omitempty"`
485
+	StoredOnly bool                       `protobuf:"varint,3,opt,name=storedOnly" json:"storedOnly,omitempty"`
486
+	Id         string                     `protobuf:"bytes,4,opt,name=id" json:"id,omitempty"`
484 487
 }
485 488
 
486 489
 func (m *EventsRequest) Reset()                    { *m = EventsRequest{} }
... ...
@@ -488,12 +492,20 @@ func (m *EventsRequest) String() string            { return proto.CompactTextStr
488 488
 func (*EventsRequest) ProtoMessage()               {}
489 489
 func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} }
490 490
 
491
+func (m *EventsRequest) GetTimestamp() *google_protobuf.Timestamp {
492
+	if m != nil {
493
+		return m.Timestamp
494
+	}
495
+	return nil
496
+}
497
+
491 498
 type Event struct {
492
-	Type      string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
493
-	Id        string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
494
-	Status    uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"`
495
-	Pid       string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"`
496
-	Timestamp uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"`
499
+	Type   string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
500
+	Id     string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
501
+	Status uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"`
502
+	Pid    string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"`
503
+	// Tag 5 is deprecated (old uint64 timestamp)
504
+	Timestamp *google_protobuf.Timestamp `protobuf:"bytes,6,opt,name=timestamp" json:"timestamp,omitempty"`
497 505
 }
498 506
 
499 507
 func (m *Event) Reset()                    { *m = Event{} }
... ...
@@ -501,6 +513,13 @@ func (m *Event) String() string            { return proto.CompactTextString(m) }
501 501
 func (*Event) ProtoMessage()               {}
502 502
 func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} }
503 503
 
504
+func (m *Event) GetTimestamp() *google_protobuf.Timestamp {
505
+	if m != nil {
506
+		return m.Timestamp
507
+	}
508
+	return nil
509
+}
510
+
504 511
 type NetworkStats struct {
505 512
 	Name       string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
506 513
 	RxBytes    uint64 `protobuf:"varint,2,opt,name=rx_bytes,json=rxBytes" json:"rx_bytes,omitempty"`
... ...
@@ -776,7 +795,8 @@ func (m *CgroupStats) GetPidsStats() *PidsStats {
776 776
 type StatsResponse struct {
777 777
 	NetworkStats []*NetworkStats `protobuf:"bytes,1,rep,name=network_stats,json=networkStats" json:"network_stats,omitempty"`
778 778
 	CgroupStats  *CgroupStats    `protobuf:"bytes,2,opt,name=cgroup_stats,json=cgroupStats" json:"cgroup_stats,omitempty"`
779
-	Timestamp    uint64          `protobuf:"varint,3,opt,name=timestamp" json:"timestamp,omitempty"`
779
+	// Tag 3 is deprecated (old uint64 timestamp)
780
+	Timestamp *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=timestamp" json:"timestamp,omitempty"`
780 781
 }
781 782
 
782 783
 func (m *StatsResponse) Reset()                    { *m = StatsResponse{} }
... ...
@@ -798,6 +818,13 @@ func (m *StatsResponse) GetCgroupStats() *CgroupStats {
798 798
 	return nil
799 799
 }
800 800
 
801
+func (m *StatsResponse) GetTimestamp() *google_protobuf.Timestamp {
802
+	if m != nil {
803
+		return m.Timestamp
804
+	}
805
+	return nil
806
+}
807
+
801 808
 type StatsRequest struct {
802 809
 	Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
803 810
 }
... ...
@@ -1316,153 +1343,156 @@ var _API_serviceDesc = grpc.ServiceDesc{
1316 1316
 }
1317 1317
 
1318 1318
 var fileDescriptor0 = []byte{
1319
-	// 2361 bytes of a gzipped FileDescriptorProto
1319
+	// 2414 bytes of a gzipped FileDescriptorProto
1320 1320
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x59, 0xcd, 0x73, 0x1b, 0x4b,
1321
-	0x11, 0x8f, 0xbe, 0xad, 0xd6, 0x87, 0xed, 0x8d, 0x3f, 0x14, 0xbd, 0x97, 0xbc, 0xb0, 0xf5, 0x80,
1322
-	0x00, 0x0f, 0x13, 0x94, 0xf7, 0x8a, 0x14, 0x54, 0x51, 0x95, 0xd8, 0xe1, 0x11, 0x5e, 0x1c, 0x94,
1323
-	0xb5, 0xcd, 0x3b, 0xaa, 0xd6, 0xab, 0x89, 0xb4, 0x58, 0xda, 0xdd, 0xec, 0x8e, 0x6c, 0xf9, 0xc2,
1324
-	0x81, 0x03, 0xdc, 0x38, 0x53, 0x05, 0xc5, 0x85, 0x1b, 0x77, 0x0e, 0xfc, 0x05, 0x54, 0xf1, 0x87,
1325
-	0x70, 0xe3, 0xce, 0x91, 0x9e, 0x9e, 0xd9, 0xd9, 0x59, 0x7d, 0xd8, 0xe1, 0x40, 0x71, 0x79, 0x17,
1326
-	0xd5, 0xf4, 0x6f, 0x7a, 0xba, 0x7b, 0xba, 0x7b, 0x7a, 0x7a, 0x47, 0x50, 0x77, 0x23, 0xff, 0x20,
1327
-	0x8a, 0x43, 0x1e, 0x5a, 0x15, 0x7e, 0x1d, 0xb1, 0xc4, 0xbe, 0x07, 0xfb, 0x9f, 0x33, 0x7e, 0xc2,
1328
-	0xe2, 0x4b, 0x16, 0xff, 0x82, 0xc5, 0x89, 0x1f, 0x06, 0x0e, 0x7b, 0x37, 0x63, 0x09, 0xb7, 0xe7,
1329
-	0xd0, 0x59, 0x9e, 0x4a, 0xa2, 0x30, 0x48, 0x98, 0xb5, 0x03, 0x95, 0xa9, 0xfb, 0xcb, 0x30, 0xee,
1330
-	0x14, 0x1e, 0x16, 0x1e, 0xb5, 0x1c, 0x49, 0x10, 0xea, 0x07, 0x88, 0x16, 0x15, 0x2a, 0x08, 0x81,
1331
-	0x46, 0x2e, 0xf7, 0xc6, 0x9d, 0x92, 0x44, 0x89, 0xb0, 0xba, 0xb0, 0x11, 0xb3, 0x4b, 0x5f, 0x48,
1332
-	0xed, 0x94, 0x71, 0xa2, 0xee, 0x68, 0xda, 0xfe, 0x4d, 0x01, 0x76, 0xce, 0xa2, 0xa1, 0xcb, 0x59,
1333
-	0x3f, 0x0e, 0x3d, 0x96, 0x24, 0xca, 0x24, 0xab, 0x0d, 0x45, 0x7f, 0x48, 0x3a, 0xeb, 0x0e, 0x8e,
1334
-	0xac, 0x2d, 0x28, 0x45, 0x08, 0x14, 0x09, 0x10, 0x43, 0xeb, 0x01, 0x80, 0x37, 0x09, 0x13, 0x76,
1335
-	0xc2, 0x87, 0x7e, 0x40, 0x1a, 0x37, 0x1c, 0x03, 0x11, 0xc6, 0x5c, 0xf9, 0x43, 0x3e, 0x26, 0x9d,
1336
-	0x68, 0x0c, 0x11, 0xd6, 0x1e, 0x54, 0xc7, 0xcc, 0x1f, 0x8d, 0x79, 0xa7, 0x42, 0xb0, 0xa2, 0xec,
1337
-	0x7d, 0xd8, 0x5d, 0xb0, 0x43, 0xee, 0xdf, 0xfe, 0x47, 0x11, 0xf6, 0x0e, 0x63, 0x86, 0x33, 0x87,
1338
-	0x61, 0xc0, 0x5d, 0x3f, 0x60, 0xf1, 0x3a, 0x1b, 0xd1, 0xa2, 0xf3, 0x59, 0x30, 0x9c, 0xb0, 0xbe,
1339
-	0x8b, 0x6a, 0xa5, 0xa9, 0x06, 0x42, 0x16, 0x8f, 0x99, 0x77, 0x11, 0x85, 0x7e, 0xc0, 0xc9, 0x62,
1340
-	0x9c, 0xcf, 0x10, 0x61, 0x71, 0x42, 0x9b, 0x91, 0x5e, 0x92, 0x84, 0xb0, 0x18, 0x07, 0xe1, 0x4c,
1341
-	0x5a, 0x5c, 0x77, 0x14, 0xa5, 0x70, 0x16, 0xc7, 0x9d, 0xaa, 0xc6, 0x91, 0x12, 0xf8, 0xc4, 0x3d,
1342
-	0x67, 0x93, 0xa4, 0x53, 0x7b, 0x58, 0x12, 0xb8, 0xa4, 0xac, 0x87, 0xd0, 0x08, 0xc2, 0xbe, 0x7f,
1343
-	0x19, 0x72, 0x27, 0x0c, 0x79, 0x67, 0x83, 0x1c, 0x66, 0x42, 0x56, 0x07, 0x6a, 0xf1, 0x2c, 0xe0,
1344
-	0xfe, 0x94, 0x75, 0xea, 0x24, 0x32, 0x25, 0xc5, 0x5a, 0x35, 0x7c, 0x16, 0x8f, 0x92, 0x0e, 0x90,
1345
-	0x60, 0x13, 0xb2, 0x3e, 0x86, 0x56, 0xb6, 0x93, 0x23, 0x3f, 0xee, 0x34, 0x48, 0x42, 0x1e, 0xb4,
1346
-	0x5f, 0xc2, 0xfe, 0x92, 0x2f, 0x55, 0x9e, 0x1d, 0x40, 0xdd, 0x4b, 0x41, 0xf2, 0x69, 0xa3, 0xb7,
1347
-	0x75, 0x40, 0x99, 0x7b, 0x90, 0x31, 0x67, 0x2c, 0x28, 0xaa, 0x75, 0xe2, 0x8f, 0x02, 0x77, 0xf2,
1348
-	0xfe, 0x19, 0x23, 0x3c, 0x46, 0x4b, 0x54, 0x7e, 0x2a, 0xca, 0xde, 0x82, 0x76, 0x2a, 0x4a, 0x05,
1349
-	0xfd, 0xaf, 0x25, 0xd8, 0x7e, 0x36, 0x1c, 0xde, 0x92, 0x93, 0x98, 0xd8, 0x9c, 0xc5, 0x98, 0xfa,
1350
-	0x28, 0xb1, 0x48, 0xee, 0xd4, 0xb4, 0xf5, 0x11, 0x94, 0x67, 0x09, 0xee, 0xa4, 0x44, 0x3b, 0x69,
1351
-	0xa8, 0x9d, 0x9c, 0x21, 0xe4, 0xd0, 0x84, 0x65, 0x41, 0xd9, 0x15, 0xbe, 0x2c, 0x93, 0x2f, 0x69,
1352
-	0x2c, 0x4c, 0x66, 0xc1, 0x25, 0xc6, 0x59, 0x40, 0x62, 0x28, 0x10, 0xef, 0x6a, 0xa8, 0x22, 0x2c,
1353
-	0x86, 0xe9, 0xb6, 0x6a, 0xd9, 0xb6, 0x74, 0xda, 0x6c, 0xac, 0x4e, 0x9b, 0xfa, 0x9a, 0xb4, 0x81,
1354
-	0x5c, 0xda, 0xd8, 0xd0, 0xf4, 0xdc, 0xc8, 0x3d, 0xf7, 0x27, 0x3e, 0xf7, 0x59, 0x82, 0xf1, 0x13,
1355
-	0x46, 0xe4, 0x30, 0xeb, 0x11, 0x6c, 0xba, 0x51, 0xe4, 0xc6, 0xd3, 0x30, 0x46, 0xd7, 0xbc, 0xf5,
1356
-	0x27, 0xac, 0xd3, 0x24, 0x21, 0x8b, 0xb0, 0x90, 0x96, 0xb0, 0x89, 0x1f, 0xcc, 0xe6, 0xaf, 0x44,
1357
-	0xf6, 0x75, 0x5a, 0xc4, 0x96, 0xc3, 0x84, 0xb4, 0x20, 0x7c, 0xcd, 0xae, 0xfa, 0xb1, 0x7f, 0x89,
1358
-	0x6b, 0x46, 0xa8, 0xb4, 0x4d, 0x5e, 0x5c, 0x84, 0xad, 0x6f, 0x62, 0x62, 0x4e, 0xfc, 0xa9, 0xcf,
1359
-	0x93, 0xce, 0x26, 0x9a, 0xd5, 0xe8, 0xb5, 0x94, 0x3f, 0x1d, 0x42, 0x9d, 0x74, 0xd6, 0x3e, 0x82,
1360
-	0xaa, 0x84, 0x84, 0x7b, 0x05, 0x8b, 0x8a, 0x16, 0x8d, 0x05, 0x96, 0x84, 0x6f, 0x39, 0xc5, 0xaa,
1361
-	0xec, 0xd0, 0x58, 0x60, 0x63, 0x37, 0x1e, 0x52, 0x9c, 0x10, 0x13, 0x63, 0xdb, 0x81, 0xb2, 0x08,
1362
-	0x94, 0x70, 0xf5, 0x4c, 0x05, 0xbc, 0xe5, 0x88, 0xa1, 0x40, 0x46, 0x2a, 0xa7, 0x10, 0xc1, 0xa1,
1363
-	0xf5, 0x0d, 0x68, 0xbb, 0xc3, 0x21, 0xba, 0x27, 0xc4, 0xa8, 0x7f, 0xee, 0x0f, 0x13, 0x94, 0x54,
1364
-	0xc2, 0xc9, 0x05, 0xd4, 0xde, 0x01, 0xcb, 0x4c, 0x28, 0x95, 0x67, 0xbf, 0x2e, 0xe8, 0x03, 0xa1,
1365
-	0xcf, 0xc9, 0xba, 0x6c, 0xfb, 0x7e, 0xae, 0x7a, 0x14, 0x29, 0xaf, 0xb6, 0xd3, 0x13, 0x92, 0xad,
1366
-	0x36, 0x0b, 0xca, 0xd2, 0xa1, 0x2c, 0xad, 0x3a, 0x94, 0x5d, 0xe8, 0x2c, 0xdb, 0xa0, 0x0c, 0xf4,
1367
-	0x60, 0xff, 0x88, 0x4d, 0xd8, 0xfb, 0xd8, 0x87, 0x9e, 0x0c, 0x5c, 0x2c, 0x1d, 0xf2, 0xc0, 0xd1,
1368
-	0xf8, 0xfd, 0x0d, 0x58, 0x56, 0xa2, 0x0c, 0x38, 0x86, 0xdd, 0x57, 0x7e, 0xc2, 0x6f, 0x57, 0xbf,
1369
-	0xa4, 0xaa, 0xb8, 0x4a, 0xd5, 0xef, 0x0b, 0x00, 0x99, 0x2c, 0x6d, 0x73, 0xc1, 0xb0, 0x19, 0x31,
1370
-	0x36, 0xf7, 0xb9, 0x3a, 0xd1, 0x34, 0x16, 0x71, 0xe7, 0x5e, 0xa4, 0x2e, 0x19, 0x31, 0x14, 0x15,
1371
-	0x71, 0x16, 0xf8, 0xf3, 0x93, 0xd0, 0xbb, 0x60, 0x3c, 0xa1, 0x8a, 0x8d, 0xd5, 0xd4, 0x80, 0xe8,
1372
-	0x58, 0x8e, 0xd9, 0x64, 0x42, 0x65, 0x7b, 0xc3, 0x91, 0x84, 0xa8, 0xb1, 0x6c, 0x1a, 0xf1, 0xeb,
1373
-	0xd7, 0x27, 0x78, 0xa8, 0xc5, 0x09, 0x4b, 0x49, 0xdc, 0xe9, 0xde, 0xe2, 0x4e, 0x55, 0x69, 0x7c,
1374
-	0x02, 0x8d, 0x6c, 0x17, 0x09, 0x1a, 0x5b, 0x5a, 0x1d, 0x7a, 0x93, 0xcb, 0x7e, 0x00, 0xcd, 0x13,
1375
-	0x8e, 0x41, 0x5d, 0xe3, 0x2f, 0xfb, 0x11, 0xb4, 0x75, 0x5d, 0x25, 0x46, 0x59, 0x19, 0x5c, 0x3e,
1376
-	0x4b, 0x14, 0x97, 0xa2, 0xec, 0xbf, 0x95, 0xa0, 0xa6, 0x12, 0x37, 0xad, 0x3e, 0x85, 0xac, 0xfa,
1377
-	0xfc, 0x5f, 0x8a, 0xe0, 0x87, 0x50, 0x4f, 0xae, 0x13, 0xce, 0xa6, 0x7d, 0x55, 0x0a, 0x5b, 0x4e,
1378
-	0x06, 0x7c, 0x55, 0x10, 0xb3, 0x82, 0xf8, 0xf7, 0x02, 0xd4, 0x75, 0x98, 0xff, 0xeb, 0x86, 0xe5,
1379
-	0x13, 0xa8, 0x47, 0x32, 0xf0, 0x4c, 0xd6, 0xb5, 0x46, 0xaf, 0xad, 0x14, 0xa5, 0x95, 0x2c, 0x63,
1380
-	0x30, 0xf2, 0xa7, 0x6c, 0xe6, 0x8f, 0xd1, 0x90, 0x54, 0x72, 0x0d, 0x09, 0x06, 0x3f, 0x12, 0x05,
1381
-	0xb3, 0x4a, 0x05, 0x93, 0xc6, 0x66, 0x0b, 0x52, 0xcb, 0xb5, 0x20, 0xf6, 0x67, 0x50, 0x3b, 0x76,
1382
-	0xbd, 0x31, 0xee, 0x43, 0x2c, 0xf4, 0x22, 0x95, 0xa6, 0xb8, 0x50, 0x8c, 0x85, 0x92, 0x29, 0x43,
1383
-	0x7f, 0x5f, 0xab, 0xea, 0xae, 0x28, 0xfb, 0x02, 0xdb, 0x04, 0x79, 0x0c, 0xd4, 0x61, 0x7a, 0x8c,
1384
-	0x65, 0x34, 0x75, 0x48, 0x7a, 0x96, 0x96, 0x1b, 0x0d, 0x83, 0x07, 0xc3, 0x52, 0x9b, 0x4a, 0xcd,
1385
-	0xaa, 0xea, 0xa6, 0x3e, 0x50, 0xf6, 0x38, 0xe9, 0xb4, 0xfd, 0xdb, 0x02, 0xec, 0xc9, 0x2e, 0xf2,
1386
-	0xd6, 0x5e, 0x71, 0x75, 0x77, 0x22, 0xdd, 0x57, 0xca, 0xb9, 0xef, 0x09, 0xd4, 0x63, 0x96, 0x84,
1387
-	0xb3, 0x18, 0xdd, 0x4c, 0x9e, 0x6d, 0xf4, 0x76, 0xd3, 0x93, 0x44, 0xba, 0x1c, 0x35, 0xeb, 0x64,
1388
-	0x7c, 0xf6, 0x1f, 0x4b, 0xd0, 0xce, 0xcf, 0x8a, 0x8a, 0x75, 0x3e, 0xb9, 0xf0, 0xc3, 0x2f, 0x65,
1389
-	0xfb, 0x5b, 0x20, 0x37, 0x99, 0x90, 0x38, 0x55, 0xe8, 0xcb, 0x13, 0xbc, 0x03, 0x51, 0x93, 0x74,
1390
-	0x63, 0x06, 0xa8, 0xd9, 0x3e, 0x8b, 0xfd, 0x30, 0xbd, 0x2e, 0x33, 0x40, 0x94, 0x01, 0x24, 0xde,
1391
-	0xcc, 0x42, 0xee, 0x92, 0x91, 0x65, 0x47, 0xd3, 0xd4, 0xf7, 0x62, 0x8c, 0x18, 0x3f, 0x14, 0x51,
1392
-	0xab, 0xa8, 0xbe, 0x57, 0x23, 0xd9, 0xfc, 0x31, 0x9b, 0x26, 0xea, 0x98, 0x1b, 0x88, 0xb0, 0x5c,
1393
-	0x46, 0xf3, 0x95, 0x48, 0x6a, 0x4a, 0x0c, 0xb4, 0xdc, 0x80, 0x84, 0x04, 0x49, 0x9e, 0x5c, 0xb9,
1394
-	0x11, 0x1d, 0xfb, 0xb2, 0x63, 0x20, 0x98, 0xc8, 0xdb, 0x92, 0x42, 0x6f, 0xe0, 0x57, 0x8e, 0x2b,
1395
-	0x2e, 0x66, 0x2a, 0x03, 0x65, 0x67, 0x79, 0x42, 0x70, 0x5f, 0xb0, 0x38, 0x60, 0x93, 0x63, 0x43,
1396
-	0x2b, 0x48, 0xee, 0xa5, 0x09, 0xab, 0x07, 0x3b, 0x12, 0x3c, 0x3d, 0xec, 0x9b, 0x0b, 0x1a, 0xb4,
1397
-	0x60, 0xe5, 0x9c, 0xf8, 0x16, 0x5b, 0xca, 0x13, 0x75, 0xe1, 0x7d, 0x17, 0x5a, 0x2f, 0x2e, 0x19,
1398
-	0x56, 0xf0, 0x34, 0x73, 0xd0, 0xef, 0xe2, 0x00, 0x60, 0x36, 0x4c, 0x23, 0x15, 0xb5, 0x0c, 0xb0,
1399
-	0x13, 0xa8, 0x10, 0xfb, 0xca, 0x86, 0x47, 0x26, 0x5d, 0x51, 0x27, 0x5d, 0x3e, 0xc5, 0x5a, 0x3a,
1400
-	0xc5, 0x54, 0x32, 0x96, 0xb3, 0x64, 0xcc, 0x29, 0xad, 0x2c, 0x2a, 0xfd, 0x5d, 0x11, 0x9a, 0xaf,
1401
-	0x19, 0xbf, 0x0a, 0xe3, 0x0b, 0x71, 0xb8, 0x92, 0x95, 0xf7, 0xe8, 0x3d, 0xfc, 0xec, 0x9b, 0x0f,
1402
-	0xce, 0xaf, 0xb9, 0x4e, 0xa6, 0x5a, 0x3c, 0x7f, 0x2e, 0x48, 0xeb, 0x3e, 0x00, 0x4e, 0xf5, 0x5d,
1403
-	0x79, 0x77, 0xaa, 0x5c, 0x8a, 0xe7, 0x0a, 0xb0, 0x3e, 0x80, 0xba, 0x33, 0x1f, 0x60, 0x0d, 0x0e,
1404
-	0xe3, 0x24, 0x4d, 0xa6, 0x78, 0xfe, 0x82, 0x68, 0xb1, 0x16, 0x27, 0x87, 0x71, 0x18, 0x45, 0x6c,
1405
-	0x98, 0x9a, 0x16, 0xcf, 0x8f, 0x24, 0x20, 0xb4, 0x9e, 0xa6, 0x5a, 0xab, 0x52, 0x2b, 0xcf, 0xb4,
1406
-	0xe2, 0x54, 0xa4, 0xb4, 0xd6, 0xd4, 0xa6, 0x4c, 0xad, 0xa7, 0x5a, 0xab, 0x4c, 0xa1, 0x0d, 0x6e,
1407
-	0x68, 0x3d, 0xcd, 0xb4, 0xd6, 0xd3, 0xb5, 0x4a, 0xab, 0xfd, 0x97, 0x02, 0x6c, 0x60, 0x2a, 0x9f,
1408
-	0x25, 0xee, 0x88, 0xe1, 0xad, 0xd7, 0xe0, 0x98, 0xf6, 0x93, 0xc1, 0x4c, 0x90, 0x2a, 0x64, 0x40,
1409
-	0x90, 0x64, 0xf8, 0x1a, 0x34, 0x23, 0x16, 0x63, 0x82, 0x2b, 0x8e, 0x22, 0x16, 0x21, 0x4c, 0x68,
1410
-	0x89, 0x49, 0x96, 0x03, 0xb8, 0x4b, 0x73, 0x03, 0x3f, 0x18, 0xc8, 0x0c, 0x9a, 0x86, 0x43, 0xa6,
1411
-	0x5c, 0xb5, 0x4d, 0x53, 0x2f, 0x83, 0x2f, 0xf4, 0x84, 0xf5, 0x6d, 0xd8, 0xd6, 0xfc, 0xe2, 0x66,
1412
-	0x25, 0x6e, 0xe9, 0xba, 0x4d, 0xc5, 0x7d, 0xa6, 0x60, 0xfb, 0x57, 0xd0, 0x3e, 0x1d, 0xc7, 0x21,
1413
-	0xe7, 0x78, 0xf5, 0x8c, 0x8e, 0x5c, 0x3c, 0xa0, 0x58, 0x75, 0x23, 0x3a, 0xc6, 0x89, 0xb2, 0x36,
1414
-	0x25, 0xad, 0xef, 0xc0, 0x36, 0x97, 0xbc, 0x6c, 0x38, 0x48, 0x79, 0x64, 0x34, 0xb7, 0xf4, 0x44,
1415
-	0x5f, 0x31, 0x7f, 0x1d, 0xda, 0x19, 0x33, 0xd5, 0x70, 0x69, 0x6f, 0x4b, 0xa3, 0xa7, 0xa2, 0x92,
1416
-	0xff, 0x41, 0x3a, 0x4b, 0x66, 0xce, 0x27, 0x54, 0x55, 0x0c, 0x57, 0x35, 0x7a, 0x9b, 0x69, 0x35,
1417
-	0x56, 0xce, 0xa0, 0x4a, 0x22, 0xdd, 0xf2, 0x63, 0xd8, 0xe4, 0xda, 0xf4, 0x01, 0x1e, 0x20, 0x57,
1418
-	0x95, 0xe4, 0xb4, 0x22, 0xe6, 0x37, 0xe6, 0xb4, 0x79, 0x7e, 0xa3, 0xe8, 0x79, 0xd9, 0x26, 0x28,
1419
-	0x85, 0xd2, 0xbe, 0x86, 0xc4, 0x48, 0x85, 0xfd, 0x23, 0xa8, 0x63, 0x0f, 0x91, 0x48, 0xeb, 0xd0,
1420
-	0x31, 0xde, 0x2c, 0x8e, 0xf1, 0x7c, 0xa5, 0x8e, 0x51, 0xa4, 0xe8, 0x31, 0xe8, 0x8a, 0x55, 0xce,
1421
-	0x90, 0x84, 0x1d, 0x02, 0xc8, 0x63, 0x4e, 0xda, 0x90, 0xc7, 0x4c, 0x01, 0x49, 0x88, 0x3c, 0x9b,
1422
-	0xba, 0x73, 0x1d, 0x7a, 0xca, 0x33, 0x04, 0xe4, 0x06, 0x51, 0xe1, 0x5b, 0xd7, 0x9f, 0x78, 0xea,
1423
-	0x7d, 0x00, 0x15, 0x2a, 0x32, 0x53, 0x58, 0x36, 0x15, 0xfe, 0xb9, 0x08, 0x0d, 0xa9, 0x51, 0x1a,
1424
-	0x8c, 0x5c, 0x1e, 0x5e, 0x46, 0x5a, 0x25, 0x11, 0xd8, 0x2e, 0x54, 0x32, 0x75, 0x59, 0xeb, 0x98,
1425
-	0x99, 0x9a, 0xda, 0x86, 0x97, 0x63, 0x82, 0xf5, 0xd2, 0xf0, 0xce, 0x4a, 0xee, 0xba, 0x60, 0x92,
1426
-	0x06, 0x7f, 0x0a, 0x4d, 0x99, 0x9f, 0x6a, 0x4d, 0x79, 0xdd, 0x9a, 0x86, 0x64, 0x93, 0xab, 0x9e,
1427
-	0x88, 0x0e, 0x0d, 0xed, 0xa5, 0x8e, 0xa0, 0xd1, 0xbb, 0x9f, 0x63, 0xa7, 0x9d, 0x1c, 0xd0, 0xef,
1428
-	0x8b, 0x80, 0x63, 0x69, 0x96, 0xbc, 0xdd, 0xa7, 0x00, 0x19, 0x28, 0x6a, 0xd6, 0x05, 0xbb, 0x4e,
1429
-	0x3b, 0x51, 0x1c, 0x8a, 0xbd, 0x5f, 0xba, 0x93, 0x59, 0xea, 0x54, 0x49, 0xfc, 0xb0, 0xf8, 0xb4,
1430
-	0x80, 0x5f, 0x31, 0x9b, 0xcf, 0xc5, 0x3d, 0x67, 0x2c, 0xcf, 0x3d, 0x6b, 0x95, 0x57, 0x3e, 0x6b,
1431
-	0x95, 0xd3, 0x67, 0x2d, 0x2c, 0xa3, 0x61, 0xa4, 0x6e, 0x65, 0x1c, 0x65, 0x8a, 0xca, 0x86, 0x22,
1432
-	0xfb, 0x9f, 0x65, 0x80, 0x4c, 0x8b, 0x75, 0x02, 0x5d, 0x3f, 0x1c, 0x88, 0x4b, 0xc5, 0xf7, 0x98,
1433
-	0x2c, 0x48, 0x83, 0x98, 0x61, 0xfa, 0x24, 0xfe, 0x25, 0x53, 0x7d, 0xc7, 0x9e, 0xda, 0xf7, 0x82,
1434
-	0x71, 0xce, 0x3e, 0x52, 0x72, 0x21, 0x55, 0x2e, 0x27, 0x5d, 0x66, 0xfd, 0x0c, 0x76, 0x33, 0xa1,
1435
-	0x43, 0x43, 0x5e, 0xf1, 0x46, 0x79, 0x77, 0xb5, 0xbc, 0x61, 0x26, 0xeb, 0x27, 0x80, 0xf0, 0x00,
1436
-	0xef, 0x98, 0x59, 0x4e, 0x52, 0xe9, 0x46, 0x49, 0xdb, 0x7e, 0xf8, 0x86, 0x56, 0x64, 0x72, 0xde,
1437
-	0xc0, 0x3d, 0x63, 0xa3, 0xe2, 0xd8, 0x1b, 0xd2, 0xca, 0x37, 0x4a, 0xdb, 0xd3, 0x76, 0x89, 0xc2,
1438
-	0x90, 0x89, 0xfc, 0x02, 0x70, 0x66, 0x70, 0xe5, 0xfa, 0x7c, 0x51, 0x5e, 0xe5, 0xb6, 0x7d, 0x7e,
1439
-	0x89, 0x8b, 0xf2, 0xc2, 0xe4, 0x3e, 0xa7, 0x2c, 0x1e, 0xe5, 0xf6, 0x59, 0xbd, 0x6d, 0x9f, 0xc7,
1440
-	0xb4, 0x22, 0x93, 0xf3, 0x1c, 0x10, 0x5c, 0xb4, 0xa7, 0x76, 0xa3, 0x94, 0x4d, 0x3f, 0xcc, 0xdb,
1441
-	0x72, 0x08, 0xdb, 0x09, 0xf3, 0x38, 0xde, 0x28, 0x86, 0x8c, 0x8d, 0x1b, 0x65, 0x6c, 0xa9, 0x05,
1442
-	0x5a, 0x88, 0xfd, 0x0e, 0x9a, 0x3f, 0x9d, 0x8d, 0x18, 0x9f, 0x9c, 0xeb, 0x33, 0xff, 0xbf, 0x2e,
1443
-	0x33, 0xff, 0xc6, 0x32, 0x73, 0x38, 0x8a, 0xc3, 0x59, 0x94, 0xab, 0xda, 0xf2, 0x0c, 0x2f, 0x55,
1444
-	0x6d, 0xe2, 0xa1, 0xaa, 0x2d, 0xb9, 0x3f, 0x83, 0xa6, 0x6c, 0xb2, 0xd4, 0x02, 0x59, 0x85, 0xac,
1445
-	0xe5, 0x43, 0x9f, 0x36, 0x75, 0x72, 0x59, 0x4f, 0x35, 0xac, 0x6a, 0x55, 0xbe, 0x1a, 0x65, 0x6e,
1446
-	0xc2, 0x2f, 0x96, 0xec, 0xd4, 0xbd, 0x84, 0xd6, 0x58, 0xfa, 0x46, 0xad, 0x92, 0x09, 0xf8, 0x71,
1447
-	0x6a, 0x5c, 0xb6, 0x87, 0x03, 0xd3, 0x87, 0xd2, 0xd5, 0xcd, 0xb1, 0xe9, 0xd6, 0xef, 0x01, 0x88,
1448
-	0x4f, 0x92, 0x41, 0x5a, 0xa8, 0xcc, 0x17, 0x49, 0x7d, 0x43, 0xe0, 0xf7, 0x4f, 0x3a, 0xec, 0x9e,
1449
-	0xc2, 0xf6, 0x92, 0xcc, 0x15, 0x65, 0xea, 0x5b, 0x66, 0x99, 0x6a, 0xf4, 0xee, 0x2a, 0x91, 0xe6,
1450
-	0x52, 0xb3, 0x76, 0xfd, 0xa9, 0x20, 0xbf, 0x60, 0xf4, 0xa3, 0x91, 0xf5, 0x14, 0x5a, 0x81, 0x6c,
1451
-	0xbe, 0x74, 0x00, 0x4a, 0x86, 0x20, 0xb3, 0x31, 0x73, 0x9a, 0x81, 0xd9, 0xa6, 0x61, 0x20, 0x3c,
1452
-	0xf2, 0xc0, 0xca, 0x40, 0x18, 0xce, 0x71, 0x1a, 0x9e, 0x11, 0xed, 0x5c, 0x33, 0x58, 0x5a, 0x6c,
1453
-	0x06, 0xd5, 0x43, 0xc3, 0xba, 0x57, 0xd2, 0xde, 0xbf, 0xaa, 0x50, 0x7a, 0xd6, 0x7f, 0x69, 0x9d,
1454
-	0xc1, 0xd6, 0xe2, 0x9f, 0x0c, 0xd6, 0x03, 0xa5, 0x7a, 0xcd, 0x1f, 0x13, 0xdd, 0x8f, 0xd6, 0xce,
1455
-	0xab, 0x6e, 0xf9, 0x8e, 0xe5, 0xc0, 0xe6, 0xc2, 0x93, 0xb2, 0x95, 0x5e, 0x27, 0xab, 0x9f, 0xed,
1456
-	0xbb, 0x0f, 0xd6, 0x4d, 0x9b, 0x32, 0x17, 0xda, 0x73, 0x2d, 0x73, 0xf5, 0xe7, 0x9d, 0x96, 0xb9,
1457
-	0xae, 0xab, 0xbf, 0x63, 0xfd, 0x00, 0xaa, 0xf2, 0x91, 0xd9, 0xda, 0x51, 0xbc, 0xb9, 0xe7, 0xeb,
1458
-	0xee, 0xee, 0x02, 0xaa, 0x17, 0xbe, 0x82, 0x56, 0xee, 0x9f, 0x09, 0xeb, 0x83, 0x9c, 0xae, 0xfc,
1459
-	0x1b, 0x75, 0xf7, 0xc3, 0xd5, 0x93, 0x5a, 0xda, 0x21, 0x40, 0xf6, 0x0e, 0x69, 0x75, 0x14, 0xf7,
1460
-	0xd2, 0x5b, 0x77, 0xf7, 0xde, 0x8a, 0x19, 0x2d, 0x04, 0x43, 0xb9, 0xf8, 0x62, 0x68, 0x2d, 0x78,
1461
-	0x75, 0xf1, 0xbd, 0x4e, 0x87, 0x72, 0xed, 0x53, 0x23, 0x89, 0x5d, 0x7c, 0x07, 0xd4, 0x62, 0xd7,
1462
-	0xbc, 0x42, 0x6a, 0xb1, 0x6b, 0x1f, 0x10, 0xef, 0x58, 0x3f, 0x87, 0x76, 0xfe, 0x61, 0xcd, 0x4a,
1463
-	0x9d, 0xb4, 0xf2, 0x65, 0xb1, 0x7b, 0x7f, 0xcd, 0xac, 0x16, 0xf8, 0x29, 0x54, 0xe4, 0x8b, 0x59,
1464
-	0x7a, 0xe4, 0xcc, 0x87, 0xb6, 0xee, 0x4e, 0x1e, 0xd4, 0xab, 0x1e, 0x43, 0x55, 0x7e, 0xd8, 0xe9,
1465
-	0x04, 0xc8, 0x7d, 0xe7, 0x75, 0x9b, 0x26, 0x6a, 0xdf, 0x79, 0x5c, 0x48, 0xf5, 0x24, 0x39, 0x3d,
1466
-	0xc9, 0x2a, 0x3d, 0x46, 0x70, 0xce, 0xab, 0xf4, 0xaf, 0xdf, 0x93, 0xff, 0x04, 0x00, 0x00, 0xff,
1467
-	0xff, 0xbf, 0xea, 0xc8, 0x11, 0x02, 0x1c, 0x00, 0x00,
1321
+	0x11, 0x8f, 0xa4, 0xb5, 0x6c, 0xb5, 0x3e, 0x6c, 0x6f, 0xfc, 0xa1, 0xe8, 0xbd, 0x7c, 0xb0, 0xf5,
1322
+	0x80, 0x00, 0xaf, 0x94, 0xa0, 0xbc, 0x57, 0xa4, 0xa0, 0x8a, 0xaa, 0xc4, 0x0e, 0x8f, 0xf0, 0xe2,
1323
+	0x3c, 0x65, 0x6d, 0xf3, 0x8e, 0xaa, 0xb5, 0x76, 0x22, 0x2d, 0x5e, 0xed, 0x6e, 0x76, 0x47, 0xb6,
1324
+	0x7c, 0xe1, 0xc0, 0x01, 0x6e, 0x70, 0xa5, 0x0a, 0x6e, 0xdc, 0xb8, 0x73, 0x80, 0x7f, 0x80, 0x2a,
1325
+	0xfe, 0x10, 0x6e, 0xdc, 0x39, 0xd2, 0xf3, 0xb9, 0xb3, 0xfa, 0xb0, 0x93, 0x03, 0xc5, 0x85, 0x8b,
1326
+	0x6a, 0xfa, 0x37, 0x3d, 0xdd, 0x3d, 0x3d, 0xdd, 0x3d, 0xbd, 0x23, 0xa8, 0x79, 0x49, 0xd0, 0x4d,
1327
+	0xd2, 0x98, 0xc6, 0xf6, 0x1a, 0xbd, 0x4a, 0x48, 0xd6, 0xb9, 0x3f, 0x8a, 0xe3, 0x51, 0x48, 0x1e,
1328
+	0x71, 0xf0, 0x6c, 0xfa, 0xf6, 0x11, 0x0d, 0x26, 0x24, 0xa3, 0xde, 0x24, 0x11, 0x7c, 0xce, 0x1d,
1329
+	0xd8, 0xff, 0x82, 0xd0, 0x63, 0x92, 0x5e, 0x90, 0xf4, 0xe7, 0x24, 0xcd, 0x82, 0x38, 0x72, 0xc9,
1330
+	0xbb, 0x29, 0xf2, 0x38, 0x33, 0x68, 0x2f, 0x4e, 0x65, 0x49, 0x1c, 0x65, 0xc4, 0xde, 0x81, 0xb5,
1331
+	0x89, 0xf7, 0x8b, 0x38, 0x6d, 0x97, 0x1e, 0x94, 0x1e, 0x36, 0x5d, 0x41, 0x70, 0x34, 0x88, 0x10,
1332
+	0x2d, 0x4b, 0x94, 0x11, 0x0c, 0x4d, 0x3c, 0x3a, 0x1c, 0xb7, 0x2b, 0x02, 0xe5, 0x84, 0xdd, 0x81,
1333
+	0x8d, 0x94, 0x5c, 0x04, 0x4c, 0x6a, 0xdb, 0xc2, 0x89, 0x9a, 0xab, 0x69, 0xe7, 0xd7, 0x25, 0xd8,
1334
+	0x39, 0x4d, 0x7c, 0x8f, 0x92, 0x7e, 0x1a, 0x0f, 0x49, 0x96, 0x49, 0x93, 0xec, 0x16, 0x94, 0x03,
1335
+	0x9f, 0xeb, 0xac, 0xb9, 0x38, 0xb2, 0xb7, 0xa0, 0x92, 0x20, 0x50, 0xe6, 0x00, 0x1b, 0xda, 0xf7,
1336
+	0x00, 0x86, 0x61, 0x9c, 0x91, 0x63, 0xea, 0x07, 0x11, 0xd7, 0xb8, 0xe1, 0x1a, 0x08, 0x33, 0xe6,
1337
+	0x32, 0xf0, 0xe9, 0x98, 0xeb, 0x44, 0x63, 0x38, 0x61, 0xef, 0x41, 0x75, 0x4c, 0x82, 0xd1, 0x98,
1338
+	0xb6, 0xd7, 0x38, 0x2c, 0x29, 0x67, 0x1f, 0x76, 0xe7, 0xec, 0x10, 0xfb, 0x77, 0xfe, 0x51, 0x86,
1339
+	0xbd, 0x83, 0x94, 0xe0, 0xcc, 0x41, 0x1c, 0x51, 0x2f, 0x88, 0x48, 0xba, 0xca, 0x46, 0xb4, 0xe8,
1340
+	0x6c, 0x1a, 0xf9, 0x21, 0xe9, 0x7b, 0xa8, 0x56, 0x98, 0x6a, 0x20, 0xdc, 0xe2, 0x31, 0x19, 0x9e,
1341
+	0x27, 0x71, 0x10, 0x51, 0x6e, 0x31, 0xce, 0xe7, 0x08, 0xb3, 0x38, 0xe3, 0x9b, 0x11, 0x5e, 0x12,
1342
+	0x04, 0xb3, 0x18, 0x07, 0xf1, 0x54, 0x58, 0x5c, 0x73, 0x25, 0x25, 0x71, 0x92, 0xa6, 0xed, 0xaa,
1343
+	0xc6, 0x91, 0x62, 0x78, 0xe8, 0x9d, 0x91, 0x30, 0x6b, 0xaf, 0x3f, 0xa8, 0x30, 0x5c, 0x50, 0xf6,
1344
+	0x03, 0xa8, 0x47, 0x71, 0x3f, 0xb8, 0x88, 0xa9, 0x1b, 0xc7, 0xb4, 0xbd, 0xc1, 0x1d, 0x66, 0x42,
1345
+	0x76, 0x1b, 0xd6, 0xd3, 0x69, 0xc4, 0xe2, 0xa6, 0x5d, 0xe3, 0x22, 0x15, 0xc9, 0xd6, 0xca, 0xe1,
1346
+	0xb3, 0x74, 0x94, 0xb5, 0x81, 0x0b, 0x36, 0x21, 0xfb, 0x13, 0x68, 0xe6, 0x3b, 0x39, 0x0c, 0xd2,
1347
+	0x76, 0x9d, 0x4b, 0x28, 0x82, 0xce, 0x4b, 0xd8, 0x5f, 0xf0, 0xa5, 0x8c, 0xb3, 0x2e, 0xd4, 0x86,
1348
+	0x0a, 0xe4, 0x3e, 0xad, 0xf7, 0xb6, 0xba, 0x3c, 0xb4, 0xbb, 0x39, 0x73, 0xce, 0x82, 0xa2, 0x9a,
1349
+	0xc7, 0xc1, 0x28, 0xf2, 0xc2, 0xf7, 0x8f, 0x18, 0xe6, 0x31, 0xbe, 0x44, 0xc6, 0xa7, 0xa4, 0x9c,
1350
+	0x2d, 0x68, 0x29, 0x51, 0xf2, 0xd0, 0xff, 0x52, 0x81, 0xed, 0x67, 0xbe, 0x7f, 0x43, 0x4c, 0x62,
1351
+	0x60, 0x53, 0x92, 0x62, 0xe8, 0xa3, 0xc4, 0x32, 0x77, 0xa7, 0xa6, 0xed, 0xfb, 0x60, 0x4d, 0x33,
1352
+	0xdc, 0x49, 0x85, 0xef, 0xa4, 0x2e, 0x77, 0x72, 0x8a, 0x90, 0xcb, 0x27, 0x6c, 0x1b, 0x2c, 0x8f,
1353
+	0xf9, 0xd2, 0xe2, 0xbe, 0xe4, 0x63, 0x66, 0x32, 0x89, 0x2e, 0xf0, 0x9c, 0x19, 0xc4, 0x86, 0x0c,
1354
+	0x19, 0x5e, 0xfa, 0xf2, 0x84, 0xd9, 0x50, 0x6d, 0x6b, 0x3d, 0xdf, 0x96, 0x0e, 0x9b, 0x8d, 0xe5,
1355
+	0x61, 0x53, 0x5b, 0x11, 0x36, 0x50, 0x08, 0x1b, 0x07, 0x1a, 0x43, 0x2f, 0xf1, 0xce, 0x82, 0x30,
1356
+	0xa0, 0x01, 0xc9, 0xf0, 0xfc, 0x98, 0x11, 0x05, 0xcc, 0x7e, 0x08, 0x9b, 0x5e, 0x92, 0x78, 0xe9,
1357
+	0x24, 0x4e, 0xd1, 0x35, 0x6f, 0x83, 0x90, 0xb4, 0x1b, 0x5c, 0xc8, 0x3c, 0xcc, 0xa4, 0x65, 0x24,
1358
+	0x0c, 0xa2, 0xe9, 0xec, 0x15, 0x8b, 0xbe, 0x76, 0x93, 0xb3, 0x15, 0x30, 0x26, 0x2d, 0x8a, 0x5f,
1359
+	0x93, 0xcb, 0x7e, 0x1a, 0x5c, 0xe0, 0x9a, 0x11, 0x2a, 0x6d, 0x71, 0x2f, 0xce, 0xc3, 0xf6, 0xb7,
1360
+	0x31, 0x30, 0xc3, 0x60, 0x12, 0xd0, 0xac, 0xbd, 0x89, 0x66, 0xd5, 0x7b, 0x4d, 0xe9, 0x4f, 0x97,
1361
+	0xa3, 0xae, 0x9a, 0x75, 0x0e, 0xa1, 0x2a, 0x20, 0xe6, 0x5e, 0xc6, 0x22, 0x4f, 0x8b, 0x8f, 0x19,
1362
+	0x96, 0xc5, 0x6f, 0x29, 0x3f, 0x2b, 0xcb, 0xe5, 0x63, 0x86, 0x8d, 0xbd, 0xd4, 0xe7, 0xe7, 0x84,
1363
+	0x18, 0x1b, 0x3b, 0x2e, 0x58, 0xec, 0xa0, 0x98, 0xab, 0xa7, 0xf2, 0xc0, 0x9b, 0x2e, 0x1b, 0x32,
1364
+	0x64, 0x24, 0x63, 0x0a, 0x11, 0x1c, 0xda, 0xdf, 0x82, 0x96, 0xe7, 0xfb, 0xe8, 0x9e, 0x18, 0x4f,
1365
+	0xfd, 0x8b, 0xc0, 0xcf, 0x50, 0x52, 0x05, 0x27, 0xe7, 0x50, 0x67, 0x07, 0x6c, 0x33, 0xa0, 0x64,
1366
+	0x9c, 0xfd, 0xaa, 0xa4, 0x13, 0x42, 0xe7, 0xc9, 0xaa, 0x68, 0xfb, 0x7e, 0xa1, 0x7a, 0x94, 0x79,
1367
+	0x5c, 0x6d, 0xab, 0x0c, 0xc9, 0x57, 0x9b, 0x05, 0x65, 0x21, 0x29, 0x2b, 0xcb, 0x92, 0xb2, 0x03,
1368
+	0xed, 0x45, 0x1b, 0xa4, 0x81, 0x43, 0xd8, 0x3f, 0x24, 0x21, 0x79, 0x1f, 0xfb, 0xd0, 0x93, 0x91,
1369
+	0x87, 0xa5, 0x43, 0x24, 0x1c, 0x1f, 0xbf, 0xbf, 0x01, 0x8b, 0x4a, 0xa4, 0x01, 0x47, 0xb0, 0xfb,
1370
+	0x2a, 0xc8, 0xe8, 0xcd, 0xea, 0x17, 0x54, 0x95, 0x97, 0xa9, 0xfa, 0x7d, 0x09, 0x20, 0x97, 0xa5,
1371
+	0x6d, 0x2e, 0x19, 0x36, 0x23, 0x46, 0x66, 0x01, 0x95, 0x19, 0xcd, 0xc7, 0xec, 0xdc, 0xe9, 0x30,
1372
+	0x91, 0x97, 0x0c, 0x1b, 0xb2, 0x8a, 0x38, 0x8d, 0x82, 0xd9, 0x71, 0x3c, 0x3c, 0x27, 0x34, 0xe3,
1373
+	0x15, 0x1b, 0xab, 0xa9, 0x01, 0xf1, 0xb4, 0x1c, 0x93, 0x30, 0xe4, 0x65, 0x7b, 0xc3, 0x15, 0x04,
1374
+	0xab, 0xb1, 0x64, 0x92, 0xd0, 0xab, 0xd7, 0xc7, 0x98, 0xd4, 0x2c, 0xc3, 0x14, 0x89, 0x3b, 0xdd,
1375
+	0x9b, 0xdf, 0xa9, 0x2c, 0x8d, 0x4f, 0xa0, 0x9e, 0xef, 0x22, 0x43, 0x63, 0x2b, 0xcb, 0x8f, 0xde,
1376
+	0xe4, 0x72, 0xee, 0x41, 0xe3, 0x98, 0xe2, 0xa1, 0xae, 0xf0, 0x97, 0xf3, 0x10, 0x5a, 0xba, 0xae,
1377
+	0x72, 0x46, 0x51, 0x19, 0x3c, 0x3a, 0xcd, 0x24, 0x97, 0xa4, 0x9c, 0xbf, 0x56, 0x60, 0x5d, 0x06,
1378
+	0xae, 0xaa, 0x3e, 0xa5, 0xbc, 0xfa, 0xfc, 0x4f, 0x8a, 0xe0, 0xc7, 0x50, 0xcb, 0xae, 0x32, 0x4a,
1379
+	0x26, 0x7d, 0x59, 0x0a, 0x9b, 0x6e, 0x0e, 0xfc, 0xbf, 0x20, 0xe6, 0x05, 0xf1, 0xef, 0x25, 0xa8,
1380
+	0xe9, 0x63, 0xfe, 0xe0, 0x86, 0xe5, 0x53, 0xa8, 0x25, 0xe2, 0xe0, 0x89, 0xa8, 0x6b, 0xf5, 0x5e,
1381
+	0x4b, 0x2a, 0x52, 0x95, 0x2c, 0x67, 0x30, 0xe2, 0xc7, 0x32, 0xe3, 0xc7, 0x68, 0x48, 0xd6, 0x0a,
1382
+	0x0d, 0x09, 0x1e, 0x7e, 0xc2, 0x0a, 0x66, 0x95, 0x17, 0x4c, 0x3e, 0x36, 0x5b, 0x90, 0xf5, 0x42,
1383
+	0x0b, 0xe2, 0x7c, 0x0e, 0xeb, 0x47, 0xde, 0x70, 0x8c, 0xfb, 0x60, 0x0b, 0x87, 0x89, 0x0c, 0x53,
1384
+	0x5c, 0xc8, 0xc6, 0x4c, 0xc9, 0x84, 0xa0, 0xbf, 0xaf, 0x64, 0x75, 0x97, 0x94, 0x73, 0x8e, 0x6d,
1385
+	0x82, 0x48, 0x03, 0x99, 0x4c, 0x8f, 0xb1, 0x8c, 0x2a, 0x87, 0xa8, 0x5c, 0x5a, 0x6c, 0x34, 0x0c,
1386
+	0x1e, 0x3c, 0x96, 0xf5, 0x89, 0xd0, 0x2c, 0xab, 0xae, 0xf2, 0x81, 0xb4, 0xc7, 0x55, 0xd3, 0xce,
1387
+	0x6f, 0x4a, 0xb0, 0x27, 0xba, 0xc8, 0x1b, 0x7b, 0xc5, 0xe5, 0xdd, 0x89, 0x70, 0x5f, 0xa5, 0xe0,
1388
+	0xbe, 0x27, 0x50, 0x4b, 0x49, 0x16, 0x4f, 0x53, 0x74, 0x33, 0xf7, 0x6c, 0xbd, 0xb7, 0xab, 0x32,
1389
+	0x89, 0xeb, 0x72, 0xe5, 0xac, 0x9b, 0xf3, 0x39, 0x7f, 0xac, 0x40, 0xab, 0x38, 0xcb, 0x2a, 0xd6,
1390
+	0x59, 0x78, 0x1e, 0xc4, 0x5f, 0x8b, 0xf6, 0xb7, 0xc4, 0xdd, 0x64, 0x42, 0x2c, 0xab, 0xd0, 0x97,
1391
+	0xc7, 0x78, 0x07, 0xa2, 0x26, 0xe1, 0xc6, 0x1c, 0x90, 0xb3, 0x7d, 0x92, 0x06, 0xb1, 0xba, 0x2e,
1392
+	0x73, 0x80, 0x95, 0x01, 0x24, 0xde, 0x4c, 0x63, 0xea, 0x71, 0x23, 0x2d, 0x57, 0xd3, 0xbc, 0xef,
1393
+	0xc5, 0x33, 0x22, 0xf4, 0x80, 0x9d, 0xda, 0x9a, 0xec, 0x7b, 0x35, 0x92, 0xcf, 0x1f, 0x91, 0x49,
1394
+	0x26, 0xd3, 0xdc, 0x40, 0x98, 0xe5, 0xe2, 0x34, 0x5f, 0xb1, 0xa0, 0xe6, 0x81, 0x81, 0x96, 0x1b,
1395
+	0x10, 0x93, 0x20, 0xc8, 0xe3, 0x4b, 0x2f, 0xe1, 0x69, 0x6f, 0xb9, 0x06, 0x82, 0x81, 0xbc, 0x2d,
1396
+	0x28, 0xf4, 0x06, 0x7e, 0xe5, 0x78, 0xec, 0x62, 0xe6, 0x65, 0xc0, 0x72, 0x17, 0x27, 0x18, 0xf7,
1397
+	0x39, 0x49, 0x23, 0x12, 0x1e, 0x19, 0x5a, 0x41, 0x70, 0x2f, 0x4c, 0xd8, 0x3d, 0xd8, 0x11, 0xe0,
1398
+	0xc9, 0x41, 0xdf, 0x5c, 0x50, 0xe7, 0x0b, 0x96, 0xce, 0xb1, 0x6f, 0xb1, 0x85, 0x38, 0x91, 0x17,
1399
+	0xde, 0x15, 0x34, 0x5f, 0x5c, 0x10, 0xac, 0xe0, 0x2a, 0x72, 0x9e, 0x42, 0x4d, 0x7f, 0xca, 0xc9,
1400
+	0x00, 0xec, 0x74, 0xc5, 0xc7, 0x5e, 0x57, 0x7d, 0xec, 0x75, 0x4f, 0x14, 0x87, 0x9b, 0x33, 0x33,
1401
+	0xaf, 0x64, 0x34, 0x4e, 0x89, 0xff, 0x55, 0x14, 0x5e, 0xa9, 0x2f, 0xa4, 0x1c, 0x91, 0x31, 0x69,
1402
+	0xe9, 0x2b, 0xe1, 0x77, 0x25, 0x58, 0xe3, 0xba, 0x97, 0x76, 0x4f, 0x82, 0xbb, 0xac, 0x23, 0xb8,
1403
+	0x18, 0xaf, 0x4d, 0x1d, 0xaf, 0x32, 0xb2, 0xad, 0x3c, 0xb2, 0x0b, 0x3b, 0xa8, 0x7e, 0xc0, 0x0e,
1404
+	0x9c, 0xdf, 0x96, 0xa1, 0xf1, 0x9a, 0xd0, 0xcb, 0x38, 0x3d, 0x67, 0x59, 0x9c, 0x2d, 0xbd, 0xb0,
1405
+	0xef, 0xe0, 0xf7, 0xe5, 0x6c, 0x70, 0x76, 0x45, 0x75, 0xd4, 0xae, 0xa7, 0xb3, 0xe7, 0x8c, 0xb4,
1406
+	0xef, 0x02, 0xe0, 0x54, 0xdf, 0x13, 0x97, 0xb4, 0x0c, 0xda, 0x74, 0x26, 0x01, 0xfb, 0x23, 0xa8,
1407
+	0xb9, 0xb3, 0x01, 0x16, 0xfb, 0x38, 0xcd, 0x54, 0xd4, 0xa6, 0xb3, 0x17, 0x9c, 0x66, 0x6b, 0x71,
1408
+	0xd2, 0x4f, 0xe3, 0x24, 0x21, 0x3e, 0x8f, 0x5a, 0xbe, 0xf6, 0x50, 0x00, 0x4c, 0xeb, 0x89, 0xd2,
1409
+	0x5a, 0x15, 0x5a, 0x69, 0xae, 0x15, 0xa7, 0x12, 0xa9, 0x55, 0x84, 0x6b, 0x8d, 0x9a, 0x5a, 0x4f,
1410
+	0xb4, 0x56, 0x11, 0xab, 0x1b, 0xd4, 0xd0, 0x7a, 0x92, 0x6b, 0xad, 0xa9, 0xb5, 0x52, 0xab, 0xf3,
1411
+	0xe7, 0x12, 0x6c, 0x60, 0xce, 0x9c, 0x66, 0xde, 0x88, 0xe0, 0xf5, 0x5a, 0xa7, 0x98, 0x5f, 0xe1,
1412
+	0x60, 0xca, 0x48, 0x99, 0xd1, 0xc0, 0x21, 0xc1, 0xf0, 0x0d, 0x68, 0x24, 0x24, 0xc5, 0x4c, 0x92,
1413
+	0x1c, 0x65, 0xac, 0x76, 0x98, 0x39, 0x02, 0x13, 0x2c, 0x5d, 0xb8, 0xcd, 0xe7, 0x06, 0x41, 0x34,
1414
+	0x10, 0xa1, 0x3a, 0x89, 0x7d, 0x22, 0x5d, 0xb5, 0xcd, 0xa7, 0x5e, 0x46, 0x5f, 0xea, 0x09, 0xfb,
1415
+	0xbb, 0xb0, 0xad, 0xf9, 0xd9, 0x15, 0xce, 0xb9, 0x85, 0xeb, 0x36, 0x25, 0xf7, 0xa9, 0x84, 0x9d,
1416
+	0x5f, 0x42, 0xeb, 0x64, 0x8c, 0xe7, 0x4b, 0xf1, 0x8e, 0x1b, 0x1d, 0x7a, 0x58, 0x09, 0xb0, 0xbc,
1417
+	0x27, 0xbc, 0x5e, 0x64, 0xd2, 0x5a, 0x45, 0xda, 0xdf, 0x83, 0x6d, 0x2a, 0x78, 0x89, 0x3f, 0x50,
1418
+	0x3c, 0xe2, 0x34, 0xb7, 0xf4, 0x44, 0x5f, 0x32, 0x7f, 0x13, 0x5a, 0x39, 0x33, 0xbf, 0x2c, 0x84,
1419
+	0xbd, 0x4d, 0x8d, 0xb2, 0x68, 0x72, 0xfe, 0x20, 0x9c, 0x25, 0x22, 0xe7, 0x53, 0x5e, 0xbe, 0x0c,
1420
+	0x57, 0xd5, 0x7b, 0x9b, 0xaa, 0xec, 0x4b, 0x67, 0xf0, 0x92, 0x25, 0xdc, 0xf2, 0x63, 0xd8, 0xa4,
1421
+	0xda, 0xf4, 0x01, 0x66, 0xaa, 0x27, 0x53, 0x4f, 0x95, 0xde, 0xe2, 0xc6, 0xdc, 0x16, 0x2d, 0x6e,
1422
+	0x14, 0x3d, 0x2f, 0xfa, 0x11, 0xa9, 0x50, 0xd8, 0x57, 0x17, 0x18, 0x57, 0xe1, 0xfc, 0x08, 0x6a,
1423
+	0xd8, 0xac, 0x64, 0xc2, 0x3a, 0x74, 0xcc, 0x70, 0x9a, 0xa6, 0x98, 0x7b, 0xca, 0x31, 0x92, 0x64,
1424
+	0xcd, 0x0c, 0xbf, 0xcb, 0xa5, 0x33, 0x04, 0xe1, 0xc4, 0x00, 0xa2, 0x9e, 0x70, 0x6d, 0xc8, 0x63,
1425
+	0x86, 0x80, 0x20, 0x58, 0x9c, 0x4d, 0xbc, 0x99, 0x3e, 0x7a, 0x1e, 0x67, 0x08, 0x88, 0x0d, 0xa2,
1426
+	0xc2, 0xb7, 0x5e, 0x10, 0x0e, 0xe5, 0x43, 0x04, 0x2a, 0x94, 0x64, 0xae, 0xd0, 0x32, 0x15, 0xfe,
1427
+	0xa9, 0x0c, 0x75, 0xa1, 0x51, 0x18, 0x8c, 0x5c, 0x43, 0xbc, 0xf5, 0xb4, 0x4a, 0x4e, 0x60, 0x5f,
1428
+	0xb2, 0x96, 0xab, 0xcb, 0x7b, 0xd4, 0xdc, 0x54, 0x65, 0x1b, 0xde, 0xc2, 0x19, 0x16, 0x66, 0xc3,
1429
+	0x3b, 0x4b, 0xb9, 0x6b, 0x8c, 0x49, 0x18, 0xfc, 0x19, 0x34, 0x44, 0x7c, 0xca, 0x35, 0xd6, 0xaa,
1430
+	0x35, 0x75, 0xc1, 0x26, 0x56, 0x3d, 0x61, 0xad, 0x20, 0xda, 0xcb, 0x5b, 0x8f, 0x7a, 0xef, 0x6e,
1431
+	0x81, 0x9d, 0xef, 0xa4, 0xcb, 0x7f, 0x5f, 0x44, 0x14, 0xef, 0x00, 0xc1, 0xdb, 0x79, 0x0a, 0x90,
1432
+	0x83, 0xac, 0x9e, 0x9d, 0x93, 0x2b, 0xd5, 0xf2, 0xe2, 0x90, 0xed, 0xfd, 0xc2, 0x0b, 0xa7, 0xca,
1433
+	0xa9, 0x82, 0xf8, 0x61, 0xf9, 0x69, 0x09, 0x3f, 0x97, 0x36, 0x9f, 0xb3, 0x0b, 0xd5, 0x58, 0x5e,
1434
+	0x78, 0x3f, 0xb3, 0x96, 0xbe, 0x9f, 0x59, 0xea, 0xfd, 0x0c, 0x4b, 0x6c, 0x9c, 0xc8, 0xeb, 0x1f,
1435
+	0x47, 0xb9, 0x22, 0xcb, 0x50, 0xe4, 0xfc, 0xd3, 0x02, 0xc8, 0xb5, 0xd8, 0xc7, 0xd0, 0x09, 0xe2,
1436
+	0x01, 0xbb, 0xbd, 0x82, 0x21, 0x11, 0x05, 0x69, 0x90, 0x12, 0x0c, 0x9f, 0x2c, 0xb8, 0x20, 0xb2,
1437
+	0xc1, 0xd9, 0x93, 0xfb, 0x9e, 0x33, 0xce, 0xdd, 0x47, 0x4a, 0x2c, 0xe4, 0x95, 0xcb, 0x55, 0xcb,
1438
+	0xec, 0x9f, 0xc1, 0x6e, 0x2e, 0xd4, 0x37, 0xe4, 0x95, 0xaf, 0x95, 0x77, 0x5b, 0xcb, 0xf3, 0x73,
1439
+	0x59, 0x3f, 0x01, 0x84, 0x07, 0x78, 0x99, 0x4d, 0x0b, 0x92, 0x2a, 0xd7, 0x4a, 0xda, 0x0e, 0xe2,
1440
+	0x37, 0x7c, 0x45, 0x2e, 0xe7, 0x0d, 0xdc, 0x31, 0x36, 0xca, 0xd2, 0xde, 0x90, 0x66, 0x5d, 0x2b,
1441
+	0x6d, 0x4f, 0xdb, 0xc5, 0x0a, 0x43, 0x2e, 0xf2, 0x4b, 0xc0, 0x99, 0xc1, 0xa5, 0x17, 0xd0, 0x79,
1442
+	0x79, 0x6b, 0x37, 0xed, 0xf3, 0x6b, 0x5c, 0x54, 0x14, 0x26, 0xf6, 0x39, 0x21, 0xe9, 0xa8, 0xb0,
1443
+	0xcf, 0xea, 0x4d, 0xfb, 0x3c, 0xe2, 0x2b, 0x72, 0x39, 0xcf, 0x01, 0xc1, 0x79, 0x7b, 0xd6, 0xaf,
1444
+	0x95, 0xb2, 0x19, 0xc4, 0x45, 0x5b, 0x0e, 0x60, 0x3b, 0x23, 0x43, 0xbc, 0xea, 0xcd, 0x58, 0xd8,
1445
+	0xb8, 0x56, 0xc6, 0x96, 0x5c, 0xa0, 0x85, 0x38, 0xef, 0xa0, 0xf1, 0xd3, 0xe9, 0x88, 0xd0, 0xf0,
1446
+	0x4c, 0xe7, 0xfc, 0x7f, 0xbb, 0xcc, 0xfc, 0x1b, 0xcb, 0xcc, 0xc1, 0x28, 0x8d, 0xa7, 0x49, 0xa1,
1447
+	0x6a, 0x8b, 0x1c, 0x5e, 0xa8, 0xda, 0x9c, 0x87, 0x57, 0x6d, 0xc1, 0xfd, 0x39, 0x34, 0x44, 0x37,
1448
+	0x27, 0x17, 0x88, 0x2a, 0x64, 0x2f, 0x26, 0xbd, 0xea, 0x1e, 0xc5, 0xb2, 0x9e, 0xec, 0x8c, 0xe5,
1449
+	0xaa, 0x62, 0x35, 0xca, 0xdd, 0x84, 0x9f, 0x46, 0x79, 0xd6, 0xbd, 0x84, 0xe6, 0x58, 0xf8, 0x46,
1450
+	0xae, 0x12, 0x01, 0xf8, 0x89, 0x32, 0x2e, 0xdf, 0x43, 0xd7, 0xf4, 0xa1, 0x70, 0x75, 0x63, 0x6c,
1451
+	0xba, 0xf5, 0x11, 0x00, 0xfb, 0xf6, 0x19, 0xa8, 0x42, 0x65, 0x3e, 0x7d, 0xea, 0x1b, 0x02, 0x3f,
1452
+	0xb4, 0xd4, 0xb0, 0x73, 0x02, 0xdb, 0x0b, 0x32, 0x97, 0x94, 0xa9, 0xef, 0x98, 0x65, 0xaa, 0xde,
1453
+	0xbb, 0x2d, 0x45, 0x9a, 0x4b, 0xcd, 0xda, 0xf5, 0xb7, 0x92, 0xf8, 0x54, 0xd2, 0xaf, 0x53, 0xd8,
1454
+	0xb7, 0x35, 0x23, 0xd1, 0x7c, 0xe9, 0x03, 0xa8, 0x18, 0x82, 0xcc, 0xc6, 0xcc, 0x6d, 0x44, 0x66,
1455
+	0x9b, 0x86, 0x07, 0x31, 0xe4, 0x1e, 0x58, 0x7a, 0x10, 0x86, 0x73, 0xdc, 0xfa, 0xd0, 0x38, 0xed,
1456
+	0x42, 0xa3, 0x68, 0x7d, 0x48, 0xa3, 0x28, 0x5f, 0x3b, 0x56, 0x3d, 0xd5, 0xf6, 0xfe, 0x55, 0x85,
1457
+	0xca, 0xb3, 0xfe, 0x4b, 0xfb, 0x14, 0xb6, 0xe6, 0xff, 0xe9, 0xb0, 0xef, 0x49, 0xb3, 0x56, 0xfc,
1458
+	0x3b, 0xd2, 0xb9, 0xbf, 0x72, 0x5e, 0xb6, 0xec, 0xb7, 0x6c, 0x17, 0x36, 0xe7, 0xde, 0xb5, 0x6d,
1459
+	0x75, 0xd5, 0x2c, 0xff, 0xef, 0xa0, 0x73, 0x6f, 0xd5, 0xb4, 0x29, 0x73, 0xee, 0x1b, 0x41, 0xcb,
1460
+	0x5c, 0xfe, 0x8d, 0xa9, 0x65, 0xae, 0xfa, 0xb4, 0xb8, 0x65, 0xff, 0x00, 0xaa, 0xe2, 0xa5, 0xdb,
1461
+	0xde, 0x91, 0xbc, 0x85, 0x37, 0xf4, 0xce, 0xee, 0x1c, 0xaa, 0x17, 0xbe, 0x82, 0x66, 0xe1, 0xef,
1462
+	0x11, 0xfb, 0xa3, 0x82, 0xae, 0xe2, 0x43, 0x79, 0xe7, 0xe3, 0xe5, 0x93, 0x5a, 0xda, 0x01, 0x40,
1463
+	0xfe, 0x18, 0x6a, 0xb7, 0x25, 0xf7, 0xc2, 0x83, 0x7b, 0xe7, 0xce, 0x92, 0x19, 0x2d, 0x04, 0x8f,
1464
+	0x72, 0xfe, 0xd9, 0xd2, 0x9e, 0xf3, 0xea, 0xfc, 0xa3, 0xa1, 0x3e, 0xca, 0x95, 0xef, 0x9d, 0x5c,
1465
+	0xec, 0xfc, 0x63, 0xa4, 0x16, 0xbb, 0xe2, 0x29, 0x54, 0x8b, 0x5d, 0xf9, 0x8a, 0x79, 0xcb, 0xfe,
1466
+	0x0a, 0x5a, 0xc5, 0xd7, 0x3d, 0x5b, 0x39, 0x69, 0xe9, 0xf3, 0x66, 0xe7, 0xee, 0x8a, 0x59, 0x2d,
1467
+	0xf0, 0x33, 0x58, 0x13, 0xcf, 0x76, 0x2a, 0x1d, 0xcd, 0xd7, 0xbe, 0xce, 0x4e, 0x11, 0xd4, 0xab,
1468
+	0x1e, 0x43, 0x55, 0x7c, 0x5d, 0xea, 0x00, 0x28, 0x7c, 0x6c, 0x76, 0x1a, 0x26, 0xea, 0xdc, 0x7a,
1469
+	0x5c, 0x52, 0x7a, 0xb2, 0x82, 0x9e, 0x6c, 0x99, 0x1e, 0xe3, 0x70, 0xce, 0xaa, 0x3c, 0x5d, 0x9f,
1470
+	0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x06, 0x1e, 0xda, 0xa8, 0x1c, 0x00, 0x00,
1468 1471
 }
... ...
@@ -2,6 +2,8 @@ syntax = "proto3";
2 2
 
3 3
 package types;
4 4
 
5
+import "google/protobuf/timestamp.proto";
6
+
5 7
 service API {
6 8
 	rpc GetServerVersion(GetServerVersionRequest) returns (GetServerVersionResponse) {}
7 9
 	rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
... ...
@@ -185,7 +187,7 @@ message StateResponse {
185 185
 message UpdateContainerRequest {
186 186
 	string id = 1; // ID of container
187 187
 	string pid = 2;
188
-	string status = 3; // Status to whcih containerd will try to change
188
+	string status = 3; // Status to which containerd will try to change
189 189
 	UpdateResource resources =4;
190 190
 }
191 191
 
... ...
@@ -207,7 +209,10 @@ message UpdateContainerResponse {
207 207
 }
208 208
 
209 209
 message EventsRequest {
210
-	uint64 timestamp = 1;
210
+	// Tag 1 is deprecated (old uint64 timestamp)
211
+	google.protobuf.Timestamp timestamp = 2;
212
+	bool storedOnly = 3;
213
+	string id = 4;
211 214
 }
212 215
 
213 216
 message Event {
... ...
@@ -215,7 +220,8 @@ message Event {
215 215
 	string id = 2;
216 216
 	uint32 status = 3;
217 217
 	string pid = 4;
218
-	uint64 timestamp = 5;
218
+	// Tag 5 is deprecated (old uint64 timestamp)
219
+	google.protobuf.Timestamp timestamp = 6;
219 220
 }
220 221
 
221 222
 message NetworkStats {
... ...
@@ -277,7 +283,7 @@ message BlkioStatsEntry {
277 277
 }
278 278
 
279 279
 message BlkioStats {
280
-	repeated BlkioStatsEntry io_service_bytes_recursive = 1; // number of bytes tranferred to and from the block device
280
+	repeated BlkioStatsEntry io_service_bytes_recursive = 1; // number of bytes transferred to and from the block device
281 281
 	repeated BlkioStatsEntry io_serviced_recursive = 2;
282 282
 	repeated BlkioStatsEntry io_queued_recursive = 3;
283 283
 	repeated BlkioStatsEntry io_service_time_recursive = 4;
... ...
@@ -305,7 +311,8 @@ message CgroupStats {
305 305
 message StatsResponse {
306 306
 	repeated NetworkStats network_stats = 1;
307 307
 	CgroupStats cgroup_stats = 2;
308
-	uint64 timestamp = 3;
308
+	// Tag 3 is deprecated (old uint64 timestamp)
309
+	google.protobuf.Timestamp timestamp = 4;
309 310
 };
310 311
 
311 312
 message StatsRequest {
312 313
new file mode 100644
... ...
@@ -0,0 +1,35 @@
0
+// Go support for Protocol Buffers - Google's data interchange format
1
+//
2
+// Copyright 2016 The Go Authors.  All rights reserved.
3
+// https://github.com/golang/protobuf
4
+//
5
+// Redistribution and use in source and binary forms, with or without
6
+// modification, are permitted provided that the following conditions are
7
+// met:
8
+//
9
+//     * Redistributions of source code must retain the above copyright
10
+// notice, this list of conditions and the following disclaimer.
11
+//     * Redistributions in binary form must reproduce the above
12
+// copyright notice, this list of conditions and the following disclaimer
13
+// in the documentation and/or other materials provided with the
14
+// distribution.
15
+//     * Neither the name of Google Inc. nor the names of its
16
+// contributors may be used to endorse or promote products derived from
17
+// this software without specific prior written permission.
18
+//
19
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+/*
32
+Package ptypes contains code for interacting with well-known types.
33
+*/
34
+package ptypes
0 35
new file mode 100644
... ...
@@ -0,0 +1,102 @@
0
+// Go support for Protocol Buffers - Google's data interchange format
1
+//
2
+// Copyright 2016 The Go Authors.  All rights reserved.
3
+// https://github.com/golang/protobuf
4
+//
5
+// Redistribution and use in source and binary forms, with or without
6
+// modification, are permitted provided that the following conditions are
7
+// met:
8
+//
9
+//     * Redistributions of source code must retain the above copyright
10
+// notice, this list of conditions and the following disclaimer.
11
+//     * Redistributions in binary form must reproduce the above
12
+// copyright notice, this list of conditions and the following disclaimer
13
+// in the documentation and/or other materials provided with the
14
+// distribution.
15
+//     * Neither the name of Google Inc. nor the names of its
16
+// contributors may be used to endorse or promote products derived from
17
+// this software without specific prior written permission.
18
+//
19
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+package ptypes
32
+
33
+// This file implements conversions between google.protobuf.Duration
34
+// and time.Duration.
35
+
36
+import (
37
+	"errors"
38
+	"fmt"
39
+	"time"
40
+
41
+	durpb "github.com/golang/protobuf/ptypes/duration"
42
+)
43
+
44
+const (
45
+	// Range of a durpb.Duration in seconds, as specified in
46
+	// google/protobuf/duration.proto. This is about 10,000 years in seconds.
47
+	maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
48
+	minSeconds = -maxSeconds
49
+)
50
+
51
+// validateDuration determines whether the durpb.Duration is valid according to the
52
+// definition in google/protobuf/duration.proto. A valid durpb.Duration
53
+// may still be too large to fit into a time.Duration (the range of durpb.Duration
54
+// is about 10,000 years, and the range of time.Duration is about 290).
55
+func validateDuration(d *durpb.Duration) error {
56
+	if d == nil {
57
+		return errors.New("duration: nil Duration")
58
+	}
59
+	if d.Seconds < minSeconds || d.Seconds > maxSeconds {
60
+		return fmt.Errorf("duration: %v: seconds out of range", d)
61
+	}
62
+	if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
63
+		return fmt.Errorf("duration: %v: nanos out of range", d)
64
+	}
65
+	// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
66
+	if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
67
+		return fmt.Errorf("duration: %v: seconds and nanos have different signs", d)
68
+	}
69
+	return nil
70
+}
71
+
72
+// Duration converts a durpb.Duration to a time.Duration. Duration
73
+// returns an error if the durpb.Duration is invalid or is too large to be
74
+// represented in a time.Duration.
75
+func Duration(p *durpb.Duration) (time.Duration, error) {
76
+	if err := validateDuration(p); err != nil {
77
+		return 0, err
78
+	}
79
+	d := time.Duration(p.Seconds) * time.Second
80
+	if int64(d/time.Second) != p.Seconds {
81
+		return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
82
+	}
83
+	if p.Nanos != 0 {
84
+		d += time.Duration(p.Nanos)
85
+		if (d < 0) != (p.Nanos < 0) {
86
+			return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
87
+		}
88
+	}
89
+	return d, nil
90
+}
91
+
92
+// DurationProto converts a time.Duration to a durpb.Duration.
93
+func DurationProto(d time.Duration) *durpb.Duration {
94
+	nanos := d.Nanoseconds()
95
+	secs := nanos / 1e9
96
+	nanos -= secs * 1e9
97
+	return &durpb.Duration{
98
+		Seconds: secs,
99
+		Nanos:   int32(nanos),
100
+	}
101
+}
0 102
new file mode 100644
... ...
@@ -0,0 +1,106 @@
0
+// Code generated by protoc-gen-go.
1
+// source: github.com/golang/protobuf/types/duration/duration.proto
2
+// DO NOT EDIT!
3
+
4
+/*
5
+Package duration is a generated protocol buffer package.
6
+
7
+It is generated from these files:
8
+	github.com/golang/protobuf/types/duration/duration.proto
9
+
10
+It has these top-level messages:
11
+	Duration
12
+*/
13
+package duration
14
+
15
+import proto "github.com/golang/protobuf/proto"
16
+import fmt "fmt"
17
+import math "math"
18
+
19
+// Reference imports to suppress errors if they are not otherwise used.
20
+var _ = proto.Marshal
21
+var _ = fmt.Errorf
22
+var _ = math.Inf
23
+
24
+// This is a compile-time assertion to ensure that this generated file
25
+// is compatible with the proto package it is being compiled against.
26
+const _ = proto.ProtoPackageIsVersion1
27
+
28
+// A Duration represents a signed, fixed-length span of time represented
29
+// as a count of seconds and fractions of seconds at nanosecond
30
+// resolution. It is independent of any calendar and concepts like "day"
31
+// or "month". It is related to Timestamp in that the difference between
32
+// two Timestamp values is a Duration and it can be added or subtracted
33
+// from a Timestamp. Range is approximately +-10,000 years.
34
+//
35
+// Example 1: Compute Duration from two Timestamps in pseudo code.
36
+//
37
+//     Timestamp start = ...;
38
+//     Timestamp end = ...;
39
+//     Duration duration = ...;
40
+//
41
+//     duration.seconds = end.seconds - start.seconds;
42
+//     duration.nanos = end.nanos - start.nanos;
43
+//
44
+//     if (duration.seconds < 0 && duration.nanos > 0) {
45
+//       duration.seconds += 1;
46
+//       duration.nanos -= 1000000000;
47
+//     } else if (durations.seconds > 0 && duration.nanos < 0) {
48
+//       duration.seconds -= 1;
49
+//       duration.nanos += 1000000000;
50
+//     }
51
+//
52
+// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
53
+//
54
+//     Timestamp start = ...;
55
+//     Duration duration = ...;
56
+//     Timestamp end = ...;
57
+//
58
+//     end.seconds = start.seconds + duration.seconds;
59
+//     end.nanos = start.nanos + duration.nanos;
60
+//
61
+//     if (end.nanos < 0) {
62
+//       end.seconds -= 1;
63
+//       end.nanos += 1000000000;
64
+//     } else if (end.nanos >= 1000000000) {
65
+//       end.seconds += 1;
66
+//       end.nanos -= 1000000000;
67
+//     }
68
+//
69
+type Duration struct {
70
+	// Signed seconds of the span of time. Must be from -315,576,000,000
71
+	// to +315,576,000,000 inclusive.
72
+	Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
73
+	// Signed fractions of a second at nanosecond resolution of the span
74
+	// of time. Durations less than one second are represented with a 0
75
+	// `seconds` field and a positive or negative `nanos` field. For durations
76
+	// of one second or more, a non-zero value for the `nanos` field must be
77
+	// of the same sign as the `seconds` field. Must be from -999,999,999
78
+	// to +999,999,999 inclusive.
79
+	Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
80
+}
81
+
82
+func (m *Duration) Reset()                    { *m = Duration{} }
83
+func (m *Duration) String() string            { return proto.CompactTextString(m) }
84
+func (*Duration) ProtoMessage()               {}
85
+func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
86
+
87
+func init() {
88
+	proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
89
+}
90
+
91
+var fileDescriptor0 = []byte{
92
+	// 186 bytes of a gzipped FileDescriptorProto
93
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9,
94
+	0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
95
+	0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0x29, 0x2d,
96
+	0x4a, 0x2c, 0xc9, 0xcc, 0xcf, 0x83, 0x33, 0xf4, 0xc0, 0x0a, 0x84, 0xf8, 0xd3, 0xf3, 0xf3, 0xd3,
97
+	0x73, 0x52, 0xf5, 0x60, 0xca, 0x95, 0xac, 0xb8, 0x38, 0x5c, 0xa0, 0x4a, 0x84, 0x24, 0xb8, 0xd8,
98
+	0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60, 0x5c,
99
+	0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0xa0, 0x38, 0x6b, 0x10, 0x84,
100
+	0xe3, 0x14, 0xc5, 0x25, 0x0c, 0x74, 0x81, 0x1e, 0x9a, 0x91, 0x4e, 0xbc, 0x30, 0x03, 0x03, 0x40,
101
+	0x22, 0x01, 0x8c, 0x51, 0x1c, 0x30, 0x47, 0x2c, 0x60, 0x64, 0x5c, 0xc4, 0xc4, 0xec, 0x1e, 0xe0,
102
+	0xb4, 0x8a, 0x49, 0xce, 0x1d, 0xa2, 0x2b, 0x00, 0xaa, 0x4b, 0x2f, 0x3c, 0x35, 0x27, 0xc7, 0x3b,
103
+	0x2f, 0xbf, 0x3c, 0x2f, 0x04, 0xe4, 0x81, 0x24, 0x36, 0xb0, 0x71, 0xc6, 0x80, 0x00, 0x00, 0x00,
104
+	0xff, 0xff, 0x04, 0x47, 0x33, 0x15, 0xeb, 0x00, 0x00, 0x00,
105
+}
0 106
new file mode 100644
... ...
@@ -0,0 +1,97 @@
0
+// Protocol Buffers - Google's data interchange format
1
+// Copyright 2008 Google Inc.  All rights reserved.
2
+// https://developers.google.com/protocol-buffers/
3
+//
4
+// Redistribution and use in source and binary forms, with or without
5
+// modification, are permitted provided that the following conditions are
6
+// met:
7
+//
8
+//     * Redistributions of source code must retain the above copyright
9
+// notice, this list of conditions and the following disclaimer.
10
+//     * Redistributions in binary form must reproduce the above
11
+// copyright notice, this list of conditions and the following disclaimer
12
+// in the documentation and/or other materials provided with the
13
+// distribution.
14
+//     * Neither the name of Google Inc. nor the names of its
15
+// contributors may be used to endorse or promote products derived from
16
+// this software without specific prior written permission.
17
+//
18
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+syntax = "proto3";
31
+
32
+package google.protobuf;
33
+option go_package = "duration";
34
+
35
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36
+option java_package = "com.google.protobuf";
37
+option java_outer_classname = "DurationProto";
38
+option java_multiple_files = true;
39
+option java_generate_equals_and_hash = true;
40
+option objc_class_prefix = "GPB";
41
+
42
+// A Duration represents a signed, fixed-length span of time represented
43
+// as a count of seconds and fractions of seconds at nanosecond
44
+// resolution. It is independent of any calendar and concepts like "day"
45
+// or "month". It is related to Timestamp in that the difference between
46
+// two Timestamp values is a Duration and it can be added or subtracted
47
+// from a Timestamp. Range is approximately +-10,000 years.
48
+//
49
+// Example 1: Compute Duration from two Timestamps in pseudo code.
50
+//
51
+//     Timestamp start = ...;
52
+//     Timestamp end = ...;
53
+//     Duration duration = ...;
54
+//
55
+//     duration.seconds = end.seconds - start.seconds;
56
+//     duration.nanos = end.nanos - start.nanos;
57
+//
58
+//     if (duration.seconds < 0 && duration.nanos > 0) {
59
+//       duration.seconds += 1;
60
+//       duration.nanos -= 1000000000;
61
+//     } else if (durations.seconds > 0 && duration.nanos < 0) {
62
+//       duration.seconds -= 1;
63
+//       duration.nanos += 1000000000;
64
+//     }
65
+//
66
+// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
67
+//
68
+//     Timestamp start = ...;
69
+//     Duration duration = ...;
70
+//     Timestamp end = ...;
71
+//
72
+//     end.seconds = start.seconds + duration.seconds;
73
+//     end.nanos = start.nanos + duration.nanos;
74
+//
75
+//     if (end.nanos < 0) {
76
+//       end.seconds -= 1;
77
+//       end.nanos += 1000000000;
78
+//     } else if (end.nanos >= 1000000000) {
79
+//       end.seconds += 1;
80
+//       end.nanos -= 1000000000;
81
+//     }
82
+//
83
+message Duration {
84
+
85
+  // Signed seconds of the span of time. Must be from -315,576,000,000
86
+  // to +315,576,000,000 inclusive.
87
+  int64 seconds = 1;
88
+
89
+  // Signed fractions of a second at nanosecond resolution of the span
90
+  // of time. Durations less than one second are represented with a 0
91
+  // `seconds` field and a positive or negative `nanos` field. For durations
92
+  // of one second or more, a non-zero value for the `nanos` field must be
93
+  // of the same sign as the `seconds` field. Must be from -999,999,999
94
+  // to +999,999,999 inclusive.
95
+  int32 nanos = 2;
96
+}
0 97
new file mode 100755
... ...
@@ -0,0 +1,72 @@
0
+#!/bin/bash -e
1
+#
2
+# This script fetches and rebuilds the "well-known types" protocol buffers.
3
+# To run this you will need protoc and goprotobuf installed;
4
+# see https://github.com/golang/protobuf for instructions.
5
+# You also need Go and Git installed.
6
+
7
+PKG=github.com/golang/protobuf/types
8
+UPSTREAM=https://github.com/google/protobuf
9
+UPSTREAM_SUBDIR=src/google/protobuf
10
+PROTO_FILES='
11
+  any.proto
12
+  duration.proto
13
+  empty.proto
14
+  struct.proto
15
+  timestamp.proto
16
+  wrappers.proto
17
+'
18
+
19
+function die() {
20
+  echo 1>&2 $*
21
+  exit 1
22
+}
23
+
24
+# Sanity check that the right tools are accessible.
25
+for tool in go git protoc protoc-gen-go; do
26
+  q=$(which $tool) || die "didn't find $tool"
27
+  echo 1>&2 "$tool: $q"
28
+done
29
+
30
+tmpdir=$(mktemp -d -t regen-wkt.XXXXXX)
31
+trap 'rm -rf $tmpdir' EXIT
32
+
33
+echo -n 1>&2 "finding package dir... "
34
+pkgdir=$(go list -f '{{.Dir}}' $PKG)
35
+echo 1>&2 $pkgdir
36
+base=$(echo $pkgdir | sed "s,/$PKG\$,,")
37
+echo 1>&2 "base: $base"
38
+cd $base
39
+
40
+echo 1>&2 "fetching latest protos... "
41
+git clone -q $UPSTREAM $tmpdir
42
+# Pass 1: build mapping from upstream filename to our filename.
43
+declare -A filename_map
44
+for f in $(cd $PKG && find * -name '*.proto'); do
45
+  echo -n 1>&2 "looking for latest version of $f... "
46
+  up=$(cd $tmpdir/$UPSTREAM_SUBDIR && find * -name $(basename $f) | grep -v /testdata/)
47
+  echo 1>&2 $up
48
+  if [ $(echo $up | wc -w) != "1" ]; then
49
+    die "not exactly one match"
50
+  fi
51
+  filename_map[$up]=$f
52
+done
53
+# Pass 2: copy files, making necessary adjustments.
54
+for up in "${!filename_map[@]}"; do
55
+  f=${filename_map[$up]}
56
+  shortname=$(basename $f | sed 's,\.proto$,,')
57
+  cat $tmpdir/$UPSTREAM_SUBDIR/$up |
58
+    # Adjust proto package.
59
+    # TODO(dsymonds): Upstream the go_package option instead.
60
+    sed '/^package /a option go_package = "'${shortname}'";' |
61
+    # Unfortunately "package struct" doesn't work.
62
+    sed '/option go_package/s,"struct","structpb",' |
63
+    cat > $PKG/$f
64
+done
65
+
66
+# Run protoc once per package.
67
+for dir in $(find $PKG -name '*.proto' | xargs dirname | sort | uniq); do
68
+  echo 1>&2 "* $dir"
69
+  protoc --go_out=. $dir/*.proto
70
+done
71
+echo 1>&2 "All OK"
0 72
new file mode 100644
... ...
@@ -0,0 +1,125 @@
0
+// Go support for Protocol Buffers - Google's data interchange format
1
+//
2
+// Copyright 2016 The Go Authors.  All rights reserved.
3
+// https://github.com/golang/protobuf
4
+//
5
+// Redistribution and use in source and binary forms, with or without
6
+// modification, are permitted provided that the following conditions are
7
+// met:
8
+//
9
+//     * Redistributions of source code must retain the above copyright
10
+// notice, this list of conditions and the following disclaimer.
11
+//     * Redistributions in binary form must reproduce the above
12
+// copyright notice, this list of conditions and the following disclaimer
13
+// in the documentation and/or other materials provided with the
14
+// distribution.
15
+//     * Neither the name of Google Inc. nor the names of its
16
+// contributors may be used to endorse or promote products derived from
17
+// this software without specific prior written permission.
18
+//
19
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+package ptypes
32
+
33
+// This file implements operations on google.protobuf.Timestamp.
34
+
35
+import (
36
+	"errors"
37
+	"fmt"
38
+	"time"
39
+
40
+	tspb "github.com/golang/protobuf/ptypes/timestamp"
41
+)
42
+
43
+const (
44
+	// Seconds field of the earliest valid Timestamp.
45
+	// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
46
+	minValidSeconds = -62135596800
47
+	// Seconds field just after the latest valid Timestamp.
48
+	// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
49
+	maxValidSeconds = 253402300800
50
+)
51
+
52
+// validateTimestamp determines whether a Timestamp is valid.
53
+// A valid timestamp represents a time in the range
54
+// [0001-01-01, 10000-01-01) and has a Nanos field
55
+// in the range [0, 1e9).
56
+//
57
+// If the Timestamp is valid, validateTimestamp returns nil.
58
+// Otherwise, it returns an error that describes
59
+// the problem.
60
+//
61
+// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
62
+func validateTimestamp(ts *tspb.Timestamp) error {
63
+	if ts == nil {
64
+		return errors.New("timestamp: nil Timestamp")
65
+	}
66
+	if ts.Seconds < minValidSeconds {
67
+		return fmt.Errorf("timestamp: %v before 0001-01-01", ts)
68
+	}
69
+	if ts.Seconds >= maxValidSeconds {
70
+		return fmt.Errorf("timestamp: %v after 10000-01-01", ts)
71
+	}
72
+	if ts.Nanos < 0 || ts.Nanos >= 1e9 {
73
+		return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts)
74
+	}
75
+	return nil
76
+}
77
+
78
+// Timestamp converts a google.protobuf.Timestamp proto to a time.Time.
79
+// It returns an error if the argument is invalid.
80
+//
81
+// Unlike most Go functions, if Timestamp returns an error, the first return value
82
+// is not the zero time.Time. Instead, it is the value obtained from the
83
+// time.Unix function when passed the contents of the Timestamp, in the UTC
84
+// locale. This may or may not be a meaningful time; many invalid Timestamps
85
+// do map to valid time.Times.
86
+//
87
+// A nil Timestamp returns an error. The first return value in that case is
88
+// undefined.
89
+func Timestamp(ts *tspb.Timestamp) (time.Time, error) {
90
+	// Don't return the zero value on error, because corresponds to a valid
91
+	// timestamp. Instead return whatever time.Unix gives us.
92
+	var t time.Time
93
+	if ts == nil {
94
+		t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
95
+	} else {
96
+		t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
97
+	}
98
+	return t, validateTimestamp(ts)
99
+}
100
+
101
+// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
102
+// It returns an error if the resulting Timestamp is invalid.
103
+func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
104
+	seconds := t.Unix()
105
+	nanos := int32(t.Sub(time.Unix(seconds, 0)))
106
+	ts := &tspb.Timestamp{
107
+		Seconds: seconds,
108
+		Nanos:   nanos,
109
+	}
110
+	if err := validateTimestamp(ts); err != nil {
111
+		return nil, err
112
+	}
113
+	return ts, nil
114
+}
115
+
116
+// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
117
+// Timestamps, it returns an error message in parentheses.
118
+func TimestampString(ts *tspb.Timestamp) string {
119
+	t, err := Timestamp(ts)
120
+	if err != nil {
121
+		return fmt.Sprintf("(%v)", err)
122
+	}
123
+	return t.Format(time.RFC3339Nano)
124
+}
0 125
new file mode 100644
... ...
@@ -0,0 +1,119 @@
0
+// Code generated by protoc-gen-go.
1
+// source: github.com/golang/protobuf/types/timestamp/timestamp.proto
2
+// DO NOT EDIT!
3
+
4
+/*
5
+Package timestamp is a generated protocol buffer package.
6
+
7
+It is generated from these files:
8
+	github.com/golang/protobuf/types/timestamp/timestamp.proto
9
+
10
+It has these top-level messages:
11
+	Timestamp
12
+*/
13
+package timestamp
14
+
15
+import proto "github.com/golang/protobuf/proto"
16
+import fmt "fmt"
17
+import math "math"
18
+
19
+// Reference imports to suppress errors if they are not otherwise used.
20
+var _ = proto.Marshal
21
+var _ = fmt.Errorf
22
+var _ = math.Inf
23
+
24
+// This is a compile-time assertion to ensure that this generated file
25
+// is compatible with the proto package it is being compiled against.
26
+const _ = proto.ProtoPackageIsVersion1
27
+
28
+// A Timestamp represents a point in time independent of any time zone
29
+// or calendar, represented as seconds and fractions of seconds at
30
+// nanosecond resolution in UTC Epoch time. It is encoded using the
31
+// Proleptic Gregorian Calendar which extends the Gregorian calendar
32
+// backwards to year one. It is encoded assuming all minutes are 60
33
+// seconds long, i.e. leap seconds are "smeared" so that no leap second
34
+// table is needed for interpretation. Range is from
35
+// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
36
+// By restricting to that range, we ensure that we can convert to
37
+// and from  RFC 3339 date strings.
38
+// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
39
+//
40
+// Example 1: Compute Timestamp from POSIX `time()`.
41
+//
42
+//     Timestamp timestamp;
43
+//     timestamp.set_seconds(time(NULL));
44
+//     timestamp.set_nanos(0);
45
+//
46
+// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
47
+//
48
+//     struct timeval tv;
49
+//     gettimeofday(&tv, NULL);
50
+//
51
+//     Timestamp timestamp;
52
+//     timestamp.set_seconds(tv.tv_sec);
53
+//     timestamp.set_nanos(tv.tv_usec * 1000);
54
+//
55
+// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
56
+//
57
+//     FILETIME ft;
58
+//     GetSystemTimeAsFileTime(&ft);
59
+//     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
60
+//
61
+//     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
62
+//     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
63
+//     Timestamp timestamp;
64
+//     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
65
+//     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
66
+//
67
+// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
68
+//
69
+//     long millis = System.currentTimeMillis();
70
+//
71
+//     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
72
+//         .setNanos((int) ((millis % 1000) * 1000000)).build();
73
+//
74
+//
75
+// Example 5: Compute Timestamp from current time in Python.
76
+//
77
+//     now = time.time()
78
+//     seconds = int(now)
79
+//     nanos = int((now - seconds) * 10**9)
80
+//     timestamp = Timestamp(seconds=seconds, nanos=nanos)
81
+//
82
+//
83
+type Timestamp struct {
84
+	// Represents seconds of UTC time since Unix epoch
85
+	// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
86
+	// 9999-12-31T23:59:59Z inclusive.
87
+	Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
88
+	// Non-negative fractions of a second at nanosecond resolution. Negative
89
+	// second values with fractions must still have non-negative nanos values
90
+	// that count forward in time. Must be from 0 to 999,999,999
91
+	// inclusive.
92
+	Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
93
+}
94
+
95
+func (m *Timestamp) Reset()                    { *m = Timestamp{} }
96
+func (m *Timestamp) String() string            { return proto.CompactTextString(m) }
97
+func (*Timestamp) ProtoMessage()               {}
98
+func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
99
+
100
+func init() {
101
+	proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
102
+}
103
+
104
+var fileDescriptor0 = []byte{
105
+	// 190 bytes of a gzipped FileDescriptorProto
106
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x4a, 0xcf, 0x2c, 0xc9,
107
+	0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
108
+	0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0xc9, 0xcc,
109
+	0x4d, 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0x40, 0xb0, 0xf4, 0xc0, 0x4a, 0x84, 0xf8, 0xd3, 0xf3, 0xf3,
110
+	0xd3, 0x73, 0x52, 0xf5, 0x60, 0x1a, 0x94, 0xac, 0xb9, 0x38, 0x43, 0x60, 0x6a, 0x84, 0x24, 0xb8,
111
+	0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60,
112
+	0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0xa0, 0x38, 0x6b, 0x10,
113
+	0x84, 0xe3, 0x14, 0xcf, 0x25, 0x0c, 0x74, 0x84, 0x1e, 0x9a, 0x99, 0x4e, 0x7c, 0x70, 0x13, 0x03,
114
+	0x40, 0x42, 0x01, 0x8c, 0x51, 0x9c, 0x70, 0x77, 0x2c, 0x60, 0x64, 0xfc, 0xc1, 0xc8, 0xb8, 0x88,
115
+	0x89, 0xd9, 0x3d, 0xc0, 0x69, 0x15, 0x93, 0x9c, 0x3b, 0x44, 0x6b, 0x00, 0x54, 0xab, 0x5e, 0x78,
116
+	0x6a, 0x4e, 0x8e, 0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0xc8, 0x23, 0x49, 0x6c, 0x60, 0x33, 0x8d,
117
+	0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x5b, 0xdd, 0x30, 0x93, 0xf3, 0x00, 0x00, 0x00,
118
+}
0 119
new file mode 100644
... ...
@@ -0,0 +1,111 @@
0
+// Protocol Buffers - Google's data interchange format
1
+// Copyright 2008 Google Inc.  All rights reserved.
2
+// https://developers.google.com/protocol-buffers/
3
+//
4
+// Redistribution and use in source and binary forms, with or without
5
+// modification, are permitted provided that the following conditions are
6
+// met:
7
+//
8
+//     * Redistributions of source code must retain the above copyright
9
+// notice, this list of conditions and the following disclaimer.
10
+//     * Redistributions in binary form must reproduce the above
11
+// copyright notice, this list of conditions and the following disclaimer
12
+// in the documentation and/or other materials provided with the
13
+// distribution.
14
+//     * Neither the name of Google Inc. nor the names of its
15
+// contributors may be used to endorse or promote products derived from
16
+// this software without specific prior written permission.
17
+//
18
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+syntax = "proto3";
31
+
32
+package google.protobuf;
33
+option go_package = "timestamp";
34
+
35
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
36
+option cc_enable_arenas = true;
37
+option java_package = "com.google.protobuf";
38
+option java_outer_classname = "TimestampProto";
39
+option java_multiple_files = true;
40
+option java_generate_equals_and_hash = true;
41
+option objc_class_prefix = "GPB";
42
+
43
+// A Timestamp represents a point in time independent of any time zone
44
+// or calendar, represented as seconds and fractions of seconds at
45
+// nanosecond resolution in UTC Epoch time. It is encoded using the
46
+// Proleptic Gregorian Calendar which extends the Gregorian calendar
47
+// backwards to year one. It is encoded assuming all minutes are 60
48
+// seconds long, i.e. leap seconds are "smeared" so that no leap second
49
+// table is needed for interpretation. Range is from
50
+// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
51
+// By restricting to that range, we ensure that we can convert to
52
+// and from  RFC 3339 date strings.
53
+// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
54
+//
55
+// Example 1: Compute Timestamp from POSIX `time()`.
56
+//
57
+//     Timestamp timestamp;
58
+//     timestamp.set_seconds(time(NULL));
59
+//     timestamp.set_nanos(0);
60
+//
61
+// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
62
+//
63
+//     struct timeval tv;
64
+//     gettimeofday(&tv, NULL);
65
+//
66
+//     Timestamp timestamp;
67
+//     timestamp.set_seconds(tv.tv_sec);
68
+//     timestamp.set_nanos(tv.tv_usec * 1000);
69
+//
70
+// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
71
+//
72
+//     FILETIME ft;
73
+//     GetSystemTimeAsFileTime(&ft);
74
+//     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
75
+//
76
+//     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
77
+//     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
78
+//     Timestamp timestamp;
79
+//     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
80
+//     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
81
+//
82
+// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
83
+//
84
+//     long millis = System.currentTimeMillis();
85
+//
86
+//     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
87
+//         .setNanos((int) ((millis % 1000) * 1000000)).build();
88
+//
89
+//
90
+// Example 5: Compute Timestamp from current time in Python.
91
+//
92
+//     now = time.time()
93
+//     seconds = int(now)
94
+//     nanos = int((now - seconds) * 10**9)
95
+//     timestamp = Timestamp(seconds=seconds, nanos=nanos)
96
+//
97
+//
98
+message Timestamp {
99
+
100
+  // Represents seconds of UTC time since Unix epoch
101
+  // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
102
+  // 9999-12-31T23:59:59Z inclusive.
103
+  int64 seconds = 1;
104
+
105
+  // Non-negative fractions of a second at nanosecond resolution. Negative
106
+  // second values with fractions must still have non-negative nanos values
107
+  // that count forward in time. Must be from 0 to 999,999,999
108
+  // inclusive.
109
+  int32 nanos = 2;
110
+}