Browse code

Update moby to runc and oci 1.0 runtime final rc

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>

Michael Crosby authored on 2017/04/28 06:52:47
Showing 39 changed files
... ...
@@ -64,8 +64,8 @@ const (
64 64
 	cgroupSystemdDriver = "systemd"
65 65
 )
66 66
 
67
-func getMemoryResources(config containertypes.Resources) *specs.Memory {
68
-	memory := specs.Memory{}
67
+func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory {
68
+	memory := specs.LinuxMemory{}
69 69
 
70 70
 	if config.Memory > 0 {
71 71
 		limit := uint64(config.Memory)
... ...
@@ -77,7 +77,7 @@ func getMemoryResources(config containertypes.Resources) *specs.Memory {
77 77
 		memory.Reservation = &reservation
78 78
 	}
79 79
 
80
-	if config.MemorySwap != 0 {
80
+	if config.MemorySwap > 0 {
81 81
 		swap := uint64(config.MemorySwap)
82 82
 		memory.Swap = &swap
83 83
 	}
... ...
@@ -95,28 +95,29 @@ func getMemoryResources(config containertypes.Resources) *specs.Memory {
95 95
 	return &memory
96 96
 }
97 97
 
98
-func getCPUResources(config containertypes.Resources) *specs.CPU {
99
-	cpu := specs.CPU{}
98
+func getCPUResources(config containertypes.Resources) (*specs.LinuxCPU, error) {
99
+	cpu := specs.LinuxCPU{}
100 100
 
101
-	if config.CPUShares != 0 {
101
+	if config.CPUShares < 0 {
102
+		return nil, fmt.Errorf("shares: invalid argument")
103
+	}
104
+	if config.CPUShares >= 0 {
102 105
 		shares := uint64(config.CPUShares)
103 106
 		cpu.Shares = &shares
104 107
 	}
105 108
 
106 109
 	if config.CpusetCpus != "" {
107
-		cpuset := config.CpusetCpus
108
-		cpu.Cpus = &cpuset
110
+		cpu.Cpus = config.CpusetCpus
109 111
 	}
110 112
 
111 113
 	if config.CpusetMems != "" {
112
-		cpuset := config.CpusetMems
113
-		cpu.Mems = &cpuset
114
+		cpu.Mems = config.CpusetMems
114 115
 	}
115 116
 
116 117
 	if config.NanoCPUs > 0 {
117 118
 		// https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt
118 119
 		period := uint64(100 * time.Millisecond / time.Microsecond)
119
-		quota := uint64(config.NanoCPUs) * period / 1e9
120
+		quota := config.NanoCPUs * int64(period) / 1e9
120 121
 		cpu.Period = &period
121 122
 		cpu.Quota = &quota
122 123
 	}
... ...
@@ -127,8 +128,8 @@ func getCPUResources(config containertypes.Resources) *specs.CPU {
127 127
 	}
128 128
 
129 129
 	if config.CPUQuota != 0 {
130
-		quota := uint64(config.CPUQuota)
131
-		cpu.Quota = &quota
130
+		q := config.CPUQuota
131
+		cpu.Quota = &q
132 132
 	}
133 133
 
134 134
 	if config.CPURealtimePeriod != 0 {
... ...
@@ -137,23 +138,23 @@ func getCPUResources(config containertypes.Resources) *specs.CPU {
137 137
 	}
138 138
 
139 139
 	if config.CPURealtimeRuntime != 0 {
140
-		runtime := uint64(config.CPURealtimeRuntime)
141
-		cpu.RealtimeRuntime = &runtime
140
+		c := config.CPURealtimeRuntime
141
+		cpu.RealtimeRuntime = &c
142 142
 	}
143 143
 
144
-	return &cpu
144
+	return &cpu, nil
145 145
 }
146 146
 
147
-func getBlkioWeightDevices(config containertypes.Resources) ([]specs.WeightDevice, error) {
147
+func getBlkioWeightDevices(config containertypes.Resources) ([]specs.LinuxWeightDevice, error) {
148 148
 	var stat syscall.Stat_t
149
-	var blkioWeightDevices []specs.WeightDevice
149
+	var blkioWeightDevices []specs.LinuxWeightDevice
150 150
 
151 151
 	for _, weightDevice := range config.BlkioWeightDevice {
152 152
 		if err := syscall.Stat(weightDevice.Path, &stat); err != nil {
153 153
 			return nil, err
154 154
 		}
155 155
 		weight := weightDevice.Weight
156
-		d := specs.WeightDevice{Weight: &weight}
156
+		d := specs.LinuxWeightDevice{Weight: &weight}
157 157
 		d.Major = int64(stat.Rdev / 256)
158 158
 		d.Minor = int64(stat.Rdev % 256)
159 159
 		blkioWeightDevices = append(blkioWeightDevices, d)
... ...
@@ -178,6 +179,10 @@ func parseSecurityOpt(container *container.Container, config *containertypes.Hos
178 178
 			container.NoNewPrivileges = true
179 179
 			continue
180 180
 		}
181
+		if opt == "disable" {
182
+			labelOpts = append(labelOpts, "disable")
183
+			continue
184
+		}
181 185
 
182 186
 		var con []string
183 187
 		if strings.Contains(opt, "=") {
... ...
@@ -186,7 +191,6 @@ func parseSecurityOpt(container *container.Container, config *containertypes.Hos
186 186
 			con = strings.SplitN(opt, ":", 2)
187 187
 			logrus.Warn("Security options with `:` as a separator are deprecated and will be completely unsupported in 17.04, use `=` instead.")
188 188
 		}
189
-
190 189
 		if len(con) != 2 {
191 190
 			return fmt.Errorf("invalid --security-opt 1: %q", opt)
192 191
 		}
... ...
@@ -213,16 +217,15 @@ func parseSecurityOpt(container *container.Container, config *containertypes.Hos
213 213
 	return err
214 214
 }
215 215
 
216
-func getBlkioThrottleDevices(devs []*blkiodev.ThrottleDevice) ([]specs.ThrottleDevice, error) {
217
-	var throttleDevices []specs.ThrottleDevice
216
+func getBlkioThrottleDevices(devs []*blkiodev.ThrottleDevice) ([]specs.LinuxThrottleDevice, error) {
217
+	var throttleDevices []specs.LinuxThrottleDevice
218 218
 	var stat syscall.Stat_t
219 219
 
220 220
 	for _, d := range devs {
221 221
 		if err := syscall.Stat(d.Path, &stat); err != nil {
222 222
 			return nil, err
223 223
 		}
224
-		rate := d.Rate
225
-		d := specs.ThrottleDevice{Rate: &rate}
224
+		d := specs.LinuxThrottleDevice{Rate: d.Rate}
226 225
 		d.Major = int64(stat.Rdev / 256)
227 226
 		d.Minor = int64(stat.Rdev % 256)
228 227
 		throttleDevices = append(throttleDevices, d)
... ...
@@ -56,13 +56,16 @@ func setResources(s *specs.Spec, r containertypes.Resources) error {
56 56
 	}
57 57
 
58 58
 	memoryRes := getMemoryResources(r)
59
-	cpuRes := getCPUResources(r)
59
+	cpuRes, err := getCPUResources(r)
60
+	if err != nil {
61
+		return err
62
+	}
60 63
 	blkioWeight := r.BlkioWeight
61 64
 
62
-	specResources := &specs.Resources{
65
+	specResources := &specs.LinuxResources{
63 66
 		Memory: memoryRes,
64 67
 		CPU:    cpuRes,
65
-		BlockIO: &specs.BlockIO{
68
+		BlockIO: &specs.LinuxBlockIO{
66 69
 			Weight:                  &blkioWeight,
67 70
 			WeightDevice:            weightDevices,
68 71
 			ThrottleReadBpsDevice:   readBpsDevice,
... ...
@@ -71,8 +74,8 @@ func setResources(s *specs.Spec, r containertypes.Resources) error {
71 71
 			ThrottleWriteIOPSDevice: writeIOpsDevice,
72 72
 		},
73 73
 		DisableOOMKiller: r.OomKillDisable,
74
-		Pids: &specs.Pids{
75
-			Limit: &r.PidsLimit,
74
+		Pids: &specs.LinuxPids{
75
+			Limit: r.PidsLimit,
76 76
 		},
77 77
 	}
78 78
 
... ...
@@ -86,7 +89,7 @@ func setResources(s *specs.Spec, r containertypes.Resources) error {
86 86
 
87 87
 func setDevices(s *specs.Spec, c *container.Container) error {
88 88
 	// Build lists of devices allowed and created within the container.
89
-	var devs []specs.Device
89
+	var devs []specs.LinuxDevice
90 90
 	devPermissions := s.Linux.Resources.Devices
91 91
 	if c.HostConfig.Privileged {
92 92
 		hostDevices, err := devices.HostDevices()
... ...
@@ -96,11 +99,10 @@ func setDevices(s *specs.Spec, c *container.Container) error {
96 96
 		for _, d := range hostDevices {
97 97
 			devs = append(devs, oci.Device(d))
98 98
 		}
99
-		rwm := "rwm"
100
-		devPermissions = []specs.DeviceCgroup{
99
+		devPermissions = []specs.LinuxDeviceCgroup{
101 100
 			{
102 101
 				Allow:  true,
103
-				Access: &rwm,
102
+				Access: "rwm",
104 103
 			},
105 104
 		}
106 105
 	} else {
... ...
@@ -120,10 +122,10 @@ func setDevices(s *specs.Spec, c *container.Container) error {
120 120
 			}
121 121
 			matches := ss[0]
122 122
 
123
-			dPermissions := specs.DeviceCgroup{
123
+			dPermissions := specs.LinuxDeviceCgroup{
124 124
 				Allow:  true,
125
-				Type:   &matches[1],
126
-				Access: &matches[4],
125
+				Type:   matches[1],
126
+				Access: matches[4],
127 127
 			}
128 128
 			if matches[2] == "*" {
129 129
 				major := int64(-1)
... ...
@@ -155,14 +157,14 @@ func setDevices(s *specs.Spec, c *container.Container) error {
155 155
 }
156 156
 
157 157
 func setRlimits(daemon *Daemon, s *specs.Spec, c *container.Container) error {
158
-	var rlimits []specs.Rlimit
158
+	var rlimits []specs.LinuxRlimit
159 159
 
160 160
 	// We want to leave the original HostConfig alone so make a copy here
161 161
 	hostConfig := *c.HostConfig
162 162
 	// Merge with the daemon defaults
163 163
 	daemon.mergeUlimits(&hostConfig)
164 164
 	for _, ul := range hostConfig.Ulimits {
165
-		rlimits = append(rlimits, specs.Rlimit{
165
+		rlimits = append(rlimits, specs.LinuxRlimit{
166 166
 			Type: "RLIMIT_" + strings.ToUpper(ul.Name),
167 167
 			Soft: uint64(ul.Soft),
168 168
 			Hard: uint64(ul.Hard),
... ...
@@ -237,7 +239,7 @@ func getUser(c *container.Container, username string) (uint32, uint32, []uint32,
237 237
 	return uid, gid, additionalGids, nil
238 238
 }
239 239
 
240
-func setNamespace(s *specs.Spec, ns specs.Namespace) {
240
+func setNamespace(s *specs.Spec, ns specs.LinuxNamespace) {
241 241
 	for i, n := range s.Linux.Namespaces {
242 242
 		if n.Type == ns.Type {
243 243
 			s.Linux.Namespaces[i] = ns
... ...
@@ -253,12 +255,15 @@ func setCapabilities(s *specs.Spec, c *container.Container) error {
253 253
 	if c.HostConfig.Privileged {
254 254
 		caplist = caps.GetAllCapabilities()
255 255
 	} else {
256
-		caplist, err = caps.TweakCapabilities(s.Process.Capabilities, c.HostConfig.CapAdd, c.HostConfig.CapDrop)
256
+		caplist, err = caps.TweakCapabilities(s.Process.Capabilities.Effective, c.HostConfig.CapAdd, c.HostConfig.CapDrop)
257 257
 		if err != nil {
258 258
 			return err
259 259
 		}
260 260
 	}
261
-	s.Process.Capabilities = caplist
261
+	s.Process.Capabilities.Effective = caplist
262
+	s.Process.Capabilities.Bounding = caplist
263
+	s.Process.Capabilities.Permitted = caplist
264
+	s.Process.Capabilities.Inheritable = caplist
262 265
 	return nil
263 266
 }
264 267
 
... ...
@@ -269,7 +274,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
269 269
 		uidMap, gidMap := daemon.GetUIDGIDMaps()
270 270
 		if uidMap != nil {
271 271
 			userNS = true
272
-			ns := specs.Namespace{Type: "user"}
272
+			ns := specs.LinuxNamespace{Type: "user"}
273 273
 			setNamespace(s, ns)
274 274
 			s.Linux.UIDMappings = specMapping(uidMap)
275 275
 			s.Linux.GIDMappings = specMapping(gidMap)
... ...
@@ -277,7 +282,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
277 277
 	}
278 278
 	// network
279 279
 	if !c.Config.NetworkDisabled {
280
-		ns := specs.Namespace{Type: "network"}
280
+		ns := specs.LinuxNamespace{Type: "network"}
281 281
 		parts := strings.SplitN(string(c.HostConfig.NetworkMode), ":", 2)
282 282
 		if parts[0] == "container" {
283 283
 			nc, err := daemon.getNetworkedContainer(c.ID, c.HostConfig.NetworkMode.ConnectedContainer())
... ...
@@ -287,7 +292,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
287 287
 			ns.Path = fmt.Sprintf("/proc/%d/ns/net", nc.State.GetPID())
288 288
 			if userNS {
289 289
 				// to share a net namespace, they must also share a user namespace
290
-				nsUser := specs.Namespace{Type: "user"}
290
+				nsUser := specs.LinuxNamespace{Type: "user"}
291 291
 				nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", nc.State.GetPID())
292 292
 				setNamespace(s, nsUser)
293 293
 			}
... ...
@@ -298,7 +303,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
298 298
 	}
299 299
 	// ipc
300 300
 	if c.HostConfig.IpcMode.IsContainer() {
301
-		ns := specs.Namespace{Type: "ipc"}
301
+		ns := specs.LinuxNamespace{Type: "ipc"}
302 302
 		ic, err := daemon.getIpcContainer(c)
303 303
 		if err != nil {
304 304
 			return err
... ...
@@ -307,19 +312,19 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
307 307
 		setNamespace(s, ns)
308 308
 		if userNS {
309 309
 			// to share an IPC namespace, they must also share a user namespace
310
-			nsUser := specs.Namespace{Type: "user"}
310
+			nsUser := specs.LinuxNamespace{Type: "user"}
311 311
 			nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", ic.State.GetPID())
312 312
 			setNamespace(s, nsUser)
313 313
 		}
314 314
 	} else if c.HostConfig.IpcMode.IsHost() {
315
-		oci.RemoveNamespace(s, specs.NamespaceType("ipc"))
315
+		oci.RemoveNamespace(s, specs.LinuxNamespaceType("ipc"))
316 316
 	} else {
317
-		ns := specs.Namespace{Type: "ipc"}
317
+		ns := specs.LinuxNamespace{Type: "ipc"}
318 318
 		setNamespace(s, ns)
319 319
 	}
320 320
 	// pid
321 321
 	if c.HostConfig.PidMode.IsContainer() {
322
-		ns := specs.Namespace{Type: "pid"}
322
+		ns := specs.LinuxNamespace{Type: "pid"}
323 323
 		pc, err := daemon.getPidContainer(c)
324 324
 		if err != nil {
325 325
 			return err
... ...
@@ -328,29 +333,29 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
328 328
 		setNamespace(s, ns)
329 329
 		if userNS {
330 330
 			// to share a PID namespace, they must also share a user namespace
331
-			nsUser := specs.Namespace{Type: "user"}
331
+			nsUser := specs.LinuxNamespace{Type: "user"}
332 332
 			nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", pc.State.GetPID())
333 333
 			setNamespace(s, nsUser)
334 334
 		}
335 335
 	} else if c.HostConfig.PidMode.IsHost() {
336
-		oci.RemoveNamespace(s, specs.NamespaceType("pid"))
336
+		oci.RemoveNamespace(s, specs.LinuxNamespaceType("pid"))
337 337
 	} else {
338
-		ns := specs.Namespace{Type: "pid"}
338
+		ns := specs.LinuxNamespace{Type: "pid"}
339 339
 		setNamespace(s, ns)
340 340
 	}
341 341
 	// uts
342 342
 	if c.HostConfig.UTSMode.IsHost() {
343
-		oci.RemoveNamespace(s, specs.NamespaceType("uts"))
343
+		oci.RemoveNamespace(s, specs.LinuxNamespaceType("uts"))
344 344
 		s.Hostname = ""
345 345
 	}
346 346
 
347 347
 	return nil
348 348
 }
349 349
 
350
-func specMapping(s []idtools.IDMap) []specs.IDMapping {
351
-	var ids []specs.IDMapping
350
+func specMapping(s []idtools.IDMap) []specs.LinuxIDMapping {
351
+	var ids []specs.LinuxIDMapping
352 352
 	for _, item := range s {
353
-		ids = append(ids, specs.IDMapping{
353
+		ids = append(ids, specs.LinuxIDMapping{
354 354
 			HostID:      uint32(item.HostID),
355 355
 			ContainerID: uint32(item.ContainerID),
356 356
 			Size:        uint32(item.Size),
... ...
@@ -675,7 +680,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
675 675
 	} else {
676 676
 		cgroupsPath = filepath.Join(parent, c.ID)
677 677
 	}
678
-	s.Linux.CgroupsPath = &cgroupsPath
678
+	s.Linux.CgroupsPath = cgroupsPath
679 679
 
680 680
 	if err := setResources(&s, c.HostConfig.Resources); err != nil {
681 681
 		return nil, fmt.Errorf("linux runtime spec resources: %v", err)
... ...
@@ -683,13 +688,13 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
683 683
 	s.Linux.Resources.OOMScoreAdj = &c.HostConfig.OomScoreAdj
684 684
 	s.Linux.Sysctl = c.HostConfig.Sysctls
685 685
 
686
-	p := *s.Linux.CgroupsPath
686
+	p := s.Linux.CgroupsPath
687 687
 	if useSystemd {
688
-		initPath, err := cgroups.GetInitCgroupDir("cpu")
688
+		initPath, err := cgroups.GetInitCgroup("cpu")
689 689
 		if err != nil {
690 690
 			return nil, err
691 691
 		}
692
-		p, _ = cgroups.GetThisCgroupDir("cpu")
692
+		p, _ = cgroups.GetOwnCgroup("cpu")
693 693
 		if err != nil {
694 694
 			return nil, err
695 695
 		}
... ...
@@ -761,7 +766,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
761 761
 				return nil, err
762 762
 			}
763 763
 
764
-			s.Hooks = specs.Hooks{
764
+			s.Hooks = &specs.Hooks{
765 765
 				Prestart: []specs.Hook{{
766 766
 					Path: target, // FIXME: cross-platform
767 767
 					Args: []string{"libnetwork-setkey", c.ID, daemon.netController.ID()},
... ...
@@ -14,7 +14,7 @@ import (
14 14
 var supportsSeccomp = true
15 15
 
16 16
 func setSeccomp(daemon *Daemon, rs *specs.Spec, c *container.Container) error {
17
-	var profile *specs.Seccomp
17
+	var profile *specs.LinuxSeccomp
18 18
 	var err error
19 19
 
20 20
 	if c.HostConfig.Privileged {
... ...
@@ -3,8 +3,8 @@
3 3
 TOMLV_COMMIT=9baf8a8a9f2ed20a8e54160840c492f937eeaf9a
4 4
 
5 5
 # When updating RUNC_COMMIT, also update runc in vendor.conf accordingly
6
-RUNC_COMMIT=9c2d8d184e5da67c95d601382adf14862e4f2228
7
-CONTAINERD_COMMIT=9048e5e50717ea4497b757314bad98ea3763c145
6
+RUNC_COMMIT=992a5be178a62e026f4069f443c6164912adbf09
7
+CONTAINERD_COMMIT=d24f39e203aa6be4944f06dd0fe38a618a36c764
8 8
 TINI_COMMIT=949e6facb77383876aeff8a6944dde66b3089574
9 9
 LIBNETWORK_COMMIT=7b2b1feb1de4817d522cc372af149ff48d25028e
10 10
 VNDR_COMMIT=c56e082291115e369f77601f9c071dd0b87c7120
... ...
@@ -20,7 +20,7 @@ RUNC_BUILDTAGS="${RUNC_BUILDTAGS:-"seccomp apparmor selinux"}"
20 20
 
21 21
 install_runc() {
22 22
 	echo "Install runc version $RUNC_COMMIT"
23
-	git clone https://github.com/docker/runc.git "$GOPATH/src/github.com/opencontainers/runc"
23
+	git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc"
24 24
 	cd "$GOPATH/src/github.com/opencontainers/runc"
25 25
 	git checkout -q "$RUNC_COMMIT"
26 26
 	make BUILDTAGS="$RUNC_BUILDTAGS" $1
... ...
@@ -29,8 +29,8 @@ install_runc() {
29 29
 
30 30
 install_containerd() {
31 31
 	echo "Install containerd version $CONTAINERD_COMMIT"
32
-	git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd"
33
-	cd "$GOPATH/src/github.com/docker/containerd"
32
+	git clone https://github.com/containerd/containerd.git "$GOPATH/src/github.com/containerd/containerd"
33
+	cd "$GOPATH/src/github.com/containerd/containerd"
34 34
 	git checkout -q "$CONTAINERD_COMMIT"
35 35
 	make $1
36 36
 	cp bin/containerd /usr/local/bin/docker-containerd
... ...
@@ -281,5 +281,5 @@ func (s *DockerSwarmSuite) TestServiceLogsTTY(c *check.C) {
281 281
 	result = icmd.RunCmd(cmd)
282 282
 	// for some reason there is carriage return in the output. i think this is
283 283
 	// just expected.
284
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: "out\r\nerr\r\n"})
284
+	c.Assert(result, icmd.Matches, icmd.Expected{Out: "out\nerr\n"})
285 285
 }
... ...
@@ -74,7 +74,10 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly
74 74
 		}
75 75
 	}
76 76
 	if specp.Capabilities != nil {
77
-		sp.Capabilities = specp.Capabilities
77
+		sp.Capabilities.Bounding = specp.Capabilities
78
+		sp.Capabilities.Effective = specp.Capabilities
79
+		sp.Capabilities.Inheritable = specp.Capabilities
80
+		sp.Capabilities.Permitted = specp.Capabilities
78 81
 	}
79 82
 
80 83
 	p := container.newProcess(processFriendlyName)
... ...
@@ -94,7 +97,7 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly
94 94
 		Stdin:           p.fifo(syscall.Stdin),
95 95
 		Stdout:          p.fifo(syscall.Stdout),
96 96
 		Stderr:          p.fifo(syscall.Stderr),
97
-		Capabilities:    sp.Capabilities,
97
+		Capabilities:    sp.Capabilities.Effective,
98 98
 		ApparmorProfile: sp.ApparmorProfile,
99 99
 		SelinuxLabel:    sp.SelinuxLabel,
100 100
 		NoNewPrivileges: sp.NoNewPrivileges,
... ...
@@ -21,7 +21,7 @@ type Process struct {
21 21
 	// Capabilities are linux capabilities that are kept for the container.
22 22
 	Capabilities []string `json:"capabilities,omitempty"`
23 23
 	// Rlimits specifies rlimit options to apply to the process.
24
-	Rlimits []specs.Rlimit `json:"rlimits,omitempty"`
24
+	Rlimits []specs.LinuxRlimit `json:"rlimits,omitempty"`
25 25
 	// ApparmorProfile specifies the apparmor profile for the container.
26 26
 	ApparmorProfile *string `json:"apparmorProfile,omitempty"`
27 27
 	// SelinuxLabel specifies the selinux context that the container process is run as.
... ...
@@ -23,7 +23,7 @@ func getRootIDs(s specs.Spec) (int, int, error) {
23 23
 	return uid, gid, nil
24 24
 }
25 25
 
26
-func hostIDFromMap(id uint32, mp []specs.IDMapping) int {
26
+func hostIDFromMap(id uint32, mp []specs.LinuxIDMapping) int {
27 27
 	for _, m := range mp {
28 28
 		if id >= m.ContainerID && id <= m.ContainerID+m.Size-1 {
29 29
 			return int(m.HostID + id - m.ContainerID)
... ...
@@ -42,7 +42,7 @@ func systemPid(ctr *containerd.Container) uint32 {
42 42
 	return pid
43 43
 }
44 44
 
45
-func convertRlimits(sr []specs.Rlimit) (cr []*containerd.Rlimit) {
45
+func convertRlimits(sr []specs.LinuxRlimit) (cr []*containerd.Rlimit) {
46 46
 	for _, r := range sr {
47 47
 		cr = append(cr, &containerd.Rlimit{
48 48
 			Type: r.Type,
... ...
@@ -7,11 +7,29 @@ import (
7 7
 	"github.com/opencontainers/runtime-spec/specs-go"
8 8
 )
9 9
 
10
-func sPtr(s string) *string      { return &s }
11 10
 func iPtr(i int64) *int64        { return &i }
12 11
 func u32Ptr(i int64) *uint32     { u := uint32(i); return &u }
13 12
 func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
14 13
 
14
+func defaultCapabilities() []string {
15
+	return []string{
16
+		"CAP_CHOWN",
17
+		"CAP_DAC_OVERRIDE",
18
+		"CAP_FSETID",
19
+		"CAP_FOWNER",
20
+		"CAP_MKNOD",
21
+		"CAP_NET_RAW",
22
+		"CAP_SETGID",
23
+		"CAP_SETUID",
24
+		"CAP_SETFCAP",
25
+		"CAP_SETPCAP",
26
+		"CAP_NET_BIND_SERVICE",
27
+		"CAP_SYS_CHROOT",
28
+		"CAP_KILL",
29
+		"CAP_AUDIT_WRITE",
30
+	}
31
+}
32
+
15 33
 // DefaultSpec returns default oci spec used by docker.
16 34
 func DefaultSpec() specs.Spec {
17 35
 	s := specs.Spec{
... ...
@@ -59,21 +77,11 @@ func DefaultSpec() specs.Spec {
59 59
 			Options:     []string{"nosuid", "noexec", "nodev"},
60 60
 		},
61 61
 	}
62
-	s.Process.Capabilities = []string{
63
-		"CAP_CHOWN",
64
-		"CAP_DAC_OVERRIDE",
65
-		"CAP_FSETID",
66
-		"CAP_FOWNER",
67
-		"CAP_MKNOD",
68
-		"CAP_NET_RAW",
69
-		"CAP_SETGID",
70
-		"CAP_SETUID",
71
-		"CAP_SETFCAP",
72
-		"CAP_SETPCAP",
73
-		"CAP_NET_BIND_SERVICE",
74
-		"CAP_SYS_CHROOT",
75
-		"CAP_KILL",
76
-		"CAP_AUDIT_WRITE",
62
+	s.Process.Capabilities = &specs.LinuxCapabilities{
63
+		Bounding:    defaultCapabilities(),
64
+		Permitted:   defaultCapabilities(),
65
+		Inheritable: defaultCapabilities(),
66
+		Effective:   defaultCapabilities(),
77 67
 	}
78 68
 
79 69
 	s.Linux = &specs.Linux{
... ...
@@ -93,7 +101,7 @@ func DefaultSpec() specs.Spec {
93 93
 			"/proc/sys",
94 94
 			"/proc/sysrq-trigger",
95 95
 		},
96
-		Namespaces: []specs.Namespace{
96
+		Namespaces: []specs.LinuxNamespace{
97 97
 			{Type: "mount"},
98 98
 			{Type: "network"},
99 99
 			{Type: "uts"},
... ...
@@ -104,61 +112,61 @@ func DefaultSpec() specs.Spec {
104 104
 		// null, zero, full, random, urandom, tty, console, and ptmx.
105 105
 		// ptmx is a bind-mount or symlink of the container's ptmx.
106 106
 		// See also: https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices
107
-		Devices: []specs.Device{},
108
-		Resources: &specs.Resources{
109
-			Devices: []specs.DeviceCgroup{
107
+		Devices: []specs.LinuxDevice{},
108
+		Resources: &specs.LinuxResources{
109
+			Devices: []specs.LinuxDeviceCgroup{
110 110
 				{
111 111
 					Allow:  false,
112
-					Access: sPtr("rwm"),
112
+					Access: "rwm",
113 113
 				},
114 114
 				{
115 115
 					Allow:  true,
116
-					Type:   sPtr("c"),
116
+					Type:   "c",
117 117
 					Major:  iPtr(1),
118 118
 					Minor:  iPtr(5),
119
-					Access: sPtr("rwm"),
119
+					Access: "rwm",
120 120
 				},
121 121
 				{
122 122
 					Allow:  true,
123
-					Type:   sPtr("c"),
123
+					Type:   "c",
124 124
 					Major:  iPtr(1),
125 125
 					Minor:  iPtr(3),
126
-					Access: sPtr("rwm"),
126
+					Access: "rwm",
127 127
 				},
128 128
 				{
129 129
 					Allow:  true,
130
-					Type:   sPtr("c"),
130
+					Type:   "c",
131 131
 					Major:  iPtr(1),
132 132
 					Minor:  iPtr(9),
133
-					Access: sPtr("rwm"),
133
+					Access: "rwm",
134 134
 				},
135 135
 				{
136 136
 					Allow:  true,
137
-					Type:   sPtr("c"),
137
+					Type:   "c",
138 138
 					Major:  iPtr(1),
139 139
 					Minor:  iPtr(8),
140
-					Access: sPtr("rwm"),
140
+					Access: "rwm",
141 141
 				},
142 142
 				{
143 143
 					Allow:  true,
144
-					Type:   sPtr("c"),
144
+					Type:   "c",
145 145
 					Major:  iPtr(5),
146 146
 					Minor:  iPtr(0),
147
-					Access: sPtr("rwm"),
147
+					Access: "rwm",
148 148
 				},
149 149
 				{
150 150
 					Allow:  true,
151
-					Type:   sPtr("c"),
151
+					Type:   "c",
152 152
 					Major:  iPtr(5),
153 153
 					Minor:  iPtr(1),
154
-					Access: sPtr("rwm"),
154
+					Access: "rwm",
155 155
 				},
156 156
 				{
157 157
 					Allow:  false,
158
-					Type:   sPtr("c"),
158
+					Type:   "c",
159 159
 					Major:  iPtr(10),
160 160
 					Minor:  iPtr(229),
161
-					Access: sPtr("rwm"),
161
+					Access: "rwm",
162 162
 				},
163 163
 			},
164 164
 		},
... ...
@@ -11,9 +11,9 @@ import (
11 11
 	specs "github.com/opencontainers/runtime-spec/specs-go"
12 12
 )
13 13
 
14
-// Device transforms a libcontainer configs.Device to a specs.Device object.
15
-func Device(d *configs.Device) specs.Device {
16
-	return specs.Device{
14
+// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
15
+func Device(d *configs.Device) specs.LinuxDevice {
16
+	return specs.LinuxDevice{
17 17
 		Type:     string(d.Type),
18 18
 		Path:     d.Path,
19 19
 		Major:    d.Major,
... ...
@@ -24,19 +24,19 @@ func Device(d *configs.Device) specs.Device {
24 24
 	}
25 25
 }
26 26
 
27
-func deviceCgroup(d *configs.Device) specs.DeviceCgroup {
27
+func deviceCgroup(d *configs.Device) specs.LinuxDeviceCgroup {
28 28
 	t := string(d.Type)
29
-	return specs.DeviceCgroup{
29
+	return specs.LinuxDeviceCgroup{
30 30
 		Allow:  true,
31
-		Type:   &t,
31
+		Type:   t,
32 32
 		Major:  &d.Major,
33 33
 		Minor:  &d.Minor,
34
-		Access: &d.Permissions,
34
+		Access: d.Permissions,
35 35
 	}
36 36
 }
37 37
 
38 38
 // DevicesFromPath computes a list of devices and device permissions from paths (pathOnHost and pathInContainer) and cgroup permissions.
39
-func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.Device, devPermissions []specs.DeviceCgroup, err error) {
39
+func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.LinuxDevice, devPermissions []specs.LinuxDeviceCgroup, err error) {
40 40
 	resolvedPathOnHost := pathOnHost
41 41
 
42 42
 	// check if it is a symbolic link
... ...
@@ -11,10 +11,10 @@ import (
11 11
 
12 12
 // Device transforms a libcontainer configs.Device to a specs.Device object.
13 13
 // Not implemented
14
-func Device(d *configs.Device) specs.Device { return specs.Device{} }
14
+func Device(d *configs.Device) specs.LinuxDevice { return specs.LinuxDevice{} }
15 15
 
16 16
 // DevicesFromPath computes a list of devices and device permissions from paths (pathOnHost and pathInContainer) and cgroup permissions.
17 17
 // Not implemented
18
-func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.Device, devPermissions []specs.DeviceCgroup, err error) {
18
+func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.LinuxDevice, devPermissions []specs.LinuxDeviceCgroup, err error) {
19 19
 	return nil, nil, errors.New("oci/devices: unsupported platform")
20 20
 }
... ...
@@ -3,7 +3,7 @@ package oci
3 3
 import specs "github.com/opencontainers/runtime-spec/specs-go"
4 4
 
5 5
 // RemoveNamespace removes the `nsType` namespace from OCI spec `s`
6
-func RemoveNamespace(s *specs.Spec, nsType specs.NamespaceType) {
6
+func RemoveNamespace(s *specs.Spec, nsType specs.LinuxNamespaceType) {
7 7
 	for i, n := range s.Linux.Namespaces {
8 8
 		if n.Type == nsType {
9 9
 			s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...)
... ...
@@ -27,6 +27,7 @@ func MakeRaw(fd uintptr) (*State, error) {
27 27
 	newState := oldState.termios
28 28
 
29 29
 	C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState)))
30
+	newState.Oflag = newState.Oflag | C.OPOST
30 31
 	if err := tcset(fd, &newState); err != 0 {
31 32
 		return nil, err
32 33
 	}
... ...
@@ -42,7 +42,7 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
42 42
 	if p.PluginObj.Config.Network.Type != "" {
43 43
 		// TODO: if net == bridge, use libnetwork controller to create a new plugin-specific bridge, bind mount /etc/hosts and /etc/resolv.conf look at the docker code (allocateNetwork, initialize)
44 44
 		if p.PluginObj.Config.Network.Type == "host" {
45
-			oci.RemoveNamespace(&s, specs.NamespaceType("network"))
45
+			oci.RemoveNamespace(&s, specs.LinuxNamespaceType("network"))
46 46
 		}
47 47
 		etcHosts := "/etc/hosts"
48 48
 		resolvConf := "/etc/resolv.conf"
... ...
@@ -61,11 +61,11 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
61 61
 			})
62 62
 	}
63 63
 	if p.PluginObj.Config.PidHost {
64
-		oci.RemoveNamespace(&s, specs.NamespaceType("pid"))
64
+		oci.RemoveNamespace(&s, specs.LinuxNamespaceType("pid"))
65 65
 	}
66 66
 
67 67
 	if p.PluginObj.Config.IpcHost {
68
-		oci.RemoveNamespace(&s, specs.NamespaceType("ipc"))
68
+		oci.RemoveNamespace(&s, specs.LinuxNamespaceType("ipc"))
69 69
 	}
70 70
 
71 71
 	for _, mnt := range mounts {
... ...
@@ -95,8 +95,7 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
95 95
 	}
96 96
 
97 97
 	if p.PluginObj.Config.Linux.AllowAllDevices {
98
-		rwm := "rwm"
99
-		s.Linux.Resources.Devices = []specs.DeviceCgroup{{Allow: true, Access: &rwm}}
98
+		s.Linux.Resources.Devices = []specs.LinuxDeviceCgroup{{Allow: true, Access: "rwm"}}
100 99
 	}
101 100
 	for _, dev := range p.PluginObj.Settings.Devices {
102 101
 		path := *dev.Path
... ...
@@ -122,7 +121,11 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
122 122
 	s.Process.Cwd = cwd
123 123
 	s.Process.Env = envs
124 124
 
125
-	s.Process.Capabilities = append(s.Process.Capabilities, p.PluginObj.Config.Linux.Capabilities...)
125
+	caps := s.Process.Capabilities
126
+	caps.Bounding = append(caps.Bounding, p.PluginObj.Config.Linux.Capabilities...)
127
+	caps.Permitted = append(caps.Permitted, p.PluginObj.Config.Linux.Capabilities...)
128
+	caps.Inheritable = append(caps.Inheritable, p.PluginObj.Config.Linux.Capabilities...)
129
+	caps.Effective = append(caps.Effective, p.PluginObj.Config.Linux.Capabilities...)
126 130
 
127 131
 	return &s, nil
128 132
 }
... ...
@@ -16,12 +16,12 @@ import (
16 16
 //go:generate go run -tags 'seccomp' generate.go
17 17
 
18 18
 // GetDefaultProfile returns the default seccomp profile.
19
-func GetDefaultProfile(rs *specs.Spec) (*specs.Seccomp, error) {
19
+func GetDefaultProfile(rs *specs.Spec) (*specs.LinuxSeccomp, error) {
20 20
 	return setupSeccomp(DefaultProfile(), rs)
21 21
 }
22 22
 
23 23
 // LoadProfile takes a json string and decodes the seccomp profile.
24
-func LoadProfile(body string, rs *specs.Spec) (*specs.Seccomp, error) {
24
+func LoadProfile(body string, rs *specs.Spec) (*specs.LinuxSeccomp, error) {
25 25
 	var config types.Seccomp
26 26
 	if err := json.Unmarshal([]byte(body), &config); err != nil {
27 27
 		return nil, fmt.Errorf("Decoding seccomp profile failed: %v", err)
... ...
@@ -39,7 +39,7 @@ var nativeToSeccomp = map[string]types.Arch{
39 39
 	"s390x":       types.ArchS390X,
40 40
 }
41 41
 
42
-func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.Seccomp, error) {
42
+func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, error) {
43 43
 	if config == nil {
44 44
 		return nil, nil
45 45
 	}
... ...
@@ -49,7 +49,7 @@ func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.Seccomp, error)
49 49
 		return nil, nil
50 50
 	}
51 51
 
52
-	newConfig := &specs.Seccomp{}
52
+	newConfig := &specs.LinuxSeccomp{}
53 53
 
54 54
 	var arch string
55 55
 	var native, err = libseccomp.GetNativeArch()
... ...
@@ -83,7 +83,7 @@ func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.Seccomp, error)
83 83
 		}
84 84
 	}
85 85
 
86
-	newConfig.DefaultAction = specs.Action(config.DefaultAction)
86
+	newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction)
87 87
 
88 88
 Loop:
89 89
 	// Loop through all syscall blocks and convert them to libcontainer format after filtering them
... ...
@@ -95,7 +95,7 @@ Loop:
95 95
 		}
96 96
 		if len(call.Excludes.Caps) > 0 {
97 97
 			for _, c := range call.Excludes.Caps {
98
-				if stringutils.InSlice(rs.Process.Capabilities, c) {
98
+				if stringutils.InSlice(rs.Process.Capabilities.Effective, c) {
99 99
 					continue Loop
100 100
 				}
101 101
 			}
... ...
@@ -107,7 +107,7 @@ Loop:
107 107
 		}
108 108
 		if len(call.Includes.Caps) > 0 {
109 109
 			for _, c := range call.Includes.Caps {
110
-				if !stringutils.InSlice(rs.Process.Capabilities, c) {
110
+				if !stringutils.InSlice(rs.Process.Capabilities.Effective, c) {
111 111
 					continue Loop
112 112
 				}
113 113
 			}
... ...
@@ -129,19 +129,19 @@ Loop:
129 129
 	return newConfig, nil
130 130
 }
131 131
 
132
-func createSpecsSyscall(name string, action types.Action, args []*types.Arg) specs.Syscall {
133
-	newCall := specs.Syscall{
134
-		Name:   name,
135
-		Action: specs.Action(action),
132
+func createSpecsSyscall(name string, action types.Action, args []*types.Arg) specs.LinuxSyscall {
133
+	newCall := specs.LinuxSyscall{
134
+		Names:  []string{name},
135
+		Action: specs.LinuxSeccompAction(action),
136 136
 	}
137 137
 
138 138
 	// Loop through all the arguments of the syscall and convert them
139 139
 	for _, arg := range args {
140
-		newArg := specs.Arg{
140
+		newArg := specs.LinuxSeccompArg{
141 141
 			Index:    arg.Index,
142 142
 			Value:    arg.Value,
143 143
 			ValueTwo: arg.ValueTwo,
144
-			Op:       specs.Operator(arg.Op),
144
+			Op:       specs.LinuxSeccompOperator(arg.Op),
145 145
 		}
146 146
 
147 147
 		newCall.Args = append(newCall.Args, newArg)
... ...
@@ -65,9 +65,11 @@ github.com/docker/go v1.5.1-1-1-gbaf439e
65 65
 github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
66 66
 
67 67
 # When updating, also update RUNC_COMMIT in hack/dockerfile/binaries-commits accordingly
68
-github.com/opencontainers/runc 9c2d8d184e5da67c95d601382adf14862e4f2228 https://github.com/docker/runc.git # libcontainer
69
-github.com/opencontainers/runtime-spec 1c7c27d043c2a5e513a44084d2b10d77d1402b8c # specs
70
-github.com/seccomp/libseccomp-golang v0.9.0
68
+github.com/opencontainers/runc b6b70e53451794e8333e9b602cc096b47a20bd0f 
69
+github.com/opencontainers/runtime-spec v1.0.0-rc5 # specs
70
+
71
+github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
72
+
71 73
 # libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
72 74
 github.com/coreos/go-systemd v4
73 75
 github.com/godbus/dbus v4.0.0
... ...
@@ -104,7 +106,7 @@ google.golang.org/genproto b3e7c2fb04031add52c4817f53f43757ccbf9c18
104 104
 github.com/docker/docker-credential-helpers v0.5.0
105 105
 
106 106
 # containerd
107
-github.com/docker/containerd 9048e5e50717ea4497b757314bad98ea3763c145
107
+github.com/docker/containerd d24f39e203aa6be4944f06dd0fe38a618a36c764
108 108
 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
109 109
 
110 110
 # cluster
... ...
@@ -144,4 +146,4 @@ github.com/xeipuuv/gojsonpointer e0fe6f68307607d540ed8eac07a342c33fa1b54a
144 144
 github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45
145 145
 github.com/xeipuuv/gojsonschema 93e72a773fade158921402d6a24c819b48aba29d
146 146
 gopkg.in/yaml.v2 4c78c975fe7c825c6d1466c42be594d1d6f3aba6
147
-github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d
147
+github.com/opencontainers/selinux v1.0.0-rc1
... ...
@@ -6,7 +6,7 @@ as checkpoint and restore for cloning and live migration of containers.
6 6
 
7 7
 ## Getting started
8 8
 
9
-The easiest way to start using containerd is to download binaries from the [releases page](https://github.com/docker/containerd/releases).
9
+The easiest way to start using containerd is to download binaries from the [releases page](https://github.com/containerd/containerd/releases).
10 10
 
11 11
 The included `ctr` command-line tool allows you interact with the containerd daemon:
12 12
 
... ...
@@ -1051,6 +1051,7 @@ type UpdateResource struct {
1051 1051
 	BlkioThrottleWriteBpsDevice  []*ThrottleDevice `protobuf:"bytes,15,rep,name=blkioThrottleWriteBpsDevice" json:"blkioThrottleWriteBpsDevice,omitempty"`
1052 1052
 	BlkioThrottleReadIopsDevice  []*ThrottleDevice `protobuf:"bytes,16,rep,name=blkioThrottleReadIopsDevice" json:"blkioThrottleReadIopsDevice,omitempty"`
1053 1053
 	BlkioThrottleWriteIopsDevice []*ThrottleDevice `protobuf:"bytes,17,rep,name=blkioThrottleWriteIopsDevice" json:"blkioThrottleWriteIopsDevice,omitempty"`
1054
+	PidsLimit                    uint64            `protobuf:"varint,18,opt,name=pidsLimit" json:"pidsLimit,omitempty"`
1054 1055
 }
1055 1056
 
1056 1057
 func (m *UpdateResource) Reset()                    { *m = UpdateResource{} }
... ...
@@ -1177,6 +1178,13 @@ func (m *UpdateResource) GetBlkioThrottleWriteIopsDevice() []*ThrottleDevice {
1177 1177
 	return nil
1178 1178
 }
1179 1179
 
1180
+func (m *UpdateResource) GetPidsLimit() uint64 {
1181
+	if m != nil {
1182
+		return m.PidsLimit
1183
+	}
1184
+	return 0
1185
+}
1186
+
1180 1187
 type BlockIODevice struct {
1181 1188
 	Major int64 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"`
1182 1189
 	Minor int64 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"`
... ...
@@ -1351,12 +1359,12 @@ type NetworkStats struct {
1351 1351
 	Name       string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
1352 1352
 	RxBytes    uint64 `protobuf:"varint,2,opt,name=rx_bytes,json=rxBytes" json:"rx_bytes,omitempty"`
1353 1353
 	Rx_Packets uint64 `protobuf:"varint,3,opt,name=rx_Packets,json=rxPackets" json:"rx_Packets,omitempty"`
1354
-	RxErrors   uint64 `protobuf:"varint,4,opt,name=Rx_errors,json=rxErrors" json:"Rx_errors,omitempty"`
1355
-	RxDropped  uint64 `protobuf:"varint,5,opt,name=Rx_dropped,json=rxDropped" json:"Rx_dropped,omitempty"`
1356
-	TxBytes    uint64 `protobuf:"varint,6,opt,name=Tx_bytes,json=txBytes" json:"Tx_bytes,omitempty"`
1357
-	TxPackets  uint64 `protobuf:"varint,7,opt,name=Tx_packets,json=txPackets" json:"Tx_packets,omitempty"`
1358
-	TxErrors   uint64 `protobuf:"varint,8,opt,name=Tx_errors,json=txErrors" json:"Tx_errors,omitempty"`
1359
-	TxDropped  uint64 `protobuf:"varint,9,opt,name=Tx_dropped,json=txDropped" json:"Tx_dropped,omitempty"`
1354
+	RxErrors   uint64 `protobuf:"varint,4,opt,name=Rx_errors,json=RxErrors" json:"Rx_errors,omitempty"`
1355
+	RxDropped  uint64 `protobuf:"varint,5,opt,name=Rx_dropped,json=RxDropped" json:"Rx_dropped,omitempty"`
1356
+	TxBytes    uint64 `protobuf:"varint,6,opt,name=Tx_bytes,json=TxBytes" json:"Tx_bytes,omitempty"`
1357
+	TxPackets  uint64 `protobuf:"varint,7,opt,name=Tx_packets,json=TxPackets" json:"Tx_packets,omitempty"`
1358
+	TxErrors   uint64 `protobuf:"varint,8,opt,name=Tx_errors,json=TxErrors" json:"Tx_errors,omitempty"`
1359
+	TxDropped  uint64 `protobuf:"varint,9,opt,name=Tx_dropped,json=TxDropped" json:"Tx_dropped,omitempty"`
1360 1360
 }
1361 1361
 
1362 1362
 func (m *NetworkStats) Reset()                    { *m = NetworkStats{} }
... ...
@@ -2407,169 +2415,170 @@ var _API_serviceDesc = grpc.ServiceDesc{
2407 2407
 func init() { proto.RegisterFile("api.proto", fileDescriptor0) }
2408 2408
 
2409 2409
 var fileDescriptor0 = []byte{
2410
-	// 2616 bytes of a gzipped FileDescriptorProto
2411
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x19, 0x4d, 0x6f, 0x1c, 0x49,
2412
-	0x35, 0x33, 0xd3, 0x9e, 0xf1, 0xbc, 0xf9, 0xb0, 0xa7, 0xe2, 0xd8, 0x9d, 0xd9, 0xdd, 0xc4, 0xdb,
2413
-	0x5a, 0x58, 0x03, 0x2b, 0x27, 0x38, 0x1b, 0x88, 0x58, 0x09, 0x29, 0xb1, 0xc3, 0x62, 0x36, 0x4e,
2414
-	0x26, 0x6d, 0x9b, 0x08, 0x09, 0x69, 0xd4, 0xee, 0xae, 0xcc, 0x14, 0xee, 0xe9, 0xea, 0x54, 0x57,
2415
-	0xdb, 0xe3, 0xcb, 0x1e, 0x38, 0xc0, 0x0d, 0xae, 0x48, 0x1c, 0xb9, 0x71, 0xe7, 0x00, 0x7f, 0x00,
2416
-	0x89, 0x1f, 0xc2, 0x6d, 0xef, 0x1c, 0x51, 0x7d, 0x74, 0x77, 0xf5, 0x7c, 0x38, 0x09, 0x12, 0xe2,
2417
-	0xc2, 0xa5, 0x55, 0xef, 0xd5, 0xfb, 0xaa, 0x57, 0xef, 0xbd, 0x7a, 0x55, 0x0d, 0x4d, 0x2f, 0x26,
2418
-	0xbb, 0x31, 0xa3, 0x9c, 0xa2, 0x15, 0x7e, 0x15, 0xe3, 0xa4, 0x7f, 0x77, 0x44, 0xe9, 0x28, 0xc4,
2419
-	0xf7, 0x24, 0xf2, 0x2c, 0x7d, 0x7d, 0x8f, 0x93, 0x09, 0x4e, 0xb8, 0x37, 0x89, 0x15, 0x9d, 0x73,
2420
-	0x1b, 0xb6, 0xbe, 0xc4, 0xfc, 0x18, 0xb3, 0x0b, 0xcc, 0x7e, 0x8e, 0x59, 0x42, 0x68, 0xe4, 0xe2,
2421
-	0x37, 0x29, 0x4e, 0xb8, 0x33, 0x05, 0x7b, 0x7e, 0x2a, 0x89, 0x69, 0x94, 0x60, 0xb4, 0x01, 0x2b,
2422
-	0x13, 0xef, 0x57, 0x94, 0xd9, 0x95, 0xed, 0xca, 0x4e, 0xc7, 0x55, 0x80, 0xc4, 0x92, 0x88, 0x32,
2423
-	0xbb, 0xaa, 0xb1, 0x02, 0x10, 0xd8, 0xd8, 0xe3, 0xfe, 0xd8, 0xae, 0x29, 0xac, 0x04, 0x50, 0x1f,
2424
-	0x56, 0x19, 0xbe, 0x20, 0x42, 0xaa, 0x6d, 0x6d, 0x57, 0x76, 0x9a, 0x6e, 0x0e, 0x3b, 0xbf, 0xa9,
2425
-	0xc0, 0xc6, 0x69, 0x1c, 0x78, 0x1c, 0x0f, 0x18, 0xf5, 0x71, 0x92, 0x68, 0x93, 0x50, 0x17, 0xaa,
2426
-	0x24, 0x90, 0x3a, 0x9b, 0x6e, 0x95, 0x04, 0x68, 0x1d, 0x6a, 0x31, 0x09, 0xa4, 0xba, 0xa6, 0x2b,
2427
-	0x86, 0xe8, 0x0e, 0x80, 0x1f, 0xd2, 0x04, 0x1f, 0xf3, 0x80, 0x44, 0x52, 0xe3, 0xaa, 0x6b, 0x60,
2428
-	0x84, 0x31, 0x97, 0x24, 0xe0, 0x63, 0xa9, 0xb3, 0xe3, 0x2a, 0x00, 0x6d, 0x42, 0x7d, 0x8c, 0xc9,
2429
-	0x68, 0xcc, 0xed, 0x15, 0x89, 0xd6, 0x90, 0xb3, 0x05, 0xb7, 0x66, 0xec, 0x50, 0xeb, 0x77, 0xfe,
2430
-	0x51, 0x85, 0xcd, 0x7d, 0x86, 0x3d, 0x8e, 0xf7, 0x69, 0xc4, 0x3d, 0x12, 0x61, 0xb6, 0xcc, 0xc6,
2431
-	0x3b, 0x00, 0x67, 0x69, 0x14, 0x84, 0x78, 0xe0, 0xf1, 0xb1, 0x36, 0xd5, 0xc0, 0x48, 0x8b, 0xc7,
2432
-	0xd8, 0x3f, 0x8f, 0x29, 0x89, 0xb8, 0xb4, 0xb8, 0xe9, 0x1a, 0x18, 0x61, 0x71, 0x22, 0x17, 0xa3,
2433
-	0xbc, 0xa4, 0x00, 0x61, 0x71, 0xc2, 0x03, 0x9a, 0x2a, 0x8b, 0x9b, 0xae, 0x86, 0x34, 0x1e, 0x33,
2434
-	0x66, 0xd7, 0x73, 0x3c, 0x66, 0x4c, 0xe0, 0x43, 0xef, 0x0c, 0x87, 0x89, 0xdd, 0xd8, 0xae, 0x09,
2435
-	0xbc, 0x82, 0xd0, 0x36, 0xb4, 0x22, 0x3a, 0x20, 0x17, 0x94, 0xbb, 0x94, 0x72, 0x7b, 0x55, 0x3a,
2436
-	0xcc, 0x44, 0x21, 0x1b, 0x1a, 0x2c, 0x8d, 0x44, 0xdc, 0xd8, 0x4d, 0x29, 0x32, 0x03, 0x05, 0xaf,
2437
-	0x1e, 0x3e, 0x66, 0xa3, 0xc4, 0x06, 0x29, 0xd8, 0x44, 0xa1, 0x4f, 0xa0, 0x53, 0xac, 0xe4, 0x80,
2438
-	0x30, 0xbb, 0x25, 0x25, 0x94, 0x91, 0xce, 0x21, 0x6c, 0xcd, 0xf9, 0x52, 0xc7, 0xd9, 0x2e, 0x34,
2439
-	0xfd, 0x0c, 0x29, 0x7d, 0xda, 0xda, 0x5b, 0xdf, 0x95, 0xa1, 0xbd, 0x5b, 0x10, 0x17, 0x24, 0xce,
2440
-	0x21, 0x74, 0x8e, 0xc9, 0x28, 0xf2, 0xc2, 0x77, 0x8f, 0x18, 0xe1, 0x31, 0xc9, 0xa2, 0xe3, 0x53,
2441
-	0x43, 0xce, 0x3a, 0x74, 0x33, 0x51, 0x7a, 0xd3, 0xff, 0x52, 0x83, 0xde, 0xe3, 0x20, 0x78, 0x4b,
2442
-	0x4c, 0xf6, 0x61, 0x95, 0x63, 0x36, 0x21, 0x42, 0x62, 0x55, 0xba, 0x33, 0x87, 0xd1, 0x5d, 0xb0,
2443
-	0xd2, 0x04, 0x33, 0xa9, 0xa9, 0xb5, 0xd7, 0xd2, 0x2b, 0x39, 0x4d, 0x30, 0x73, 0xe5, 0x04, 0x42,
2444
-	0x60, 0x79, 0xc2, 0x97, 0x96, 0xf4, 0xa5, 0x1c, 0x0b, 0x93, 0x71, 0x74, 0x61, 0xaf, 0x48, 0x94,
2445
-	0x18, 0x0a, 0x8c, 0x7f, 0x19, 0xe8, 0x1d, 0x16, 0xc3, 0x6c, 0x59, 0x8d, 0x62, 0x59, 0x79, 0xd8,
2446
-	0xac, 0x2e, 0x0e, 0x9b, 0xe6, 0x92, 0xb0, 0x81, 0x52, 0xd8, 0x38, 0xd0, 0xf6, 0xbd, 0xd8, 0x3b,
2447
-	0x23, 0x21, 0xe1, 0x04, 0x27, 0x76, 0x4b, 0x1a, 0x51, 0xc2, 0xa1, 0x1d, 0x58, 0xf3, 0xe2, 0xd8,
2448
-	0x63, 0x13, 0xca, 0x06, 0x8c, 0xbe, 0x26, 0x21, 0xb6, 0xdb, 0x52, 0xc8, 0x2c, 0x5a, 0x48, 0x4b,
2449
-	0x70, 0x48, 0xa2, 0x74, 0xfa, 0x4c, 0x44, 0x9f, 0xdd, 0x91, 0x64, 0x25, 0x9c, 0x90, 0x16, 0xd1,
2450
-	0xe7, 0xf8, 0x72, 0xc0, 0xc8, 0x05, 0x09, 0xf1, 0x08, 0x27, 0x76, 0x57, 0x7a, 0x71, 0x16, 0x8d,
2451
-	0x3e, 0x85, 0x06, 0x0b, 0xc9, 0x84, 0xf0, 0xc4, 0x5e, 0xdb, 0xae, 0xed, 0xb4, 0xf6, 0x3a, 0xda,
2452
-	0x9f, 0xae, 0xc4, 0xba, 0xd9, 0xac, 0x73, 0x00, 0x75, 0x85, 0x12, 0xee, 0x15, 0x24, 0x7a, 0xb7,
2453
-	0xe4, 0x58, 0xe0, 0x12, 0xfa, 0x9a, 0xcb, 0xbd, 0xb2, 0x5c, 0x39, 0x16, 0xb8, 0xb1, 0xc7, 0x02,
2454
-	0xb9, 0x4f, 0x96, 0x2b, 0xc7, 0x8e, 0x0b, 0x96, 0xd8, 0x28, 0xe1, 0xea, 0x54, 0x6f, 0x78, 0xc7,
2455
-	0x15, 0x43, 0x81, 0x19, 0xe9, 0x98, 0xea, 0xb8, 0x62, 0x88, 0xbe, 0x0d, 0x5d, 0x2f, 0x08, 0x08,
2456
-	0x27, 0x34, 0xf2, 0xc2, 0x2f, 0x49, 0x90, 0xd8, 0xb5, 0xed, 0xda, 0x4e, 0xc7, 0x9d, 0xc1, 0x3a,
2457
-	0x7b, 0x80, 0xcc, 0x80, 0xd2, 0x41, 0xff, 0x21, 0x34, 0x93, 0xab, 0x84, 0xe3, 0xc9, 0x20, 0xd7,
2458
-	0x53, 0x20, 0x9c, 0x5f, 0x57, 0xf2, 0x74, 0xc9, 0xb3, 0x68, 0x59, 0x2c, 0x7e, 0xbf, 0x54, 0x5b,
2459
-	0xaa, 0x32, 0xea, 0x7a, 0x59, 0xfe, 0x14, 0xdc, 0x66, 0xb9, 0x99, 0x4b, 0xd9, 0xda, 0xa2, 0x94,
2460
-	0xed, 0x83, 0x3d, 0x6f, 0x83, 0x4e, 0x13, 0x1f, 0xb6, 0x0e, 0x70, 0x88, 0xdf, 0xc5, 0x3e, 0x04,
2461
-	0x56, 0xe4, 0x4d, 0xb0, 0x4e, 0x47, 0x39, 0x7e, 0x77, 0x03, 0xe6, 0x95, 0x68, 0x03, 0x8e, 0xe0,
2462
-	0xd6, 0x33, 0x92, 0xf0, 0xb7, 0xab, 0x9f, 0x53, 0x55, 0x5d, 0xa4, 0xea, 0x0f, 0x15, 0x80, 0x42,
2463
-	0x56, 0x6e, 0x73, 0xc5, 0xb0, 0x19, 0x81, 0x85, 0xa7, 0x84, 0xeb, 0x7c, 0x97, 0x63, 0x11, 0x15,
2464
-	0xdc, 0x8f, 0xf5, 0x11, 0x24, 0x86, 0xa2, 0x5e, 0xa6, 0x11, 0x99, 0x1e, 0x53, 0xff, 0x1c, 0xf3,
2465
-	0x44, 0xd6, 0xf3, 0x55, 0xd7, 0x44, 0xc9, 0xa4, 0x1d, 0xe3, 0x30, 0x94, 0x45, 0x7d, 0xd5, 0x55,
2466
-	0x80, 0xa8, 0xc0, 0x78, 0x12, 0xf3, 0xab, 0xe7, 0xc7, 0x76, 0x5d, 0xe6, 0x5f, 0x06, 0x3a, 0x47,
2467
-	0xb0, 0x39, 0xbb, 0x52, 0x1d, 0x43, 0x0f, 0xa0, 0x55, 0xac, 0x22, 0xb1, 0x2b, 0x32, 0x41, 0x16,
2468
-	0x6c, 0xbd, 0x49, 0xe5, 0xdc, 0x81, 0xf6, 0x31, 0xf7, 0x38, 0x5e, 0xe2, 0x2f, 0x67, 0x07, 0xba,
2469
-	0x79, 0xd5, 0x95, 0x84, 0xaa, 0x6e, 0x78, 0x3c, 0x4d, 0x34, 0x95, 0x86, 0x9c, 0xbf, 0xd6, 0xa0,
2470
-	0xa1, 0xc3, 0x3a, 0xab, 0x4d, 0x95, 0xa2, 0x36, 0xfd, 0x4f, 0x4a, 0x64, 0x29, 0xab, 0x1a, 0x33,
2471
-	0x59, 0xf5, 0xff, 0x72, 0x59, 0x94, 0xcb, 0xbf, 0x57, 0xa0, 0x99, 0x6f, 0xf3, 0x7b, 0xb7, 0x33,
2472
-	0x9f, 0x41, 0x33, 0x56, 0x1b, 0x8f, 0x55, 0xd5, 0x6b, 0xed, 0x75, 0xb5, 0xa2, 0xac, 0xce, 0x15,
2473
-	0x04, 0x46, 0xfc, 0x58, 0x66, 0xfc, 0x18, 0xed, 0xca, 0x4a, 0xa9, 0x5d, 0x41, 0x60, 0xc5, 0xa2,
2474
-	0x9c, 0xd6, 0x65, 0x39, 0x95, 0x63, 0xb3, 0x41, 0x69, 0x94, 0x1a, 0x14, 0xe7, 0x21, 0x34, 0x8e,
2475
-	0x3c, 0x7f, 0x4c, 0x22, 0x99, 0xa1, 0x7e, 0xac, 0xc3, 0xb4, 0xe3, 0xca, 0xb1, 0x50, 0x32, 0xc1,
2476
-	0x13, 0xca, 0xae, 0x74, 0xed, 0xd7, 0x90, 0x73, 0x0e, 0x1d, 0x9d, 0x06, 0x3a, 0x99, 0xee, 0x03,
2477
-	0xe4, 0x2d, 0x46, 0x96, 0x4b, 0xf3, 0x6d, 0x88, 0x41, 0x83, 0x76, 0xa0, 0x31, 0x51, 0x9a, 0x75,
2478
-	0xd5, 0xcd, 0x7c, 0xa0, 0xed, 0x71, 0xb3, 0x69, 0xe7, 0xb7, 0x15, 0xd8, 0x54, 0x3d, 0xe6, 0x5b,
2479
-	0x3b, 0xc9, 0xc5, 0xbd, 0x8b, 0x72, 0x5f, 0xad, 0xe4, 0xbe, 0x07, 0xd0, 0x64, 0x38, 0xa1, 0x29,
2480
-	0xf3, 0xb1, 0xf2, 0x6c, 0x6b, 0xef, 0x56, 0x96, 0x49, 0x52, 0x97, 0xab, 0x67, 0xdd, 0x82, 0xce,
2481
-	0xf9, 0xa6, 0x0e, 0xdd, 0xf2, 0xac, 0xa8, 0x58, 0x67, 0xe1, 0x39, 0xa1, 0xaf, 0x54, 0x73, 0x5c,
2482
-	0x91, 0x6e, 0x32, 0x51, 0x22, 0xab, 0xfc, 0x38, 0x3d, 0x1e, 0x7b, 0x0c, 0x27, 0xda, 0x8d, 0x05,
2483
-	0x42, 0xcf, 0x0e, 0x30, 0x23, 0x34, 0x3b, 0x4c, 0x0b, 0x84, 0x28, 0x03, 0x7e, 0x9c, 0xbe, 0x4c,
2484
-	0x29, 0xf7, 0xa4, 0x91, 0x96, 0x9b, 0xc3, 0xb2, 0x2b, 0x8e, 0xd3, 0x04, 0xf3, 0x7d, 0xb1, 0x6b,
2485
-	0x2b, 0xba, 0x2b, 0xce, 0x31, 0xc5, 0xfc, 0x11, 0x9e, 0x24, 0x3a, 0xcd, 0x0d, 0x8c, 0xb0, 0x5c,
2486
-	0xed, 0xe6, 0x33, 0x11, 0xd4, 0x32, 0x30, 0x2c, 0xd7, 0x44, 0x09, 0x09, 0x0a, 0x3c, 0xbe, 0xf4,
2487
-	0x62, 0x99, 0xf6, 0x96, 0x6b, 0x60, 0xd0, 0x67, 0xd0, 0x53, 0x90, 0x8b, 0x13, 0xcc, 0x2e, 0x3c,
2488
-	0x71, 0x6c, 0xcb, 0x32, 0x60, 0xb9, 0xf3, 0x13, 0x82, 0xfa, 0x1c, 0xb3, 0x08, 0x87, 0x47, 0x86,
2489
-	0x56, 0x50, 0xd4, 0x73, 0x13, 0x68, 0x0f, 0x36, 0x14, 0xf2, 0x64, 0x7f, 0x60, 0x32, 0xb4, 0x24,
2490
-	0xc3, 0xc2, 0x39, 0x91, 0xe9, 0xd2, 0xf1, 0xcf, 0xb0, 0xf7, 0x5a, 0xef, 0x47, 0x5b, 0x92, 0xcf,
2491
-	0xa2, 0xd1, 0x63, 0xe8, 0x19, 0x5b, 0x74, 0x80, 0x2f, 0x88, 0x8f, 0xed, 0x8e, 0x8c, 0xda, 0x9b,
2492
-	0x3a, 0x0a, 0xcc, 0x29, 0x77, 0x9e, 0x1a, 0x9d, 0x42, 0x5f, 0x22, 0x4f, 0xc6, 0x8c, 0x72, 0x1e,
2493
-	0x62, 0x17, 0x7b, 0xc1, 0x93, 0x38, 0xd1, 0xb2, 0xba, 0x52, 0x56, 0x16, 0x51, 0x19, 0x8d, 0x96,
2494
-	0x76, 0x0d, 0x23, 0x7a, 0x05, 0x1f, 0x94, 0x66, 0x5f, 0x31, 0xc2, 0x71, 0x21, 0x77, 0xed, 0x3a,
2495
-	0xb9, 0xd7, 0x71, 0xce, 0x09, 0x16, 0x6a, 0x0f, 0x69, 0x2e, 0x78, 0xfd, 0xdd, 0x05, 0x97, 0x39,
2496
-	0xd1, 0x2f, 0xe0, 0xc3, 0x79, 0xbd, 0x86, 0xe4, 0xde, 0x75, 0x92, 0xaf, 0x65, 0x75, 0xbe, 0x80,
2497
-	0xce, 0x93, 0x90, 0xfa, 0xe7, 0x87, 0x2f, 0xb4, 0xae, 0xd2, 0xa5, 0xba, 0xb6, 0xf0, 0x52, 0x5d,
2498
-	0xd3, 0x97, 0x6a, 0xe7, 0x6b, 0x68, 0x97, 0x36, 0xec, 0x07, 0x32, 0x53, 0x33, 0x51, 0xfa, 0xaa,
2499
-	0xb4, 0xa1, 0xcd, 0x2a, 0xa9, 0x71, 0x4d, 0x42, 0x51, 0x41, 0x2e, 0x55, 0x30, 0xa9, 0xf6, 0x55,
2500
-	0x43, 0x22, 0x3b, 0xc2, 0x22, 0xd0, 0xd4, 0xcd, 0xc8, 0xc0, 0x38, 0xbf, 0x84, 0x6e, 0x79, 0xb1,
2501
-	0xff, 0xb1, 0x05, 0x08, 0x2c, 0xe6, 0x71, 0x9c, 0xf5, 0xdf, 0x62, 0xec, 0xdc, 0x86, 0xad, 0xb9,
2502
-	0x9a, 0xa8, 0x9b, 0xbb, 0x2b, 0xe8, 0x3c, 0xbd, 0xc0, 0x11, 0xcf, 0xef, 0x5f, 0x8f, 0xa0, 0x99,
2503
-	0x3f, 0x6a, 0xe8, 0x62, 0xdb, 0xdf, 0x55, 0xcf, 0x1e, 0xbb, 0xd9, 0xb3, 0xc7, 0xee, 0x49, 0x46,
2504
-	0xe1, 0x16, 0xc4, 0x62, 0x8d, 0x09, 0xa7, 0x0c, 0x07, 0x2f, 0xa2, 0xf0, 0x2a, 0x7b, 0x2b, 0x28,
2505
-	0x30, 0xba, 0xfe, 0x5a, 0x79, 0xfb, 0xf3, 0xfb, 0x0a, 0xac, 0x48, 0xdd, 0x0b, 0xef, 0x11, 0x8a,
2506
-	0xba, 0x9a, 0x57, 0xeb, 0x72, 0x6d, 0xee, 0xe4, 0xb5, 0x59, 0x57, 0x71, 0xab, 0xa8, 0xe2, 0xa5,
2507
-	0x15, 0xd4, 0xdf, 0x63, 0x05, 0xce, 0xef, 0xaa, 0xd0, 0x7e, 0x8e, 0xf9, 0x25, 0x65, 0xe7, 0xe2,
2508
-	0xc4, 0x4a, 0x16, 0x36, 0xa7, 0xb7, 0x61, 0x95, 0x4d, 0x87, 0x67, 0x57, 0x3c, 0xaf, 0xd0, 0x0d,
2509
-	0x36, 0x7d, 0x22, 0x40, 0xf4, 0x11, 0x00, 0x9b, 0x0e, 0x07, 0x9e, 0x6a, 0x48, 0x75, 0x81, 0x66,
2510
-	0x53, 0x8d, 0x40, 0x1f, 0x40, 0xd3, 0x9d, 0x0e, 0x31, 0x63, 0x94, 0x25, 0x59, 0x85, 0x66, 0xd3,
2511
-	0xa7, 0x12, 0x16, 0xbc, 0xee, 0x74, 0x18, 0x30, 0x1a, 0xc7, 0x38, 0x90, 0x15, 0x5a, 0xf2, 0x1e,
2512
-	0x28, 0x84, 0xd0, 0x7a, 0x92, 0x69, 0xad, 0x2b, 0xad, 0xbc, 0xd0, 0x7a, 0x32, 0x1d, 0xc6, 0x5a,
2513
-	0xab, 0x2a, 0xcd, 0x4d, 0x6e, 0x6a, 0x3d, 0xc9, 0xb5, 0xaa, 0xba, 0xbc, 0xca, 0x0d, 0xad, 0x27,
2514
-	0x85, 0xd6, 0x66, 0xc6, 0xab, 0xb5, 0x3a, 0x7f, 0xae, 0xc0, 0xea, 0x7e, 0x9c, 0x9e, 0x26, 0xde,
2515
-	0x08, 0xa3, 0xbb, 0xd0, 0xe2, 0x94, 0x7b, 0xe1, 0x30, 0x15, 0xa0, 0x3e, 0xbd, 0x40, 0xa2, 0x14,
2516
-	0xc1, 0xc7, 0xd0, 0x8e, 0x31, 0xf3, 0xe3, 0x54, 0x53, 0x54, 0xb7, 0x6b, 0xe2, 0x94, 0x50, 0x38,
2517
-	0x45, 0xb2, 0x0b, 0x37, 0xe5, 0xdc, 0x90, 0x44, 0x43, 0x55, 0x96, 0x27, 0x34, 0xc0, 0xda, 0x55,
2518
-	0x3d, 0x39, 0x75, 0x18, 0x7d, 0x95, 0x4f, 0xa0, 0xef, 0x42, 0x2f, 0xa7, 0x17, 0xed, 0xaa, 0xa4,
2519
-	0x56, 0xae, 0x5b, 0xd3, 0xd4, 0xa7, 0x1a, 0xed, 0x7c, 0x9d, 0xe7, 0x10, 0x89, 0x46, 0x07, 0x1e,
2520
-	0xf7, 0x44, 0x2b, 0x13, 0xcb, 0xb3, 0x31, 0xd1, 0xd6, 0x66, 0x20, 0xfa, 0x1e, 0xf4, 0xb8, 0xce,
2521
-	0xb7, 0x60, 0x98, 0xd1, 0xa8, 0xdd, 0x5c, 0xcf, 0x27, 0x06, 0x9a, 0xf8, 0x5b, 0xd0, 0x2d, 0x88,
2522
-	0x65, 0x63, 0xa4, 0xec, 0xed, 0xe4, 0x58, 0x11, 0x4d, 0xce, 0x1f, 0x95, 0xb3, 0x54, 0xe4, 0x7c,
2523
-	0x26, 0x8f, 0x6a, 0xc3, 0x55, 0xad, 0xbd, 0xb5, 0xac, 0xc5, 0xd1, 0xce, 0x90, 0xc7, 0xb3, 0x72,
2524
-	0xcb, 0x8f, 0x61, 0x8d, 0xe7, 0xa6, 0x0f, 0x03, 0x8f, 0x7b, 0x3a, 0xf5, 0x66, 0x2a, 0xa1, 0x5e,
2525
-	0x98, 0xdb, 0xe5, 0xe5, 0x85, 0x7e, 0x0c, 0x6d, 0xd5, 0x7b, 0x6b, 0x85, 0xca, 0xbe, 0x96, 0xc2,
2526
-	0x49, 0x15, 0xce, 0x17, 0xd0, 0x1c, 0x90, 0x20, 0x51, 0xd6, 0xd9, 0xd0, 0xf0, 0x53, 0xc6, 0x70,
2527
-	0x94, 0x35, 0x21, 0x19, 0x28, 0xca, 0xa3, 0xec, 0x5b, 0xb5, 0x33, 0x14, 0xe0, 0x50, 0x00, 0x75,
2528
-	0x76, 0x4a, 0x6d, 0x1b, 0xb0, 0x62, 0x86, 0x80, 0x02, 0x44, 0x9c, 0x4d, 0xbc, 0x69, 0xbe, 0xf5,
2529
-	0x32, 0xce, 0x26, 0xde, 0x54, 0x2d, 0xd0, 0x86, 0xc6, 0x6b, 0x8f, 0x84, 0xbe, 0x7e, 0x92, 0xb3,
2530
-	0xdc, 0x0c, 0x2c, 0x14, 0x5a, 0xa6, 0xc2, 0x3f, 0x55, 0xa1, 0xa5, 0x34, 0x2a, 0x83, 0x37, 0x60,
2531
-	0xc5, 0xf7, 0xfc, 0x71, 0xae, 0x52, 0x02, 0xe8, 0xd3, 0xcc, 0x90, 0xf2, 0x55, 0xbc, 0x30, 0x35,
2532
-	0xb3, 0xed, 0x3e, 0x40, 0x72, 0xe9, 0xc5, 0x86, 0x77, 0x16, 0x52, 0x37, 0x05, 0x91, 0x32, 0xf8,
2533
-	0x73, 0x68, 0xab, 0xf8, 0xd4, 0x3c, 0xd6, 0x32, 0x9e, 0x96, 0x22, 0x53, 0x5c, 0x0f, 0xc4, 0xb5,
2534
-	0xc7, 0xe3, 0xaa, 0xcd, 0x6e, 0xed, 0x7d, 0x54, 0x22, 0x97, 0x2b, 0xd9, 0x95, 0xdf, 0xa7, 0x11,
2535
-	0x67, 0x57, 0xae, 0xa2, 0xed, 0x3f, 0x02, 0x28, 0x90, 0xa2, 0x9e, 0x9d, 0xe3, 0xab, 0xec, 0x7a,
2536
-	0x77, 0x8e, 0xaf, 0xc4, 0xda, 0x2f, 0xbc, 0x30, 0xcd, 0x9c, 0xaa, 0x80, 0x1f, 0x55, 0x1f, 0x55,
2537
-	0x1c, 0x1f, 0xd6, 0x9e, 0x88, 0x23, 0xd1, 0x60, 0x2f, 0x1d, 0x7a, 0xd6, 0xc2, 0x43, 0xcf, 0xca,
2538
-	0x5e, 0x92, 0xbb, 0x50, 0xa5, 0xb1, 0x6e, 0x75, 0xab, 0x34, 0x2e, 0x14, 0x59, 0x86, 0x22, 0xe7,
2539
-	0x9f, 0x16, 0x40, 0xa1, 0x05, 0x1d, 0x43, 0x9f, 0xd0, 0xa1, 0xe8, 0xd4, 0x88, 0x8f, 0x55, 0x41,
2540
-	0x1a, 0x32, 0xec, 0xa7, 0x2c, 0x21, 0x17, 0x58, 0x37, 0xf3, 0x9b, 0xf9, 0x31, 0x55, 0x32, 0xce,
2541
-	0xdd, 0x22, 0xf4, 0x58, 0x31, 0xca, 0xca, 0xe5, 0x66, 0x6c, 0xe8, 0x67, 0x70, 0xab, 0x10, 0x1a,
2542
-	0x18, 0xf2, 0xaa, 0xd7, 0xca, 0xbb, 0x99, 0xcb, 0x0b, 0x0a, 0x59, 0x3f, 0x81, 0x9b, 0x84, 0x0e,
2543
-	0xdf, 0xa4, 0x38, 0x2d, 0x49, 0xaa, 0x5d, 0x2b, 0xa9, 0x47, 0xe8, 0x4b, 0xc9, 0x51, 0xc8, 0x79,
2544
-	0x09, 0xb7, 0x8d, 0x85, 0x8a, 0xb4, 0x37, 0xa4, 0x59, 0xd7, 0x4a, 0xdb, 0xcc, 0xed, 0x12, 0x85,
2545
-	0xa1, 0x10, 0xf9, 0x15, 0x6c, 0x12, 0x3a, 0xbc, 0xf4, 0x08, 0x9f, 0x95, 0xb7, 0xf2, 0xb6, 0x75,
2546
-	0xbe, 0xf2, 0x08, 0x2f, 0x0b, 0x53, 0xeb, 0x9c, 0x60, 0x36, 0x2a, 0xad, 0xb3, 0xfe, 0xb6, 0x75,
2547
-	0x1e, 0x49, 0x8e, 0x42, 0xce, 0x13, 0xe8, 0x11, 0x3a, 0x6b, 0x4f, 0xe3, 0x5a, 0x29, 0x6b, 0x84,
2548
-	0x96, 0x6d, 0xd9, 0x87, 0x5e, 0x82, 0x7d, 0x4e, 0x99, 0x19, 0x0b, 0xab, 0xd7, 0xca, 0x58, 0xd7,
2549
-	0x0c, 0xb9, 0x10, 0xe7, 0x0d, 0xb4, 0x7f, 0x9a, 0x8e, 0x30, 0x0f, 0xcf, 0xf2, 0x9c, 0xff, 0x6f,
2550
-	0x97, 0x99, 0x7f, 0x55, 0xa1, 0xb5, 0x3f, 0x62, 0x34, 0x8d, 0x4b, 0x55, 0x5b, 0xe5, 0xf0, 0x5c,
2551
-	0xd5, 0x96, 0x34, 0xb2, 0x6a, 0x2b, 0xea, 0x87, 0xd0, 0x56, 0x37, 0x17, 0xcd, 0xa0, 0xaa, 0x10,
2552
-	0x9a, 0x4f, 0xfa, 0xec, 0xa6, 0xa4, 0xd8, 0xf6, 0xf4, 0x2d, 0x50, 0x73, 0x95, 0xab, 0x51, 0xe1,
2553
-	0x26, 0x17, 0xce, 0x8a, 0xac, 0x3b, 0x84, 0xce, 0x58, 0xf9, 0x46, 0x73, 0xa9, 0x00, 0xfc, 0x24,
2554
-	0x33, 0xae, 0x58, 0xc3, 0xae, 0xe9, 0x43, 0xe5, 0xea, 0xf6, 0xd8, 0x74, 0xeb, 0x3d, 0x00, 0x71,
2555
-	0xcf, 0x1f, 0x66, 0x85, 0xca, 0xfc, 0x09, 0x90, 0x9f, 0x10, 0x6e, 0x33, 0xce, 0x86, 0xfd, 0x13,
2556
-	0xe8, 0xcd, 0xc9, 0x5c, 0x50, 0xa6, 0xbe, 0x63, 0x96, 0xa9, 0xe2, 0x6a, 0x64, 0xb2, 0x9a, 0xb5,
2557
-	0xeb, 0x6f, 0x15, 0xf5, 0x2c, 0x50, 0xbc, 0xd3, 0x3e, 0x82, 0x4e, 0xa4, 0x9a, 0xaf, 0x7c, 0x03,
2558
-	0xcc, 0x3b, 0x96, 0xd9, 0x98, 0xb9, 0xed, 0xc8, 0x6c, 0xd3, 0x1e, 0x42, 0xdb, 0x97, 0x1e, 0x58,
2559
-	0xb8, 0x11, 0x86, 0x73, 0xdc, 0x96, 0x6f, 0xec, 0x76, 0xa9, 0x51, 0xb4, 0xde, 0xa7, 0x51, 0xd4,
2560
-	0x2f, 0x7b, 0xcb, 0x7e, 0x5a, 0xec, 0x7d, 0x53, 0x87, 0xda, 0xe3, 0xc1, 0x21, 0x3a, 0x85, 0xf5,
2561
-	0xd9, 0x7f, 0x7e, 0xe8, 0x8e, 0x36, 0x6b, 0xc9, 0x7f, 0xc2, 0xfe, 0xdd, 0xa5, 0xf3, 0xba, 0x65,
2562
-	0xbf, 0x81, 0x5c, 0x58, 0x9b, 0xf9, 0xc3, 0x83, 0xb2, 0xa3, 0x66, 0xf1, 0x5f, 0xb4, 0xfe, 0x9d,
2563
-	0x65, 0xd3, 0xa6, 0xcc, 0x99, 0x3b, 0x42, 0x2e, 0x73, 0xf1, 0x7b, 0x4a, 0x2e, 0x73, 0xd9, 0xd5,
2564
-	0xe2, 0x06, 0xfa, 0x21, 0xd4, 0xd5, 0x3f, 0x1f, 0x94, 0x5d, 0x5c, 0x4a, 0x7f, 0x93, 0xfa, 0xb7,
2565
-	0x66, 0xb0, 0x39, 0xe3, 0x33, 0xe8, 0x94, 0x7e, 0x14, 0xa2, 0x0f, 0x4a, 0xba, 0xca, 0xbf, 0x8c,
2566
-	0xfa, 0x1f, 0x2e, 0x9e, 0xcc, 0xa5, 0xed, 0x03, 0x14, 0xbf, 0x05, 0x90, 0xad, 0xa9, 0xe7, 0x7e,
2567
-	0x3d, 0xf5, 0x6f, 0x2f, 0x98, 0xc9, 0x85, 0x9c, 0xc2, 0xfa, 0xec, 0x13, 0x3d, 0x9a, 0xf1, 0xea,
2568
-	0xec, 0x03, 0x79, 0xbe, 0x95, 0x4b, 0xdf, 0xf6, 0xa5, 0xd8, 0xd9, 0x87, 0xf7, 0x5c, 0xec, 0x92,
2569
-	0x67, 0xff, 0x5c, 0xec, 0xd2, 0x17, 0xfb, 0x1b, 0xe8, 0x05, 0x74, 0xcb, 0x2f, 0xd9, 0x28, 0x73,
2570
-	0xd2, 0xc2, 0xa7, 0xfc, 0xfe, 0x47, 0x4b, 0x66, 0x73, 0x81, 0x9f, 0xc3, 0x8a, 0x7a, 0xa2, 0xce,
2571
-	0xd2, 0xd1, 0x7c, 0xd9, 0xee, 0x6f, 0x94, 0x91, 0x39, 0xd7, 0x7d, 0xa8, 0xab, 0xdb, 0x65, 0x1e,
2572
-	0x00, 0xa5, 0xcb, 0x66, 0xbf, 0x6d, 0x62, 0x9d, 0x1b, 0xf7, 0x2b, 0x99, 0x9e, 0xa4, 0xa4, 0x27,
2573
-	0x59, 0xa4, 0xc7, 0xd8, 0x9c, 0xb3, 0xba, 0x4c, 0xd7, 0x07, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff,
2574
-	0x11, 0x58, 0x45, 0xd9, 0xb2, 0x1f, 0x00, 0x00,
2410
+	// 2632 bytes of a gzipped FileDescriptorProto
2411
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x19, 0x4d, 0x6f, 0x24, 0x47,
2412
+	0x75, 0x67, 0xa6, 0xed, 0xf1, 0xbc, 0xf9, 0xb0, 0xa7, 0xd6, 0xeb, 0xed, 0x9d, 0x24, 0xbb, 0x4e,
2413
+	0x2b, 0x10, 0x03, 0x91, 0xb3, 0x78, 0x13, 0x58, 0x11, 0x09, 0x69, 0xd7, 0x1b, 0x82, 0xc9, 0x3a,
2414
+	0x99, 0xb4, 0x6d, 0x56, 0x48, 0x48, 0xa3, 0x76, 0x77, 0xed, 0x4c, 0xe1, 0x9e, 0xae, 0x4e, 0x75,
2415
+	0xb5, 0x3d, 0xbe, 0xe4, 0xc0, 0x01, 0x0e, 0x48, 0x70, 0x45, 0xe2, 0xc8, 0x8d, 0x3b, 0x07, 0xf8,
2416
+	0x03, 0x48, 0xfc, 0x10, 0x6e, 0xdc, 0x39, 0xa2, 0xfa, 0xe8, 0xea, 0xea, 0xf9, 0xf0, 0x6e, 0x90,
2417
+	0x10, 0x17, 0x2e, 0xad, 0x7a, 0xaf, 0xde, 0x57, 0xbd, 0x7a, 0xef, 0xd5, 0xab, 0x6a, 0x68, 0x05,
2418
+	0x29, 0xd9, 0x4f, 0x19, 0xe5, 0x14, 0xad, 0xf1, 0xeb, 0x14, 0x67, 0x83, 0x07, 0x63, 0x4a, 0xc7,
2419
+	0x31, 0x7e, 0x5f, 0x22, 0xcf, 0xf3, 0x97, 0xef, 0x73, 0x32, 0xc5, 0x19, 0x0f, 0xa6, 0xa9, 0xa2,
2420
+	0xf3, 0xee, 0xc1, 0xdd, 0x4f, 0x30, 0x3f, 0xc1, 0xec, 0x12, 0xb3, 0x9f, 0x62, 0x96, 0x11, 0x9a,
2421
+	0xf8, 0xf8, 0xcb, 0x1c, 0x67, 0xdc, 0x9b, 0x81, 0xbb, 0x38, 0x95, 0xa5, 0x34, 0xc9, 0x30, 0xda,
2422
+	0x86, 0xb5, 0x69, 0xf0, 0x0b, 0xca, 0xdc, 0xda, 0x6e, 0x6d, 0xaf, 0xeb, 0x2b, 0x40, 0x62, 0x49,
2423
+	0x42, 0x99, 0x5b, 0xd7, 0x58, 0x01, 0x08, 0x6c, 0x1a, 0xf0, 0x70, 0xe2, 0x36, 0x14, 0x56, 0x02,
2424
+	0x68, 0x00, 0x1b, 0x0c, 0x5f, 0x12, 0x21, 0xd5, 0x75, 0x76, 0x6b, 0x7b, 0x2d, 0xdf, 0xc0, 0xde,
2425
+	0xaf, 0x6a, 0xb0, 0x7d, 0x96, 0x46, 0x01, 0xc7, 0x43, 0x46, 0x43, 0x9c, 0x65, 0xda, 0x24, 0xd4,
2426
+	0x83, 0x3a, 0x89, 0xa4, 0xce, 0x96, 0x5f, 0x27, 0x11, 0xda, 0x82, 0x46, 0x4a, 0x22, 0xa9, 0xae,
2427
+	0xe5, 0x8b, 0x21, 0xba, 0x0f, 0x10, 0xc6, 0x34, 0xc3, 0x27, 0x3c, 0x22, 0x89, 0xd4, 0xb8, 0xe1,
2428
+	0x5b, 0x18, 0x61, 0xcc, 0x15, 0x89, 0xf8, 0x44, 0xea, 0xec, 0xfa, 0x0a, 0x40, 0x3b, 0xb0, 0x3e,
2429
+	0xc1, 0x64, 0x3c, 0xe1, 0xee, 0x9a, 0x44, 0x6b, 0xc8, 0xbb, 0x0b, 0x77, 0xe6, 0xec, 0x50, 0xeb,
2430
+	0xf7, 0xfe, 0x5e, 0x87, 0x9d, 0x43, 0x86, 0x03, 0x8e, 0x0f, 0x69, 0xc2, 0x03, 0x92, 0x60, 0xb6,
2431
+	0xca, 0xc6, 0xfb, 0x00, 0xe7, 0x79, 0x12, 0xc5, 0x78, 0x18, 0xf0, 0x89, 0x36, 0xd5, 0xc2, 0x48,
2432
+	0x8b, 0x27, 0x38, 0xbc, 0x48, 0x29, 0x49, 0xb8, 0xb4, 0xb8, 0xe5, 0x5b, 0x18, 0x61, 0x71, 0x26,
2433
+	0x17, 0xa3, 0xbc, 0xa4, 0x00, 0x61, 0x71, 0xc6, 0x23, 0x9a, 0x2b, 0x8b, 0x5b, 0xbe, 0x86, 0x34,
2434
+	0x1e, 0x33, 0xe6, 0xae, 0x1b, 0x3c, 0x66, 0x4c, 0xe0, 0xe3, 0xe0, 0x1c, 0xc7, 0x99, 0xdb, 0xdc,
2435
+	0x6d, 0x08, 0xbc, 0x82, 0xd0, 0x2e, 0xb4, 0x13, 0x3a, 0x24, 0x97, 0x94, 0xfb, 0x94, 0x72, 0x77,
2436
+	0x43, 0x3a, 0xcc, 0x46, 0x21, 0x17, 0x9a, 0x2c, 0x4f, 0x44, 0xdc, 0xb8, 0x2d, 0x29, 0xb2, 0x00,
2437
+	0x05, 0xaf, 0x1e, 0x3e, 0x61, 0xe3, 0xcc, 0x05, 0x29, 0xd8, 0x46, 0xa1, 0x77, 0xa0, 0x5b, 0xae,
2438
+	0xe4, 0x19, 0x61, 0x6e, 0x5b, 0x4a, 0xa8, 0x22, 0xbd, 0x23, 0xb8, 0xbb, 0xe0, 0x4b, 0x1d, 0x67,
2439
+	0xfb, 0xd0, 0x0a, 0x0b, 0xa4, 0xf4, 0x69, 0xfb, 0x60, 0x6b, 0x5f, 0x86, 0xf6, 0x7e, 0x49, 0x5c,
2440
+	0x92, 0x78, 0x47, 0xd0, 0x3d, 0x21, 0xe3, 0x24, 0x88, 0x5f, 0x3f, 0x62, 0x84, 0xc7, 0x24, 0x8b,
2441
+	0x8e, 0x4f, 0x0d, 0x79, 0x5b, 0xd0, 0x2b, 0x44, 0xe9, 0x4d, 0xff, 0x73, 0x03, 0xfa, 0x4f, 0xa2,
2442
+	0xe8, 0x15, 0x31, 0x39, 0x80, 0x0d, 0x8e, 0xd9, 0x94, 0x08, 0x89, 0x75, 0xe9, 0x4e, 0x03, 0xa3,
2443
+	0x07, 0xe0, 0xe4, 0x19, 0x66, 0x52, 0x53, 0xfb, 0xa0, 0xad, 0x57, 0x72, 0x96, 0x61, 0xe6, 0xcb,
2444
+	0x09, 0x84, 0xc0, 0x09, 0x84, 0x2f, 0x1d, 0xe9, 0x4b, 0x39, 0x16, 0x26, 0xe3, 0xe4, 0xd2, 0x5d,
2445
+	0x93, 0x28, 0x31, 0x14, 0x98, 0xf0, 0x2a, 0xd2, 0x3b, 0x2c, 0x86, 0xc5, 0xb2, 0x9a, 0xe5, 0xb2,
2446
+	0x4c, 0xd8, 0x6c, 0x2c, 0x0f, 0x9b, 0xd6, 0x8a, 0xb0, 0x81, 0x4a, 0xd8, 0x78, 0xd0, 0x09, 0x83,
2447
+	0x34, 0x38, 0x27, 0x31, 0xe1, 0x04, 0x67, 0x6e, 0x5b, 0x1a, 0x51, 0xc1, 0xa1, 0x3d, 0xd8, 0x0c,
2448
+	0xd2, 0x34, 0x60, 0x53, 0xca, 0x86, 0x8c, 0xbe, 0x24, 0x31, 0x76, 0x3b, 0x52, 0xc8, 0x3c, 0x5a,
2449
+	0x48, 0xcb, 0x70, 0x4c, 0x92, 0x7c, 0xf6, 0x5c, 0x44, 0x9f, 0xdb, 0x95, 0x64, 0x15, 0x9c, 0x90,
2450
+	0x96, 0xd0, 0xcf, 0xf0, 0xd5, 0x90, 0x91, 0x4b, 0x12, 0xe3, 0x31, 0xce, 0xdc, 0x9e, 0xf4, 0xe2,
2451
+	0x3c, 0x1a, 0xbd, 0x0b, 0x4d, 0x16, 0x93, 0x29, 0xe1, 0x99, 0xbb, 0xb9, 0xdb, 0xd8, 0x6b, 0x1f,
2452
+	0x74, 0xb5, 0x3f, 0x7d, 0x89, 0xf5, 0x8b, 0x59, 0xef, 0x19, 0xac, 0x2b, 0x94, 0x70, 0xaf, 0x20,
2453
+	0xd1, 0xbb, 0x25, 0xc7, 0x02, 0x97, 0xd1, 0x97, 0x5c, 0xee, 0x95, 0xe3, 0xcb, 0xb1, 0xc0, 0x4d,
2454
+	0x02, 0x16, 0xc9, 0x7d, 0x72, 0x7c, 0x39, 0xf6, 0x7c, 0x70, 0xc4, 0x46, 0x09, 0x57, 0xe7, 0x7a,
2455
+	0xc3, 0xbb, 0xbe, 0x18, 0x0a, 0xcc, 0x58, 0xc7, 0x54, 0xd7, 0x17, 0x43, 0xf4, 0x4d, 0xe8, 0x05,
2456
+	0x51, 0x44, 0x38, 0xa1, 0x49, 0x10, 0x7f, 0x42, 0xa2, 0xcc, 0x6d, 0xec, 0x36, 0xf6, 0xba, 0xfe,
2457
+	0x1c, 0xd6, 0x3b, 0x00, 0x64, 0x07, 0x94, 0x0e, 0xfa, 0x37, 0xa1, 0x95, 0x5d, 0x67, 0x1c, 0x4f,
2458
+	0x87, 0x46, 0x4f, 0x89, 0xf0, 0x7e, 0x59, 0x33, 0xe9, 0x62, 0xb2, 0x68, 0x55, 0x2c, 0x7e, 0xb7,
2459
+	0x52, 0x5b, 0xea, 0x32, 0xea, 0xfa, 0x45, 0xfe, 0x94, 0xdc, 0x76, 0xb9, 0x59, 0x48, 0xd9, 0xc6,
2460
+	0xb2, 0x94, 0x1d, 0x80, 0xbb, 0x68, 0x83, 0x4e, 0x93, 0x10, 0xee, 0x3e, 0xc3, 0x31, 0x7e, 0x1d,
2461
+	0xfb, 0x10, 0x38, 0x49, 0x30, 0xc5, 0x3a, 0x1d, 0xe5, 0xf8, 0xf5, 0x0d, 0x58, 0x54, 0xa2, 0x0d,
2462
+	0x38, 0x86, 0x3b, 0xcf, 0x49, 0xc6, 0x5f, 0xad, 0x7e, 0x41, 0x55, 0x7d, 0x99, 0xaa, 0xdf, 0xd7,
2463
+	0x00, 0x4a, 0x59, 0xc6, 0xe6, 0x9a, 0x65, 0x33, 0x02, 0x07, 0xcf, 0x08, 0xd7, 0xf9, 0x2e, 0xc7,
2464
+	0x22, 0x2a, 0x78, 0x98, 0xea, 0x23, 0x48, 0x0c, 0x45, 0xbd, 0xcc, 0x13, 0x32, 0x3b, 0xa1, 0xe1,
2465
+	0x05, 0xe6, 0x99, 0xac, 0xe7, 0x1b, 0xbe, 0x8d, 0x92, 0x49, 0x3b, 0xc1, 0x71, 0x2c, 0x8b, 0xfa,
2466
+	0x86, 0xaf, 0x00, 0x51, 0x81, 0xf1, 0x34, 0xe5, 0xd7, 0x9f, 0x9d, 0xb8, 0xeb, 0x32, 0xff, 0x0a,
2467
+	0xd0, 0x3b, 0x86, 0x9d, 0xf9, 0x95, 0xea, 0x18, 0x7a, 0x04, 0xed, 0x72, 0x15, 0x99, 0x5b, 0x93,
2468
+	0x09, 0xb2, 0x64, 0xeb, 0x6d, 0x2a, 0xef, 0x3e, 0x74, 0x4e, 0x78, 0xc0, 0xf1, 0x0a, 0x7f, 0x79,
2469
+	0x7b, 0xd0, 0x33, 0x55, 0x57, 0x12, 0xaa, 0xba, 0x11, 0xf0, 0x3c, 0xd3, 0x54, 0x1a, 0xf2, 0xfe,
2470
+	0xd2, 0x80, 0xa6, 0x0e, 0xeb, 0xa2, 0x36, 0xd5, 0xca, 0xda, 0xf4, 0x3f, 0x29, 0x91, 0x95, 0xac,
2471
+	0x6a, 0xce, 0x65, 0xd5, 0xff, 0xcb, 0x65, 0x59, 0x2e, 0xff, 0x56, 0x83, 0x96, 0xd9, 0xe6, 0xaf,
2472
+	0xdd, 0xce, 0xbc, 0x07, 0xad, 0x54, 0x6d, 0x3c, 0x56, 0x55, 0xaf, 0x7d, 0xd0, 0xd3, 0x8a, 0x8a,
2473
+	0x3a, 0x57, 0x12, 0x58, 0xf1, 0xe3, 0xd8, 0xf1, 0x63, 0xb5, 0x2b, 0x6b, 0x95, 0x76, 0x05, 0x81,
2474
+	0x93, 0x8a, 0x72, 0xba, 0x2e, 0xcb, 0xa9, 0x1c, 0xdb, 0x0d, 0x4a, 0xb3, 0xd2, 0xa0, 0x78, 0x1f,
2475
+	0x42, 0xf3, 0x38, 0x08, 0x27, 0x24, 0x91, 0x19, 0x1a, 0xa6, 0x3a, 0x4c, 0xbb, 0xbe, 0x1c, 0x0b,
2476
+	0x25, 0x53, 0x3c, 0xa5, 0xec, 0x5a, 0xd7, 0x7e, 0x0d, 0x79, 0x17, 0xd0, 0xd5, 0x69, 0xa0, 0x93,
2477
+	0xe9, 0x21, 0x80, 0x69, 0x31, 0x8a, 0x5c, 0x5a, 0x6c, 0x43, 0x2c, 0x1a, 0xb4, 0x07, 0xcd, 0xa9,
2478
+	0xd2, 0xac, 0xab, 0x6e, 0xe1, 0x03, 0x6d, 0x8f, 0x5f, 0x4c, 0x7b, 0xbf, 0xae, 0xc1, 0x8e, 0xea,
2479
+	0x31, 0x5f, 0xd9, 0x49, 0x2e, 0xef, 0x5d, 0x94, 0xfb, 0x1a, 0x15, 0xf7, 0x3d, 0x82, 0x16, 0xc3,
2480
+	0x19, 0xcd, 0x59, 0x88, 0x95, 0x67, 0xdb, 0x07, 0x77, 0x8a, 0x4c, 0x92, 0xba, 0x7c, 0x3d, 0xeb,
2481
+	0x97, 0x74, 0xde, 0x6f, 0x9a, 0xd0, 0xab, 0xce, 0x8a, 0x8a, 0x75, 0x1e, 0x5f, 0x10, 0xfa, 0x42,
2482
+	0x35, 0xc7, 0x35, 0xe9, 0x26, 0x1b, 0x25, 0xb2, 0x2a, 0x4c, 0xf3, 0x93, 0x49, 0xc0, 0x70, 0xa6,
2483
+	0xdd, 0x58, 0x22, 0xf4, 0xec, 0x10, 0x33, 0x42, 0x8b, 0xc3, 0xb4, 0x44, 0x88, 0x32, 0x10, 0xa6,
2484
+	0xf9, 0x17, 0x39, 0xe5, 0x81, 0x34, 0xd2, 0xf1, 0x0d, 0x2c, 0xbb, 0xe2, 0x34, 0xcf, 0x30, 0x3f,
2485
+	0x14, 0xbb, 0xb6, 0xa6, 0xbb, 0x62, 0x83, 0x29, 0xe7, 0x8f, 0xf1, 0x34, 0xd3, 0x69, 0x6e, 0x61,
2486
+	0x84, 0xe5, 0x6a, 0x37, 0x9f, 0x8b, 0xa0, 0x96, 0x81, 0xe1, 0xf8, 0x36, 0x4a, 0x48, 0x50, 0xe0,
2487
+	0xc9, 0x55, 0x90, 0xca, 0xb4, 0x77, 0x7c, 0x0b, 0x83, 0xde, 0x83, 0xbe, 0x82, 0x7c, 0x9c, 0x61,
2488
+	0x76, 0x19, 0x88, 0x63, 0x5b, 0x96, 0x01, 0xc7, 0x5f, 0x9c, 0x10, 0xd4, 0x17, 0x98, 0x25, 0x38,
2489
+	0x3e, 0xb6, 0xb4, 0x82, 0xa2, 0x5e, 0x98, 0x40, 0x07, 0xb0, 0xad, 0x90, 0xa7, 0x87, 0x43, 0x9b,
2490
+	0xa1, 0x2d, 0x19, 0x96, 0xce, 0x89, 0x4c, 0x97, 0x8e, 0x7f, 0x8e, 0x83, 0x97, 0x7a, 0x3f, 0x3a,
2491
+	0x92, 0x7c, 0x1e, 0x8d, 0x9e, 0x40, 0xdf, 0xda, 0xa2, 0x67, 0xf8, 0x92, 0x84, 0xd8, 0xed, 0xca,
2492
+	0xa8, 0xbd, 0xad, 0xa3, 0xc0, 0x9e, 0xf2, 0x17, 0xa9, 0xd1, 0x19, 0x0c, 0x24, 0xf2, 0x74, 0xc2,
2493
+	0x28, 0xe7, 0x31, 0xf6, 0x71, 0x10, 0x3d, 0x4d, 0x33, 0x2d, 0xab, 0x27, 0x65, 0x15, 0x11, 0x55,
2494
+	0xd0, 0x68, 0x69, 0x37, 0x30, 0xa2, 0x17, 0xf0, 0x46, 0x65, 0xf6, 0x05, 0x23, 0x1c, 0x97, 0x72,
2495
+	0x37, 0x6f, 0x92, 0x7b, 0x13, 0xe7, 0x82, 0x60, 0xa1, 0xf6, 0x88, 0x1a, 0xc1, 0x5b, 0xaf, 0x2f,
2496
+	0xb8, 0xca, 0x89, 0x7e, 0x06, 0x6f, 0x2e, 0xea, 0xb5, 0x24, 0xf7, 0x6f, 0x92, 0x7c, 0x23, 0xab,
2497
+	0x48, 0x0e, 0x51, 0xbf, 0xd4, 0xce, 0x23, 0x95, 0x1c, 0x06, 0xe1, 0x7d, 0x04, 0xdd, 0xa7, 0x31,
2498
+	0x0d, 0x2f, 0x8e, 0x3e, 0xd7, 0xe4, 0x95, 0x2b, 0x77, 0x63, 0xe9, 0x95, 0xbb, 0xa1, 0xaf, 0xdc,
2499
+	0xde, 0x57, 0xd0, 0xa9, 0x6c, 0xe7, 0xf7, 0x64, 0x1e, 0x17, 0xa2, 0xf4, 0x45, 0x6a, 0x5b, 0x1b,
2500
+	0x5d, 0x51, 0xe3, 0xdb, 0x84, 0xa2, 0xbe, 0x5c, 0xa9, 0x50, 0x53, 0xcd, 0xad, 0x86, 0x44, 0xee,
2501
+	0xc4, 0x65, 0x18, 0xaa, 0x7b, 0x93, 0x85, 0xf1, 0x7e, 0x0e, 0xbd, 0xaa, 0x2b, 0xfe, 0x63, 0x0b,
2502
+	0x10, 0x38, 0x2c, 0xe0, 0xb8, 0xe8, 0xce, 0xc5, 0xd8, 0xbb, 0x07, 0x77, 0x17, 0x2a, 0xa6, 0x6e,
2503
+	0xfd, 0xae, 0xa1, 0xfb, 0xf1, 0x25, 0x4e, 0xb8, 0xb9, 0x9d, 0x3d, 0x86, 0x96, 0x79, 0xf2, 0xd0,
2504
+	0xa5, 0x78, 0xb0, 0xaf, 0x1e, 0x45, 0xf6, 0x8b, 0x47, 0x91, 0xfd, 0xd3, 0x82, 0xc2, 0x2f, 0x89,
2505
+	0xc5, 0x1a, 0x33, 0x4e, 0x19, 0x8e, 0x3e, 0x4f, 0xe2, 0xeb, 0xe2, 0x25, 0xa1, 0xc4, 0xe8, 0xea,
2506
+	0xec, 0x98, 0xe6, 0xe8, 0x77, 0x35, 0x58, 0x93, 0xba, 0x97, 0xde, 0x32, 0x14, 0x75, 0xdd, 0xd4,
2507
+	0xf2, 0x6a, 0xe5, 0xee, 0x9a, 0xca, 0xad, 0x6b, 0xbc, 0x53, 0xd6, 0xf8, 0xca, 0x0a, 0xd6, 0xbf,
2508
+	0xc6, 0x0a, 0xbc, 0xdf, 0xd6, 0xa1, 0xf3, 0x19, 0xe6, 0x57, 0x94, 0x5d, 0x88, 0xf3, 0x2c, 0x5b,
2509
+	0xda, 0xba, 0xde, 0x83, 0x0d, 0x36, 0x1b, 0x9d, 0x5f, 0x73, 0x53, 0xbf, 0x9b, 0x6c, 0xf6, 0x54,
2510
+	0x80, 0xe8, 0x2d, 0x00, 0x36, 0x1b, 0x0d, 0x03, 0xd5, 0xae, 0xea, 0xf2, 0xcd, 0x66, 0x1a, 0x81,
2511
+	0xde, 0x80, 0x96, 0x3f, 0x1b, 0x61, 0xc6, 0x28, 0xcb, 0x8a, 0xfa, 0xed, 0xcf, 0x3e, 0x96, 0xb0,
2512
+	0xe0, 0xf5, 0x67, 0xa3, 0x88, 0xd1, 0x34, 0xc5, 0x91, 0xac, 0xdf, 0x8e, 0xdf, 0xf2, 0x67, 0xcf,
2513
+	0x14, 0x42, 0x68, 0x3d, 0x2d, 0xb4, 0xae, 0x2b, 0xad, 0xa7, 0xa5, 0xd6, 0xd3, 0xd9, 0x28, 0xd5,
2514
+	0x5a, 0x55, 0xe1, 0x6e, 0x9d, 0xda, 0x5a, 0x4f, 0x8d, 0x56, 0x55, 0xb5, 0x37, 0x4e, 0x2d, 0xad,
2515
+	0xa7, 0xa5, 0xd6, 0x56, 0xc1, 0xab, 0xb5, 0x7a, 0x7f, 0xaa, 0xc1, 0xc6, 0x61, 0x9a, 0x9f, 0x65,
2516
+	0xc1, 0x18, 0xa3, 0x07, 0xd0, 0xe6, 0x94, 0x07, 0xf1, 0x28, 0x17, 0xa0, 0x3e, 0xdb, 0x40, 0xa2,
2517
+	0x14, 0xc1, 0xdb, 0xd0, 0x49, 0x31, 0x0b, 0xd3, 0x5c, 0x53, 0xd4, 0x77, 0x1b, 0xe2, 0x0c, 0x51,
2518
+	0x38, 0x45, 0xb2, 0x0f, 0xb7, 0xe5, 0xdc, 0x88, 0x24, 0x23, 0x55, 0xb4, 0xa7, 0x34, 0xc2, 0xda,
2519
+	0x55, 0x7d, 0x39, 0x75, 0x94, 0x7c, 0x6a, 0x26, 0xd0, 0xb7, 0xa1, 0x6f, 0xe8, 0x45, 0x33, 0x2b,
2520
+	0xa9, 0x95, 0xeb, 0x36, 0x35, 0xf5, 0x99, 0x46, 0x7b, 0x5f, 0x99, 0x1c, 0x22, 0xc9, 0xf8, 0x59,
2521
+	0xc0, 0x03, 0xd1, 0xe8, 0xa4, 0xf2, 0xe4, 0xcc, 0xb4, 0xb5, 0x05, 0x88, 0xbe, 0x03, 0x7d, 0xae,
2522
+	0xf3, 0x2d, 0x1a, 0x15, 0x34, 0x6a, 0x37, 0xb7, 0xcc, 0xc4, 0x50, 0x13, 0x7f, 0x03, 0x7a, 0x25,
2523
+	0xb1, 0x6c, 0x9b, 0x94, 0xbd, 0x5d, 0x83, 0x15, 0xd1, 0xe4, 0xfd, 0x41, 0x39, 0x4b, 0x45, 0xce,
2524
+	0x7b, 0xf2, 0x20, 0xb7, 0x5c, 0xd5, 0x3e, 0xd8, 0x2c, 0x1a, 0x20, 0xed, 0x0c, 0x79, 0x78, 0x2b,
2525
+	0xb7, 0xfc, 0x10, 0x36, 0xb9, 0x31, 0x7d, 0x14, 0x05, 0x3c, 0xd0, 0xa9, 0x37, 0x57, 0x27, 0xf5,
2526
+	0xc2, 0xfc, 0x1e, 0xaf, 0x2e, 0xf4, 0x6d, 0xe8, 0xa8, 0xce, 0x5c, 0x2b, 0x54, 0xf6, 0xb5, 0x15,
2527
+	0x4e, 0xaa, 0xf0, 0x3e, 0x82, 0xd6, 0x90, 0x44, 0x99, 0xb2, 0xce, 0x85, 0x66, 0x98, 0x33, 0x86,
2528
+	0x93, 0xa2, 0x45, 0x29, 0x40, 0x51, 0x1e, 0x65, 0x57, 0xab, 0x9d, 0xa1, 0x00, 0x8f, 0x02, 0xa8,
2529
+	0x93, 0x55, 0x6a, 0xdb, 0x86, 0x35, 0x3b, 0x04, 0x14, 0x20, 0xe2, 0x6c, 0x1a, 0xcc, 0xcc, 0xd6,
2530
+	0xcb, 0x38, 0x9b, 0x06, 0x33, 0xb5, 0x40, 0x17, 0x9a, 0x2f, 0x03, 0x12, 0x87, 0xfa, 0xc1, 0xce,
2531
+	0xf1, 0x0b, 0xb0, 0x54, 0xe8, 0xd8, 0x0a, 0xff, 0x58, 0x87, 0xb6, 0xd2, 0xa8, 0x0c, 0xde, 0x86,
2532
+	0xb5, 0x30, 0x08, 0x27, 0x46, 0xa5, 0x04, 0xd0, 0xbb, 0x85, 0x21, 0xd5, 0x8b, 0x7a, 0x69, 0x6a,
2533
+	0x61, 0xdb, 0x43, 0x80, 0xec, 0x2a, 0x48, 0x2d, 0xef, 0x2c, 0xa5, 0x6e, 0x09, 0x22, 0x65, 0xf0,
2534
+	0x07, 0xd0, 0x51, 0xf1, 0xa9, 0x79, 0x9c, 0x55, 0x3c, 0x6d, 0x45, 0xa6, 0xb8, 0x1e, 0x89, 0x4b,
2535
+	0x51, 0xc0, 0x55, 0x13, 0xde, 0x3e, 0x78, 0xab, 0x42, 0x2e, 0x57, 0xb2, 0x2f, 0xbf, 0x1f, 0x27,
2536
+	0x9c, 0x5d, 0xfb, 0x8a, 0x76, 0xf0, 0x18, 0xa0, 0x44, 0x8a, 0x7a, 0x76, 0x81, 0xaf, 0x8b, 0xcb,
2537
+	0xdf, 0x05, 0xbe, 0x16, 0x6b, 0xbf, 0x0c, 0xe2, 0xbc, 0x70, 0xaa, 0x02, 0x7e, 0x50, 0x7f, 0x5c,
2538
+	0xf3, 0x42, 0xd8, 0x7c, 0x2a, 0x0e, 0x4c, 0x8b, 0xbd, 0x72, 0xe8, 0x39, 0x4b, 0x0f, 0x3d, 0xa7,
2539
+	0x78, 0x67, 0xee, 0x41, 0x9d, 0xa6, 0xba, 0x11, 0xae, 0xd3, 0xb4, 0x54, 0xe4, 0x58, 0x8a, 0xbc,
2540
+	0x7f, 0x38, 0x00, 0xa5, 0x16, 0x74, 0x02, 0x03, 0x42, 0x47, 0xa2, 0x8f, 0x23, 0x21, 0x56, 0x05,
2541
+	0x69, 0xc4, 0x70, 0x98, 0xb3, 0x8c, 0x5c, 0x62, 0xdd, 0xea, 0xef, 0x98, 0x63, 0xaa, 0x62, 0x9c,
2542
+	0x7f, 0x97, 0xd0, 0x13, 0xc5, 0x28, 0x2b, 0x97, 0x5f, 0xb0, 0xa1, 0x9f, 0xc0, 0x9d, 0x52, 0x68,
2543
+	0x64, 0xc9, 0xab, 0xdf, 0x28, 0xef, 0xb6, 0x91, 0x17, 0x95, 0xb2, 0x7e, 0x04, 0xb7, 0x09, 0x1d,
2544
+	0x7d, 0x99, 0xe3, 0xbc, 0x22, 0xa9, 0x71, 0xa3, 0xa4, 0x3e, 0xa1, 0x5f, 0x48, 0x8e, 0x52, 0xce,
2545
+	0x17, 0x70, 0xcf, 0x5a, 0xa8, 0x48, 0x7b, 0x4b, 0x9a, 0x73, 0xa3, 0xb4, 0x1d, 0x63, 0x97, 0x28,
2546
+	0x0c, 0xa5, 0xc8, 0x4f, 0x61, 0x87, 0xd0, 0xd1, 0x55, 0x40, 0xf8, 0xbc, 0xbc, 0xb5, 0x57, 0xad,
2547
+	0xf3, 0x45, 0x40, 0x78, 0x55, 0x98, 0x5a, 0xe7, 0x14, 0xb3, 0x71, 0x65, 0x9d, 0xeb, 0xaf, 0x5a,
2548
+	0xe7, 0xb1, 0xe4, 0x28, 0xe5, 0x3c, 0x85, 0x3e, 0xa1, 0xf3, 0xf6, 0x34, 0x6f, 0x94, 0xb2, 0x49,
2549
+	0x68, 0xd5, 0x96, 0x43, 0xe8, 0x67, 0x38, 0xe4, 0x94, 0xd9, 0xb1, 0xb0, 0x71, 0xa3, 0x8c, 0x2d,
2550
+	0xcd, 0x60, 0x84, 0x78, 0x5f, 0x42, 0xe7, 0xc7, 0xf9, 0x18, 0xf3, 0xf8, 0xdc, 0xe4, 0xfc, 0x7f,
2551
+	0xbb, 0xcc, 0xfc, 0xab, 0x0e, 0xed, 0xc3, 0x31, 0xa3, 0x79, 0x5a, 0xa9, 0xda, 0x2a, 0x87, 0x17,
2552
+	0xaa, 0xb6, 0xa4, 0x91, 0x55, 0x5b, 0x51, 0x7f, 0x08, 0x1d, 0x75, 0xaf, 0xd1, 0x0c, 0xaa, 0x0a,
2553
+	0xa1, 0xc5, 0xa4, 0x2f, 0xee, 0x51, 0x8a, 0xed, 0x40, 0xdf, 0x11, 0x35, 0x57, 0xb5, 0x1a, 0x95,
2554
+	0x6e, 0xf2, 0xe1, 0xbc, 0xcc, 0xba, 0x23, 0xe8, 0x4e, 0x94, 0x6f, 0x34, 0x97, 0x0a, 0xc0, 0x77,
2555
+	0x0a, 0xe3, 0xca, 0x35, 0xec, 0xdb, 0x3e, 0x54, 0xae, 0xee, 0x4c, 0x6c, 0xb7, 0xbe, 0x0f, 0x20,
2556
+	0x9a, 0xe6, 0x51, 0x51, 0xa8, 0xec, 0x5f, 0x04, 0xe6, 0x84, 0x50, 0x8d, 0xb5, 0x1c, 0x0e, 0x4e,
2557
+	0xa1, 0xbf, 0x20, 0x73, 0x49, 0x99, 0xfa, 0x96, 0x5d, 0xa6, 0xca, 0x8b, 0x93, 0xcd, 0x6a, 0xd7,
2558
+	0xae, 0xbf, 0xd6, 0xd4, 0xa3, 0x41, 0xf9, 0x8a, 0xfb, 0x18, 0xba, 0x89, 0x6a, 0xbe, 0xcc, 0x06,
2559
+	0xd8, 0x37, 0x30, 0xbb, 0x31, 0xf3, 0x3b, 0x89, 0xdd, 0xa6, 0x7d, 0x08, 0x9d, 0x50, 0x7a, 0x60,
2560
+	0xe9, 0x46, 0x58, 0xce, 0xf1, 0xdb, 0xa1, 0xb5, 0xdb, 0x95, 0x46, 0xd1, 0xf9, 0x3a, 0x8d, 0xa2,
2561
+	0x7e, 0xf7, 0x5b, 0xf5, 0x4b, 0xe3, 0xe0, 0x9f, 0xeb, 0xd0, 0x78, 0x32, 0x3c, 0x42, 0x67, 0xb0,
2562
+	0x35, 0xff, 0x47, 0x10, 0xdd, 0xd7, 0x66, 0xad, 0xf8, 0x8b, 0x38, 0x78, 0xb0, 0x72, 0x5e, 0xb7,
2563
+	0xec, 0xb7, 0x90, 0x0f, 0x9b, 0x73, 0xff, 0x7f, 0x50, 0x71, 0xd4, 0x2c, 0xff, 0xc7, 0x36, 0xb8,
2564
+	0xbf, 0x6a, 0xda, 0x96, 0x39, 0x77, 0x47, 0x30, 0x32, 0x97, 0xbf, 0xb6, 0x18, 0x99, 0xab, 0xae,
2565
+	0x16, 0xb7, 0xd0, 0xf7, 0x61, 0x5d, 0xfd, 0x11, 0x42, 0xc5, 0xc5, 0xa5, 0xf2, 0xaf, 0x69, 0x70,
2566
+	0x67, 0x0e, 0x6b, 0x18, 0x9f, 0x43, 0xb7, 0xf2, 0x1b, 0x11, 0xbd, 0x51, 0xd1, 0x55, 0xfd, 0xa1,
2567
+	0x34, 0x78, 0x73, 0xf9, 0xa4, 0x91, 0x76, 0x08, 0x50, 0xfe, 0x34, 0x40, 0xae, 0xa6, 0x5e, 0xf8,
2568
+	0x31, 0x35, 0xb8, 0xb7, 0x64, 0xc6, 0x08, 0x39, 0x83, 0xad, 0xf9, 0x07, 0x7c, 0x34, 0xe7, 0xd5,
2569
+	0xf9, 0xe7, 0x73, 0xb3, 0x95, 0x2b, 0x5f, 0xfe, 0xa5, 0xd8, 0xf9, 0x67, 0x79, 0x23, 0x76, 0xc5,
2570
+	0x4f, 0x01, 0x23, 0x76, 0xe5, 0x7b, 0xfe, 0x2d, 0xf4, 0x39, 0xf4, 0xaa, 0xef, 0xdc, 0xa8, 0x70,
2571
+	0xd2, 0xd2, 0x87, 0xfe, 0xc1, 0x5b, 0x2b, 0x66, 0x8d, 0xc0, 0x0f, 0x60, 0x4d, 0x3d, 0x60, 0x17,
2572
+	0xe9, 0x68, 0xbf, 0x7b, 0x0f, 0xb6, 0xab, 0x48, 0xc3, 0xf5, 0x10, 0xd6, 0xd5, 0xed, 0xd2, 0x04,
2573
+	0x40, 0xe5, 0xb2, 0x39, 0xe8, 0xd8, 0x58, 0xef, 0xd6, 0xc3, 0x5a, 0xa1, 0x27, 0xab, 0xe8, 0xc9,
2574
+	0x96, 0xe9, 0xb1, 0x36, 0xe7, 0x7c, 0x5d, 0xa6, 0xeb, 0xa3, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff,
2575
+	0x4c, 0xa9, 0xa8, 0x4d, 0xd0, 0x1f, 0x00, 0x00,
2575 2576
 }
... ...
@@ -210,6 +210,7 @@ message UpdateResource {
210 210
 	repeated ThrottleDevice blkioThrottleWriteBpsDevice = 15;
211 211
 	repeated ThrottleDevice blkioThrottleReadIopsDevice = 16;
212 212
 	repeated ThrottleDevice blkioThrottleWriteIopsDevice = 17;
213
+	uint64 pidsLimit = 18;
213 214
 }
214 215
 
215 216
 message BlockIODevice {
... ...
@@ -1,6 +1,10 @@
1
-[![Build Status](https://jenkins.dockerproject.org/buildStatus/icon?job=runc Master)](https://jenkins.dockerproject.org/job/runc Master)
1
+# runc
2 2
 
3
-## runc
3
+[![Build Status](https://travis-ci.org/opencontainers/runc.svg?branch=master)](https://travis-ci.org/opencontainers/runc)
4
+[![Go Report Card](https://goreportcard.com/badge/github.com/opencontainers/runc)](https://goreportcard.com/report/github.com/opencontainers/runc)
5
+[![GoDoc](https://godoc.org/github.com/opencontainers/runc?status.svg)](https://godoc.org/github.com/opencontainers/runc)
6
+
7
+## Introduction
4 8
 
5 9
 `runc` is a CLI tool for spawning and running containers according to the OCI specification.
6 10
 
... ...
@@ -12,9 +16,14 @@ This means that `runc` 1.0.0 should implement the 1.0 version of the specificati
12 12
 
13 13
 You can find official releases of `runc` on the [release](https://github.com/opencontainers/runc/releases) page.
14 14
 
15
+### Security
16
+
17
+If you wish to report a security issue, please disclose the issue responsibly
18
+to security@opencontainers.org.
19
+
15 20
 ## Building
16 21
 
17
-`runc` currently supports the Linux platform with various architecture support. 
22
+`runc` currently supports the Linux platform with various architecture support.
18 23
 It must be built with Go version 1.6 or higher in order for some features to function properly.
19 24
 
20 25
 In order to enable seccomp support you will need to install `libseccomp` on your platform.
... ...
@@ -68,6 +77,12 @@ You can run a specific test case by setting the `TESTFLAGS` variable.
68 68
 # make test TESTFLAGS="-run=SomeTestFunction"
69 69
 ```
70 70
 
71
+### Dependencies Management
72
+
73
+`runc` uses [vndr](https://github.com/LK4D4/vndr) for dependencies management.
74
+Please refer to [vndr](https://github.com/LK4D4/vndr) for how to add or update
75
+new dependencies.
76
+
71 77
 ## Using runc
72 78
 
73 79
 ### Creating an OCI Bundle
... ...
@@ -102,8 +117,8 @@ Assuming you have an OCI bundle from the previous step you can execute the conta
102 102
 The first way is to use the convenience command `run` that will handle creating, starting, and deleting the container after it exits.
103 103
 
104 104
 ```bash
105
+# run as root
105 106
 cd /mycontainer
106
-
107 107
 runc run mycontainerid
108 108
 ```
109 109
 
... ...
@@ -150,8 +165,8 @@ Now we can go though the lifecycle operations in your shell.
150 150
 
151 151
 
152 152
 ```bash
153
+# run as root
153 154
 cd /mycontainer
154
-
155 155
 runc create mycontainerid
156 156
 
157 157
 # view the container is created and in the "created" state
... ...
@@ -170,6 +185,22 @@ runc delete mycontainerid
170 170
 This adds more complexity but allows higher level systems to manage runc and provides points in the containers creation to setup various settings after the container has created and/or before it is deleted.
171 171
 This is commonly used to setup the container's network stack after `create` but before `start` where the user's defined process will be running.
172 172
 
173
+#### Rootless containers
174
+`runc` has the ability to run containers without root privileges. This is called `rootless`. You need to pass some parameters to `runc` in order to run rootless containers. See below and compare with the previous version. Run the following commands as an ordinary user:
175
+```bash
176
+# Same as the first example
177
+mkdir ~/mycontainer
178
+cd ~/mycontainer
179
+mkdir rootfs
180
+docker export $(docker create busybox) | tar -C rootfs -xvf -
181
+
182
+# The --rootless parameter instructs runc spec to generate a configuration for a rootless container, which will allow you to run the container as a non-root user.
183
+runc spec --rootless
184
+
185
+# The --root parameter tells runc where to store the container state. It must be writable by the user.
186
+runc --root /tmp/runc run mycontainerid
187
+```
188
+
173 189
 #### Supervisors
174 190
 
175 191
 `runc` can be used with process supervisors and init systems to ensure that containers are restarted when they exit.
... ...
@@ -1,3 +1,7 @@
1
+# libcontainer
2
+
3
+[![GoDoc](https://godoc.org/github.com/opencontainers/runc/libcontainer?status.svg)](https://godoc.org/github.com/opencontainers/runc/libcontainer)
4
+
1 5
 Libcontainer provides a native Go implementation for creating containers
2 6
 with namespaces, cgroups, capabilities, and filesystem access controls.
3 7
 It allows you to manage the lifecycle of the container performing additional operations
... ...
@@ -16,7 +20,14 @@ the current binary (/proc/self/exe) to be executed as the init process, and use
16 16
 arg "init", we call the first step process "bootstrap", so you always need a "init"
17 17
 function as the entry of "bootstrap".
18 18
 
19
+In addition to the go init function the early stage bootstrap is handled by importing
20
+[nsenter](https://github.com/opencontainers/runc/blob/master/libcontainer/nsenter/README.md).
21
+
19 22
 ```go
23
+import (
24
+	_ "github.com/opencontainers/runc/libcontainer/nsenter"
25
+)
26
+
20 27
 func init() {
21 28
 	if len(os.Args) > 1 && os.Args[1] == "init" {
22 29
 		runtime.GOMAXPROCS(1)
... ...
@@ -27,9 +27,9 @@ type Manager interface {
27 27
 	// Destroys the cgroup set
28 28
 	Destroy() error
29 29
 
30
-	// NewCgroupManager() and LoadCgroupManager() require following attributes:
30
+	// The option func SystemdCgroups() and Cgroupfs() require following attributes:
31 31
 	// 	Paths   map[string]string
32
-	// 	Cgroups *cgroups.Cgroup
32
+	// 	Cgroups *configs.Cgroup
33 33
 	// Paths maps cgroup subsystem to path at which it is mounted.
34 34
 	// Cgroups specifies specific cgroup settings for the various subsystems
35 35
 
... ...
@@ -23,36 +23,14 @@ const (
23 23
 
24 24
 // https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
25 25
 func FindCgroupMountpoint(subsystem string) (string, error) {
26
-	// We are not using mount.GetMounts() because it's super-inefficient,
27
-	// parsing it directly sped up x10 times because of not using Sscanf.
28
-	// It was one of two major performance drawbacks in container start.
29
-	if !isSubsystemAvailable(subsystem) {
30
-		return "", NewNotFoundError(subsystem)
31
-	}
32
-	f, err := os.Open("/proc/self/mountinfo")
33
-	if err != nil {
34
-		return "", err
35
-	}
36
-	defer f.Close()
37
-
38
-	scanner := bufio.NewScanner(f)
39
-	for scanner.Scan() {
40
-		txt := scanner.Text()
41
-		fields := strings.Split(txt, " ")
42
-		for _, opt := range strings.Split(fields[len(fields)-1], ",") {
43
-			if opt == subsystem {
44
-				return fields[4], nil
45
-			}
46
-		}
47
-	}
48
-	if err := scanner.Err(); err != nil {
49
-		return "", err
50
-	}
51
-
52
-	return "", NewNotFoundError(subsystem)
26
+	mnt, _, err := FindCgroupMountpointAndRoot(subsystem)
27
+	return mnt, err
53 28
 }
54 29
 
55 30
 func FindCgroupMountpointAndRoot(subsystem string) (string, string, error) {
31
+	// We are not using mount.GetMounts() because it's super-inefficient,
32
+	// parsing it directly sped up x10 times because of not using Sscanf.
33
+	// It was one of two major performance drawbacks in container start.
56 34
 	if !isSubsystemAvailable(subsystem) {
57 35
 		return "", "", NewNotFoundError(subsystem)
58 36
 	}
... ...
@@ -131,7 +109,7 @@ type Mount struct {
131 131
 	Subsystems []string
132 132
 }
133 133
 
134
-func (m Mount) GetThisCgroupDir(cgroups map[string]string) (string, error) {
134
+func (m Mount) GetOwnCgroup(cgroups map[string]string) (string, error) {
135 135
 	if len(m.Subsystems) == 0 {
136 136
 		return "", fmt.Errorf("no subsystem for mount")
137 137
 	}
... ...
@@ -211,9 +189,6 @@ func GetAllSubsystems() ([]string, error) {
211 211
 
212 212
 	s := bufio.NewScanner(f)
213 213
 	for s.Scan() {
214
-		if err := s.Err(); err != nil {
215
-			return nil, err
216
-		}
217 214
 		text := s.Text()
218 215
 		if text[0] != '#' {
219 216
 			parts := strings.Fields(text)
... ...
@@ -222,11 +197,14 @@ func GetAllSubsystems() ([]string, error) {
222 222
 			}
223 223
 		}
224 224
 	}
225
+	if err := s.Err(); err != nil {
226
+		return nil, err
227
+	}
225 228
 	return subsystems, nil
226 229
 }
227 230
 
228
-// GetThisCgroupDir returns the relative path to the cgroup docker is running in.
229
-func GetThisCgroupDir(subsystem string) (string, error) {
231
+// GetOwnCgroup returns the relative path to the cgroup docker is running in.
232
+func GetOwnCgroup(subsystem string) (string, error) {
230 233
 	cgroups, err := ParseCgroupFile("/proc/self/cgroup")
231 234
 	if err != nil {
232 235
 		return "", err
... ...
@@ -235,8 +213,16 @@ func GetThisCgroupDir(subsystem string) (string, error) {
235 235
 	return getControllerPath(subsystem, cgroups)
236 236
 }
237 237
 
238
-func GetInitCgroupDir(subsystem string) (string, error) {
238
+func GetOwnCgroupPath(subsystem string) (string, error) {
239
+	cgroup, err := GetOwnCgroup(subsystem)
240
+	if err != nil {
241
+		return "", err
242
+	}
243
+
244
+	return getCgroupPathHelper(subsystem, cgroup)
245
+}
239 246
 
247
+func GetInitCgroup(subsystem string) (string, error) {
240 248
 	cgroups, err := ParseCgroupFile("/proc/1/cgroup")
241 249
 	if err != nil {
242 250
 		return "", err
... ...
@@ -245,6 +231,31 @@ func GetInitCgroupDir(subsystem string) (string, error) {
245 245
 	return getControllerPath(subsystem, cgroups)
246 246
 }
247 247
 
248
+func GetInitCgroupPath(subsystem string) (string, error) {
249
+	cgroup, err := GetInitCgroup(subsystem)
250
+	if err != nil {
251
+		return "", err
252
+	}
253
+
254
+	return getCgroupPathHelper(subsystem, cgroup)
255
+}
256
+
257
+func getCgroupPathHelper(subsystem, cgroup string) (string, error) {
258
+	mnt, root, err := FindCgroupMountpointAndRoot(subsystem)
259
+	if err != nil {
260
+		return "", err
261
+	}
262
+
263
+	// This is needed for nested containers, because in /proc/self/cgroup we
264
+	// see pathes from host, which don't exist in container.
265
+	relCgroup, err := filepath.Rel(root, cgroup)
266
+	if err != nil {
267
+		return "", err
268
+	}
269
+
270
+	return filepath.Join(mnt, relCgroup), nil
271
+}
272
+
248 273
 func readProcsFile(dir string) ([]int, error) {
249 274
 	f, err := os.Open(filepath.Join(dir, CgroupProcesses))
250 275
 	if err != nil {
... ...
@@ -287,10 +298,6 @@ func parseCgroupFromReader(r io.Reader) (map[string]string, error) {
287 287
 	cgroups := make(map[string]string)
288 288
 
289 289
 	for s.Scan() {
290
-		if err := s.Err(); err != nil {
291
-			return nil, err
292
-		}
293
-
294 290
 		text := s.Text()
295 291
 		// from cgroups(7):
296 292
 		// /proc/[pid]/cgroup
... ...
@@ -307,6 +314,10 @@ func parseCgroupFromReader(r io.Reader) (map[string]string, error) {
307 307
 			cgroups[subs] = parts[2]
308 308
 		}
309 309
 	}
310
+	if err := s.Err(); err != nil {
311
+		return nil, err
312
+	}
313
+
310 314
 	return cgroups, nil
311 315
 }
312 316
 
... ...
@@ -45,34 +45,34 @@ type Resources struct {
45 45
 	Devices []*Device `json:"devices"`
46 46
 
47 47
 	// Memory limit (in bytes)
48
-	Memory int64 `json:"memory"`
48
+	Memory uint64 `json:"memory"`
49 49
 
50 50
 	// Memory reservation or soft_limit (in bytes)
51
-	MemoryReservation int64 `json:"memory_reservation"`
51
+	MemoryReservation uint64 `json:"memory_reservation"`
52 52
 
53 53
 	// Total memory usage (memory + swap); set `-1` to enable unlimited swap
54
-	MemorySwap int64 `json:"memory_swap"`
54
+	MemorySwap uint64 `json:"memory_swap"`
55 55
 
56 56
 	// Kernel memory limit (in bytes)
57
-	KernelMemory int64 `json:"kernel_memory"`
57
+	KernelMemory uint64 `json:"kernel_memory"`
58 58
 
59 59
 	// Kernel memory limit for TCP use (in bytes)
60
-	KernelMemoryTCP int64 `json:"kernel_memory_tcp"`
60
+	KernelMemoryTCP uint64 `json:"kernel_memory_tcp"`
61 61
 
62 62
 	// CPU shares (relative weight vs. other containers)
63
-	CpuShares int64 `json:"cpu_shares"`
63
+	CpuShares uint64 `json:"cpu_shares"`
64 64
 
65 65
 	// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
66 66
 	CpuQuota int64 `json:"cpu_quota"`
67 67
 
68 68
 	// CPU period to be used for hardcapping (in usecs). 0 to use system default.
69
-	CpuPeriod int64 `json:"cpu_period"`
69
+	CpuPeriod uint64 `json:"cpu_period"`
70 70
 
71 71
 	// How many time CPU will use in realtime scheduling (in usecs).
72 72
 	CpuRtRuntime int64 `json:"cpu_rt_quota"`
73 73
 
74 74
 	// CPU period to be used for realtime scheduling (in usecs).
75
-	CpuRtPeriod int64 `json:"cpu_rt_period"`
75
+	CpuRtPeriod uint64 `json:"cpu_rt_period"`
76 76
 
77 77
 	// CPU to use
78 78
 	CpusetCpus string `json:"cpuset_cpus"`
... ...
@@ -114,7 +114,7 @@ type Resources struct {
114 114
 	OomKillDisable bool `json:"oom_kill_disable"`
115 115
 
116 116
 	// Tuning swappiness behaviour per cgroup
117
-	MemorySwappiness *int64 `json:"memory_swappiness"`
117
+	MemorySwappiness *uint64 `json:"memory_swappiness"`
118 118
 
119 119
 	// Set priority of network traffic for container
120 120
 	NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap"`
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"time"
9 9
 
10 10
 	"github.com/Sirupsen/logrus"
11
+	"github.com/opencontainers/runtime-spec/specs-go"
11 12
 )
12 13
 
13 14
 type Rlimit struct {
... ...
@@ -112,8 +113,8 @@ type Config struct {
112 112
 	Namespaces Namespaces `json:"namespaces"`
113 113
 
114 114
 	// Capabilities specify the capabilities to keep when executing the process inside the container
115
-	// All capbilities not specified will be dropped from the processes capability mask
116
-	Capabilities []string `json:"capabilities"`
115
+	// All capabilities not specified will be dropped from the processes capability mask
116
+	Capabilities *Capabilities `json:"capabilities"`
117 117
 
118 118
 	// Networks specifies the container's network setup to be created
119 119
 	Networks []*Network `json:"networks"`
... ...
@@ -182,6 +183,9 @@ type Config struct {
182 182
 	// NoNewKeyring will not allocated a new session keyring for the container.  It will use the
183 183
 	// callers keyring in this case.
184 184
 	NoNewKeyring bool `json:"no_new_keyring"`
185
+
186
+	// Rootless specifies whether the container is a rootless container.
187
+	Rootless bool `json:"rootless"`
185 188
 }
186 189
 
187 190
 type Hooks struct {
... ...
@@ -196,6 +200,19 @@ type Hooks struct {
196 196
 	Poststop []Hook
197 197
 }
198 198
 
199
+type Capabilities struct {
200
+	// Bounding is the set of capabilities checked by the kernel.
201
+	Bounding []string
202
+	// Effective is the set of capabilities checked by the kernel.
203
+	Effective []string
204
+	// Inheritable is the capabilities preserved across execve.
205
+	Inheritable []string
206
+	// Permitted is the limiting superset for effective capabilities.
207
+	Permitted []string
208
+	// Ambient is the ambient set of capabilities that are kept.
209
+	Ambient []string
210
+}
211
+
199 212
 func (hooks *Hooks) UnmarshalJSON(b []byte) error {
200 213
 	var state struct {
201 214
 		Prestart  []CommandHook
... ...
@@ -243,13 +260,7 @@ func (hooks Hooks) MarshalJSON() ([]byte, error) {
243 243
 }
244 244
 
245 245
 // HookState is the payload provided to a hook on execution.
246
-type HookState struct {
247
-	Version    string `json:"ociVersion"`
248
-	ID         string `json:"id"`
249
-	Pid        int    `json:"pid"`
250
-	Root       string `json:"root"`
251
-	BundlePath string `json:"bundlePath"`
252
-}
246
+type HookState specs.State
253 247
 
254 248
 type Hook interface {
255 249
 	// Run executes the hook with the provided state.
... ...
@@ -4,38 +4,50 @@ package configs
4 4
 
5 5
 import "fmt"
6 6
 
7
-// HostUID gets the root uid for the process on host which could be non-zero
8
-// when user namespaces are enabled.
9
-func (c Config) HostUID() (int, error) {
7
+// HostUID gets the translated uid for the process on host which could be
8
+// different when user namespaces are enabled.
9
+func (c Config) HostUID(containerId int) (int, error) {
10 10
 	if c.Namespaces.Contains(NEWUSER) {
11 11
 		if c.UidMappings == nil {
12
-			return -1, fmt.Errorf("User namespaces enabled, but no user mappings found.")
12
+			return -1, fmt.Errorf("User namespaces enabled, but no uid mappings found.")
13 13
 		}
14
-		id, found := c.hostIDFromMapping(0, c.UidMappings)
14
+		id, found := c.hostIDFromMapping(containerId, c.UidMappings)
15 15
 		if !found {
16
-			return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
16
+			return -1, fmt.Errorf("User namespaces enabled, but no user mapping found.")
17 17
 		}
18 18
 		return id, nil
19 19
 	}
20
-	// Return default root uid 0
21
-	return 0, nil
20
+	// Return unchanged id.
21
+	return containerId, nil
22 22
 }
23 23
 
24
-// HostGID gets the root gid for the process on host which could be non-zero
24
+// HostRootUID gets the root uid for the process on host which could be non-zero
25 25
 // when user namespaces are enabled.
26
-func (c Config) HostGID() (int, error) {
26
+func (c Config) HostRootUID() (int, error) {
27
+	return c.HostUID(0)
28
+}
29
+
30
+// HostGID gets the translated gid for the process on host which could be
31
+// different when user namespaces are enabled.
32
+func (c Config) HostGID(containerId int) (int, error) {
27 33
 	if c.Namespaces.Contains(NEWUSER) {
28 34
 		if c.GidMappings == nil {
29 35
 			return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
30 36
 		}
31
-		id, found := c.hostIDFromMapping(0, c.GidMappings)
37
+		id, found := c.hostIDFromMapping(containerId, c.GidMappings)
32 38
 		if !found {
33
-			return -1, fmt.Errorf("User namespaces enabled, but no root group mapping found.")
39
+			return -1, fmt.Errorf("User namespaces enabled, but no group mapping found.")
34 40
 		}
35 41
 		return id, nil
36 42
 	}
37
-	// Return default root gid 0
38
-	return 0, nil
43
+	// Return unchanged id.
44
+	return containerId, nil
45
+}
46
+
47
+// HostRootGID gets the root gid for the process on host which could be non-zero
48
+// when user namespaces are enabled.
49
+func (c Config) HostRootGID() (int, error) {
50
+	return c.HostGID(0)
39 51
 }
40 52
 
41 53
 // Utility function that gets a host ID for a container ID from user namespace map
... ...
@@ -4,12 +4,10 @@ package configs
4 4
 
5 5
 func (n *Namespace) Syscall() int {
6 6
 	panic("No namespace syscall support")
7
-	return 0
8 7
 }
9 8
 
10 9
 // CloneFlags parses the container's Namespaces options to set the correct
11 10
 // flags on clone, unshare. This function returns flags only for new namespaces.
12 11
 func (n *Namespaces) CloneFlags() uintptr {
13 12
 	panic("No namespace syscall support")
14
-	return uintptr(0)
15 13
 }
... ...
@@ -23,7 +23,7 @@ var (
23 23
 	ioutilReadDir = ioutil.ReadDir
24 24
 )
25 25
 
26
-// Given the path to a device and it's cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct.
26
+// Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct.
27 27
 func DeviceFromPath(path, permissions string) (*configs.Device, error) {
28 28
 	fileInfo, err := osLstat(path)
29 29
 	if err != nil {
... ...
@@ -75,7 +75,8 @@ func getDevices(path string) ([]*configs.Device, error) {
75 75
 		switch {
76 76
 		case f.IsDir():
77 77
 			switch f.Name() {
78
-			case "pts", "shm", "fd", "mqueue":
78
+			// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
79
+			case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts":
79 80
 				continue
80 81
 			default:
81 82
 				sub, err := getDevices(filepath.Join(path, f.Name()))
... ...
@@ -94,6 +95,9 @@ func getDevices(path string) ([]*configs.Device, error) {
94 94
 			if err == ErrNotADevice {
95 95
 				continue
96 96
 			}
97
+			if os.IsNotExist(err) {
98
+				continue
99
+			}
97 100
 			return nil, err
98 101
 		}
99 102
 		out = append(out, device)
... ...
@@ -33,6 +33,8 @@ enum sync_t {
33 33
 	SYNC_USERMAP_ACK = 0x41, /* Mapping finished by the parent. */
34 34
 	SYNC_RECVPID_PLS = 0x42, /* Tell parent we're sending the PID. */
35 35
 	SYNC_RECVPID_ACK = 0x43, /* PID was correctly received by parent. */
36
+	SYNC_GRANDCHILD  = 0x44, /* The grandchild is ready to run. */
37
+	SYNC_CHILD_READY = 0x45, /* The child or grandchild is ready to return. */
36 38
 
37 39
 	/* XXX: This doesn't help with segfaults and other such issues. */
38 40
 	SYNC_ERR = 0xFF, /* Fatal error, no turning back. The error code follows. */
... ...
@@ -70,20 +72,23 @@ struct nlconfig_t {
70 70
 	char *namespaces;
71 71
 	size_t namespaces_len;
72 72
 	uint8_t is_setgroup;
73
-	int consolefd;
73
+	uint8_t is_rootless;
74
+	char *oom_score_adj;
75
+	size_t oom_score_adj_len;
74 76
 };
75 77
 
76 78
 /*
77 79
  * List of netlink message types sent to us as part of bootstrapping the init.
78 80
  * These constants are defined in libcontainer/message_linux.go.
79 81
  */
80
-#define INIT_MSG		62000
82
+#define INIT_MSG			62000
81 83
 #define CLONE_FLAGS_ATTR	27281
82
-#define CONSOLE_PATH_ATTR	27282
83
-#define NS_PATHS_ATTR		27283
84
-#define UIDMAP_ATTR		27284
85
-#define GIDMAP_ATTR		27285
86
-#define SETGROUP_ATTR		27286
84
+#define NS_PATHS_ATTR		27282
85
+#define UIDMAP_ATTR			27283
86
+#define GIDMAP_ATTR			27284
87
+#define SETGROUP_ATTR		27285
88
+#define OOM_SCORE_ADJ_ATTR	27286
89
+#define ROOTLESS_ATTR	    27287
87 90
 
88 91
 /*
89 92
  * Use the raw syscall for versions of glibc which don't include a function for
... ...
@@ -172,6 +177,7 @@ static void update_setgroups(int pid, enum policy_t setgroup)
172 172
 			policy = "deny";
173 173
 			break;
174 174
 		case SETGROUPS_DEFAULT:
175
+		default:
175 176
 			/* Nothing to do. */
176 177
 			return;
177 178
 	}
... ...
@@ -186,7 +192,7 @@ static void update_setgroups(int pid, enum policy_t setgroup)
186 186
 	}
187 187
 }
188 188
 
189
-static void update_uidmap(int pid, char *map, int map_len)
189
+static void update_uidmap(int pid, char *map, size_t map_len)
190 190
 {
191 191
 	if (map == NULL || map_len <= 0)
192 192
 		return;
... ...
@@ -195,7 +201,7 @@ static void update_uidmap(int pid, char *map, int map_len)
195 195
 		bail("failed to update /proc/%d/uid_map", pid);
196 196
 }
197 197
 
198
-static void update_gidmap(int pid, char *map, int map_len)
198
+static void update_gidmap(int pid, char *map, size_t map_len)
199 199
 {
200 200
 	if (map == NULL || map_len <= 0)
201 201
 		return;
... ...
@@ -204,6 +210,15 @@ static void update_gidmap(int pid, char *map, int map_len)
204 204
 		bail("failed to update /proc/%d/gid_map", pid);
205 205
 }
206 206
 
207
+static void update_oom_score_adj(char *data, size_t len)
208
+{
209
+	if (data == NULL || len <= 0)
210
+		return;
211
+
212
+	if (write_file(data, len, "/proc/self/oom_score_adj") < 0)
213
+		bail("failed to update /proc/self/oom_score_adj");
214
+}
215
+
207 216
 /* A dummy function that just jumps to the given jumpval. */
208 217
 static int child_func(void *arg) __attribute__ ((noinline));
209 218
 static int child_func(void *arg)
... ...
@@ -285,7 +300,7 @@ static void nl_parse(int fd, struct nlconfig_t *config)
285 285
 	/* Retrieve the netlink header. */
286 286
 	len = read(fd, &hdr, NLMSG_HDRLEN);
287 287
 	if (len != NLMSG_HDRLEN)
288
-		bail("invalid netlink header length %lu", len);
288
+		bail("invalid netlink header length %zu", len);
289 289
 
290 290
 	if (hdr.nlmsg_type == NLMSG_ERROR)
291 291
 		bail("failed to read netlink message");
... ...
@@ -301,11 +316,10 @@ static void nl_parse(int fd, struct nlconfig_t *config)
301 301
 
302 302
 	len = read(fd, data, size);
303 303
 	if (len != size)
304
-		bail("failed to read netlink payload, %lu != %lu", len, size);
304
+		bail("failed to read netlink payload, %zu != %zu", len, size);
305 305
 
306 306
 	/* Parse the netlink payload. */
307 307
 	config->data = data;
308
-	config->consolefd = -1;
309 308
 	while (current < data + size) {
310 309
 		struct nlattr *nlattr = (struct nlattr *)current;
311 310
 		size_t payload_len = nlattr->nla_len - NLA_HDRLEN;
... ...
@@ -318,14 +332,12 @@ static void nl_parse(int fd, struct nlconfig_t *config)
318 318
 		case CLONE_FLAGS_ATTR:
319 319
 			config->cloneflags = readint32(current);
320 320
 			break;
321
-		case CONSOLE_PATH_ATTR:
322
-			/*
323
-			 * We open the console here because we currently evaluate console
324
-			 * paths from the *host* namespaces.
325
-			 */
326
-			config->consolefd = open(current, O_RDWR);
327
-			if (config->consolefd < 0)
328
-				bail("failed to open console %s", current);
321
+		case ROOTLESS_ATTR:
322
+			config->is_rootless = readint8(current);
323
+			break;
324
+		case OOM_SCORE_ADJ_ATTR:
325
+			config->oom_score_adj = current;
326
+			config->oom_score_adj_len = payload_len;
329 327
 			break;
330 328
 		case NS_PATHS_ATTR:
331 329
 			config->namespaces = current;
... ...
@@ -394,7 +406,7 @@ void join_namespaces(char *nslist)
394 394
 
395 395
 		fd = open(path, O_RDONLY);
396 396
 		if (fd < 0)
397
-			bail("failed to open %s", namespace);
397
+			bail("failed to open %s", path);
398 398
 
399 399
 		ns->fd = fd;
400 400
 		ns->ns = nsflag(namespace);
... ...
@@ -424,7 +436,7 @@ void nsexec(void)
424 424
 {
425 425
 	int pipenum;
426 426
 	jmp_buf env;
427
-	int syncpipe[2];
427
+	int sync_child_pipe[2], sync_grandchild_pipe[2];
428 428
 	struct nlconfig_t config = {0};
429 429
 
430 430
 	/*
... ...
@@ -435,18 +447,43 @@ void nsexec(void)
435 435
 	if (pipenum == -1)
436 436
 		return;
437 437
 
438
-	/* make the process non-dumpable */
439
-	if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) {
440
-		bail("failed to set process as non-dumpable");
441
-	}
442
-
443 438
 	/* Parse all of the netlink configuration. */
444 439
 	nl_parse(pipenum, &config);
445 440
 
441
+	/* Set oom_score_adj. This has to be done before !dumpable because
442
+	 * /proc/self/oom_score_adj is not writeable unless you're an privileged
443
+	 * user (if !dumpable is set). All children inherit their parent's
444
+	 * oom_score_adj value on fork(2) so this will always be propagated
445
+	 * properly.
446
+	 */
447
+	update_oom_score_adj(config.oom_score_adj, config.oom_score_adj_len);
448
+
449
+	/*
450
+	 * Make the process non-dumpable, to avoid various race conditions that
451
+	 * could cause processes in namespaces we're joining to access host
452
+	 * resources (or potentially execute code).
453
+	 *
454
+	 * However, if the number of namespaces we are joining is 0, we are not
455
+	 * going to be switching to a different security context. Thus setting
456
+	 * ourselves to be non-dumpable only breaks things (like rootless
457
+	 * containers), which is the recommendation from the kernel folks.
458
+	 */
459
+	if (config.namespaces) {
460
+		if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) < 0)
461
+			bail("failed to set process as non-dumpable");
462
+	}
463
+
446 464
 	/* Pipe so we can tell the child when we've finished setting up. */
447
-	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, syncpipe) < 0)
465
+	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sync_child_pipe) < 0)
448 466
 		bail("failed to setup sync pipe between parent and child");
449 467
 
468
+	/*
469
+	 * We need a new socketpair to sync with grandchild so we don't have
470
+	 * race condition with child.
471
+	 */
472
+	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sync_grandchild_pipe) < 0)
473
+		bail("failed to setup sync pipe between parent and grandchild");
474
+
450 475
 	/* TODO: Currently we aren't dealing with child deaths properly. */
451 476
 
452 477
 	/*
... ...
@@ -508,6 +545,7 @@ void nsexec(void)
508 508
 			int len;
509 509
 			pid_t child;
510 510
 			char buf[JSON_MAX];
511
+			bool ready = false;
511 512
 
512 513
 			/* For debugging. */
513 514
 			prctl(PR_SET_NAME, (unsigned long) "runc:[0:PARENT]", 0, 0, 0);
... ...
@@ -517,31 +555,46 @@ void nsexec(void)
517 517
 			if (child < 0)
518 518
 				bail("unable to fork: child_func");
519 519
 
520
-			/* State machine for synchronisation with the children. */
521
-			while (true) {
520
+			/*
521
+			 * State machine for synchronisation with the children.
522
+			 *
523
+			 * Father only return when both child and grandchild are
524
+			 * ready, so we can receive all possible error codes
525
+			 * generated by children.
526
+			 */
527
+			while (!ready) {
522 528
 				enum sync_t s;
529
+				int ret;
523 530
 
524
-				/* This doesn't need to be global, we're in the parent. */
525
-				int syncfd = syncpipe[1];
531
+				syncfd = sync_child_pipe[1];
532
+				close(sync_child_pipe[0]);
526 533
 
527 534
 				if (read(syncfd, &s, sizeof(s)) != sizeof(s))
528 535
 					bail("failed to sync with child: next state");
529 536
 
530 537
 				switch (s) {
531
-				case SYNC_ERR: {
532
-						/* We have to mirror the error code of the child. */
533
-						int ret;
534
-
535
-						if (read(syncfd, &ret, sizeof(ret)) != sizeof(ret))
536
-							bail("failed to sync with child: read(error code)");
538
+				case SYNC_ERR:
539
+					/* We have to mirror the error code of the child. */
540
+					if (read(syncfd, &ret, sizeof(ret)) != sizeof(ret))
541
+						bail("failed to sync with child: read(error code)");
537 542
 
538
-						exit(ret);
539
-					}
540
-					break;
543
+					exit(ret);
541 544
 				case SYNC_USERMAP_PLS:
542
-					/* Enable setgroups(2) if we've been asked to. */
545
+					/*
546
+					 * Enable setgroups(2) if we've been asked to. But we also
547
+					 * have to explicitly disable setgroups(2) if we're
548
+					 * creating a rootless container (this is required since
549
+					 * Linux 3.19).
550
+					 */
551
+					if (config.is_rootless && config.is_setgroup) {
552
+						kill(child, SIGKILL);
553
+						bail("cannot allow setgroup in an unprivileged user namespace setup");
554
+					}
555
+
543 556
 					if (config.is_setgroup)
544 557
 						update_setgroups(child, SETGROUPS_ALLOW);
558
+					if (config.is_rootless)
559
+						update_setgroups(child, SETGROUPS_DENY);
545 560
 
546 561
 					/* Set up mappings. */
547 562
 					update_uidmap(child, config.uidmap, config.uidmap_len);
... ...
@@ -553,11 +606,6 @@ void nsexec(void)
553 553
 						bail("failed to sync with child: write(SYNC_USERMAP_ACK)");
554 554
 					}
555 555
 					break;
556
-				case SYNC_USERMAP_ACK:
557
-					/* We should _never_ receive acks. */
558
-					kill(child, SIGKILL);
559
-					bail("failed to sync with child: unexpected SYNC_USERMAP_ACK");
560
-					break;
561 556
 				case SYNC_RECVPID_PLS: {
562 557
 						pid_t old = child;
563 558
 
... ...
@@ -575,18 +623,49 @@ void nsexec(void)
575 575
 							bail("failed to sync with child: write(SYNC_RECVPID_ACK)");
576 576
 						}
577 577
 					}
578
+					break;
579
+				case SYNC_CHILD_READY:
580
+					ready = true;
581
+					break;
582
+				default:
583
+					bail("unexpected sync value: %u", s);
584
+				}
585
+			}
586
+
587
+			/* Now sync with grandchild. */
588
+
589
+			ready = false;
590
+			while (!ready) {
591
+				enum sync_t s;
592
+				int ret;
578 593
 
579
-					/* Leave the loop. */
580
-					goto out;
581
-				case SYNC_RECVPID_ACK:
582
-					/* We should _never_ receive acks. */
594
+				syncfd = sync_grandchild_pipe[1];
595
+				close(sync_grandchild_pipe[0]);
596
+
597
+				s = SYNC_GRANDCHILD;
598
+				if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
583 599
 					kill(child, SIGKILL);
584
-					bail("failed to sync with child: unexpected SYNC_RECVPID_ACK");
600
+					bail("failed to sync with child: write(SYNC_GRANDCHILD)");
601
+				}
602
+
603
+				if (read(syncfd, &s, sizeof(s)) != sizeof(s))
604
+					bail("failed to sync with child: next state");
605
+
606
+				switch (s) {
607
+				case SYNC_ERR:
608
+					/* We have to mirror the error code of the child. */
609
+					if (read(syncfd, &ret, sizeof(ret)) != sizeof(ret))
610
+						bail("failed to sync with child: read(error code)");
611
+
612
+					exit(ret);
613
+				case SYNC_CHILD_READY:
614
+					ready = true;
585 615
 					break;
616
+				default:
617
+					bail("unexpected sync value: %u", s);
586 618
 				}
587 619
 			}
588 620
 
589
-		out:
590 621
 			/* Send the init_func pid back to our parent. */
591 622
 			len = snprintf(buf, JSON_MAX, "{\"pid\": %d}\n", child);
592 623
 			if (len < 0) {
... ...
@@ -615,7 +694,8 @@ void nsexec(void)
615 615
 			enum sync_t s;
616 616
 
617 617
 			/* We're in a child and thus need to tell the parent if we die. */
618
-			syncfd = syncpipe[0];
618
+			syncfd = sync_child_pipe[0];
619
+			close(sync_child_pipe[1]);
619 620
 
620 621
 			/* For debugging. */
621 622
 			prctl(PR_SET_NAME, (unsigned long) "runc:[1:CHILD]", 0, 0, 0);
... ...
@@ -653,6 +733,11 @@ void nsexec(void)
653 653
 				 * clone_parent rant). So signal our parent to hook us up.
654 654
 				 */
655 655
 
656
+				/* Switching is only necessary if we joined namespaces. */
657
+				if (config.namespaces) {
658
+					if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0)
659
+						bail("failed to set process as dumpable");
660
+				}
656 661
 				s = SYNC_USERMAP_PLS;
657 662
 				if (write(syncfd, &s, sizeof(s)) != sizeof(s))
658 663
 					bail("failed to sync with parent: write(SYNC_USERMAP_PLS)");
... ...
@@ -663,6 +748,11 @@ void nsexec(void)
663 663
 					bail("failed to sync with parent: read(SYNC_USERMAP_ACK)");
664 664
 				if (s != SYNC_USERMAP_ACK)
665 665
 					bail("failed to sync with parent: SYNC_USERMAP_ACK: got %u", s);
666
+				/* Switching is only necessary if we joined namespaces. */
667
+				if (config.namespaces) {
668
+					if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) < 0)
669
+						bail("failed to set process as dumpable");
670
+				}
666 671
 			}
667 672
 
668 673
 			/*
... ...
@@ -700,6 +790,12 @@ void nsexec(void)
700 700
 				bail("failed to sync with parent: SYNC_RECVPID_ACK: got %u", s);
701 701
 			}
702 702
 
703
+			s = SYNC_CHILD_READY;
704
+			if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
705
+				kill(child, SIGKILL);
706
+				bail("failed to sync with parent: write(SYNC_CHILD_READY)");
707
+			}
708
+
703 709
 			/* Our work is done. [Stage 2: JUMP_INIT] is doing the rest of the work. */
704 710
 			exit(0);
705 711
 		}
... ...
@@ -715,14 +811,22 @@ void nsexec(void)
715 715
 			 * We're inside the child now, having jumped from the
716 716
 			 * start_child() code after forking in the parent.
717 717
 			 */
718
-			int consolefd = config.consolefd;
718
+			enum sync_t s;
719 719
 
720 720
 			/* We're in a child and thus need to tell the parent if we die. */
721
-			syncfd = syncpipe[0];
721
+			syncfd = sync_grandchild_pipe[0];
722
+			close(sync_grandchild_pipe[1]);
723
+			close(sync_child_pipe[0]);
724
+			close(sync_child_pipe[1]);
722 725
 
723 726
 			/* For debugging. */
724 727
 			prctl(PR_SET_NAME, (unsigned long) "runc:[2:INIT]", 0, 0, 0);
725 728
 
729
+			if (read(syncfd, &s, sizeof(s)) != sizeof(s))
730
+				bail("failed to sync with parent: read(SYNC_GRANDCHILD)");
731
+			if (s != SYNC_GRANDCHILD)
732
+				bail("failed to sync with parent: SYNC_GRANDCHILD: got %u", s);
733
+
726 734
 			if (setsid() < 0)
727 735
 				bail("setsid failed");
728 736
 
... ...
@@ -732,23 +836,17 @@ void nsexec(void)
732 732
 			if (setgid(0) < 0)
733 733
 				bail("setgid failed");
734 734
 
735
-			if (setgroups(0, NULL) < 0)
736
-				bail("setgroups failed");
737
-
738
-			if (consolefd != -1) {
739
-				if (ioctl(consolefd, TIOCSCTTY, 0) < 0)
740
-					bail("ioctl TIOCSCTTY failed");
741
-				if (dup3(consolefd, STDIN_FILENO, 0) != STDIN_FILENO)
742
-					bail("failed to dup stdin");
743
-				if (dup3(consolefd, STDOUT_FILENO, 0) != STDOUT_FILENO)
744
-					bail("failed to dup stdout");
745
-				if (dup3(consolefd, STDERR_FILENO, 0) != STDERR_FILENO)
746
-					bail("failed to dup stderr");
735
+			if (!config.is_rootless && config.is_setgroup) {
736
+				if (setgroups(0, NULL) < 0)
737
+					bail("setgroups failed");
747 738
 			}
748 739
 
740
+			s = SYNC_CHILD_READY;
741
+			if (write(syncfd, &s, sizeof(s)) != sizeof(s))
742
+				bail("failed to sync with patent: write(SYNC_CHILD_READY)");
743
+
749 744
 			/* Close sync pipes. */
750
-			close(syncpipe[0]);
751
-			close(syncpipe[1]);
745
+			close(sync_grandchild_pipe[0]);
752 746
 
753 747
 			/* Free netlink data. */
754 748
 			nl_free(&config);
... ...
@@ -758,7 +856,6 @@ void nsexec(void)
758 758
 		}
759 759
 	default:
760 760
 		bail("unexpected jump value");
761
-		break;
762 761
 	}
763 762
 
764 763
 	/* Should never be reached. */
... ...
@@ -199,18 +199,16 @@ type ExecUser struct {
199 199
 // files cannot be opened for any reason, the error is ignored and a nil
200 200
 // io.Reader is passed instead.
201 201
 func GetExecUserPath(userSpec string, defaults *ExecUser, passwdPath, groupPath string) (*ExecUser, error) {
202
-	passwd, err := os.Open(passwdPath)
203
-	if err != nil {
204
-		passwd = nil
205
-	} else {
206
-		defer passwd.Close()
202
+	var passwd, group io.Reader
203
+
204
+	if passwdFile, err := os.Open(passwdPath); err == nil {
205
+		passwd = passwdFile
206
+		defer passwdFile.Close()
207 207
 	}
208 208
 
209
-	group, err := os.Open(groupPath)
210
-	if err != nil {
211
-		group = nil
212
-	} else {
213
-		defer group.Close()
209
+	if groupFile, err := os.Open(groupPath); err == nil {
210
+		group = groupFile
211
+		defer groupFile.Close()
214 212
 	}
215 213
 
216 214
 	return GetExecUser(userSpec, defaults, passwd, group)
... ...
@@ -343,7 +341,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
343 343
 			if len(groups) > 0 {
344 344
 				// First match wins, even if there's more than one matching entry.
345 345
 				user.Gid = groups[0].Gid
346
-			} else if groupArg != "" {
346
+			} else {
347 347
 				// If we can't find a group with the given name, the only other valid
348 348
 				// option is if it's a numeric group name with no associated entry in group.
349 349
 
... ...
@@ -433,9 +431,11 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err
433 433
 // that opens the groupPath given and gives it as an argument to
434 434
 // GetAdditionalGroups.
435 435
 func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int, error) {
436
-	group, err := os.Open(groupPath)
437
-	if err == nil {
438
-		defer group.Close()
436
+	var group io.Reader
437
+
438
+	if groupFile, err := os.Open(groupPath); err == nil {
439
+		group = groupFile
440
+		defer groupFile.Close()
439 441
 	}
440 442
 	return GetAdditionalGroups(additionalGroups, group)
441 443
 }
442 444
new file mode 100644
... ...
@@ -0,0 +1,21 @@
0
+# OCI runtime-spec. When updating this, make sure you use a version tag rather
1
+# than a commit ID so it's much more obvious what version of the spec we are
2
+# using.
3
+github.com/opencontainers/runtime-spec v1.0.0-rc5
4
+# Core libcontainer functionality.
5
+github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
6
+github.com/opencontainers/selinux v1.0.0-rc1
7
+github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
8
+github.com/Sirupsen/logrus 26709e2714106fb8ad40b773b711ebce25b78914
9
+github.com/syndtr/gocapability e7cb7fa329f456b3855136a2642b197bad7366ba
10
+github.com/vishvananda/netlink 1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270
11
+# systemd integration.
12
+github.com/coreos/go-systemd v14
13
+github.com/coreos/pkg v3
14
+github.com/godbus/dbus v3
15
+github.com/golang/protobuf f7137ae6b19afbfd61a94b746fda3b3fe0491874
16
+# Command-line interface.
17
+github.com/docker/docker 0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d
18
+github.com/docker/go-units v0.2.0
19
+github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
20
+golang.org/x/sys 9a7256cb28ed514b4e1e5f68959914c4c28a92e0 https://github.com/golang/sys
... ...
@@ -1,76 +1,53 @@
1 1
 # Open Container Initiative Runtime Specification
2 2
 
3
-The [Open Container Initiative](http://www.opencontainers.org/) develops specifications for standards on Operating System process and application containers.
3
+The [Open Container Initiative][oci] develops specifications for standards on Operating System process and application containers.
4 4
 
5
+The specification can be found [here](spec.md).
5 6
 
6
-Table of Contents
7
+## Table of Contents
7 8
 
8
-- [Introduction](README.md)
9
-  - [Code of Conduct](#code-of-conduct)
10
-  - [Container Principles](principles.md)
11
-  - [Style and Conventions](style.md)
12
-  - [Roadmap](ROADMAP.md)
13
-  - [Implementations](implementations.md)
14
-  - [project](project.md)
15
-- [Filesystem Bundle](bundle.md)
16
-- Runtime and Lifecycle
17
-  - [General Runtime and Lifecycle](runtime.md)
18
-  - [Linux-specific Runtime and Lifecycle](runtime-linux.md)
19
-- Configuration
20
-  - [General Configuration](config.md)
21
-  - [Linux-specific Configuration](config-linux.md)
22
-  - [Solaris-specific Configuration](config-solaris.md)
23
-  - [Windows-specific Configuration](config-windows.md)
24
-- [Glossary](glossary.md)
9
+Additional documentation about how this group operates:
25 10
 
26
-In the specifications in the above table of contents, the keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in [RFC 2119](http://tools.ietf.org/html/rfc2119) (Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997).
11
+- [Code of Conduct][code-of-conduct]
12
+- [Style and Conventions](style.md)
13
+- [Roadmap](ROADMAP.md)
14
+- [Implementations](implementations.md)
15
+- [Releases](RELEASES.md)
16
+- [project](project.md)
17
+- [charter][charter]
27 18
 
28
-The keywords "unspecified", "undefined", and "implementation-defined" are to be interpreted as described in the [rationale for the C99 standard][c99-unspecified].
29
-
30
-An implementation is not compliant for a given CPU architecture if it fails to satisfy one or more of the MUST, REQUIRED, or SHALL requirements for the protocols it implements.
31
-An implementation is compliant for a given CPU architecture if it satisfies all the MUST, REQUIRED, and SHALL requirements for the protocols it implements.
32
-
33
-Protocols defined by this specification are:
34
-* Linux containers: [runtime.md](runtime.md), [config.md](config.md), [config-linux.md](config-linux.md), and [runtime-linux.md](runtime-linux.md).
35
-* Solaris containers: [runtime.md](runtime.md), [config.md](config.md), and [config-solaris.md](config-solaris.md).
36
-* Windows containers: [runtime.md](runtime.md), [config.md](config.md), and [config-windows.md](config-windows.md).
37
-
38
-# Use Cases
19
+## Use Cases
39 20
 
40 21
 To provide context for users the following section gives example use cases for each part of the spec.
41 22
 
42
-#### Application Bundle Builders
23
+### Application Bundle Builders
43 24
 
44 25
 Application bundle builders can create a [bundle](bundle.md) directory that includes all of the files required for launching an application as a container.
45
-The bundle contains an OCI [configuration file](config.md) where the builder can specify host-independent details such as [which executable to launch](config.md#process-configuration) and host-specific settings such as [mount](config.md#mounts) locations, [hook](config.md#hooks) paths, Linux [namespaces](config-linux.md#namespaces) and [cgroups](config-linux.md#control-groups).
26
+The bundle contains an OCI [configuration file](config.md) where the builder can specify host-independent details such as [which executable to launch](config.md#process) and host-specific settings such as [mount](config.md#mounts) locations, [hook](config.md#hooks) paths, Linux [namespaces](config-linux.md#namespaces) and [cgroups](config-linux.md#control-groups).
46 27
 Because the configuration includes host-specific settings, application bundle directories copied between two hosts may require configuration adjustments.
47 28
 
48
-#### Hook Developers
29
+### Hook Developers
49 30
 
50 31
 [Hook](config.md#hooks) developers can extend the functionality of an OCI-compliant runtime by hooking into a container's lifecycle with an external application.
51 32
 Example use cases include sophisticated network configuration, volume garbage collection, etc.
52 33
 
53
-#### Runtime Developers
34
+### Runtime Developers
54 35
 
55 36
 Runtime developers can build runtime implementations that run OCI-compliant bundles and container configuration, containing low-level OS and host specific details, on a particular platform.
56 37
 
57
-# Releases
38
+## Releases
58 39
 
59 40
 There is a loose [Road Map](./ROADMAP.md).
60 41
 During the `0.x` series of OCI releases we make no backwards compatibility guarantees and intend to break the schema during this series.
61 42
 
62
-# Contributing
43
+## Contributing
63 44
 
64 45
 Development happens on GitHub for the spec.
65 46
 Issues are used for bugs and actionable items and longer discussions can happen on the [mailing list](#mailing-list).
66 47
 
67 48
 The specification and code is licensed under the Apache 2.0 license found in the [LICENSE](./LICENSE) file.
68 49
 
69
-## Code of Conduct
70
-
71
-Participation in the OpenContainers community is governed by [OpenContainer's Code of Conduct](https://github.com/opencontainers/tob/blob/d2f9d68c1332870e40693fe077d311e0742bc73d/code-of-conduct.md).
72
-
73
-## Discuss your design
50
+### Discuss your design
74 51
 
75 52
 The project welcomes submissions, but please let everyone know what you are working on.
76 53
 
... ...
@@ -81,27 +58,27 @@ It also guarantees that the design is sound before code is written; a GitHub pul
81 81
 Typos and grammatical errors can go straight to a pull-request.
82 82
 When in doubt, start on the [mailing-list](#mailing-list).
83 83
 
84
-## Weekly Call
84
+### Weekly Call
85 85
 
86 86
 The contributors and maintainers of all OCI projects have a weekly meeting Wednesdays at 2:00 PM (USA Pacific).
87
-Everyone is welcome to participate via [UberConference web][UberConference] or audio-only: 415-968-0849 (no PIN needed.)
87
+Everyone is welcome to participate via [UberConference web][uberconference] or audio-only: 415-968-0849 (no PIN needed.)
88 88
 An initial agenda will be posted to the [mailing list](#mailing-list) earlier in the week, and everyone is welcome to propose additional topics or suggest other agenda alterations there.
89
-Minutes are posted to the [mailing list](#mailing-list) and minutes from past calls are archived to the [wiki](https://github.com/opencontainers/runtime-spec/wiki) for those who are unable to join the call.
89
+Minutes are posted to the [mailing list](#mailing-list) and minutes from past calls are archived to the [wiki][runtime-wiki].
90 90
 
91
-## Mailing List
91
+### Mailing List
92 92
 
93
-You can subscribe and join the mailing list on [Google Groups](https://groups.google.com/a/opencontainers.org/forum/#!forum/dev).
93
+You can subscribe and join the mailing list on [Google Groups][dev-list].
94 94
 
95
-## IRC
95
+### IRC
96 96
 
97 97
 OCI discussion happens on #opencontainers on Freenode ([logs][irc-logs]).
98 98
 
99
-## Git commit
99
+### Git commit
100 100
 
101
-### Sign your work
101
+#### Sign your work
102 102
 
103 103
 The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch.
104
-The rules are pretty simple: if you can certify the below (from [developercertificate.org](http://developercertificate.org/)):
104
+The rules are pretty simple: if you can certify the below (from http://developercertificate.org):
105 105
 
106 106
 ```
107 107
 Developer Certificate of Origin
... ...
@@ -150,10 +127,10 @@ using your real name (sorry, no pseudonyms or anonymous contributions.)
150 150
 
151 151
 You can add the sign off when creating the git commit via `git commit -s`.
152 152
 
153
-### Commit Style
153
+#### Commit Style
154 154
 
155 155
 Simple house-keeping for clean git history.
156
-Read more on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) or the Discussion section of [`git-commit(1)`](http://git-scm.com/docs/git-commit).
156
+Read more on [How to Write a Git Commit Message][how-to-git-commit] or the Discussion section of [git-commit(1)][git-commit.1].
157 157
 
158 158
 1. Separate the subject from body with a blank line
159 159
 2. Limit the subject line to 50 characters
... ...
@@ -165,6 +142,14 @@ Read more on [How to Write a Git Commit Message](http://chris.beams.io/posts/git
165 165
   * If there was important/useful/essential conversation or information, copy or include a reference
166 166
 8. When possible, one keyword to scope the change in the subject (i.e. "README: ...", "runtime: ...")
167 167
 
168
-[c99-unspecified]: http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf#page=18
169
-[UberConference]: https://www.uberconference.com/opencontainers
168
+
169
+[charter]: https://www.opencontainers.org/about/governance
170
+[code-of-conduct]: https://github.com/opencontainers/tob/blob/master/code-of-conduct.md
171
+[dev-list]: https://groups.google.com/a/opencontainers.org/forum/#!forum/dev
172
+[how-to-git-commit]: http://chris.beams.io/posts/git-commit
170 173
 [irc-logs]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/
174
+[oci]: https://www.opencontainers.org
175
+[runtime-wiki]: https://github.com/opencontainers/runtime-spec/wiki
176
+[uberconference]: https://www.uberconference.com/opencontainers
177
+
178
+[git-commit.1]: http://git-scm.com/docs/git-commit
... ...
@@ -17,7 +17,7 @@ type Spec struct {
17 17
 	// Mounts configures additional mounts (on top of Root).
18 18
 	Mounts []Mount `json:"mounts,omitempty"`
19 19
 	// Hooks configures callbacks for container lifecycle events.
20
-	Hooks Hooks `json:"hooks"`
20
+	Hooks *Hooks `json:"hooks,omitempty"`
21 21
 	// Annotations contains arbitrary metadata for the container.
22 22
 	Annotations map[string]string `json:"annotations,omitempty"`
23 23
 
... ...
@@ -44,10 +44,10 @@ type Process struct {
44 44
 	// Cwd is the current working directory for the process and must be
45 45
 	// relative to the container's root.
46 46
 	Cwd string `json:"cwd"`
47
-	// Capabilities are Linux capabilities that are kept for the container.
48
-	Capabilities []string `json:"capabilities,omitempty" platform:"linux"`
47
+	// Capabilities are Linux capabilities that are kept for the process.
48
+	Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"`
49 49
 	// Rlimits specifies rlimit options to apply to the process.
50
-	Rlimits []Rlimit `json:"rlimits,omitempty" platform:"linux"`
50
+	Rlimits []LinuxRlimit `json:"rlimits,omitempty" platform:"linux"`
51 51
 	// NoNewPrivileges controls whether additional privileges could be gained by processes in the container.
52 52
 	NoNewPrivileges bool `json:"noNewPrivileges,omitempty" platform:"linux"`
53 53
 	// ApparmorProfile specifies the apparmor profile for the container.
... ...
@@ -56,6 +56,21 @@ type Process struct {
56 56
 	SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"`
57 57
 }
58 58
 
59
+// LinuxCapabilities specifies the whitelist of capabilities that are kept for a process.
60
+// http://man7.org/linux/man-pages/man7/capabilities.7.html
61
+type LinuxCapabilities struct {
62
+	// Bounding is the set of capabilities checked by the kernel.
63
+	Bounding []string `json:"bounding,omitempty" platform:"linux"`
64
+	// Effective is the set of capabilities checked by the kernel.
65
+	Effective []string `json:"effective,omitempty" platform:"linux"`
66
+	// Inheritable is the capabilities preserved across execve.
67
+	Inheritable []string `json:"inheritable,omitempty" platform:"linux"`
68
+	// Permitted is the limiting superset for effective capabilities.
69
+	Permitted []string `json:"permitted,omitempty" platform:"linux"`
70
+	// Ambient is the ambient set of capabilities that are kept.
71
+	Ambient []string `json:"ambient,omitempty" platform:"linux"`
72
+}
73
+
59 74
 // Box specifies dimensions of a rectangle. Used for specifying the size of a console.
60 75
 type Box struct {
61 76
 	// Height is the vertical dimension of a box.
... ...
@@ -98,10 +113,10 @@ type Mount struct {
98 98
 	// Destination is the path where the mount will be placed relative to the container's root.  The path and child directories MUST exist, a runtime MUST NOT create directories automatically to a mount point.
99 99
 	Destination string `json:"destination"`
100 100
 	// Type specifies the mount kind.
101
-	Type string `json:"type"`
101
+	Type string `json:"type,omitempty"`
102 102
 	// Source specifies the source path of the mount.  In the case of bind mounts on
103 103
 	// Linux based systems this would be the file on the host.
104
-	Source string `json:"source"`
104
+	Source string `json:"source,omitempty"`
105 105
 	// Options are fstab style mount options.
106 106
 	Options []string `json:"options,omitempty"`
107 107
 }
... ...
@@ -128,24 +143,24 @@ type Hooks struct {
128 128
 // Linux contains platform specific configuration for Linux based containers.
129 129
 type Linux struct {
130 130
 	// UIDMapping specifies user mappings for supporting user namespaces on Linux.
131
-	UIDMappings []IDMapping `json:"uidMappings,omitempty"`
131
+	UIDMappings []LinuxIDMapping `json:"uidMappings,omitempty"`
132 132
 	// GIDMapping specifies group mappings for supporting user namespaces on Linux.
133
-	GIDMappings []IDMapping `json:"gidMappings,omitempty"`
133
+	GIDMappings []LinuxIDMapping `json:"gidMappings,omitempty"`
134 134
 	// Sysctl are a set of key value pairs that are set for the container on start
135 135
 	Sysctl map[string]string `json:"sysctl,omitempty"`
136 136
 	// Resources contain cgroup information for handling resource constraints
137 137
 	// for the container
138
-	Resources *Resources `json:"resources,omitempty"`
138
+	Resources *LinuxResources `json:"resources,omitempty"`
139 139
 	// CgroupsPath specifies the path to cgroups that are created and/or joined by the container.
140 140
 	// The path is expected to be relative to the cgroups mountpoint.
141 141
 	// If resources are specified, the cgroups at CgroupsPath will be updated based on resources.
142
-	CgroupsPath *string `json:"cgroupsPath,omitempty"`
142
+	CgroupsPath string `json:"cgroupsPath,omitempty"`
143 143
 	// Namespaces contains the namespaces that are created and/or joined by the container
144
-	Namespaces []Namespace `json:"namespaces,omitempty"`
144
+	Namespaces []LinuxNamespace `json:"namespaces,omitempty"`
145 145
 	// Devices are a list of device nodes that are created for the container
146
-	Devices []Device `json:"devices,omitempty"`
146
+	Devices []LinuxDevice `json:"devices,omitempty"`
147 147
 	// Seccomp specifies the seccomp security settings for the container.
148
-	Seccomp *Seccomp `json:"seccomp,omitempty"`
148
+	Seccomp *LinuxSeccomp `json:"seccomp,omitempty"`
149 149
 	// RootfsPropagation is the rootfs mount propagation mode for the container.
150 150
 	RootfsPropagation string `json:"rootfsPropagation,omitempty"`
151 151
 	// MaskedPaths masks over the provided paths inside the container.
... ...
@@ -156,21 +171,21 @@ type Linux struct {
156 156
 	MountLabel string `json:"mountLabel,omitempty"`
157 157
 }
158 158
 
159
-// Namespace is the configuration for a Linux namespace
160
-type Namespace struct {
159
+// LinuxNamespace is the configuration for a Linux namespace
160
+type LinuxNamespace struct {
161 161
 	// Type is the type of Linux namespace
162
-	Type NamespaceType `json:"type"`
162
+	Type LinuxNamespaceType `json:"type"`
163 163
 	// Path is a path to an existing namespace persisted on disk that can be joined
164 164
 	// and is of the same type
165 165
 	Path string `json:"path,omitempty"`
166 166
 }
167 167
 
168
-// NamespaceType is one of the Linux namespaces
169
-type NamespaceType string
168
+// LinuxNamespaceType is one of the Linux namespaces
169
+type LinuxNamespaceType string
170 170
 
171 171
 const (
172 172
 	// PIDNamespace for isolating process IDs
173
-	PIDNamespace NamespaceType = "pid"
173
+	PIDNamespace LinuxNamespaceType = "pid"
174 174
 	// NetworkNamespace for isolating network devices, stacks, ports, etc
175 175
 	NetworkNamespace = "network"
176 176
 	// MountNamespace for isolating mount points
... ...
@@ -185,18 +200,18 @@ const (
185 185
 	CgroupNamespace = "cgroup"
186 186
 )
187 187
 
188
-// IDMapping specifies UID/GID mappings
189
-type IDMapping struct {
190
-	// HostID is the UID/GID of the host user or group
188
+// LinuxIDMapping specifies UID/GID mappings
189
+type LinuxIDMapping struct {
190
+	// HostID is the starting UID/GID on the host to be mapped to 'ContainerID'
191 191
 	HostID uint32 `json:"hostID"`
192
-	// ContainerID is the UID/GID of the container's user or group
192
+	// ContainerID is the starting UID/GID in the container
193 193
 	ContainerID uint32 `json:"containerID"`
194
-	// Size is the length of the range of IDs mapped between the two namespaces
194
+	// Size is the number of IDs to be mapped
195 195
 	Size uint32 `json:"size"`
196 196
 }
197 197
 
198
-// Rlimit type and restrictions
199
-type Rlimit struct {
198
+// LinuxRlimit type and restrictions
199
+type LinuxRlimit struct {
200 200
 	// Type of the rlimit to set
201 201
 	Type string `json:"type"`
202 202
 	// Hard is the hard limit for the specified type
... ...
@@ -205,66 +220,66 @@ type Rlimit struct {
205 205
 	Soft uint64 `json:"soft"`
206 206
 }
207 207
 
208
-// HugepageLimit structure corresponds to limiting kernel hugepages
209
-type HugepageLimit struct {
208
+// LinuxHugepageLimit structure corresponds to limiting kernel hugepages
209
+type LinuxHugepageLimit struct {
210 210
 	// Pagesize is the hugepage size
211
-	Pagesize *string `json:"pageSize,omitempty"`
211
+	Pagesize string `json:"pageSize"`
212 212
 	// Limit is the limit of "hugepagesize" hugetlb usage
213
-	Limit *uint64 `json:"limit,omitempty"`
213
+	Limit uint64 `json:"limit"`
214 214
 }
215 215
 
216
-// InterfacePriority for network interfaces
217
-type InterfacePriority struct {
216
+// LinuxInterfacePriority for network interfaces
217
+type LinuxInterfacePriority struct {
218 218
 	// Name is the name of the network interface
219 219
 	Name string `json:"name"`
220 220
 	// Priority for the interface
221 221
 	Priority uint32 `json:"priority"`
222 222
 }
223 223
 
224
-// blockIODevice holds major:minor format supported in blkio cgroup
225
-type blockIODevice struct {
224
+// linuxBlockIODevice holds major:minor format supported in blkio cgroup
225
+type linuxBlockIODevice struct {
226 226
 	// Major is the device's major number.
227 227
 	Major int64 `json:"major"`
228 228
 	// Minor is the device's minor number.
229 229
 	Minor int64 `json:"minor"`
230 230
 }
231 231
 
232
-// WeightDevice struct holds a `major:minor weight` pair for blkioWeightDevice
233
-type WeightDevice struct {
234
-	blockIODevice
232
+// LinuxWeightDevice struct holds a `major:minor weight` pair for blkioWeightDevice
233
+type LinuxWeightDevice struct {
234
+	linuxBlockIODevice
235 235
 	// Weight is the bandwidth rate for the device, range is from 10 to 1000
236 236
 	Weight *uint16 `json:"weight,omitempty"`
237 237
 	// LeafWeight is the bandwidth rate for the device while competing with the cgroup's child cgroups, range is from 10 to 1000, CFQ scheduler only
238 238
 	LeafWeight *uint16 `json:"leafWeight,omitempty"`
239 239
 }
240 240
 
241
-// ThrottleDevice struct holds a `major:minor rate_per_second` pair
242
-type ThrottleDevice struct {
243
-	blockIODevice
241
+// LinuxThrottleDevice struct holds a `major:minor rate_per_second` pair
242
+type LinuxThrottleDevice struct {
243
+	linuxBlockIODevice
244 244
 	// Rate is the IO rate limit per cgroup per device
245
-	Rate *uint64 `json:"rate,omitempty"`
245
+	Rate uint64 `json:"rate"`
246 246
 }
247 247
 
248
-// BlockIO for Linux cgroup 'blkio' resource management
249
-type BlockIO struct {
248
+// LinuxBlockIO for Linux cgroup 'blkio' resource management
249
+type LinuxBlockIO struct {
250 250
 	// Specifies per cgroup weight, range is from 10 to 1000
251 251
 	Weight *uint16 `json:"blkioWeight,omitempty"`
252 252
 	// Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, range is from 10 to 1000, CFQ scheduler only
253 253
 	LeafWeight *uint16 `json:"blkioLeafWeight,omitempty"`
254 254
 	// Weight per cgroup per device, can override BlkioWeight
255
-	WeightDevice []WeightDevice `json:"blkioWeightDevice,omitempty"`
255
+	WeightDevice []LinuxWeightDevice `json:"blkioWeightDevice,omitempty"`
256 256
 	// IO read rate limit per cgroup per device, bytes per second
257
-	ThrottleReadBpsDevice []ThrottleDevice `json:"blkioThrottleReadBpsDevice,omitempty"`
257
+	ThrottleReadBpsDevice []LinuxThrottleDevice `json:"blkioThrottleReadBpsDevice,omitempty"`
258 258
 	// IO write rate limit per cgroup per device, bytes per second
259
-	ThrottleWriteBpsDevice []ThrottleDevice `json:"blkioThrottleWriteBpsDevice,omitempty"`
259
+	ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"blkioThrottleWriteBpsDevice,omitempty"`
260 260
 	// IO read rate limit per cgroup per device, IO per second
261
-	ThrottleReadIOPSDevice []ThrottleDevice `json:"blkioThrottleReadIOPSDevice,omitempty"`
261
+	ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleReadIOPSDevice,omitempty"`
262 262
 	// IO write rate limit per cgroup per device, IO per second
263
-	ThrottleWriteIOPSDevice []ThrottleDevice `json:"blkioThrottleWriteIOPSDevice,omitempty"`
263
+	ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleWriteIOPSDevice,omitempty"`
264 264
 }
265 265
 
266
-// Memory for Linux cgroup 'memory' resource management
267
-type Memory struct {
266
+// LinuxMemory for Linux cgroup 'memory' resource management
267
+type LinuxMemory struct {
268 268
 	// Memory limit (in bytes).
269 269
 	Limit *uint64 `json:"limit,omitempty"`
270 270
 	// Memory reservation or soft_limit (in bytes).
... ...
@@ -279,62 +294,62 @@ type Memory struct {
279 279
 	Swappiness *uint64 `json:"swappiness,omitempty"`
280 280
 }
281 281
 
282
-// CPU for Linux cgroup 'cpu' resource management
283
-type CPU struct {
282
+// LinuxCPU for Linux cgroup 'cpu' resource management
283
+type LinuxCPU struct {
284 284
 	// CPU shares (relative weight (ratio) vs. other cgroups with cpu shares).
285 285
 	Shares *uint64 `json:"shares,omitempty"`
286 286
 	// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
287
-	Quota *uint64 `json:"quota,omitempty"`
287
+	Quota *int64 `json:"quota,omitempty"`
288 288
 	// CPU period to be used for hardcapping (in usecs).
289 289
 	Period *uint64 `json:"period,omitempty"`
290 290
 	// How much time realtime scheduling may use (in usecs).
291
-	RealtimeRuntime *uint64 `json:"realtimeRuntime,omitempty"`
291
+	RealtimeRuntime *int64 `json:"realtimeRuntime,omitempty"`
292 292
 	// CPU period to be used for realtime scheduling (in usecs).
293 293
 	RealtimePeriod *uint64 `json:"realtimePeriod,omitempty"`
294 294
 	// CPUs to use within the cpuset. Default is to use any CPU available.
295
-	Cpus *string `json:"cpus,omitempty"`
295
+	Cpus string `json:"cpus,omitempty"`
296 296
 	// List of memory nodes in the cpuset. Default is to use any available memory node.
297
-	Mems *string `json:"mems,omitempty"`
297
+	Mems string `json:"mems,omitempty"`
298 298
 }
299 299
 
300
-// Pids for Linux cgroup 'pids' resource management (Linux 4.3)
301
-type Pids struct {
300
+// LinuxPids for Linux cgroup 'pids' resource management (Linux 4.3)
301
+type LinuxPids struct {
302 302
 	// Maximum number of PIDs. Default is "no limit".
303
-	Limit *int64 `json:"limit,omitempty"`
303
+	Limit int64 `json:"limit"`
304 304
 }
305 305
 
306
-// Network identification and priority configuration
307
-type Network struct {
306
+// LinuxNetwork identification and priority configuration
307
+type LinuxNetwork struct {
308 308
 	// Set class identifier for container's network packets
309 309
 	ClassID *uint32 `json:"classID,omitempty"`
310 310
 	// Set priority of network traffic for container
311
-	Priorities []InterfacePriority `json:"priorities,omitempty"`
311
+	Priorities []LinuxInterfacePriority `json:"priorities,omitempty"`
312 312
 }
313 313
 
314
-// Resources has container runtime resource constraints
315
-type Resources struct {
314
+// LinuxResources has container runtime resource constraints
315
+type LinuxResources struct {
316 316
 	// Devices configures the device whitelist.
317
-	Devices []DeviceCgroup `json:"devices,omitempty"`
317
+	Devices []LinuxDeviceCgroup `json:"devices,omitempty"`
318 318
 	// DisableOOMKiller disables the OOM killer for out of memory conditions
319 319
 	DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
320 320
 	// Specify an oom_score_adj for the container.
321 321
 	OOMScoreAdj *int `json:"oomScoreAdj,omitempty"`
322 322
 	// Memory restriction configuration
323
-	Memory *Memory `json:"memory,omitempty"`
323
+	Memory *LinuxMemory `json:"memory,omitempty"`
324 324
 	// CPU resource restriction configuration
325
-	CPU *CPU `json:"cpu,omitempty"`
325
+	CPU *LinuxCPU `json:"cpu,omitempty"`
326 326
 	// Task resource restriction configuration.
327
-	Pids *Pids `json:"pids,omitempty"`
327
+	Pids *LinuxPids `json:"pids,omitempty"`
328 328
 	// BlockIO restriction configuration
329
-	BlockIO *BlockIO `json:"blockIO,omitempty"`
329
+	BlockIO *LinuxBlockIO `json:"blockIO,omitempty"`
330 330
 	// Hugetlb limit (in bytes)
331
-	HugepageLimits []HugepageLimit `json:"hugepageLimits,omitempty"`
331
+	HugepageLimits []LinuxHugepageLimit `json:"hugepageLimits,omitempty"`
332 332
 	// Network restriction configuration
333
-	Network *Network `json:"network,omitempty"`
333
+	Network *LinuxNetwork `json:"network,omitempty"`
334 334
 }
335 335
 
336
-// Device represents the mknod information for a Linux special device file
337
-type Device struct {
336
+// LinuxDevice represents the mknod information for a Linux special device file
337
+type LinuxDevice struct {
338 338
 	// Path to the device.
339 339
 	Path string `json:"path"`
340 340
 	// Device type, block, char, etc.
... ...
@@ -351,25 +366,18 @@ type Device struct {
351 351
 	GID *uint32 `json:"gid,omitempty"`
352 352
 }
353 353
 
354
-// DeviceCgroup represents a device rule for the whitelist controller
355
-type DeviceCgroup struct {
354
+// LinuxDeviceCgroup represents a device rule for the whitelist controller
355
+type LinuxDeviceCgroup struct {
356 356
 	// Allow or deny
357 357
 	Allow bool `json:"allow"`
358 358
 	// Device type, block, char, etc.
359
-	Type *string `json:"type,omitempty"`
359
+	Type string `json:"type,omitempty"`
360 360
 	// Major is the device's major number.
361 361
 	Major *int64 `json:"major,omitempty"`
362 362
 	// Minor is the device's minor number.
363 363
 	Minor *int64 `json:"minor,omitempty"`
364 364
 	// Cgroup access permissions format, rwm.
365
-	Access *string `json:"access,omitempty"`
366
-}
367
-
368
-// Seccomp represents syscall restrictions
369
-type Seccomp struct {
370
-	DefaultAction Action    `json:"defaultAction"`
371
-	Architectures []Arch    `json:"architectures"`
372
-	Syscalls      []Syscall `json:"syscalls,omitempty"`
365
+	Access string `json:"access,omitempty"`
373 366
 }
374 367
 
375 368
 // Solaris contains platform specific configuration for Solaris application containers.
... ...
@@ -381,26 +389,26 @@ type Solaris struct {
381 381
 	// The maximum amount of shared memory allowed for this container.
382 382
 	MaxShmMemory string `json:"maxShmMemory,omitempty"`
383 383
 	// Specification for automatic creation of network resources for this container.
384
-	Anet []Anet `json:"anet,omitempty"`
384
+	Anet []SolarisAnet `json:"anet,omitempty"`
385 385
 	// Set limit on the amount of CPU time that can be used by container.
386
-	CappedCPU *CappedCPU `json:"cappedCPU,omitempty"`
386
+	CappedCPU *SolarisCappedCPU `json:"cappedCPU,omitempty"`
387 387
 	// The physical and swap caps on the memory that can be used by this container.
388
-	CappedMemory *CappedMemory `json:"cappedMemory,omitempty"`
388
+	CappedMemory *SolarisCappedMemory `json:"cappedMemory,omitempty"`
389 389
 }
390 390
 
391
-// CappedCPU allows users to set limit on the amount of CPU time that can be used by container.
392
-type CappedCPU struct {
391
+// SolarisCappedCPU allows users to set limit on the amount of CPU time that can be used by container.
392
+type SolarisCappedCPU struct {
393 393
 	Ncpus string `json:"ncpus,omitempty"`
394 394
 }
395 395
 
396
-// CappedMemory allows users to set the physical and swap caps on the memory that can be used by this container.
397
-type CappedMemory struct {
396
+// SolarisCappedMemory allows users to set the physical and swap caps on the memory that can be used by this container.
397
+type SolarisCappedMemory struct {
398 398
 	Physical string `json:"physical,omitempty"`
399 399
 	Swap     string `json:"swap,omitempty"`
400 400
 }
401 401
 
402
-// Anet provides the specification for automatic creation of network resources for this container.
403
-type Anet struct {
402
+// SolarisAnet provides the specification for automatic creation of network resources for this container.
403
+type SolarisAnet struct {
404 404
 	// Specify a name for the automatically created VNIC datalink.
405 405
 	Linkname string `json:"linkname,omitempty"`
406 406
 	// Specify the link over which the VNIC will be created.
... ...
@@ -469,6 +477,13 @@ type WindowsNetworkResources struct {
469 469
 	EgressBandwidth *uint64 `json:"egressBandwidth,omitempty"`
470 470
 }
471 471
 
472
+// LinuxSeccomp represents syscall restrictions
473
+type LinuxSeccomp struct {
474
+	DefaultAction LinuxSeccompAction `json:"defaultAction"`
475
+	Architectures []Arch             `json:"architectures,omitempty"`
476
+	Syscalls      []LinuxSyscall     `json:"syscalls"`
477
+}
478
+
472 479
 // Arch used for additional architectures
473 480
 type Arch string
474 481
 
... ...
@@ -491,45 +506,48 @@ const (
491 491
 	ArchPPC64LE     Arch = "SCMP_ARCH_PPC64LE"
492 492
 	ArchS390        Arch = "SCMP_ARCH_S390"
493 493
 	ArchS390X       Arch = "SCMP_ARCH_S390X"
494
+	ArchPARISC      Arch = "SCMP_ARCH_PARISC"
495
+	ArchPARISC64    Arch = "SCMP_ARCH_PARISC64"
494 496
 )
495 497
 
496
-// Action taken upon Seccomp rule match
497
-type Action string
498
+// LinuxSeccompAction taken upon Seccomp rule match
499
+type LinuxSeccompAction string
498 500
 
499 501
 // Define actions for Seccomp rules
500 502
 const (
501
-	ActKill  Action = "SCMP_ACT_KILL"
502
-	ActTrap  Action = "SCMP_ACT_TRAP"
503
-	ActErrno Action = "SCMP_ACT_ERRNO"
504
-	ActTrace Action = "SCMP_ACT_TRACE"
505
-	ActAllow Action = "SCMP_ACT_ALLOW"
503
+	ActKill  LinuxSeccompAction = "SCMP_ACT_KILL"
504
+	ActTrap  LinuxSeccompAction = "SCMP_ACT_TRAP"
505
+	ActErrno LinuxSeccompAction = "SCMP_ACT_ERRNO"
506
+	ActTrace LinuxSeccompAction = "SCMP_ACT_TRACE"
507
+	ActAllow LinuxSeccompAction = "SCMP_ACT_ALLOW"
506 508
 )
507 509
 
508
-// Operator used to match syscall arguments in Seccomp
509
-type Operator string
510
+// LinuxSeccompOperator used to match syscall arguments in Seccomp
511
+type LinuxSeccompOperator string
510 512
 
511 513
 // Define operators for syscall arguments in Seccomp
512 514
 const (
513
-	OpNotEqual     Operator = "SCMP_CMP_NE"
514
-	OpLessThan     Operator = "SCMP_CMP_LT"
515
-	OpLessEqual    Operator = "SCMP_CMP_LE"
516
-	OpEqualTo      Operator = "SCMP_CMP_EQ"
517
-	OpGreaterEqual Operator = "SCMP_CMP_GE"
518
-	OpGreaterThan  Operator = "SCMP_CMP_GT"
519
-	OpMaskedEqual  Operator = "SCMP_CMP_MASKED_EQ"
515
+	OpNotEqual     LinuxSeccompOperator = "SCMP_CMP_NE"
516
+	OpLessThan     LinuxSeccompOperator = "SCMP_CMP_LT"
517
+	OpLessEqual    LinuxSeccompOperator = "SCMP_CMP_LE"
518
+	OpEqualTo      LinuxSeccompOperator = "SCMP_CMP_EQ"
519
+	OpGreaterEqual LinuxSeccompOperator = "SCMP_CMP_GE"
520
+	OpGreaterThan  LinuxSeccompOperator = "SCMP_CMP_GT"
521
+	OpMaskedEqual  LinuxSeccompOperator = "SCMP_CMP_MASKED_EQ"
520 522
 )
521 523
 
522
-// Arg used for matching specific syscall arguments in Seccomp
523
-type Arg struct {
524
-	Index    uint     `json:"index"`
525
-	Value    uint64   `json:"value"`
526
-	ValueTwo uint64   `json:"valueTwo"`
527
-	Op       Operator `json:"op"`
524
+// LinuxSeccompArg used for matching specific syscall arguments in Seccomp
525
+type LinuxSeccompArg struct {
526
+	Index    uint                 `json:"index"`
527
+	Value    uint64               `json:"value"`
528
+	ValueTwo uint64               `json:"valueTwo"`
529
+	Op       LinuxSeccompOperator `json:"op"`
528 530
 }
529 531
 
530
-// Syscall is used to match a syscall in Seccomp
531
-type Syscall struct {
532
-	Name   string `json:"name"`
533
-	Action Action `json:"action"`
534
-	Args   []Arg  `json:"args,omitempty"`
532
+// LinuxSyscall is used to match a syscall in Seccomp
533
+type LinuxSyscall struct {
534
+	Names   []string           `json:"names"`
535
+	Action  LinuxSeccompAction `json:"action"`
536
+	Args    []LinuxSeccompArg  `json:"args"`
537
+	Comment string             `json:"comment"`
535 538
 }
... ...
@@ -3,15 +3,15 @@ package specs
3 3
 // State holds information about the runtime state of the container.
4 4
 type State struct {
5 5
 	// Version is the version of the specification that is supported.
6
-	Version string `json:"version"`
6
+	Version string `json:"ociVersion"`
7 7
 	// ID is the container ID
8 8
 	ID string `json:"id"`
9
-	// Status is the runtime state of the container.
9
+	// Status is the runtime status of the container.
10 10
 	Status string `json:"status"`
11 11
 	// Pid is the process ID for the container process.
12 12
 	Pid int `json:"pid"`
13
-	// BundlePath is the path to the container's bundle directory.
14
-	BundlePath string `json:"bundlePath"`
15
-	// Annotations are the annotations associated with the container.
16
-	Annotations map[string]string `json:"annotations"`
13
+	// Bundle is the path to the container's bundle directory.
14
+	Bundle string `json:"bundle"`
15
+	// Annotations are key values associated with the container.
16
+	Annotations map[string]string `json:"annotations,omitempty"`
17 17
 }
... ...
@@ -11,7 +11,7 @@ const (
11 11
 	VersionPatch = 0
12 12
 
13 13
 	// VersionDev indicates development branch. Releases will be empty string.
14
-	VersionDev = "-rc2-dev"
14
+	VersionDev = "-rc5"
15 15
 )
16 16
 
17 17
 // Version is the specification version that the package types support.
... ...
@@ -24,28 +24,3 @@ please note that a Google account is not required to subscribe to the mailing
24 24
 list.
25 25
 
26 26
 	-> https://groups.google.com/d/forum/libseccomp
27
-
28
-Documentation is also available at:
29
-
30
-	-> https://godoc.org/github.com/seccomp/libseccomp-golang
31
-
32
-* Installing the package
33
-
34
-The libseccomp-golang bindings require at least Go v1.2.1 and GCC v4.8.4;
35
-earlier versions may yield unpredictable results.  If you meet these
36
-requirements you can install this package using the command below:
37
-
38
-	$ go get github.com/seccomp/libseccomp-golang
39
-
40
-* Testing the Library
41
-
42
-A number of tests and lint related recipes are provided in the Makefile, if
43
-you want to run the standard regression tests, you can excute the following:
44
-
45
-	$ make check
46
-
47
-In order to execute the 'make lint' recipe the 'golint' tool is needed, it
48
-can be found at:
49
-
50
-	-> https://github.com/golang/lint
51
-
... ...
@@ -27,28 +27,6 @@ import "C"
27 27
 
28 28
 // Exported types
29 29
 
30
-// VersionError denotes that the system libseccomp version is incompatible
31
-// with this package.
32
-type VersionError struct {
33
-	message string
34
-	minimum string
35
-}
36
-
37
-func (e VersionError) Error() string {
38
-	format := "Libseccomp version too low: "
39
-	if e.message != "" {
40
-		format += e.message + ": "
41
-	}
42
-	format += "minimum supported is "
43
-	if e.minimum != "" {
44
-		format += e.minimum + ": "
45
-	} else {
46
-		format += "2.1.0: "
47
-	}
48
-	format += "detected %d.%d.%d"
49
-	return fmt.Sprintf(format, verMajor, verMinor, verMicro)
50
-}
51
-
52 30
 // ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a
53 31
 // per-architecture basis.
54 32
 type ScmpArch uint
... ...
@@ -173,10 +151,6 @@ const (
173 173
 // GetArchFromString returns an ScmpArch constant from a string representing an
174 174
 // architecture
175 175
 func GetArchFromString(arch string) (ScmpArch, error) {
176
-	if err := ensureSupportedVersion(); err != nil {
177
-		return ArchInvalid, err
178
-	}
179
-
180 176
 	switch strings.ToLower(arch) {
181 177
 	case "x86":
182 178
 		return ArchX86, nil
... ...
@@ -364,10 +338,6 @@ func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) {
364 364
 // Returns the number of the syscall, or an error if no syscall with that name
365 365
 // was found.
366 366
 func GetSyscallFromName(name string) (ScmpSyscall, error) {
367
-	if err := ensureSupportedVersion(); err != nil {
368
-		return 0, err
369
-	}
370
-
371 367
 	cString := C.CString(name)
372 368
 	defer C.free(unsafe.Pointer(cString))
373 369
 
... ...
@@ -385,9 +355,6 @@ func GetSyscallFromName(name string) (ScmpSyscall, error) {
385 385
 // Returns the number of the syscall, or an error if an invalid architecture is
386 386
 // passed or a syscall with that name was not found.
387 387
 func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
388
-	if err := ensureSupportedVersion(); err != nil {
389
-		return 0, err
390
-	}
391 388
 	if err := sanitizeArch(arch); err != nil {
392 389
 		return 0, err
393 390
 	}
... ...
@@ -419,10 +386,6 @@ func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
419 419
 func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) {
420 420
 	var condStruct ScmpCondition
421 421
 
422
-	if err := ensureSupportedVersion(); err != nil {
423
-		return condStruct, err
424
-	}
425
-
426 422
 	if comparison == CompareInvalid {
427 423
 		return condStruct, fmt.Errorf("invalid comparison operator")
428 424
 	} else if arg > 5 {
... ...
@@ -450,10 +413,6 @@ func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCo
450 450
 // GetNativeArch returns architecture token representing the native kernel
451 451
 // architecture
452 452
 func GetNativeArch() (ScmpArch, error) {
453
-	if err := ensureSupportedVersion(); err != nil {
454
-		return ArchInvalid, err
455
-	}
456
-
457 453
 	arch := C.seccomp_arch_native()
458 454
 
459 455
 	return archFromNative(arch)
... ...
@@ -476,10 +435,6 @@ type ScmpFilter struct {
476 476
 // Returns a reference to a valid filter context, or nil and an error if the
477 477
 // filter context could not be created or an invalid default action was given.
478 478
 func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
479
-	if err := ensureSupportedVersion(); err != nil {
480
-		return nil, err
481
-	}
482
-
483 479
 	if err := sanitizeAction(defaultAction); err != nil {
484 480
 		return nil, err
485 481
 	}
... ...
@@ -7,6 +7,7 @@ package seccomp
7 7
 
8 8
 import (
9 9
 	"fmt"
10
+	"os"
10 11
 	"syscall"
11 12
 )
12 13
 
... ...
@@ -191,12 +192,12 @@ func checkVersionAbove(major, minor, micro int) bool {
191 191
 		(verMajor == major && verMinor == minor && verMicro >= micro)
192 192
 }
193 193
 
194
-// Ensure that the library is supported, i.e. >= 2.1.0.
195
-func ensureSupportedVersion() error {
194
+// Init function: Verify library version is appropriate
195
+func init() {
196 196
 	if !checkVersionAbove(2, 1, 0) {
197
-		return VersionError{}
197
+		fmt.Fprintf(os.Stderr, "Libseccomp version too low: minimum supported is 2.1.0, detected %d.%d.%d", C.C_VERSION_MAJOR, C.C_VERSION_MINOR, C.C_VERSION_MICRO)
198
+		os.Exit(-1)
198 199
 	}
199
-	return nil
200 200
 }
201 201
 
202 202
 // Filter helpers
... ...
@@ -216,10 +217,7 @@ func (f *ScmpFilter) getFilterAttr(attr scmpFilterAttr) (C.uint32_t, error) {
216 216
 	}
217 217
 
218 218
 	if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
219
-		return 0x0, VersionError{
220
-			message: "thread synchronization attribute is not supported",
221
-			minimum: "2.2.0",
222
-		}
219
+		return 0x0, fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
223 220
 	}
224 221
 
225 222
 	var attribute C.uint32_t
... ...
@@ -242,10 +240,7 @@ func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) error
242 242
 	}
243 243
 
244 244
 	if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
245
-		return VersionError{
246
-			message: "thread synchronization attribute is not supported",
247
-			minimum: "2.2.0",
248
-		}
245
+		return fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
249 246
 	}
250 247
 
251 248
 	retCode := C.seccomp_attr_set(f.filterCtx, attr.toNative(), value)
... ...
@@ -301,10 +296,7 @@ func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact b
301 301
 	} else {
302 302
 		// We don't support conditional filtering in library version v2.1
303 303
 		if !checkVersionAbove(2, 2, 1) {
304
-			return VersionError{
305
-				message: "conditional filtering is not supported",
306
-				minimum: "2.2.1",
307
-			}
304
+			return fmt.Errorf("conditional filtering requires libseccomp version >= 2.2.1")
308 305
 		}
309 306
 
310 307
 		for _, cond := range conds {