Update moby to runc and oci 1.0 runtime final rc

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2017-04-27 14:52:47 -07:00
parent b61ffbfb52
commit 005506d36c
39 changed files with 907 additions and 751 deletions

View file

@ -64,8 +64,8 @@ const (
cgroupSystemdDriver = "systemd"
)
func getMemoryResources(config containertypes.Resources) *specs.Memory {
memory := specs.Memory{}
func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory {
memory := specs.LinuxMemory{}
if config.Memory > 0 {
limit := uint64(config.Memory)
@ -77,7 +77,7 @@ func getMemoryResources(config containertypes.Resources) *specs.Memory {
memory.Reservation = &reservation
}
if config.MemorySwap != 0 {
if config.MemorySwap > 0 {
swap := uint64(config.MemorySwap)
memory.Swap = &swap
}
@ -95,28 +95,29 @@ func getMemoryResources(config containertypes.Resources) *specs.Memory {
return &memory
}
func getCPUResources(config containertypes.Resources) *specs.CPU {
cpu := specs.CPU{}
func getCPUResources(config containertypes.Resources) (*specs.LinuxCPU, error) {
cpu := specs.LinuxCPU{}
if config.CPUShares != 0 {
if config.CPUShares < 0 {
return nil, fmt.Errorf("shares: invalid argument")
}
if config.CPUShares >= 0 {
shares := uint64(config.CPUShares)
cpu.Shares = &shares
}
if config.CpusetCpus != "" {
cpuset := config.CpusetCpus
cpu.Cpus = &cpuset
cpu.Cpus = config.CpusetCpus
}
if config.CpusetMems != "" {
cpuset := config.CpusetMems
cpu.Mems = &cpuset
cpu.Mems = config.CpusetMems
}
if config.NanoCPUs > 0 {
// https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt
period := uint64(100 * time.Millisecond / time.Microsecond)
quota := uint64(config.NanoCPUs) * period / 1e9
quota := config.NanoCPUs * int64(period) / 1e9
cpu.Period = &period
cpu.Quota = &quota
}
@ -127,8 +128,8 @@ func getCPUResources(config containertypes.Resources) *specs.CPU {
}
if config.CPUQuota != 0 {
quota := uint64(config.CPUQuota)
cpu.Quota = &quota
q := config.CPUQuota
cpu.Quota = &q
}
if config.CPURealtimePeriod != 0 {
@ -137,23 +138,23 @@ func getCPUResources(config containertypes.Resources) *specs.CPU {
}
if config.CPURealtimeRuntime != 0 {
runtime := uint64(config.CPURealtimeRuntime)
cpu.RealtimeRuntime = &runtime
c := config.CPURealtimeRuntime
cpu.RealtimeRuntime = &c
}
return &cpu
return &cpu, nil
}
func getBlkioWeightDevices(config containertypes.Resources) ([]specs.WeightDevice, error) {
func getBlkioWeightDevices(config containertypes.Resources) ([]specs.LinuxWeightDevice, error) {
var stat syscall.Stat_t
var blkioWeightDevices []specs.WeightDevice
var blkioWeightDevices []specs.LinuxWeightDevice
for _, weightDevice := range config.BlkioWeightDevice {
if err := syscall.Stat(weightDevice.Path, &stat); err != nil {
return nil, err
}
weight := weightDevice.Weight
d := specs.WeightDevice{Weight: &weight}
d := specs.LinuxWeightDevice{Weight: &weight}
d.Major = int64(stat.Rdev / 256)
d.Minor = int64(stat.Rdev % 256)
blkioWeightDevices = append(blkioWeightDevices, d)
@ -178,6 +179,10 @@ func parseSecurityOpt(container *container.Container, config *containertypes.Hos
container.NoNewPrivileges = true
continue
}
if opt == "disable" {
labelOpts = append(labelOpts, "disable")
continue
}
var con []string
if strings.Contains(opt, "=") {
@ -186,7 +191,6 @@ func parseSecurityOpt(container *container.Container, config *containertypes.Hos
con = strings.SplitN(opt, ":", 2)
logrus.Warn("Security options with `:` as a separator are deprecated and will be completely unsupported in 17.04, use `=` instead.")
}
if len(con) != 2 {
return fmt.Errorf("invalid --security-opt 1: %q", opt)
}
@ -213,16 +217,15 @@ func parseSecurityOpt(container *container.Container, config *containertypes.Hos
return err
}
func getBlkioThrottleDevices(devs []*blkiodev.ThrottleDevice) ([]specs.ThrottleDevice, error) {
var throttleDevices []specs.ThrottleDevice
func getBlkioThrottleDevices(devs []*blkiodev.ThrottleDevice) ([]specs.LinuxThrottleDevice, error) {
var throttleDevices []specs.LinuxThrottleDevice
var stat syscall.Stat_t
for _, d := range devs {
if err := syscall.Stat(d.Path, &stat); err != nil {
return nil, err
}
rate := d.Rate
d := specs.ThrottleDevice{Rate: &rate}
d := specs.LinuxThrottleDevice{Rate: d.Rate}
d.Major = int64(stat.Rdev / 256)
d.Minor = int64(stat.Rdev % 256)
throttleDevices = append(throttleDevices, d)

View file

@ -56,13 +56,16 @@ func setResources(s *specs.Spec, r containertypes.Resources) error {
}
memoryRes := getMemoryResources(r)
cpuRes := getCPUResources(r)
cpuRes, err := getCPUResources(r)
if err != nil {
return err
}
blkioWeight := r.BlkioWeight
specResources := &specs.Resources{
specResources := &specs.LinuxResources{
Memory: memoryRes,
CPU: cpuRes,
BlockIO: &specs.BlockIO{
BlockIO: &specs.LinuxBlockIO{
Weight: &blkioWeight,
WeightDevice: weightDevices,
ThrottleReadBpsDevice: readBpsDevice,
@ -71,8 +74,8 @@ func setResources(s *specs.Spec, r containertypes.Resources) error {
ThrottleWriteIOPSDevice: writeIOpsDevice,
},
DisableOOMKiller: r.OomKillDisable,
Pids: &specs.Pids{
Limit: &r.PidsLimit,
Pids: &specs.LinuxPids{
Limit: r.PidsLimit,
},
}
@ -86,7 +89,7 @@ func setResources(s *specs.Spec, r containertypes.Resources) error {
func setDevices(s *specs.Spec, c *container.Container) error {
// Build lists of devices allowed and created within the container.
var devs []specs.Device
var devs []specs.LinuxDevice
devPermissions := s.Linux.Resources.Devices
if c.HostConfig.Privileged {
hostDevices, err := devices.HostDevices()
@ -96,11 +99,10 @@ func setDevices(s *specs.Spec, c *container.Container) error {
for _, d := range hostDevices {
devs = append(devs, oci.Device(d))
}
rwm := "rwm"
devPermissions = []specs.DeviceCgroup{
devPermissions = []specs.LinuxDeviceCgroup{
{
Allow: true,
Access: &rwm,
Access: "rwm",
},
}
} else {
@ -120,10 +122,10 @@ func setDevices(s *specs.Spec, c *container.Container) error {
}
matches := ss[0]
dPermissions := specs.DeviceCgroup{
dPermissions := specs.LinuxDeviceCgroup{
Allow: true,
Type: &matches[1],
Access: &matches[4],
Type: matches[1],
Access: matches[4],
}
if matches[2] == "*" {
major := int64(-1)
@ -155,14 +157,14 @@ func setDevices(s *specs.Spec, c *container.Container) error {
}
func setRlimits(daemon *Daemon, s *specs.Spec, c *container.Container) error {
var rlimits []specs.Rlimit
var rlimits []specs.LinuxRlimit
// We want to leave the original HostConfig alone so make a copy here
hostConfig := *c.HostConfig
// Merge with the daemon defaults
daemon.mergeUlimits(&hostConfig)
for _, ul := range hostConfig.Ulimits {
rlimits = append(rlimits, specs.Rlimit{
rlimits = append(rlimits, specs.LinuxRlimit{
Type: "RLIMIT_" + strings.ToUpper(ul.Name),
Soft: uint64(ul.Soft),
Hard: uint64(ul.Hard),
@ -237,7 +239,7 @@ func getUser(c *container.Container, username string) (uint32, uint32, []uint32,
return uid, gid, additionalGids, nil
}
func setNamespace(s *specs.Spec, ns specs.Namespace) {
func setNamespace(s *specs.Spec, ns specs.LinuxNamespace) {
for i, n := range s.Linux.Namespaces {
if n.Type == ns.Type {
s.Linux.Namespaces[i] = ns
@ -253,12 +255,15 @@ func setCapabilities(s *specs.Spec, c *container.Container) error {
if c.HostConfig.Privileged {
caplist = caps.GetAllCapabilities()
} else {
caplist, err = caps.TweakCapabilities(s.Process.Capabilities, c.HostConfig.CapAdd, c.HostConfig.CapDrop)
caplist, err = caps.TweakCapabilities(s.Process.Capabilities.Effective, c.HostConfig.CapAdd, c.HostConfig.CapDrop)
if err != nil {
return err
}
}
s.Process.Capabilities = caplist
s.Process.Capabilities.Effective = caplist
s.Process.Capabilities.Bounding = caplist
s.Process.Capabilities.Permitted = caplist
s.Process.Capabilities.Inheritable = caplist
return nil
}
@ -269,7 +274,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
uidMap, gidMap := daemon.GetUIDGIDMaps()
if uidMap != nil {
userNS = true
ns := specs.Namespace{Type: "user"}
ns := specs.LinuxNamespace{Type: "user"}
setNamespace(s, ns)
s.Linux.UIDMappings = specMapping(uidMap)
s.Linux.GIDMappings = specMapping(gidMap)
@ -277,7 +282,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
}
// network
if !c.Config.NetworkDisabled {
ns := specs.Namespace{Type: "network"}
ns := specs.LinuxNamespace{Type: "network"}
parts := strings.SplitN(string(c.HostConfig.NetworkMode), ":", 2)
if parts[0] == "container" {
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
ns.Path = fmt.Sprintf("/proc/%d/ns/net", nc.State.GetPID())
if userNS {
// to share a net namespace, they must also share a user namespace
nsUser := specs.Namespace{Type: "user"}
nsUser := specs.LinuxNamespace{Type: "user"}
nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", nc.State.GetPID())
setNamespace(s, nsUser)
}
@ -298,7 +303,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
}
// ipc
if c.HostConfig.IpcMode.IsContainer() {
ns := specs.Namespace{Type: "ipc"}
ns := specs.LinuxNamespace{Type: "ipc"}
ic, err := daemon.getIpcContainer(c)
if err != nil {
return err
@ -307,19 +312,19 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
setNamespace(s, ns)
if userNS {
// to share an IPC namespace, they must also share a user namespace
nsUser := specs.Namespace{Type: "user"}
nsUser := specs.LinuxNamespace{Type: "user"}
nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", ic.State.GetPID())
setNamespace(s, nsUser)
}
} else if c.HostConfig.IpcMode.IsHost() {
oci.RemoveNamespace(s, specs.NamespaceType("ipc"))
oci.RemoveNamespace(s, specs.LinuxNamespaceType("ipc"))
} else {
ns := specs.Namespace{Type: "ipc"}
ns := specs.LinuxNamespace{Type: "ipc"}
setNamespace(s, ns)
}
// pid
if c.HostConfig.PidMode.IsContainer() {
ns := specs.Namespace{Type: "pid"}
ns := specs.LinuxNamespace{Type: "pid"}
pc, err := daemon.getPidContainer(c)
if err != nil {
return err
@ -328,29 +333,29 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error
setNamespace(s, ns)
if userNS {
// to share a PID namespace, they must also share a user namespace
nsUser := specs.Namespace{Type: "user"}
nsUser := specs.LinuxNamespace{Type: "user"}
nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", pc.State.GetPID())
setNamespace(s, nsUser)
}
} else if c.HostConfig.PidMode.IsHost() {
oci.RemoveNamespace(s, specs.NamespaceType("pid"))
oci.RemoveNamespace(s, specs.LinuxNamespaceType("pid"))
} else {
ns := specs.Namespace{Type: "pid"}
ns := specs.LinuxNamespace{Type: "pid"}
setNamespace(s, ns)
}
// uts
if c.HostConfig.UTSMode.IsHost() {
oci.RemoveNamespace(s, specs.NamespaceType("uts"))
oci.RemoveNamespace(s, specs.LinuxNamespaceType("uts"))
s.Hostname = ""
}
return nil
}
func specMapping(s []idtools.IDMap) []specs.IDMapping {
var ids []specs.IDMapping
func specMapping(s []idtools.IDMap) []specs.LinuxIDMapping {
var ids []specs.LinuxIDMapping
for _, item := range s {
ids = append(ids, specs.IDMapping{
ids = append(ids, specs.LinuxIDMapping{
HostID: uint32(item.HostID),
ContainerID: uint32(item.ContainerID),
Size: uint32(item.Size),
@ -675,7 +680,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
} else {
cgroupsPath = filepath.Join(parent, c.ID)
}
s.Linux.CgroupsPath = &cgroupsPath
s.Linux.CgroupsPath = cgroupsPath
if err := setResources(&s, c.HostConfig.Resources); err != nil {
return nil, fmt.Errorf("linux runtime spec resources: %v", err)
@ -683,13 +688,13 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
s.Linux.Resources.OOMScoreAdj = &c.HostConfig.OomScoreAdj
s.Linux.Sysctl = c.HostConfig.Sysctls
p := *s.Linux.CgroupsPath
p := s.Linux.CgroupsPath
if useSystemd {
initPath, err := cgroups.GetInitCgroupDir("cpu")
initPath, err := cgroups.GetInitCgroup("cpu")
if err != nil {
return nil, err
}
p, _ = cgroups.GetThisCgroupDir("cpu")
p, _ = cgroups.GetOwnCgroup("cpu")
if err != nil {
return nil, err
}
@ -761,7 +766,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
return nil, err
}
s.Hooks = specs.Hooks{
s.Hooks = &specs.Hooks{
Prestart: []specs.Hook{{
Path: target, // FIXME: cross-platform
Args: []string{"libnetwork-setkey", c.ID, daemon.netController.ID()},

View file

@ -14,7 +14,7 @@ import (
var supportsSeccomp = true
func setSeccomp(daemon *Daemon, rs *specs.Spec, c *container.Container) error {
var profile *specs.Seccomp
var profile *specs.LinuxSeccomp
var err error
if c.HostConfig.Privileged {

View file

@ -3,8 +3,8 @@
TOMLV_COMMIT=9baf8a8a9f2ed20a8e54160840c492f937eeaf9a
# When updating RUNC_COMMIT, also update runc in vendor.conf accordingly
RUNC_COMMIT=9c2d8d184e5da67c95d601382adf14862e4f2228
CONTAINERD_COMMIT=9048e5e50717ea4497b757314bad98ea3763c145
RUNC_COMMIT=992a5be178a62e026f4069f443c6164912adbf09
CONTAINERD_COMMIT=d24f39e203aa6be4944f06dd0fe38a618a36c764
TINI_COMMIT=949e6facb77383876aeff8a6944dde66b3089574
LIBNETWORK_COMMIT=7b2b1feb1de4817d522cc372af149ff48d25028e
VNDR_COMMIT=c56e082291115e369f77601f9c071dd0b87c7120

View file

@ -20,7 +20,7 @@ RUNC_BUILDTAGS="${RUNC_BUILDTAGS:-"seccomp apparmor selinux"}"
install_runc() {
echo "Install runc version $RUNC_COMMIT"
git clone https://github.com/docker/runc.git "$GOPATH/src/github.com/opencontainers/runc"
git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc"
cd "$GOPATH/src/github.com/opencontainers/runc"
git checkout -q "$RUNC_COMMIT"
make BUILDTAGS="$RUNC_BUILDTAGS" $1
@ -29,8 +29,8 @@ install_runc() {
install_containerd() {
echo "Install containerd version $CONTAINERD_COMMIT"
git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd"
cd "$GOPATH/src/github.com/docker/containerd"
git clone https://github.com/containerd/containerd.git "$GOPATH/src/github.com/containerd/containerd"
cd "$GOPATH/src/github.com/containerd/containerd"
git checkout -q "$CONTAINERD_COMMIT"
make $1
cp bin/containerd /usr/local/bin/docker-containerd

View file

@ -281,5 +281,5 @@ func (s *DockerSwarmSuite) TestServiceLogsTTY(c *check.C) {
result = icmd.RunCmd(cmd)
// for some reason there is carriage return in the output. i think this is
// just expected.
c.Assert(result, icmd.Matches, icmd.Expected{Out: "out\r\nerr\r\n"})
c.Assert(result, icmd.Matches, icmd.Expected{Out: "out\nerr\n"})
}

View file

@ -74,7 +74,10 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly
}
}
if specp.Capabilities != nil {
sp.Capabilities = specp.Capabilities
sp.Capabilities.Bounding = specp.Capabilities
sp.Capabilities.Effective = specp.Capabilities
sp.Capabilities.Inheritable = specp.Capabilities
sp.Capabilities.Permitted = specp.Capabilities
}
p := container.newProcess(processFriendlyName)
@ -94,7 +97,7 @@ func (clnt *client) AddProcess(ctx context.Context, containerID, processFriendly
Stdin: p.fifo(syscall.Stdin),
Stdout: p.fifo(syscall.Stdout),
Stderr: p.fifo(syscall.Stderr),
Capabilities: sp.Capabilities,
Capabilities: sp.Capabilities.Effective,
ApparmorProfile: sp.ApparmorProfile,
SelinuxLabel: sp.SelinuxLabel,
NoNewPrivileges: sp.NoNewPrivileges,

View file

@ -21,7 +21,7 @@ type Process struct {
// Capabilities are linux capabilities that are kept for the container.
Capabilities []string `json:"capabilities,omitempty"`
// Rlimits specifies rlimit options to apply to the process.
Rlimits []specs.Rlimit `json:"rlimits,omitempty"`
Rlimits []specs.LinuxRlimit `json:"rlimits,omitempty"`
// ApparmorProfile specifies the apparmor profile for the container.
ApparmorProfile *string `json:"apparmorProfile,omitempty"`
// SelinuxLabel specifies the selinux context that the container process is run as.

View file

@ -23,7 +23,7 @@ func getRootIDs(s specs.Spec) (int, int, error) {
return uid, gid, nil
}
func hostIDFromMap(id uint32, mp []specs.IDMapping) int {
func hostIDFromMap(id uint32, mp []specs.LinuxIDMapping) int {
for _, m := range mp {
if id >= m.ContainerID && id <= m.ContainerID+m.Size-1 {
return int(m.HostID + id - m.ContainerID)
@ -42,7 +42,7 @@ func systemPid(ctr *containerd.Container) uint32 {
return pid
}
func convertRlimits(sr []specs.Rlimit) (cr []*containerd.Rlimit) {
func convertRlimits(sr []specs.LinuxRlimit) (cr []*containerd.Rlimit) {
for _, r := range sr {
cr = append(cr, &containerd.Rlimit{
Type: r.Type,

View file

@ -7,11 +7,29 @@ import (
"github.com/opencontainers/runtime-spec/specs-go"
)
func sPtr(s string) *string { return &s }
func iPtr(i int64) *int64 { return &i }
func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
func defaultCapabilities() []string {
return []string{
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE",
}
}
// DefaultSpec returns default oci spec used by docker.
func DefaultSpec() specs.Spec {
s := specs.Spec{
@ -59,21 +77,11 @@ func DefaultSpec() specs.Spec {
Options: []string{"nosuid", "noexec", "nodev"},
},
}
s.Process.Capabilities = []string{
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE",
s.Process.Capabilities = &specs.LinuxCapabilities{
Bounding: defaultCapabilities(),
Permitted: defaultCapabilities(),
Inheritable: defaultCapabilities(),
Effective: defaultCapabilities(),
}
s.Linux = &specs.Linux{
@ -93,7 +101,7 @@ func DefaultSpec() specs.Spec {
"/proc/sys",
"/proc/sysrq-trigger",
},
Namespaces: []specs.Namespace{
Namespaces: []specs.LinuxNamespace{
{Type: "mount"},
{Type: "network"},
{Type: "uts"},
@ -104,61 +112,61 @@ func DefaultSpec() specs.Spec {
// null, zero, full, random, urandom, tty, console, and ptmx.
// ptmx is a bind-mount or symlink of the container's ptmx.
// See also: https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices
Devices: []specs.Device{},
Resources: &specs.Resources{
Devices: []specs.DeviceCgroup{
Devices: []specs.LinuxDevice{},
Resources: &specs.LinuxResources{
Devices: []specs.LinuxDeviceCgroup{
{
Allow: false,
Access: sPtr("rwm"),
Access: "rwm",
},
{
Allow: true,
Type: sPtr("c"),
Type: "c",
Major: iPtr(1),
Minor: iPtr(5),
Access: sPtr("rwm"),
Access: "rwm",
},
{
Allow: true,
Type: sPtr("c"),
Type: "c",
Major: iPtr(1),
Minor: iPtr(3),
Access: sPtr("rwm"),
Access: "rwm",
},
{
Allow: true,
Type: sPtr("c"),
Type: "c",
Major: iPtr(1),
Minor: iPtr(9),
Access: sPtr("rwm"),
Access: "rwm",
},
{
Allow: true,
Type: sPtr("c"),
Type: "c",
Major: iPtr(1),
Minor: iPtr(8),
Access: sPtr("rwm"),
Access: "rwm",
},
{
Allow: true,
Type: sPtr("c"),
Type: "c",
Major: iPtr(5),
Minor: iPtr(0),
Access: sPtr("rwm"),
Access: "rwm",
},
{
Allow: true,
Type: sPtr("c"),
Type: "c",
Major: iPtr(5),
Minor: iPtr(1),
Access: sPtr("rwm"),
Access: "rwm",
},
{
Allow: false,
Type: sPtr("c"),
Type: "c",
Major: iPtr(10),
Minor: iPtr(229),
Access: sPtr("rwm"),
Access: "rwm",
},
},
},

View file

@ -11,9 +11,9 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
)
// Device transforms a libcontainer configs.Device to a specs.Device object.
func Device(d *configs.Device) specs.Device {
return specs.Device{
// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
func Device(d *configs.Device) specs.LinuxDevice {
return specs.LinuxDevice{
Type: string(d.Type),
Path: d.Path,
Major: d.Major,
@ -24,19 +24,19 @@ func Device(d *configs.Device) specs.Device {
}
}
func deviceCgroup(d *configs.Device) specs.DeviceCgroup {
func deviceCgroup(d *configs.Device) specs.LinuxDeviceCgroup {
t := string(d.Type)
return specs.DeviceCgroup{
return specs.LinuxDeviceCgroup{
Allow: true,
Type: &t,
Type: t,
Major: &d.Major,
Minor: &d.Minor,
Access: &d.Permissions,
Access: d.Permissions,
}
}
// DevicesFromPath computes a list of devices and device permissions from paths (pathOnHost and pathInContainer) and cgroup permissions.
func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.Device, devPermissions []specs.DeviceCgroup, err error) {
func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.LinuxDevice, devPermissions []specs.LinuxDeviceCgroup, err error) {
resolvedPathOnHost := pathOnHost
// check if it is a symbolic link

View file

@ -11,10 +11,10 @@ import (
// Device transforms a libcontainer configs.Device to a specs.Device object.
// Not implemented
func Device(d *configs.Device) specs.Device { return specs.Device{} }
func Device(d *configs.Device) specs.LinuxDevice { return specs.LinuxDevice{} }
// DevicesFromPath computes a list of devices and device permissions from paths (pathOnHost and pathInContainer) and cgroup permissions.
// Not implemented
func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.Device, devPermissions []specs.DeviceCgroup, err error) {
func DevicesFromPath(pathOnHost, pathInContainer, cgroupPermissions string) (devs []specs.LinuxDevice, devPermissions []specs.LinuxDeviceCgroup, err error) {
return nil, nil, errors.New("oci/devices: unsupported platform")
}

View file

@ -3,7 +3,7 @@ package oci
import specs "github.com/opencontainers/runtime-spec/specs-go"
// RemoveNamespace removes the `nsType` namespace from OCI spec `s`
func RemoveNamespace(s *specs.Spec, nsType specs.NamespaceType) {
func RemoveNamespace(s *specs.Spec, nsType specs.LinuxNamespaceType) {
for i, n := range s.Linux.Namespaces {
if n.Type == nsType {
s.Linux.Namespaces = append(s.Linux.Namespaces[:i], s.Linux.Namespaces[i+1:]...)

View file

@ -27,6 +27,7 @@ func MakeRaw(fd uintptr) (*State, error) {
newState := oldState.termios
C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState)))
newState.Oflag = newState.Oflag | C.OPOST
if err := tcset(fd, &newState); err != 0 {
return nil, err
}

View file

@ -42,7 +42,7 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
if p.PluginObj.Config.Network.Type != "" {
// 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)
if p.PluginObj.Config.Network.Type == "host" {
oci.RemoveNamespace(&s, specs.NamespaceType("network"))
oci.RemoveNamespace(&s, specs.LinuxNamespaceType("network"))
}
etcHosts := "/etc/hosts"
resolvConf := "/etc/resolv.conf"
@ -61,11 +61,11 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
})
}
if p.PluginObj.Config.PidHost {
oci.RemoveNamespace(&s, specs.NamespaceType("pid"))
oci.RemoveNamespace(&s, specs.LinuxNamespaceType("pid"))
}
if p.PluginObj.Config.IpcHost {
oci.RemoveNamespace(&s, specs.NamespaceType("ipc"))
oci.RemoveNamespace(&s, specs.LinuxNamespaceType("ipc"))
}
for _, mnt := range mounts {
@ -95,8 +95,7 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
}
if p.PluginObj.Config.Linux.AllowAllDevices {
rwm := "rwm"
s.Linux.Resources.Devices = []specs.DeviceCgroup{{Allow: true, Access: &rwm}}
s.Linux.Resources.Devices = []specs.LinuxDeviceCgroup{{Allow: true, Access: "rwm"}}
}
for _, dev := range p.PluginObj.Settings.Devices {
path := *dev.Path
@ -122,7 +121,11 @@ func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
s.Process.Cwd = cwd
s.Process.Env = envs
s.Process.Capabilities = append(s.Process.Capabilities, p.PluginObj.Config.Linux.Capabilities...)
caps := s.Process.Capabilities
caps.Bounding = append(caps.Bounding, p.PluginObj.Config.Linux.Capabilities...)
caps.Permitted = append(caps.Permitted, p.PluginObj.Config.Linux.Capabilities...)
caps.Inheritable = append(caps.Inheritable, p.PluginObj.Config.Linux.Capabilities...)
caps.Effective = append(caps.Effective, p.PluginObj.Config.Linux.Capabilities...)
return &s, nil
}

View file

@ -16,12 +16,12 @@ import (
//go:generate go run -tags 'seccomp' generate.go
// GetDefaultProfile returns the default seccomp profile.
func GetDefaultProfile(rs *specs.Spec) (*specs.Seccomp, error) {
func GetDefaultProfile(rs *specs.Spec) (*specs.LinuxSeccomp, error) {
return setupSeccomp(DefaultProfile(), rs)
}
// LoadProfile takes a json string and decodes the seccomp profile.
func LoadProfile(body string, rs *specs.Spec) (*specs.Seccomp, error) {
func LoadProfile(body string, rs *specs.Spec) (*specs.LinuxSeccomp, error) {
var config types.Seccomp
if err := json.Unmarshal([]byte(body), &config); err != nil {
return nil, fmt.Errorf("Decoding seccomp profile failed: %v", err)
@ -39,7 +39,7 @@ var nativeToSeccomp = map[string]types.Arch{
"s390x": types.ArchS390X,
}
func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.Seccomp, error) {
func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, error) {
if config == nil {
return nil, nil
}
@ -49,7 +49,7 @@ func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.Seccomp, error)
return nil, nil
}
newConfig := &specs.Seccomp{}
newConfig := &specs.LinuxSeccomp{}
var arch string
var native, err = libseccomp.GetNativeArch()
@ -83,7 +83,7 @@ func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.Seccomp, error)
}
}
newConfig.DefaultAction = specs.Action(config.DefaultAction)
newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction)
Loop:
// Loop through all syscall blocks and convert them to libcontainer format after filtering them
@ -95,7 +95,7 @@ Loop:
}
if len(call.Excludes.Caps) > 0 {
for _, c := range call.Excludes.Caps {
if stringutils.InSlice(rs.Process.Capabilities, c) {
if stringutils.InSlice(rs.Process.Capabilities.Effective, c) {
continue Loop
}
}
@ -107,7 +107,7 @@ Loop:
}
if len(call.Includes.Caps) > 0 {
for _, c := range call.Includes.Caps {
if !stringutils.InSlice(rs.Process.Capabilities, c) {
if !stringutils.InSlice(rs.Process.Capabilities.Effective, c) {
continue Loop
}
}
@ -129,19 +129,19 @@ Loop:
return newConfig, nil
}
func createSpecsSyscall(name string, action types.Action, args []*types.Arg) specs.Syscall {
newCall := specs.Syscall{
Name: name,
Action: specs.Action(action),
func createSpecsSyscall(name string, action types.Action, args []*types.Arg) specs.LinuxSyscall {
newCall := specs.LinuxSyscall{
Names: []string{name},
Action: specs.LinuxSeccompAction(action),
}
// Loop through all the arguments of the syscall and convert them
for _, arg := range args {
newArg := specs.Arg{
newArg := specs.LinuxSeccompArg{
Index: arg.Index,
Value: arg.Value,
ValueTwo: arg.ValueTwo,
Op: specs.Operator(arg.Op),
Op: specs.LinuxSeccompOperator(arg.Op),
}
newCall.Args = append(newCall.Args, newArg)

View file

@ -65,9 +65,11 @@ github.com/docker/go v1.5.1-1-1-gbaf439e
github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
# When updating, also update RUNC_COMMIT in hack/dockerfile/binaries-commits accordingly
github.com/opencontainers/runc 9c2d8d184e5da67c95d601382adf14862e4f2228 https://github.com/docker/runc.git # libcontainer
github.com/opencontainers/runtime-spec 1c7c27d043c2a5e513a44084d2b10d77d1402b8c # specs
github.com/seccomp/libseccomp-golang v0.9.0
github.com/opencontainers/runc b6b70e53451794e8333e9b602cc096b47a20bd0f
github.com/opencontainers/runtime-spec v1.0.0-rc5 # specs
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
# libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
github.com/coreos/go-systemd v4
github.com/godbus/dbus v4.0.0
@ -104,7 +106,7 @@ google.golang.org/genproto b3e7c2fb04031add52c4817f53f43757ccbf9c18
github.com/docker/docker-credential-helpers v0.5.0
# containerd
github.com/docker/containerd 9048e5e50717ea4497b757314bad98ea3763c145
github.com/docker/containerd d24f39e203aa6be4944f06dd0fe38a618a36c764
github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
# cluster
@ -144,4 +146,4 @@ github.com/xeipuuv/gojsonpointer e0fe6f68307607d540ed8eac07a342c33fa1b54a
github.com/xeipuuv/gojsonreference e02fc20de94c78484cd5ffb007f8af96be030a45
github.com/xeipuuv/gojsonschema 93e72a773fade158921402d6a24c819b48aba29d
gopkg.in/yaml.v2 4c78c975fe7c825c6d1466c42be594d1d6f3aba6
github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d
github.com/opencontainers/selinux v1.0.0-rc1

View file

@ -6,7 +6,7 @@ as checkpoint and restore for cloning and live migration of containers.
## Getting started
The easiest way to start using containerd is to download binaries from the [releases page](https://github.com/docker/containerd/releases).
The easiest way to start using containerd is to download binaries from the [releases page](https://github.com/containerd/containerd/releases).
The included `ctr` command-line tool allows you interact with the containerd daemon:

View file

@ -1051,6 +1051,7 @@ type UpdateResource struct {
BlkioThrottleWriteBpsDevice []*ThrottleDevice `protobuf:"bytes,15,rep,name=blkioThrottleWriteBpsDevice" json:"blkioThrottleWriteBpsDevice,omitempty"`
BlkioThrottleReadIopsDevice []*ThrottleDevice `protobuf:"bytes,16,rep,name=blkioThrottleReadIopsDevice" json:"blkioThrottleReadIopsDevice,omitempty"`
BlkioThrottleWriteIopsDevice []*ThrottleDevice `protobuf:"bytes,17,rep,name=blkioThrottleWriteIopsDevice" json:"blkioThrottleWriteIopsDevice,omitempty"`
PidsLimit uint64 `protobuf:"varint,18,opt,name=pidsLimit" json:"pidsLimit,omitempty"`
}
func (m *UpdateResource) Reset() { *m = UpdateResource{} }
@ -1177,6 +1178,13 @@ func (m *UpdateResource) GetBlkioThrottleWriteIopsDevice() []*ThrottleDevice {
return nil
}
func (m *UpdateResource) GetPidsLimit() uint64 {
if m != nil {
return m.PidsLimit
}
return 0
}
type BlockIODevice struct {
Major int64 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"`
Minor int64 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"`
@ -1351,12 +1359,12 @@ type NetworkStats struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
RxBytes uint64 `protobuf:"varint,2,opt,name=rx_bytes,json=rxBytes" json:"rx_bytes,omitempty"`
Rx_Packets uint64 `protobuf:"varint,3,opt,name=rx_Packets,json=rxPackets" json:"rx_Packets,omitempty"`
RxErrors uint64 `protobuf:"varint,4,opt,name=Rx_errors,json=rxErrors" json:"Rx_errors,omitempty"`
RxDropped uint64 `protobuf:"varint,5,opt,name=Rx_dropped,json=rxDropped" json:"Rx_dropped,omitempty"`
TxBytes uint64 `protobuf:"varint,6,opt,name=Tx_bytes,json=txBytes" json:"Tx_bytes,omitempty"`
TxPackets uint64 `protobuf:"varint,7,opt,name=Tx_packets,json=txPackets" json:"Tx_packets,omitempty"`
TxErrors uint64 `protobuf:"varint,8,opt,name=Tx_errors,json=txErrors" json:"Tx_errors,omitempty"`
TxDropped uint64 `protobuf:"varint,9,opt,name=Tx_dropped,json=txDropped" json:"Tx_dropped,omitempty"`
RxErrors uint64 `protobuf:"varint,4,opt,name=Rx_errors,json=RxErrors" json:"Rx_errors,omitempty"`
RxDropped uint64 `protobuf:"varint,5,opt,name=Rx_dropped,json=RxDropped" json:"Rx_dropped,omitempty"`
TxBytes uint64 `protobuf:"varint,6,opt,name=Tx_bytes,json=TxBytes" json:"Tx_bytes,omitempty"`
TxPackets uint64 `protobuf:"varint,7,opt,name=Tx_packets,json=TxPackets" json:"Tx_packets,omitempty"`
TxErrors uint64 `protobuf:"varint,8,opt,name=Tx_errors,json=TxErrors" json:"Tx_errors,omitempty"`
TxDropped uint64 `protobuf:"varint,9,opt,name=Tx_dropped,json=TxDropped" json:"Tx_dropped,omitempty"`
}
func (m *NetworkStats) Reset() { *m = NetworkStats{} }
@ -2407,169 +2415,170 @@ var _API_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("api.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 2616 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x19, 0x4d, 0x6f, 0x1c, 0x49,
0x35, 0x33, 0xd3, 0x9e, 0xf1, 0xbc, 0xf9, 0xb0, 0xa7, 0xe2, 0xd8, 0x9d, 0xd9, 0xdd, 0xc4, 0xdb,
0x5a, 0x58, 0x03, 0x2b, 0x27, 0x38, 0x1b, 0x88, 0x58, 0x09, 0x29, 0xb1, 0xc3, 0x62, 0x36, 0x4e,
0x26, 0x6d, 0x9b, 0x08, 0x09, 0x69, 0xd4, 0xee, 0xae, 0xcc, 0x14, 0xee, 0xe9, 0xea, 0x54, 0x57,
0xdb, 0xe3, 0xcb, 0x1e, 0x38, 0xc0, 0x0d, 0xae, 0x48, 0x1c, 0xb9, 0x71, 0xe7, 0x00, 0x7f, 0x00,
0x89, 0x1f, 0xc2, 0x6d, 0xef, 0x1c, 0x51, 0x7d, 0x74, 0x77, 0xf5, 0x7c, 0x38, 0x09, 0x12, 0xe2,
0xc2, 0xa5, 0x55, 0xef, 0xd5, 0xfb, 0xaa, 0x57, 0xef, 0xbd, 0x7a, 0x55, 0x0d, 0x4d, 0x2f, 0x26,
0xbb, 0x31, 0xa3, 0x9c, 0xa2, 0x15, 0x7e, 0x15, 0xe3, 0xa4, 0x7f, 0x77, 0x44, 0xe9, 0x28, 0xc4,
0xf7, 0x24, 0xf2, 0x2c, 0x7d, 0x7d, 0x8f, 0x93, 0x09, 0x4e, 0xb8, 0x37, 0x89, 0x15, 0x9d, 0x73,
0x1b, 0xb6, 0xbe, 0xc4, 0xfc, 0x18, 0xb3, 0x0b, 0xcc, 0x7e, 0x8e, 0x59, 0x42, 0x68, 0xe4, 0xe2,
0x37, 0x29, 0x4e, 0xb8, 0x33, 0x05, 0x7b, 0x7e, 0x2a, 0x89, 0x69, 0x94, 0x60, 0xb4, 0x01, 0x2b,
0x13, 0xef, 0x57, 0x94, 0xd9, 0x95, 0xed, 0xca, 0x4e, 0xc7, 0x55, 0x80, 0xc4, 0x92, 0x88, 0x32,
0xbb, 0xaa, 0xb1, 0x02, 0x10, 0xd8, 0xd8, 0xe3, 0xfe, 0xd8, 0xae, 0x29, 0xac, 0x04, 0x50, 0x1f,
0x56, 0x19, 0xbe, 0x20, 0x42, 0xaa, 0x6d, 0x6d, 0x57, 0x76, 0x9a, 0x6e, 0x0e, 0x3b, 0xbf, 0xa9,
0xc0, 0xc6, 0x69, 0x1c, 0x78, 0x1c, 0x0f, 0x18, 0xf5, 0x71, 0x92, 0x68, 0x93, 0x50, 0x17, 0xaa,
0x24, 0x90, 0x3a, 0x9b, 0x6e, 0x95, 0x04, 0x68, 0x1d, 0x6a, 0x31, 0x09, 0xa4, 0xba, 0xa6, 0x2b,
0x86, 0xe8, 0x0e, 0x80, 0x1f, 0xd2, 0x04, 0x1f, 0xf3, 0x80, 0x44, 0x52, 0xe3, 0xaa, 0x6b, 0x60,
0x84, 0x31, 0x97, 0x24, 0xe0, 0x63, 0xa9, 0xb3, 0xe3, 0x2a, 0x00, 0x6d, 0x42, 0x7d, 0x8c, 0xc9,
0x68, 0xcc, 0xed, 0x15, 0x89, 0xd6, 0x90, 0xb3, 0x05, 0xb7, 0x66, 0xec, 0x50, 0xeb, 0x77, 0xfe,
0x51, 0x85, 0xcd, 0x7d, 0x86, 0x3d, 0x8e, 0xf7, 0x69, 0xc4, 0x3d, 0x12, 0x61, 0xb6, 0xcc, 0xc6,
0x3b, 0x00, 0x67, 0x69, 0x14, 0x84, 0x78, 0xe0, 0xf1, 0xb1, 0x36, 0xd5, 0xc0, 0x48, 0x8b, 0xc7,
0xd8, 0x3f, 0x8f, 0x29, 0x89, 0xb8, 0xb4, 0xb8, 0xe9, 0x1a, 0x18, 0x61, 0x71, 0x22, 0x17, 0xa3,
0xbc, 0xa4, 0x00, 0x61, 0x71, 0xc2, 0x03, 0x9a, 0x2a, 0x8b, 0x9b, 0xae, 0x86, 0x34, 0x1e, 0x33,
0x66, 0xd7, 0x73, 0x3c, 0x66, 0x4c, 0xe0, 0x43, 0xef, 0x0c, 0x87, 0x89, 0xdd, 0xd8, 0xae, 0x09,
0xbc, 0x82, 0xd0, 0x36, 0xb4, 0x22, 0x3a, 0x20, 0x17, 0x94, 0xbb, 0x94, 0x72, 0x7b, 0x55, 0x3a,
0xcc, 0x44, 0x21, 0x1b, 0x1a, 0x2c, 0x8d, 0x44, 0xdc, 0xd8, 0x4d, 0x29, 0x32, 0x03, 0x05, 0xaf,
0x1e, 0x3e, 0x66, 0xa3, 0xc4, 0x06, 0x29, 0xd8, 0x44, 0xa1, 0x4f, 0xa0, 0x53, 0xac, 0xe4, 0x80,
0x30, 0xbb, 0x25, 0x25, 0x94, 0x91, 0xce, 0x21, 0x6c, 0xcd, 0xf9, 0x52, 0xc7, 0xd9, 0x2e, 0x34,
0xfd, 0x0c, 0x29, 0x7d, 0xda, 0xda, 0x5b, 0xdf, 0x95, 0xa1, 0xbd, 0x5b, 0x10, 0x17, 0x24, 0xce,
0x21, 0x74, 0x8e, 0xc9, 0x28, 0xf2, 0xc2, 0x77, 0x8f, 0x18, 0xe1, 0x31, 0xc9, 0xa2, 0xe3, 0x53,
0x43, 0xce, 0x3a, 0x74, 0x33, 0x51, 0x7a, 0xd3, 0xff, 0x52, 0x83, 0xde, 0xe3, 0x20, 0x78, 0x4b,
0x4c, 0xf6, 0x61, 0x95, 0x63, 0x36, 0x21, 0x42, 0x62, 0x55, 0xba, 0x33, 0x87, 0xd1, 0x5d, 0xb0,
0xd2, 0x04, 0x33, 0xa9, 0xa9, 0xb5, 0xd7, 0xd2, 0x2b, 0x39, 0x4d, 0x30, 0x73, 0xe5, 0x04, 0x42,
0x60, 0x79, 0xc2, 0x97, 0x96, 0xf4, 0xa5, 0x1c, 0x0b, 0x93, 0x71, 0x74, 0x61, 0xaf, 0x48, 0x94,
0x18, 0x0a, 0x8c, 0x7f, 0x19, 0xe8, 0x1d, 0x16, 0xc3, 0x6c, 0x59, 0x8d, 0x62, 0x59, 0x79, 0xd8,
0xac, 0x2e, 0x0e, 0x9b, 0xe6, 0x92, 0xb0, 0x81, 0x52, 0xd8, 0x38, 0xd0, 0xf6, 0xbd, 0xd8, 0x3b,
0x23, 0x21, 0xe1, 0x04, 0x27, 0x76, 0x4b, 0x1a, 0x51, 0xc2, 0xa1, 0x1d, 0x58, 0xf3, 0xe2, 0xd8,
0x63, 0x13, 0xca, 0x06, 0x8c, 0xbe, 0x26, 0x21, 0xb6, 0xdb, 0x52, 0xc8, 0x2c, 0x5a, 0x48, 0x4b,
0x70, 0x48, 0xa2, 0x74, 0xfa, 0x4c, 0x44, 0x9f, 0xdd, 0x91, 0x64, 0x25, 0x9c, 0x90, 0x16, 0xd1,
0xe7, 0xf8, 0x72, 0xc0, 0xc8, 0x05, 0x09, 0xf1, 0x08, 0x27, 0x76, 0x57, 0x7a, 0x71, 0x16, 0x8d,
0x3e, 0x85, 0x06, 0x0b, 0xc9, 0x84, 0xf0, 0xc4, 0x5e, 0xdb, 0xae, 0xed, 0xb4, 0xf6, 0x3a, 0xda,
0x9f, 0xae, 0xc4, 0xba, 0xd9, 0xac, 0x73, 0x00, 0x75, 0x85, 0x12, 0xee, 0x15, 0x24, 0x7a, 0xb7,
0xe4, 0x58, 0xe0, 0x12, 0xfa, 0x9a, 0xcb, 0xbd, 0xb2, 0x5c, 0x39, 0x16, 0xb8, 0xb1, 0xc7, 0x02,
0xb9, 0x4f, 0x96, 0x2b, 0xc7, 0x8e, 0x0b, 0x96, 0xd8, 0x28, 0xe1, 0xea, 0x54, 0x6f, 0x78, 0xc7,
0x15, 0x43, 0x81, 0x19, 0xe9, 0x98, 0xea, 0xb8, 0x62, 0x88, 0xbe, 0x0d, 0x5d, 0x2f, 0x08, 0x08,
0x27, 0x34, 0xf2, 0xc2, 0x2f, 0x49, 0x90, 0xd8, 0xb5, 0xed, 0xda, 0x4e, 0xc7, 0x9d, 0xc1, 0x3a,
0x7b, 0x80, 0xcc, 0x80, 0xd2, 0x41, 0xff, 0x21, 0x34, 0x93, 0xab, 0x84, 0xe3, 0xc9, 0x20, 0xd7,
0x53, 0x20, 0x9c, 0x5f, 0x57, 0xf2, 0x74, 0xc9, 0xb3, 0x68, 0x59, 0x2c, 0x7e, 0xbf, 0x54, 0x5b,
0xaa, 0x32, 0xea, 0x7a, 0x59, 0xfe, 0x14, 0xdc, 0x66, 0xb9, 0x99, 0x4b, 0xd9, 0xda, 0xa2, 0x94,
0xed, 0x83, 0x3d, 0x6f, 0x83, 0x4e, 0x13, 0x1f, 0xb6, 0x0e, 0x70, 0x88, 0xdf, 0xc5, 0x3e, 0x04,
0x56, 0xe4, 0x4d, 0xb0, 0x4e, 0x47, 0x39, 0x7e, 0x77, 0x03, 0xe6, 0x95, 0x68, 0x03, 0x8e, 0xe0,
0xd6, 0x33, 0x92, 0xf0, 0xb7, 0xab, 0x9f, 0x53, 0x55, 0x5d, 0xa4, 0xea, 0x0f, 0x15, 0x80, 0x42,
0x56, 0x6e, 0x73, 0xc5, 0xb0, 0x19, 0x81, 0x85, 0xa7, 0x84, 0xeb, 0x7c, 0x97, 0x63, 0x11, 0x15,
0xdc, 0x8f, 0xf5, 0x11, 0x24, 0x86, 0xa2, 0x5e, 0xa6, 0x11, 0x99, 0x1e, 0x53, 0xff, 0x1c, 0xf3,
0x44, 0xd6, 0xf3, 0x55, 0xd7, 0x44, 0xc9, 0xa4, 0x1d, 0xe3, 0x30, 0x94, 0x45, 0x7d, 0xd5, 0x55,
0x80, 0xa8, 0xc0, 0x78, 0x12, 0xf3, 0xab, 0xe7, 0xc7, 0x76, 0x5d, 0xe6, 0x5f, 0x06, 0x3a, 0x47,
0xb0, 0x39, 0xbb, 0x52, 0x1d, 0x43, 0x0f, 0xa0, 0x55, 0xac, 0x22, 0xb1, 0x2b, 0x32, 0x41, 0x16,
0x6c, 0xbd, 0x49, 0xe5, 0xdc, 0x81, 0xf6, 0x31, 0xf7, 0x38, 0x5e, 0xe2, 0x2f, 0x67, 0x07, 0xba,
0x79, 0xd5, 0x95, 0x84, 0xaa, 0x6e, 0x78, 0x3c, 0x4d, 0x34, 0x95, 0x86, 0x9c, 0xbf, 0xd6, 0xa0,
0xa1, 0xc3, 0x3a, 0xab, 0x4d, 0x95, 0xa2, 0x36, 0xfd, 0x4f, 0x4a, 0x64, 0x29, 0xab, 0x1a, 0x33,
0x59, 0xf5, 0xff, 0x72, 0x59, 0x94, 0xcb, 0xbf, 0x57, 0xa0, 0x99, 0x6f, 0xf3, 0x7b, 0xb7, 0x33,
0x9f, 0x41, 0x33, 0x56, 0x1b, 0x8f, 0x55, 0xd5, 0x6b, 0xed, 0x75, 0xb5, 0xa2, 0xac, 0xce, 0x15,
0x04, 0x46, 0xfc, 0x58, 0x66, 0xfc, 0x18, 0xed, 0xca, 0x4a, 0xa9, 0x5d, 0x41, 0x60, 0xc5, 0xa2,
0x9c, 0xd6, 0x65, 0x39, 0x95, 0x63, 0xb3, 0x41, 0x69, 0x94, 0x1a, 0x14, 0xe7, 0x21, 0x34, 0x8e,
0x3c, 0x7f, 0x4c, 0x22, 0x99, 0xa1, 0x7e, 0xac, 0xc3, 0xb4, 0xe3, 0xca, 0xb1, 0x50, 0x32, 0xc1,
0x13, 0xca, 0xae, 0x74, 0xed, 0xd7, 0x90, 0x73, 0x0e, 0x1d, 0x9d, 0x06, 0x3a, 0x99, 0xee, 0x03,
0xe4, 0x2d, 0x46, 0x96, 0x4b, 0xf3, 0x6d, 0x88, 0x41, 0x83, 0x76, 0xa0, 0x31, 0x51, 0x9a, 0x75,
0xd5, 0xcd, 0x7c, 0xa0, 0xed, 0x71, 0xb3, 0x69, 0xe7, 0xb7, 0x15, 0xd8, 0x54, 0x3d, 0xe6, 0x5b,
0x3b, 0xc9, 0xc5, 0xbd, 0x8b, 0x72, 0x5f, 0xad, 0xe4, 0xbe, 0x07, 0xd0, 0x64, 0x38, 0xa1, 0x29,
0xf3, 0xb1, 0xf2, 0x6c, 0x6b, 0xef, 0x56, 0x96, 0x49, 0x52, 0x97, 0xab, 0x67, 0xdd, 0x82, 0xce,
0xf9, 0xa6, 0x0e, 0xdd, 0xf2, 0xac, 0xa8, 0x58, 0x67, 0xe1, 0x39, 0xa1, 0xaf, 0x54, 0x73, 0x5c,
0x91, 0x6e, 0x32, 0x51, 0x22, 0xab, 0xfc, 0x38, 0x3d, 0x1e, 0x7b, 0x0c, 0x27, 0xda, 0x8d, 0x05,
0x42, 0xcf, 0x0e, 0x30, 0x23, 0x34, 0x3b, 0x4c, 0x0b, 0x84, 0x28, 0x03, 0x7e, 0x9c, 0xbe, 0x4c,
0x29, 0xf7, 0xa4, 0x91, 0x96, 0x9b, 0xc3, 0xb2, 0x2b, 0x8e, 0xd3, 0x04, 0xf3, 0x7d, 0xb1, 0x6b,
0x2b, 0xba, 0x2b, 0xce, 0x31, 0xc5, 0xfc, 0x11, 0x9e, 0x24, 0x3a, 0xcd, 0x0d, 0x8c, 0xb0, 0x5c,
0xed, 0xe6, 0x33, 0x11, 0xd4, 0x32, 0x30, 0x2c, 0xd7, 0x44, 0x09, 0x09, 0x0a, 0x3c, 0xbe, 0xf4,
0x62, 0x99, 0xf6, 0x96, 0x6b, 0x60, 0xd0, 0x67, 0xd0, 0x53, 0x90, 0x8b, 0x13, 0xcc, 0x2e, 0x3c,
0x71, 0x6c, 0xcb, 0x32, 0x60, 0xb9, 0xf3, 0x13, 0x82, 0xfa, 0x1c, 0xb3, 0x08, 0x87, 0x47, 0x86,
0x56, 0x50, 0xd4, 0x73, 0x13, 0x68, 0x0f, 0x36, 0x14, 0xf2, 0x64, 0x7f, 0x60, 0x32, 0xb4, 0x24,
0xc3, 0xc2, 0x39, 0x91, 0xe9, 0xd2, 0xf1, 0xcf, 0xb0, 0xf7, 0x5a, 0xef, 0x47, 0x5b, 0x92, 0xcf,
0xa2, 0xd1, 0x63, 0xe8, 0x19, 0x5b, 0x74, 0x80, 0x2f, 0x88, 0x8f, 0xed, 0x8e, 0x8c, 0xda, 0x9b,
0x3a, 0x0a, 0xcc, 0x29, 0x77, 0x9e, 0x1a, 0x9d, 0x42, 0x5f, 0x22, 0x4f, 0xc6, 0x8c, 0x72, 0x1e,
0x62, 0x17, 0x7b, 0xc1, 0x93, 0x38, 0xd1, 0xb2, 0xba, 0x52, 0x56, 0x16, 0x51, 0x19, 0x8d, 0x96,
0x76, 0x0d, 0x23, 0x7a, 0x05, 0x1f, 0x94, 0x66, 0x5f, 0x31, 0xc2, 0x71, 0x21, 0x77, 0xed, 0x3a,
0xb9, 0xd7, 0x71, 0xce, 0x09, 0x16, 0x6a, 0x0f, 0x69, 0x2e, 0x78, 0xfd, 0xdd, 0x05, 0x97, 0x39,
0xd1, 0x2f, 0xe0, 0xc3, 0x79, 0xbd, 0x86, 0xe4, 0xde, 0x75, 0x92, 0xaf, 0x65, 0x75, 0xbe, 0x80,
0xce, 0x93, 0x90, 0xfa, 0xe7, 0x87, 0x2f, 0xb4, 0xae, 0xd2, 0xa5, 0xba, 0xb6, 0xf0, 0x52, 0x5d,
0xd3, 0x97, 0x6a, 0xe7, 0x6b, 0x68, 0x97, 0x36, 0xec, 0x07, 0x32, 0x53, 0x33, 0x51, 0xfa, 0xaa,
0xb4, 0xa1, 0xcd, 0x2a, 0xa9, 0x71, 0x4d, 0x42, 0x51, 0x41, 0x2e, 0x55, 0x30, 0xa9, 0xf6, 0x55,
0x43, 0x22, 0x3b, 0xc2, 0x22, 0xd0, 0xd4, 0xcd, 0xc8, 0xc0, 0x38, 0xbf, 0x84, 0x6e, 0x79, 0xb1,
0xff, 0xb1, 0x05, 0x08, 0x2c, 0xe6, 0x71, 0x9c, 0xf5, 0xdf, 0x62, 0xec, 0xdc, 0x86, 0xad, 0xb9,
0x9a, 0xa8, 0x9b, 0xbb, 0x2b, 0xe8, 0x3c, 0xbd, 0xc0, 0x11, 0xcf, 0xef, 0x5f, 0x8f, 0xa0, 0x99,
0x3f, 0x6a, 0xe8, 0x62, 0xdb, 0xdf, 0x55, 0xcf, 0x1e, 0xbb, 0xd9, 0xb3, 0xc7, 0xee, 0x49, 0x46,
0xe1, 0x16, 0xc4, 0x62, 0x8d, 0x09, 0xa7, 0x0c, 0x07, 0x2f, 0xa2, 0xf0, 0x2a, 0x7b, 0x2b, 0x28,
0x30, 0xba, 0xfe, 0x5a, 0x79, 0xfb, 0xf3, 0xfb, 0x0a, 0xac, 0x48, 0xdd, 0x0b, 0xef, 0x11, 0x8a,
0xba, 0x9a, 0x57, 0xeb, 0x72, 0x6d, 0xee, 0xe4, 0xb5, 0x59, 0x57, 0x71, 0xab, 0xa8, 0xe2, 0xa5,
0x15, 0xd4, 0xdf, 0x63, 0x05, 0xce, 0xef, 0xaa, 0xd0, 0x7e, 0x8e, 0xf9, 0x25, 0x65, 0xe7, 0xe2,
0xc4, 0x4a, 0x16, 0x36, 0xa7, 0xb7, 0x61, 0x95, 0x4d, 0x87, 0x67, 0x57, 0x3c, 0xaf, 0xd0, 0x0d,
0x36, 0x7d, 0x22, 0x40, 0xf4, 0x11, 0x00, 0x9b, 0x0e, 0x07, 0x9e, 0x6a, 0x48, 0x75, 0x81, 0x66,
0x53, 0x8d, 0x40, 0x1f, 0x40, 0xd3, 0x9d, 0x0e, 0x31, 0x63, 0x94, 0x25, 0x59, 0x85, 0x66, 0xd3,
0xa7, 0x12, 0x16, 0xbc, 0xee, 0x74, 0x18, 0x30, 0x1a, 0xc7, 0x38, 0x90, 0x15, 0x5a, 0xf2, 0x1e,
0x28, 0x84, 0xd0, 0x7a, 0x92, 0x69, 0xad, 0x2b, 0xad, 0xbc, 0xd0, 0x7a, 0x32, 0x1d, 0xc6, 0x5a,
0xab, 0x2a, 0xcd, 0x4d, 0x6e, 0x6a, 0x3d, 0xc9, 0xb5, 0xaa, 0xba, 0xbc, 0xca, 0x0d, 0xad, 0x27,
0x85, 0xd6, 0x66, 0xc6, 0xab, 0xb5, 0x3a, 0x7f, 0xae, 0xc0, 0xea, 0x7e, 0x9c, 0x9e, 0x26, 0xde,
0x08, 0xa3, 0xbb, 0xd0, 0xe2, 0x94, 0x7b, 0xe1, 0x30, 0x15, 0xa0, 0x3e, 0xbd, 0x40, 0xa2, 0x14,
0xc1, 0xc7, 0xd0, 0x8e, 0x31, 0xf3, 0xe3, 0x54, 0x53, 0x54, 0xb7, 0x6b, 0xe2, 0x94, 0x50, 0x38,
0x45, 0xb2, 0x0b, 0x37, 0xe5, 0xdc, 0x90, 0x44, 0x43, 0x55, 0x96, 0x27, 0x34, 0xc0, 0xda, 0x55,
0x3d, 0x39, 0x75, 0x18, 0x7d, 0x95, 0x4f, 0xa0, 0xef, 0x42, 0x2f, 0xa7, 0x17, 0xed, 0xaa, 0xa4,
0x56, 0xae, 0x5b, 0xd3, 0xd4, 0xa7, 0x1a, 0xed, 0x7c, 0x9d, 0xe7, 0x10, 0x89, 0x46, 0x07, 0x1e,
0xf7, 0x44, 0x2b, 0x13, 0xcb, 0xb3, 0x31, 0xd1, 0xd6, 0x66, 0x20, 0xfa, 0x1e, 0xf4, 0xb8, 0xce,
0xb7, 0x60, 0x98, 0xd1, 0xa8, 0xdd, 0x5c, 0xcf, 0x27, 0x06, 0x9a, 0xf8, 0x5b, 0xd0, 0x2d, 0x88,
0x65, 0x63, 0xa4, 0xec, 0xed, 0xe4, 0x58, 0x11, 0x4d, 0xce, 0x1f, 0x95, 0xb3, 0x54, 0xe4, 0x7c,
0x26, 0x8f, 0x6a, 0xc3, 0x55, 0xad, 0xbd, 0xb5, 0xac, 0xc5, 0xd1, 0xce, 0x90, 0xc7, 0xb3, 0x72,
0xcb, 0x8f, 0x61, 0x8d, 0xe7, 0xa6, 0x0f, 0x03, 0x8f, 0x7b, 0x3a, 0xf5, 0x66, 0x2a, 0xa1, 0x5e,
0x98, 0xdb, 0xe5, 0xe5, 0x85, 0x7e, 0x0c, 0x6d, 0xd5, 0x7b, 0x6b, 0x85, 0xca, 0xbe, 0x96, 0xc2,
0x49, 0x15, 0xce, 0x17, 0xd0, 0x1c, 0x90, 0x20, 0x51, 0xd6, 0xd9, 0xd0, 0xf0, 0x53, 0xc6, 0x70,
0x94, 0x35, 0x21, 0x19, 0x28, 0xca, 0xa3, 0xec, 0x5b, 0xb5, 0x33, 0x14, 0xe0, 0x50, 0x00, 0x75,
0x76, 0x4a, 0x6d, 0x1b, 0xb0, 0x62, 0x86, 0x80, 0x02, 0x44, 0x9c, 0x4d, 0xbc, 0x69, 0xbe, 0xf5,
0x32, 0xce, 0x26, 0xde, 0x54, 0x2d, 0xd0, 0x86, 0xc6, 0x6b, 0x8f, 0x84, 0xbe, 0x7e, 0x92, 0xb3,
0xdc, 0x0c, 0x2c, 0x14, 0x5a, 0xa6, 0xc2, 0x3f, 0x55, 0xa1, 0xa5, 0x34, 0x2a, 0x83, 0x37, 0x60,
0xc5, 0xf7, 0xfc, 0x71, 0xae, 0x52, 0x02, 0xe8, 0xd3, 0xcc, 0x90, 0xf2, 0x55, 0xbc, 0x30, 0x35,
0xb3, 0xed, 0x3e, 0x40, 0x72, 0xe9, 0xc5, 0x86, 0x77, 0x16, 0x52, 0x37, 0x05, 0x91, 0x32, 0xf8,
0x73, 0x68, 0xab, 0xf8, 0xd4, 0x3c, 0xd6, 0x32, 0x9e, 0x96, 0x22, 0x53, 0x5c, 0x0f, 0xc4, 0xb5,
0xc7, 0xe3, 0xaa, 0xcd, 0x6e, 0xed, 0x7d, 0x54, 0x22, 0x97, 0x2b, 0xd9, 0x95, 0xdf, 0xa7, 0x11,
0x67, 0x57, 0xae, 0xa2, 0xed, 0x3f, 0x02, 0x28, 0x90, 0xa2, 0x9e, 0x9d, 0xe3, 0xab, 0xec, 0x7a,
0x77, 0x8e, 0xaf, 0xc4, 0xda, 0x2f, 0xbc, 0x30, 0xcd, 0x9c, 0xaa, 0x80, 0x1f, 0x55, 0x1f, 0x55,
0x1c, 0x1f, 0xd6, 0x9e, 0x88, 0x23, 0xd1, 0x60, 0x2f, 0x1d, 0x7a, 0xd6, 0xc2, 0x43, 0xcf, 0xca,
0x5e, 0x92, 0xbb, 0x50, 0xa5, 0xb1, 0x6e, 0x75, 0xab, 0x34, 0x2e, 0x14, 0x59, 0x86, 0x22, 0xe7,
0x9f, 0x16, 0x40, 0xa1, 0x05, 0x1d, 0x43, 0x9f, 0xd0, 0xa1, 0xe8, 0xd4, 0x88, 0x8f, 0x55, 0x41,
0x1a, 0x32, 0xec, 0xa7, 0x2c, 0x21, 0x17, 0x58, 0x37, 0xf3, 0x9b, 0xf9, 0x31, 0x55, 0x32, 0xce,
0xdd, 0x22, 0xf4, 0x58, 0x31, 0xca, 0xca, 0xe5, 0x66, 0x6c, 0xe8, 0x67, 0x70, 0xab, 0x10, 0x1a,
0x18, 0xf2, 0xaa, 0xd7, 0xca, 0xbb, 0x99, 0xcb, 0x0b, 0x0a, 0x59, 0x3f, 0x81, 0x9b, 0x84, 0x0e,
0xdf, 0xa4, 0x38, 0x2d, 0x49, 0xaa, 0x5d, 0x2b, 0xa9, 0x47, 0xe8, 0x4b, 0xc9, 0x51, 0xc8, 0x79,
0x09, 0xb7, 0x8d, 0x85, 0x8a, 0xb4, 0x37, 0xa4, 0x59, 0xd7, 0x4a, 0xdb, 0xcc, 0xed, 0x12, 0x85,
0xa1, 0x10, 0xf9, 0x15, 0x6c, 0x12, 0x3a, 0xbc, 0xf4, 0x08, 0x9f, 0x95, 0xb7, 0xf2, 0xb6, 0x75,
0xbe, 0xf2, 0x08, 0x2f, 0x0b, 0x53, 0xeb, 0x9c, 0x60, 0x36, 0x2a, 0xad, 0xb3, 0xfe, 0xb6, 0x75,
0x1e, 0x49, 0x8e, 0x42, 0xce, 0x13, 0xe8, 0x11, 0x3a, 0x6b, 0x4f, 0xe3, 0x5a, 0x29, 0x6b, 0x84,
0x96, 0x6d, 0xd9, 0x87, 0x5e, 0x82, 0x7d, 0x4e, 0x99, 0x19, 0x0b, 0xab, 0xd7, 0xca, 0x58, 0xd7,
0x0c, 0xb9, 0x10, 0xe7, 0x0d, 0xb4, 0x7f, 0x9a, 0x8e, 0x30, 0x0f, 0xcf, 0xf2, 0x9c, 0xff, 0x6f,
0x97, 0x99, 0x7f, 0x55, 0xa1, 0xb5, 0x3f, 0x62, 0x34, 0x8d, 0x4b, 0x55, 0x5b, 0xe5, 0xf0, 0x5c,
0xd5, 0x96, 0x34, 0xb2, 0x6a, 0x2b, 0xea, 0x87, 0xd0, 0x56, 0x37, 0x17, 0xcd, 0xa0, 0xaa, 0x10,
0x9a, 0x4f, 0xfa, 0xec, 0xa6, 0xa4, 0xd8, 0xf6, 0xf4, 0x2d, 0x50, 0x73, 0x95, 0xab, 0x51, 0xe1,
0x26, 0x17, 0xce, 0x8a, 0xac, 0x3b, 0x84, 0xce, 0x58, 0xf9, 0x46, 0x73, 0xa9, 0x00, 0xfc, 0x24,
0x33, 0xae, 0x58, 0xc3, 0xae, 0xe9, 0x43, 0xe5, 0xea, 0xf6, 0xd8, 0x74, 0xeb, 0x3d, 0x00, 0x71,
0xcf, 0x1f, 0x66, 0x85, 0xca, 0xfc, 0x09, 0x90, 0x9f, 0x10, 0x6e, 0x33, 0xce, 0x86, 0xfd, 0x13,
0xe8, 0xcd, 0xc9, 0x5c, 0x50, 0xa6, 0xbe, 0x63, 0x96, 0xa9, 0xe2, 0x6a, 0x64, 0xb2, 0x9a, 0xb5,
0xeb, 0x6f, 0x15, 0xf5, 0x2c, 0x50, 0xbc, 0xd3, 0x3e, 0x82, 0x4e, 0xa4, 0x9a, 0xaf, 0x7c, 0x03,
0xcc, 0x3b, 0x96, 0xd9, 0x98, 0xb9, 0xed, 0xc8, 0x6c, 0xd3, 0x1e, 0x42, 0xdb, 0x97, 0x1e, 0x58,
0xb8, 0x11, 0x86, 0x73, 0xdc, 0x96, 0x6f, 0xec, 0x76, 0xa9, 0x51, 0xb4, 0xde, 0xa7, 0x51, 0xd4,
0x2f, 0x7b, 0xcb, 0x7e, 0x5a, 0xec, 0x7d, 0x53, 0x87, 0xda, 0xe3, 0xc1, 0x21, 0x3a, 0x85, 0xf5,
0xd9, 0x7f, 0x7e, 0xe8, 0x8e, 0x36, 0x6b, 0xc9, 0x7f, 0xc2, 0xfe, 0xdd, 0xa5, 0xf3, 0xba, 0x65,
0xbf, 0x81, 0x5c, 0x58, 0x9b, 0xf9, 0xc3, 0x83, 0xb2, 0xa3, 0x66, 0xf1, 0x5f, 0xb4, 0xfe, 0x9d,
0x65, 0xd3, 0xa6, 0xcc, 0x99, 0x3b, 0x42, 0x2e, 0x73, 0xf1, 0x7b, 0x4a, 0x2e, 0x73, 0xd9, 0xd5,
0xe2, 0x06, 0xfa, 0x21, 0xd4, 0xd5, 0x3f, 0x1f, 0x94, 0x5d, 0x5c, 0x4a, 0x7f, 0x93, 0xfa, 0xb7,
0x66, 0xb0, 0x39, 0xe3, 0x33, 0xe8, 0x94, 0x7e, 0x14, 0xa2, 0x0f, 0x4a, 0xba, 0xca, 0xbf, 0x8c,
0xfa, 0x1f, 0x2e, 0x9e, 0xcc, 0xa5, 0xed, 0x03, 0x14, 0xbf, 0x05, 0x90, 0xad, 0xa9, 0xe7, 0x7e,
0x3d, 0xf5, 0x6f, 0x2f, 0x98, 0xc9, 0x85, 0x9c, 0xc2, 0xfa, 0xec, 0x13, 0x3d, 0x9a, 0xf1, 0xea,
0xec, 0x03, 0x79, 0xbe, 0x95, 0x4b, 0xdf, 0xf6, 0xa5, 0xd8, 0xd9, 0x87, 0xf7, 0x5c, 0xec, 0x92,
0x67, 0xff, 0x5c, 0xec, 0xd2, 0x17, 0xfb, 0x1b, 0xe8, 0x05, 0x74, 0xcb, 0x2f, 0xd9, 0x28, 0x73,
0xd2, 0xc2, 0xa7, 0xfc, 0xfe, 0x47, 0x4b, 0x66, 0x73, 0x81, 0x9f, 0xc3, 0x8a, 0x7a, 0xa2, 0xce,
0xd2, 0xd1, 0x7c, 0xd9, 0xee, 0x6f, 0x94, 0x91, 0x39, 0xd7, 0x7d, 0xa8, 0xab, 0xdb, 0x65, 0x1e,
0x00, 0xa5, 0xcb, 0x66, 0xbf, 0x6d, 0x62, 0x9d, 0x1b, 0xf7, 0x2b, 0x99, 0x9e, 0xa4, 0xa4, 0x27,
0x59, 0xa4, 0xc7, 0xd8, 0x9c, 0xb3, 0xba, 0x4c, 0xd7, 0x07, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff,
0x11, 0x58, 0x45, 0xd9, 0xb2, 0x1f, 0x00, 0x00,
// 2632 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x19, 0x4d, 0x6f, 0x24, 0x47,
0x75, 0x67, 0xa6, 0xed, 0xf1, 0xbc, 0xf9, 0xb0, 0xa7, 0xd6, 0xeb, 0xed, 0x9d, 0x24, 0xbb, 0x4e,
0x2b, 0x10, 0x03, 0x91, 0xb3, 0x78, 0x13, 0x58, 0x11, 0x09, 0x69, 0xd7, 0x1b, 0x82, 0xc9, 0x3a,
0x99, 0xb4, 0x6d, 0x56, 0x48, 0x48, 0xa3, 0x76, 0x77, 0xed, 0x4c, 0xe1, 0x9e, 0xae, 0x4e, 0x75,
0xb5, 0x3d, 0xbe, 0xe4, 0xc0, 0x01, 0x0e, 0x48, 0x70, 0x45, 0xe2, 0xc8, 0x8d, 0x3b, 0x07, 0xf8,
0x03, 0x48, 0xfc, 0x10, 0x6e, 0xdc, 0x39, 0xa2, 0xfa, 0xe8, 0xea, 0xea, 0xf9, 0xf0, 0x6e, 0x90,
0x10, 0x17, 0x2e, 0xad, 0x7a, 0xaf, 0xde, 0x57, 0xbd, 0x7a, 0xef, 0xd5, 0xab, 0x6a, 0x68, 0x05,
0x29, 0xd9, 0x4f, 0x19, 0xe5, 0x14, 0xad, 0xf1, 0xeb, 0x14, 0x67, 0x83, 0x07, 0x63, 0x4a, 0xc7,
0x31, 0x7e, 0x5f, 0x22, 0xcf, 0xf3, 0x97, 0xef, 0x73, 0x32, 0xc5, 0x19, 0x0f, 0xa6, 0xa9, 0xa2,
0xf3, 0xee, 0xc1, 0xdd, 0x4f, 0x30, 0x3f, 0xc1, 0xec, 0x12, 0xb3, 0x9f, 0x62, 0x96, 0x11, 0x9a,
0xf8, 0xf8, 0xcb, 0x1c, 0x67, 0xdc, 0x9b, 0x81, 0xbb, 0x38, 0x95, 0xa5, 0x34, 0xc9, 0x30, 0xda,
0x86, 0xb5, 0x69, 0xf0, 0x0b, 0xca, 0xdc, 0xda, 0x6e, 0x6d, 0xaf, 0xeb, 0x2b, 0x40, 0x62, 0x49,
0x42, 0x99, 0x5b, 0xd7, 0x58, 0x01, 0x08, 0x6c, 0x1a, 0xf0, 0x70, 0xe2, 0x36, 0x14, 0x56, 0x02,
0x68, 0x00, 0x1b, 0x0c, 0x5f, 0x12, 0x21, 0xd5, 0x75, 0x76, 0x6b, 0x7b, 0x2d, 0xdf, 0xc0, 0xde,
0xaf, 0x6a, 0xb0, 0x7d, 0x96, 0x46, 0x01, 0xc7, 0x43, 0x46, 0x43, 0x9c, 0x65, 0xda, 0x24, 0xd4,
0x83, 0x3a, 0x89, 0xa4, 0xce, 0x96, 0x5f, 0x27, 0x11, 0xda, 0x82, 0x46, 0x4a, 0x22, 0xa9, 0xae,
0xe5, 0x8b, 0x21, 0xba, 0x0f, 0x10, 0xc6, 0x34, 0xc3, 0x27, 0x3c, 0x22, 0x89, 0xd4, 0xb8, 0xe1,
0x5b, 0x18, 0x61, 0xcc, 0x15, 0x89, 0xf8, 0x44, 0xea, 0xec, 0xfa, 0x0a, 0x40, 0x3b, 0xb0, 0x3e,
0xc1, 0x64, 0x3c, 0xe1, 0xee, 0x9a, 0x44, 0x6b, 0xc8, 0xbb, 0x0b, 0x77, 0xe6, 0xec, 0x50, 0xeb,
0xf7, 0xfe, 0x5e, 0x87, 0x9d, 0x43, 0x86, 0x03, 0x8e, 0x0f, 0x69, 0xc2, 0x03, 0x92, 0x60, 0xb6,
0xca, 0xc6, 0xfb, 0x00, 0xe7, 0x79, 0x12, 0xc5, 0x78, 0x18, 0xf0, 0x89, 0x36, 0xd5, 0xc2, 0x48,
0x8b, 0x27, 0x38, 0xbc, 0x48, 0x29, 0x49, 0xb8, 0xb4, 0xb8, 0xe5, 0x5b, 0x18, 0x61, 0x71, 0x26,
0x17, 0xa3, 0xbc, 0xa4, 0x00, 0x61, 0x71, 0xc6, 0x23, 0x9a, 0x2b, 0x8b, 0x5b, 0xbe, 0x86, 0x34,
0x1e, 0x33, 0xe6, 0xae, 0x1b, 0x3c, 0x66, 0x4c, 0xe0, 0xe3, 0xe0, 0x1c, 0xc7, 0x99, 0xdb, 0xdc,
0x6d, 0x08, 0xbc, 0x82, 0xd0, 0x2e, 0xb4, 0x13, 0x3a, 0x24, 0x97, 0x94, 0xfb, 0x94, 0x72, 0x77,
0x43, 0x3a, 0xcc, 0x46, 0x21, 0x17, 0x9a, 0x2c, 0x4f, 0x44, 0xdc, 0xb8, 0x2d, 0x29, 0xb2, 0x00,
0x05, 0xaf, 0x1e, 0x3e, 0x61, 0xe3, 0xcc, 0x05, 0x29, 0xd8, 0x46, 0xa1, 0x77, 0xa0, 0x5b, 0xae,
0xe4, 0x19, 0x61, 0x6e, 0x5b, 0x4a, 0xa8, 0x22, 0xbd, 0x23, 0xb8, 0xbb, 0xe0, 0x4b, 0x1d, 0x67,
0xfb, 0xd0, 0x0a, 0x0b, 0xa4, 0xf4, 0x69, 0xfb, 0x60, 0x6b, 0x5f, 0x86, 0xf6, 0x7e, 0x49, 0x5c,
0x92, 0x78, 0x47, 0xd0, 0x3d, 0x21, 0xe3, 0x24, 0x88, 0x5f, 0x3f, 0x62, 0x84, 0xc7, 0x24, 0x8b,
0x8e, 0x4f, 0x0d, 0x79, 0x5b, 0xd0, 0x2b, 0x44, 0xe9, 0x4d, 0xff, 0x73, 0x03, 0xfa, 0x4f, 0xa2,
0xe8, 0x15, 0x31, 0x39, 0x80, 0x0d, 0x8e, 0xd9, 0x94, 0x08, 0x89, 0x75, 0xe9, 0x4e, 0x03, 0xa3,
0x07, 0xe0, 0xe4, 0x19, 0x66, 0x52, 0x53, 0xfb, 0xa0, 0xad, 0x57, 0x72, 0x96, 0x61, 0xe6, 0xcb,
0x09, 0x84, 0xc0, 0x09, 0x84, 0x2f, 0x1d, 0xe9, 0x4b, 0x39, 0x16, 0x26, 0xe3, 0xe4, 0xd2, 0x5d,
0x93, 0x28, 0x31, 0x14, 0x98, 0xf0, 0x2a, 0xd2, 0x3b, 0x2c, 0x86, 0xc5, 0xb2, 0x9a, 0xe5, 0xb2,
0x4c, 0xd8, 0x6c, 0x2c, 0x0f, 0x9b, 0xd6, 0x8a, 0xb0, 0x81, 0x4a, 0xd8, 0x78, 0xd0, 0x09, 0x83,
0x34, 0x38, 0x27, 0x31, 0xe1, 0x04, 0x67, 0x6e, 0x5b, 0x1a, 0x51, 0xc1, 0xa1, 0x3d, 0xd8, 0x0c,
0xd2, 0x34, 0x60, 0x53, 0xca, 0x86, 0x8c, 0xbe, 0x24, 0x31, 0x76, 0x3b, 0x52, 0xc8, 0x3c, 0x5a,
0x48, 0xcb, 0x70, 0x4c, 0x92, 0x7c, 0xf6, 0x5c, 0x44, 0x9f, 0xdb, 0x95, 0x64, 0x15, 0x9c, 0x90,
0x96, 0xd0, 0xcf, 0xf0, 0xd5, 0x90, 0x91, 0x4b, 0x12, 0xe3, 0x31, 0xce, 0xdc, 0x9e, 0xf4, 0xe2,
0x3c, 0x1a, 0xbd, 0x0b, 0x4d, 0x16, 0x93, 0x29, 0xe1, 0x99, 0xbb, 0xb9, 0xdb, 0xd8, 0x6b, 0x1f,
0x74, 0xb5, 0x3f, 0x7d, 0x89, 0xf5, 0x8b, 0x59, 0xef, 0x19, 0xac, 0x2b, 0x94, 0x70, 0xaf, 0x20,
0xd1, 0xbb, 0x25, 0xc7, 0x02, 0x97, 0xd1, 0x97, 0x5c, 0xee, 0x95, 0xe3, 0xcb, 0xb1, 0xc0, 0x4d,
0x02, 0x16, 0xc9, 0x7d, 0x72, 0x7c, 0x39, 0xf6, 0x7c, 0x70, 0xc4, 0x46, 0x09, 0x57, 0xe7, 0x7a,
0xc3, 0xbb, 0xbe, 0x18, 0x0a, 0xcc, 0x58, 0xc7, 0x54, 0xd7, 0x17, 0x43, 0xf4, 0x4d, 0xe8, 0x05,
0x51, 0x44, 0x38, 0xa1, 0x49, 0x10, 0x7f, 0x42, 0xa2, 0xcc, 0x6d, 0xec, 0x36, 0xf6, 0xba, 0xfe,
0x1c, 0xd6, 0x3b, 0x00, 0x64, 0x07, 0x94, 0x0e, 0xfa, 0x37, 0xa1, 0x95, 0x5d, 0x67, 0x1c, 0x4f,
0x87, 0x46, 0x4f, 0x89, 0xf0, 0x7e, 0x59, 0x33, 0xe9, 0x62, 0xb2, 0x68, 0x55, 0x2c, 0x7e, 0xb7,
0x52, 0x5b, 0xea, 0x32, 0xea, 0xfa, 0x45, 0xfe, 0x94, 0xdc, 0x76, 0xb9, 0x59, 0x48, 0xd9, 0xc6,
0xb2, 0x94, 0x1d, 0x80, 0xbb, 0x68, 0x83, 0x4e, 0x93, 0x10, 0xee, 0x3e, 0xc3, 0x31, 0x7e, 0x1d,
0xfb, 0x10, 0x38, 0x49, 0x30, 0xc5, 0x3a, 0x1d, 0xe5, 0xf8, 0xf5, 0x0d, 0x58, 0x54, 0xa2, 0x0d,
0x38, 0x86, 0x3b, 0xcf, 0x49, 0xc6, 0x5f, 0xad, 0x7e, 0x41, 0x55, 0x7d, 0x99, 0xaa, 0xdf, 0xd7,
0x00, 0x4a, 0x59, 0xc6, 0xe6, 0x9a, 0x65, 0x33, 0x02, 0x07, 0xcf, 0x08, 0xd7, 0xf9, 0x2e, 0xc7,
0x22, 0x2a, 0x78, 0x98, 0xea, 0x23, 0x48, 0x0c, 0x45, 0xbd, 0xcc, 0x13, 0x32, 0x3b, 0xa1, 0xe1,
0x05, 0xe6, 0x99, 0xac, 0xe7, 0x1b, 0xbe, 0x8d, 0x92, 0x49, 0x3b, 0xc1, 0x71, 0x2c, 0x8b, 0xfa,
0x86, 0xaf, 0x00, 0x51, 0x81, 0xf1, 0x34, 0xe5, 0xd7, 0x9f, 0x9d, 0xb8, 0xeb, 0x32, 0xff, 0x0a,
0xd0, 0x3b, 0x86, 0x9d, 0xf9, 0x95, 0xea, 0x18, 0x7a, 0x04, 0xed, 0x72, 0x15, 0x99, 0x5b, 0x93,
0x09, 0xb2, 0x64, 0xeb, 0x6d, 0x2a, 0xef, 0x3e, 0x74, 0x4e, 0x78, 0xc0, 0xf1, 0x0a, 0x7f, 0x79,
0x7b, 0xd0, 0x33, 0x55, 0x57, 0x12, 0xaa, 0xba, 0x11, 0xf0, 0x3c, 0xd3, 0x54, 0x1a, 0xf2, 0xfe,
0xd2, 0x80, 0xa6, 0x0e, 0xeb, 0xa2, 0x36, 0xd5, 0xca, 0xda, 0xf4, 0x3f, 0x29, 0x91, 0x95, 0xac,
0x6a, 0xce, 0x65, 0xd5, 0xff, 0xcb, 0x65, 0x59, 0x2e, 0xff, 0x56, 0x83, 0x96, 0xd9, 0xe6, 0xaf,
0xdd, 0xce, 0xbc, 0x07, 0xad, 0x54, 0x6d, 0x3c, 0x56, 0x55, 0xaf, 0x7d, 0xd0, 0xd3, 0x8a, 0x8a,
0x3a, 0x57, 0x12, 0x58, 0xf1, 0xe3, 0xd8, 0xf1, 0x63, 0xb5, 0x2b, 0x6b, 0x95, 0x76, 0x05, 0x81,
0x93, 0x8a, 0x72, 0xba, 0x2e, 0xcb, 0xa9, 0x1c, 0xdb, 0x0d, 0x4a, 0xb3, 0xd2, 0xa0, 0x78, 0x1f,
0x42, 0xf3, 0x38, 0x08, 0x27, 0x24, 0x91, 0x19, 0x1a, 0xa6, 0x3a, 0x4c, 0xbb, 0xbe, 0x1c, 0x0b,
0x25, 0x53, 0x3c, 0xa5, 0xec, 0x5a, 0xd7, 0x7e, 0x0d, 0x79, 0x17, 0xd0, 0xd5, 0x69, 0xa0, 0x93,
0xe9, 0x21, 0x80, 0x69, 0x31, 0x8a, 0x5c, 0x5a, 0x6c, 0x43, 0x2c, 0x1a, 0xb4, 0x07, 0xcd, 0xa9,
0xd2, 0xac, 0xab, 0x6e, 0xe1, 0x03, 0x6d, 0x8f, 0x5f, 0x4c, 0x7b, 0xbf, 0xae, 0xc1, 0x8e, 0xea,
0x31, 0x5f, 0xd9, 0x49, 0x2e, 0xef, 0x5d, 0x94, 0xfb, 0x1a, 0x15, 0xf7, 0x3d, 0x82, 0x16, 0xc3,
0x19, 0xcd, 0x59, 0x88, 0x95, 0x67, 0xdb, 0x07, 0x77, 0x8a, 0x4c, 0x92, 0xba, 0x7c, 0x3d, 0xeb,
0x97, 0x74, 0xde, 0x6f, 0x9a, 0xd0, 0xab, 0xce, 0x8a, 0x8a, 0x75, 0x1e, 0x5f, 0x10, 0xfa, 0x42,
0x35, 0xc7, 0x35, 0xe9, 0x26, 0x1b, 0x25, 0xb2, 0x2a, 0x4c, 0xf3, 0x93, 0x49, 0xc0, 0x70, 0xa6,
0xdd, 0x58, 0x22, 0xf4, 0xec, 0x10, 0x33, 0x42, 0x8b, 0xc3, 0xb4, 0x44, 0x88, 0x32, 0x10, 0xa6,
0xf9, 0x17, 0x39, 0xe5, 0x81, 0x34, 0xd2, 0xf1, 0x0d, 0x2c, 0xbb, 0xe2, 0x34, 0xcf, 0x30, 0x3f,
0x14, 0xbb, 0xb6, 0xa6, 0xbb, 0x62, 0x83, 0x29, 0xe7, 0x8f, 0xf1, 0x34, 0xd3, 0x69, 0x6e, 0x61,
0x84, 0xe5, 0x6a, 0x37, 0x9f, 0x8b, 0xa0, 0x96, 0x81, 0xe1, 0xf8, 0x36, 0x4a, 0x48, 0x50, 0xe0,
0xc9, 0x55, 0x90, 0xca, 0xb4, 0x77, 0x7c, 0x0b, 0x83, 0xde, 0x83, 0xbe, 0x82, 0x7c, 0x9c, 0x61,
0x76, 0x19, 0x88, 0x63, 0x5b, 0x96, 0x01, 0xc7, 0x5f, 0x9c, 0x10, 0xd4, 0x17, 0x98, 0x25, 0x38,
0x3e, 0xb6, 0xb4, 0x82, 0xa2, 0x5e, 0x98, 0x40, 0x07, 0xb0, 0xad, 0x90, 0xa7, 0x87, 0x43, 0x9b,
0xa1, 0x2d, 0x19, 0x96, 0xce, 0x89, 0x4c, 0x97, 0x8e, 0x7f, 0x8e, 0x83, 0x97, 0x7a, 0x3f, 0x3a,
0x92, 0x7c, 0x1e, 0x8d, 0x9e, 0x40, 0xdf, 0xda, 0xa2, 0x67, 0xf8, 0x92, 0x84, 0xd8, 0xed, 0xca,
0xa8, 0xbd, 0xad, 0xa3, 0xc0, 0x9e, 0xf2, 0x17, 0xa9, 0xd1, 0x19, 0x0c, 0x24, 0xf2, 0x74, 0xc2,
0x28, 0xe7, 0x31, 0xf6, 0x71, 0x10, 0x3d, 0x4d, 0x33, 0x2d, 0xab, 0x27, 0x65, 0x15, 0x11, 0x55,
0xd0, 0x68, 0x69, 0x37, 0x30, 0xa2, 0x17, 0xf0, 0x46, 0x65, 0xf6, 0x05, 0x23, 0x1c, 0x97, 0x72,
0x37, 0x6f, 0x92, 0x7b, 0x13, 0xe7, 0x82, 0x60, 0xa1, 0xf6, 0x88, 0x1a, 0xc1, 0x5b, 0xaf, 0x2f,
0xb8, 0xca, 0x89, 0x7e, 0x06, 0x6f, 0x2e, 0xea, 0xb5, 0x24, 0xf7, 0x6f, 0x92, 0x7c, 0x23, 0xab,
0x48, 0x0e, 0x51, 0xbf, 0xd4, 0xce, 0x23, 0x95, 0x1c, 0x06, 0xe1, 0x7d, 0x04, 0xdd, 0xa7, 0x31,
0x0d, 0x2f, 0x8e, 0x3e, 0xd7, 0xe4, 0x95, 0x2b, 0x77, 0x63, 0xe9, 0x95, 0xbb, 0xa1, 0xaf, 0xdc,
0xde, 0x57, 0xd0, 0xa9, 0x6c, 0xe7, 0xf7, 0x64, 0x1e, 0x17, 0xa2, 0xf4, 0x45, 0x6a, 0x5b, 0x1b,
0x5d, 0x51, 0xe3, 0xdb, 0x84, 0xa2, 0xbe, 0x5c, 0xa9, 0x50, 0x53, 0xcd, 0xad, 0x86, 0x44, 0xee,
0xc4, 0x65, 0x18, 0xaa, 0x7b, 0x93, 0x85, 0xf1, 0x7e, 0x0e, 0xbd, 0xaa, 0x2b, 0xfe, 0x63, 0x0b,
0x10, 0x38, 0x2c, 0xe0, 0xb8, 0xe8, 0xce, 0xc5, 0xd8, 0xbb, 0x07, 0x77, 0x17, 0x2a, 0xa6, 0x6e,
0xfd, 0xae, 0xa1, 0xfb, 0xf1, 0x25, 0x4e, 0xb8, 0xb9, 0x9d, 0x3d, 0x86, 0x96, 0x79, 0xf2, 0xd0,
0xa5, 0x78, 0xb0, 0xaf, 0x1e, 0x45, 0xf6, 0x8b, 0x47, 0x91, 0xfd, 0xd3, 0x82, 0xc2, 0x2f, 0x89,
0xc5, 0x1a, 0x33, 0x4e, 0x19, 0x8e, 0x3e, 0x4f, 0xe2, 0xeb, 0xe2, 0x25, 0xa1, 0xc4, 0xe8, 0xea,
0xec, 0x98, 0xe6, 0xe8, 0x77, 0x35, 0x58, 0x93, 0xba, 0x97, 0xde, 0x32, 0x14, 0x75, 0xdd, 0xd4,
0xf2, 0x6a, 0xe5, 0xee, 0x9a, 0xca, 0xad, 0x6b, 0xbc, 0x53, 0xd6, 0xf8, 0xca, 0x0a, 0xd6, 0xbf,
0xc6, 0x0a, 0xbc, 0xdf, 0xd6, 0xa1, 0xf3, 0x19, 0xe6, 0x57, 0x94, 0x5d, 0x88, 0xf3, 0x2c, 0x5b,
0xda, 0xba, 0xde, 0x83, 0x0d, 0x36, 0x1b, 0x9d, 0x5f, 0x73, 0x53, 0xbf, 0x9b, 0x6c, 0xf6, 0x54,
0x80, 0xe8, 0x2d, 0x00, 0x36, 0x1b, 0x0d, 0x03, 0xd5, 0xae, 0xea, 0xf2, 0xcd, 0x66, 0x1a, 0x81,
0xde, 0x80, 0x96, 0x3f, 0x1b, 0x61, 0xc6, 0x28, 0xcb, 0x8a, 0xfa, 0xed, 0xcf, 0x3e, 0x96, 0xb0,
0xe0, 0xf5, 0x67, 0xa3, 0x88, 0xd1, 0x34, 0xc5, 0x91, 0xac, 0xdf, 0x8e, 0xdf, 0xf2, 0x67, 0xcf,
0x14, 0x42, 0x68, 0x3d, 0x2d, 0xb4, 0xae, 0x2b, 0xad, 0xa7, 0xa5, 0xd6, 0xd3, 0xd9, 0x28, 0xd5,
0x5a, 0x55, 0xe1, 0x6e, 0x9d, 0xda, 0x5a, 0x4f, 0x8d, 0x56, 0x55, 0xb5, 0x37, 0x4e, 0x2d, 0xad,
0xa7, 0xa5, 0xd6, 0x56, 0xc1, 0xab, 0xb5, 0x7a, 0x7f, 0xaa, 0xc1, 0xc6, 0x61, 0x9a, 0x9f, 0x65,
0xc1, 0x18, 0xa3, 0x07, 0xd0, 0xe6, 0x94, 0x07, 0xf1, 0x28, 0x17, 0xa0, 0x3e, 0xdb, 0x40, 0xa2,
0x14, 0xc1, 0xdb, 0xd0, 0x49, 0x31, 0x0b, 0xd3, 0x5c, 0x53, 0xd4, 0x77, 0x1b, 0xe2, 0x0c, 0x51,
0x38, 0x45, 0xb2, 0x0f, 0xb7, 0xe5, 0xdc, 0x88, 0x24, 0x23, 0x55, 0xb4, 0xa7, 0x34, 0xc2, 0xda,
0x55, 0x7d, 0x39, 0x75, 0x94, 0x7c, 0x6a, 0x26, 0xd0, 0xb7, 0xa1, 0x6f, 0xe8, 0x45, 0x33, 0x2b,
0xa9, 0x95, 0xeb, 0x36, 0x35, 0xf5, 0x99, 0x46, 0x7b, 0x5f, 0x99, 0x1c, 0x22, 0xc9, 0xf8, 0x59,
0xc0, 0x03, 0xd1, 0xe8, 0xa4, 0xf2, 0xe4, 0xcc, 0xb4, 0xb5, 0x05, 0x88, 0xbe, 0x03, 0x7d, 0xae,
0xf3, 0x2d, 0x1a, 0x15, 0x34, 0x6a, 0x37, 0xb7, 0xcc, 0xc4, 0x50, 0x13, 0x7f, 0x03, 0x7a, 0x25,
0xb1, 0x6c, 0x9b, 0x94, 0xbd, 0x5d, 0x83, 0x15, 0xd1, 0xe4, 0xfd, 0x41, 0x39, 0x4b, 0x45, 0xce,
0x7b, 0xf2, 0x20, 0xb7, 0x5c, 0xd5, 0x3e, 0xd8, 0x2c, 0x1a, 0x20, 0xed, 0x0c, 0x79, 0x78, 0x2b,
0xb7, 0xfc, 0x10, 0x36, 0xb9, 0x31, 0x7d, 0x14, 0x05, 0x3c, 0xd0, 0xa9, 0x37, 0x57, 0x27, 0xf5,
0xc2, 0xfc, 0x1e, 0xaf, 0x2e, 0xf4, 0x6d, 0xe8, 0xa8, 0xce, 0x5c, 0x2b, 0x54, 0xf6, 0xb5, 0x15,
0x4e, 0xaa, 0xf0, 0x3e, 0x82, 0xd6, 0x90, 0x44, 0x99, 0xb2, 0xce, 0x85, 0x66, 0x98, 0x33, 0x86,
0x93, 0xa2, 0x45, 0x29, 0x40, 0x51, 0x1e, 0x65, 0x57, 0xab, 0x9d, 0xa1, 0x00, 0x8f, 0x02, 0xa8,
0x93, 0x55, 0x6a, 0xdb, 0x86, 0x35, 0x3b, 0x04, 0x14, 0x20, 0xe2, 0x6c, 0x1a, 0xcc, 0xcc, 0xd6,
0xcb, 0x38, 0x9b, 0x06, 0x33, 0xb5, 0x40, 0x17, 0x9a, 0x2f, 0x03, 0x12, 0x87, 0xfa, 0xc1, 0xce,
0xf1, 0x0b, 0xb0, 0x54, 0xe8, 0xd8, 0x0a, 0xff, 0x58, 0x87, 0xb6, 0xd2, 0xa8, 0x0c, 0xde, 0x86,
0xb5, 0x30, 0x08, 0x27, 0x46, 0xa5, 0x04, 0xd0, 0xbb, 0x85, 0x21, 0xd5, 0x8b, 0x7a, 0x69, 0x6a,
0x61, 0xdb, 0x43, 0x80, 0xec, 0x2a, 0x48, 0x2d, 0xef, 0x2c, 0xa5, 0x6e, 0x09, 0x22, 0x65, 0xf0,
0x07, 0xd0, 0x51, 0xf1, 0xa9, 0x79, 0x9c, 0x55, 0x3c, 0x6d, 0x45, 0xa6, 0xb8, 0x1e, 0x89, 0x4b,
0x51, 0xc0, 0x55, 0x13, 0xde, 0x3e, 0x78, 0xab, 0x42, 0x2e, 0x57, 0xb2, 0x2f, 0xbf, 0x1f, 0x27,
0x9c, 0x5d, 0xfb, 0x8a, 0x76, 0xf0, 0x18, 0xa0, 0x44, 0x8a, 0x7a, 0x76, 0x81, 0xaf, 0x8b, 0xcb,
0xdf, 0x05, 0xbe, 0x16, 0x6b, 0xbf, 0x0c, 0xe2, 0xbc, 0x70, 0xaa, 0x02, 0x7e, 0x50, 0x7f, 0x5c,
0xf3, 0x42, 0xd8, 0x7c, 0x2a, 0x0e, 0x4c, 0x8b, 0xbd, 0x72, 0xe8, 0x39, 0x4b, 0x0f, 0x3d, 0xa7,
0x78, 0x67, 0xee, 0x41, 0x9d, 0xa6, 0xba, 0x11, 0xae, 0xd3, 0xb4, 0x54, 0xe4, 0x58, 0x8a, 0xbc,
0x7f, 0x38, 0x00, 0xa5, 0x16, 0x74, 0x02, 0x03, 0x42, 0x47, 0xa2, 0x8f, 0x23, 0x21, 0x56, 0x05,
0x69, 0xc4, 0x70, 0x98, 0xb3, 0x8c, 0x5c, 0x62, 0xdd, 0xea, 0xef, 0x98, 0x63, 0xaa, 0x62, 0x9c,
0x7f, 0x97, 0xd0, 0x13, 0xc5, 0x28, 0x2b, 0x97, 0x5f, 0xb0, 0xa1, 0x9f, 0xc0, 0x9d, 0x52, 0x68,
0x64, 0xc9, 0xab, 0xdf, 0x28, 0xef, 0xb6, 0x91, 0x17, 0x95, 0xb2, 0x7e, 0x04, 0xb7, 0x09, 0x1d,
0x7d, 0x99, 0xe3, 0xbc, 0x22, 0xa9, 0x71, 0xa3, 0xa4, 0x3e, 0xa1, 0x5f, 0x48, 0x8e, 0x52, 0xce,
0x17, 0x70, 0xcf, 0x5a, 0xa8, 0x48, 0x7b, 0x4b, 0x9a, 0x73, 0xa3, 0xb4, 0x1d, 0x63, 0x97, 0x28,
0x0c, 0xa5, 0xc8, 0x4f, 0x61, 0x87, 0xd0, 0xd1, 0x55, 0x40, 0xf8, 0xbc, 0xbc, 0xb5, 0x57, 0xad,
0xf3, 0x45, 0x40, 0x78, 0x55, 0x98, 0x5a, 0xe7, 0x14, 0xb3, 0x71, 0x65, 0x9d, 0xeb, 0xaf, 0x5a,
0xe7, 0xb1, 0xe4, 0x28, 0xe5, 0x3c, 0x85, 0x3e, 0xa1, 0xf3, 0xf6, 0x34, 0x6f, 0x94, 0xb2, 0x49,
0x68, 0xd5, 0x96, 0x43, 0xe8, 0x67, 0x38, 0xe4, 0x94, 0xd9, 0xb1, 0xb0, 0x71, 0xa3, 0x8c, 0x2d,
0xcd, 0x60, 0x84, 0x78, 0x5f, 0x42, 0xe7, 0xc7, 0xf9, 0x18, 0xf3, 0xf8, 0xdc, 0xe4, 0xfc, 0x7f,
0xbb, 0xcc, 0xfc, 0xab, 0x0e, 0xed, 0xc3, 0x31, 0xa3, 0x79, 0x5a, 0xa9, 0xda, 0x2a, 0x87, 0x17,
0xaa, 0xb6, 0xa4, 0x91, 0x55, 0x5b, 0x51, 0x7f, 0x08, 0x1d, 0x75, 0xaf, 0xd1, 0x0c, 0xaa, 0x0a,
0xa1, 0xc5, 0xa4, 0x2f, 0xee, 0x51, 0x8a, 0xed, 0x40, 0xdf, 0x11, 0x35, 0x57, 0xb5, 0x1a, 0x95,
0x6e, 0xf2, 0xe1, 0xbc, 0xcc, 0xba, 0x23, 0xe8, 0x4e, 0x94, 0x6f, 0x34, 0x97, 0x0a, 0xc0, 0x77,
0x0a, 0xe3, 0xca, 0x35, 0xec, 0xdb, 0x3e, 0x54, 0xae, 0xee, 0x4c, 0x6c, 0xb7, 0xbe, 0x0f, 0x20,
0x9a, 0xe6, 0x51, 0x51, 0xa8, 0xec, 0x5f, 0x04, 0xe6, 0x84, 0x50, 0x8d, 0xb5, 0x1c, 0x0e, 0x4e,
0xa1, 0xbf, 0x20, 0x73, 0x49, 0x99, 0xfa, 0x96, 0x5d, 0xa6, 0xca, 0x8b, 0x93, 0xcd, 0x6a, 0xd7,
0xae, 0xbf, 0xd6, 0xd4, 0xa3, 0x41, 0xf9, 0x8a, 0xfb, 0x18, 0xba, 0x89, 0x6a, 0xbe, 0xcc, 0x06,
0xd8, 0x37, 0x30, 0xbb, 0x31, 0xf3, 0x3b, 0x89, 0xdd, 0xa6, 0x7d, 0x08, 0x9d, 0x50, 0x7a, 0x60,
0xe9, 0x46, 0x58, 0xce, 0xf1, 0xdb, 0xa1, 0xb5, 0xdb, 0x95, 0x46, 0xd1, 0xf9, 0x3a, 0x8d, 0xa2,
0x7e, 0xf7, 0x5b, 0xf5, 0x4b, 0xe3, 0xe0, 0x9f, 0xeb, 0xd0, 0x78, 0x32, 0x3c, 0x42, 0x67, 0xb0,
0x35, 0xff, 0x47, 0x10, 0xdd, 0xd7, 0x66, 0xad, 0xf8, 0x8b, 0x38, 0x78, 0xb0, 0x72, 0x5e, 0xb7,
0xec, 0xb7, 0x90, 0x0f, 0x9b, 0x73, 0xff, 0x7f, 0x50, 0x71, 0xd4, 0x2c, 0xff, 0xc7, 0x36, 0xb8,
0xbf, 0x6a, 0xda, 0x96, 0x39, 0x77, 0x47, 0x30, 0x32, 0x97, 0xbf, 0xb6, 0x18, 0x99, 0xab, 0xae,
0x16, 0xb7, 0xd0, 0xf7, 0x61, 0x5d, 0xfd, 0x11, 0x42, 0xc5, 0xc5, 0xa5, 0xf2, 0xaf, 0x69, 0x70,
0x67, 0x0e, 0x6b, 0x18, 0x9f, 0x43, 0xb7, 0xf2, 0x1b, 0x11, 0xbd, 0x51, 0xd1, 0x55, 0xfd, 0xa1,
0x34, 0x78, 0x73, 0xf9, 0xa4, 0x91, 0x76, 0x08, 0x50, 0xfe, 0x34, 0x40, 0xae, 0xa6, 0x5e, 0xf8,
0x31, 0x35, 0xb8, 0xb7, 0x64, 0xc6, 0x08, 0x39, 0x83, 0xad, 0xf9, 0x07, 0x7c, 0x34, 0xe7, 0xd5,
0xf9, 0xe7, 0x73, 0xb3, 0x95, 0x2b, 0x5f, 0xfe, 0xa5, 0xd8, 0xf9, 0x67, 0x79, 0x23, 0x76, 0xc5,
0x4f, 0x01, 0x23, 0x76, 0xe5, 0x7b, 0xfe, 0x2d, 0xf4, 0x39, 0xf4, 0xaa, 0xef, 0xdc, 0xa8, 0x70,
0xd2, 0xd2, 0x87, 0xfe, 0xc1, 0x5b, 0x2b, 0x66, 0x8d, 0xc0, 0x0f, 0x60, 0x4d, 0x3d, 0x60, 0x17,
0xe9, 0x68, 0xbf, 0x7b, 0x0f, 0xb6, 0xab, 0x48, 0xc3, 0xf5, 0x10, 0xd6, 0xd5, 0xed, 0xd2, 0x04,
0x40, 0xe5, 0xb2, 0x39, 0xe8, 0xd8, 0x58, 0xef, 0xd6, 0xc3, 0x5a, 0xa1, 0x27, 0xab, 0xe8, 0xc9,
0x96, 0xe9, 0xb1, 0x36, 0xe7, 0x7c, 0x5d, 0xa6, 0xeb, 0xa3, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff,
0x4c, 0xa9, 0xa8, 0x4d, 0xd0, 0x1f, 0x00, 0x00,
}

View file

@ -210,6 +210,7 @@ message UpdateResource {
repeated ThrottleDevice blkioThrottleWriteBpsDevice = 15;
repeated ThrottleDevice blkioThrottleReadIopsDevice = 16;
repeated ThrottleDevice blkioThrottleWriteIopsDevice = 17;
uint64 pidsLimit = 18;
}
message BlockIODevice {

View file

@ -1,6 +1,10 @@
[![Build Status](https://jenkins.dockerproject.org/buildStatus/icon?job=runc Master)](https://jenkins.dockerproject.org/job/runc Master)
# runc
## runc
[![Build Status](https://travis-ci.org/opencontainers/runc.svg?branch=master)](https://travis-ci.org/opencontainers/runc)
[![Go Report Card](https://goreportcard.com/badge/github.com/opencontainers/runc)](https://goreportcard.com/report/github.com/opencontainers/runc)
[![GoDoc](https://godoc.org/github.com/opencontainers/runc?status.svg)](https://godoc.org/github.com/opencontainers/runc)
## Introduction
`runc` is a CLI tool for spawning and running containers according to the OCI specification.
@ -12,6 +16,11 @@ This means that `runc` 1.0.0 should implement the 1.0 version of the specificati
You can find official releases of `runc` on the [release](https://github.com/opencontainers/runc/releases) page.
### Security
If you wish to report a security issue, please disclose the issue responsibly
to security@opencontainers.org.
## Building
`runc` currently supports the Linux platform with various architecture support.
@ -68,6 +77,12 @@ You can run a specific test case by setting the `TESTFLAGS` variable.
# make test TESTFLAGS="-run=SomeTestFunction"
```
### Dependencies Management
`runc` uses [vndr](https://github.com/LK4D4/vndr) for dependencies management.
Please refer to [vndr](https://github.com/LK4D4/vndr) for how to add or update
new dependencies.
## Using runc
### Creating an OCI Bundle
@ -102,8 +117,8 @@ Assuming you have an OCI bundle from the previous step you can execute the conta
The first way is to use the convenience command `run` that will handle creating, starting, and deleting the container after it exits.
```bash
# run as root
cd /mycontainer
runc run mycontainerid
```
@ -150,8 +165,8 @@ Now we can go though the lifecycle operations in your shell.
```bash
# run as root
cd /mycontainer
runc create mycontainerid
# view the container is created and in the "created" state
@ -170,6 +185,22 @@ runc delete mycontainerid
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.
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.
#### Rootless containers
`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:
```bash
# Same as the first example
mkdir ~/mycontainer
cd ~/mycontainer
mkdir rootfs
docker export $(docker create busybox) | tar -C rootfs -xvf -
# 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.
runc spec --rootless
# The --root parameter tells runc where to store the container state. It must be writable by the user.
runc --root /tmp/runc run mycontainerid
```
#### Supervisors
`runc` can be used with process supervisors and init systems to ensure that containers are restarted when they exit.

View file

@ -1,3 +1,7 @@
# libcontainer
[![GoDoc](https://godoc.org/github.com/opencontainers/runc/libcontainer?status.svg)](https://godoc.org/github.com/opencontainers/runc/libcontainer)
Libcontainer provides a native Go implementation for creating containers
with namespaces, cgroups, capabilities, and filesystem access controls.
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
arg "init", we call the first step process "bootstrap", so you always need a "init"
function as the entry of "bootstrap".
In addition to the go init function the early stage bootstrap is handled by importing
[nsenter](https://github.com/opencontainers/runc/blob/master/libcontainer/nsenter/README.md).
```go
import (
_ "github.com/opencontainers/runc/libcontainer/nsenter"
)
func init() {
if len(os.Args) > 1 && os.Args[1] == "init" {
runtime.GOMAXPROCS(1)

View file

@ -27,9 +27,9 @@ type Manager interface {
// Destroys the cgroup set
Destroy() error
// NewCgroupManager() and LoadCgroupManager() require following attributes:
// The option func SystemdCgroups() and Cgroupfs() require following attributes:
// Paths map[string]string
// Cgroups *cgroups.Cgroup
// Cgroups *configs.Cgroup
// Paths maps cgroup subsystem to path at which it is mounted.
// Cgroups specifies specific cgroup settings for the various subsystems

View file

@ -23,36 +23,14 @@ const (
// https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
func FindCgroupMountpoint(subsystem string) (string, error) {
// We are not using mount.GetMounts() because it's super-inefficient,
// parsing it directly sped up x10 times because of not using Sscanf.
// It was one of two major performance drawbacks in container start.
if !isSubsystemAvailable(subsystem) {
return "", NewNotFoundError(subsystem)
}
f, err := os.Open("/proc/self/mountinfo")
if err != nil {
return "", err
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
txt := scanner.Text()
fields := strings.Split(txt, " ")
for _, opt := range strings.Split(fields[len(fields)-1], ",") {
if opt == subsystem {
return fields[4], nil
}
}
}
if err := scanner.Err(); err != nil {
return "", err
}
return "", NewNotFoundError(subsystem)
mnt, _, err := FindCgroupMountpointAndRoot(subsystem)
return mnt, err
}
func FindCgroupMountpointAndRoot(subsystem string) (string, string, error) {
// We are not using mount.GetMounts() because it's super-inefficient,
// parsing it directly sped up x10 times because of not using Sscanf.
// It was one of two major performance drawbacks in container start.
if !isSubsystemAvailable(subsystem) {
return "", "", NewNotFoundError(subsystem)
}
@ -131,7 +109,7 @@ type Mount struct {
Subsystems []string
}
func (m Mount) GetThisCgroupDir(cgroups map[string]string) (string, error) {
func (m Mount) GetOwnCgroup(cgroups map[string]string) (string, error) {
if len(m.Subsystems) == 0 {
return "", fmt.Errorf("no subsystem for mount")
}
@ -211,9 +189,6 @@ func GetAllSubsystems() ([]string, error) {
s := bufio.NewScanner(f)
for s.Scan() {
if err := s.Err(); err != nil {
return nil, err
}
text := s.Text()
if text[0] != '#' {
parts := strings.Fields(text)
@ -222,11 +197,14 @@ func GetAllSubsystems() ([]string, error) {
}
}
}
if err := s.Err(); err != nil {
return nil, err
}
return subsystems, nil
}
// GetThisCgroupDir returns the relative path to the cgroup docker is running in.
func GetThisCgroupDir(subsystem string) (string, error) {
// GetOwnCgroup returns the relative path to the cgroup docker is running in.
func GetOwnCgroup(subsystem string) (string, error) {
cgroups, err := ParseCgroupFile("/proc/self/cgroup")
if err != nil {
return "", err
@ -235,8 +213,16 @@ func GetThisCgroupDir(subsystem string) (string, error) {
return getControllerPath(subsystem, cgroups)
}
func GetInitCgroupDir(subsystem string) (string, error) {
func GetOwnCgroupPath(subsystem string) (string, error) {
cgroup, err := GetOwnCgroup(subsystem)
if err != nil {
return "", err
}
return getCgroupPathHelper(subsystem, cgroup)
}
func GetInitCgroup(subsystem string) (string, error) {
cgroups, err := ParseCgroupFile("/proc/1/cgroup")
if err != nil {
return "", err
@ -245,6 +231,31 @@ func GetInitCgroupDir(subsystem string) (string, error) {
return getControllerPath(subsystem, cgroups)
}
func GetInitCgroupPath(subsystem string) (string, error) {
cgroup, err := GetInitCgroup(subsystem)
if err != nil {
return "", err
}
return getCgroupPathHelper(subsystem, cgroup)
}
func getCgroupPathHelper(subsystem, cgroup string) (string, error) {
mnt, root, err := FindCgroupMountpointAndRoot(subsystem)
if err != nil {
return "", err
}
// This is needed for nested containers, because in /proc/self/cgroup we
// see pathes from host, which don't exist in container.
relCgroup, err := filepath.Rel(root, cgroup)
if err != nil {
return "", err
}
return filepath.Join(mnt, relCgroup), nil
}
func readProcsFile(dir string) ([]int, error) {
f, err := os.Open(filepath.Join(dir, CgroupProcesses))
if err != nil {
@ -287,10 +298,6 @@ func parseCgroupFromReader(r io.Reader) (map[string]string, error) {
cgroups := make(map[string]string)
for s.Scan() {
if err := s.Err(); err != nil {
return nil, err
}
text := s.Text()
// from cgroups(7):
// /proc/[pid]/cgroup
@ -307,6 +314,10 @@ func parseCgroupFromReader(r io.Reader) (map[string]string, error) {
cgroups[subs] = parts[2]
}
}
if err := s.Err(); err != nil {
return nil, err
}
return cgroups, nil
}

View file

@ -45,34 +45,34 @@ type Resources struct {
Devices []*Device `json:"devices"`
// Memory limit (in bytes)
Memory int64 `json:"memory"`
Memory uint64 `json:"memory"`
// Memory reservation or soft_limit (in bytes)
MemoryReservation int64 `json:"memory_reservation"`
MemoryReservation uint64 `json:"memory_reservation"`
// Total memory usage (memory + swap); set `-1` to enable unlimited swap
MemorySwap int64 `json:"memory_swap"`
MemorySwap uint64 `json:"memory_swap"`
// Kernel memory limit (in bytes)
KernelMemory int64 `json:"kernel_memory"`
KernelMemory uint64 `json:"kernel_memory"`
// Kernel memory limit for TCP use (in bytes)
KernelMemoryTCP int64 `json:"kernel_memory_tcp"`
KernelMemoryTCP uint64 `json:"kernel_memory_tcp"`
// CPU shares (relative weight vs. other containers)
CpuShares int64 `json:"cpu_shares"`
CpuShares uint64 `json:"cpu_shares"`
// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
CpuQuota int64 `json:"cpu_quota"`
// CPU period to be used for hardcapping (in usecs). 0 to use system default.
CpuPeriod int64 `json:"cpu_period"`
CpuPeriod uint64 `json:"cpu_period"`
// How many time CPU will use in realtime scheduling (in usecs).
CpuRtRuntime int64 `json:"cpu_rt_quota"`
// CPU period to be used for realtime scheduling (in usecs).
CpuRtPeriod int64 `json:"cpu_rt_period"`
CpuRtPeriod uint64 `json:"cpu_rt_period"`
// CPU to use
CpusetCpus string `json:"cpuset_cpus"`
@ -114,7 +114,7 @@ type Resources struct {
OomKillDisable bool `json:"oom_kill_disable"`
// Tuning swappiness behaviour per cgroup
MemorySwappiness *int64 `json:"memory_swappiness"`
MemorySwappiness *uint64 `json:"memory_swappiness"`
// Set priority of network traffic for container
NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap"`

View file

@ -8,6 +8,7 @@ import (
"time"
"github.com/Sirupsen/logrus"
"github.com/opencontainers/runtime-spec/specs-go"
)
type Rlimit struct {
@ -112,8 +113,8 @@ type Config struct {
Namespaces Namespaces `json:"namespaces"`
// Capabilities specify the capabilities to keep when executing the process inside the container
// All capbilities not specified will be dropped from the processes capability mask
Capabilities []string `json:"capabilities"`
// All capabilities not specified will be dropped from the processes capability mask
Capabilities *Capabilities `json:"capabilities"`
// Networks specifies the container's network setup to be created
Networks []*Network `json:"networks"`
@ -182,6 +183,9 @@ type Config struct {
// NoNewKeyring will not allocated a new session keyring for the container. It will use the
// callers keyring in this case.
NoNewKeyring bool `json:"no_new_keyring"`
// Rootless specifies whether the container is a rootless container.
Rootless bool `json:"rootless"`
}
type Hooks struct {
@ -196,6 +200,19 @@ type Hooks struct {
Poststop []Hook
}
type Capabilities struct {
// Bounding is the set of capabilities checked by the kernel.
Bounding []string
// Effective is the set of capabilities checked by the kernel.
Effective []string
// Inheritable is the capabilities preserved across execve.
Inheritable []string
// Permitted is the limiting superset for effective capabilities.
Permitted []string
// Ambient is the ambient set of capabilities that are kept.
Ambient []string
}
func (hooks *Hooks) UnmarshalJSON(b []byte) error {
var state struct {
Prestart []CommandHook
@ -243,13 +260,7 @@ func (hooks Hooks) MarshalJSON() ([]byte, error) {
}
// HookState is the payload provided to a hook on execution.
type HookState struct {
Version string `json:"ociVersion"`
ID string `json:"id"`
Pid int `json:"pid"`
Root string `json:"root"`
BundlePath string `json:"bundlePath"`
}
type HookState specs.State
type Hook interface {
// Run executes the hook with the provided state.

View file

@ -4,38 +4,50 @@ package configs
import "fmt"
// HostUID gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostUID() (int, error) {
// HostUID gets the translated uid for the process on host which could be
// different when user namespaces are enabled.
func (c Config) HostUID(containerId int) (int, error) {
if c.Namespaces.Contains(NEWUSER) {
if c.UidMappings == nil {
return -1, fmt.Errorf("User namespaces enabled, but no user mappings found.")
return -1, fmt.Errorf("User namespaces enabled, but no uid mappings found.")
}
id, found := c.hostIDFromMapping(0, c.UidMappings)
id, found := c.hostIDFromMapping(containerId, c.UidMappings)
if !found {
return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
return -1, fmt.Errorf("User namespaces enabled, but no user mapping found.")
}
return id, nil
}
// Return default root uid 0
return 0, nil
// Return unchanged id.
return containerId, nil
}
// HostGID gets the root gid for the process on host which could be non-zero
// HostRootUID gets the root uid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostGID() (int, error) {
func (c Config) HostRootUID() (int, error) {
return c.HostUID(0)
}
// HostGID gets the translated gid for the process on host which could be
// different when user namespaces are enabled.
func (c Config) HostGID(containerId int) (int, error) {
if c.Namespaces.Contains(NEWUSER) {
if c.GidMappings == nil {
return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
}
id, found := c.hostIDFromMapping(0, c.GidMappings)
id, found := c.hostIDFromMapping(containerId, c.GidMappings)
if !found {
return -1, fmt.Errorf("User namespaces enabled, but no root group mapping found.")
return -1, fmt.Errorf("User namespaces enabled, but no group mapping found.")
}
return id, nil
}
// Return default root gid 0
return 0, nil
// Return unchanged id.
return containerId, nil
}
// HostRootGID gets the root gid for the process on host which could be non-zero
// when user namespaces are enabled.
func (c Config) HostRootGID() (int, error) {
return c.HostGID(0)
}
// Utility function that gets a host ID for a container ID from user namespace map

View file

@ -4,12 +4,10 @@ package configs
func (n *Namespace) Syscall() int {
panic("No namespace syscall support")
return 0
}
// CloneFlags parses the container's Namespaces options to set the correct
// flags on clone, unshare. This function returns flags only for new namespaces.
func (n *Namespaces) CloneFlags() uintptr {
panic("No namespace syscall support")
return uintptr(0)
}

View file

@ -23,7 +23,7 @@ var (
ioutilReadDir = ioutil.ReadDir
)
// 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.
// 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.
func DeviceFromPath(path, permissions string) (*configs.Device, error) {
fileInfo, err := osLstat(path)
if err != nil {
@ -75,7 +75,8 @@ func getDevices(path string) ([]*configs.Device, error) {
switch {
case f.IsDir():
switch f.Name() {
case "pts", "shm", "fd", "mqueue":
// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts":
continue
default:
sub, err := getDevices(filepath.Join(path, f.Name()))
@ -94,6 +95,9 @@ func getDevices(path string) ([]*configs.Device, error) {
if err == ErrNotADevice {
continue
}
if os.IsNotExist(err) {
continue
}
return nil, err
}
out = append(out, device)

View file

@ -33,6 +33,8 @@ enum sync_t {
SYNC_USERMAP_ACK = 0x41, /* Mapping finished by the parent. */
SYNC_RECVPID_PLS = 0x42, /* Tell parent we're sending the PID. */
SYNC_RECVPID_ACK = 0x43, /* PID was correctly received by parent. */
SYNC_GRANDCHILD = 0x44, /* The grandchild is ready to run. */
SYNC_CHILD_READY = 0x45, /* The child or grandchild is ready to return. */
/* XXX: This doesn't help with segfaults and other such issues. */
SYNC_ERR = 0xFF, /* Fatal error, no turning back. The error code follows. */
@ -70,7 +72,9 @@ struct nlconfig_t {
char *namespaces;
size_t namespaces_len;
uint8_t is_setgroup;
int consolefd;
uint8_t is_rootless;
char *oom_score_adj;
size_t oom_score_adj_len;
};
/*
@ -79,11 +83,12 @@ struct nlconfig_t {
*/
#define INIT_MSG 62000
#define CLONE_FLAGS_ATTR 27281
#define CONSOLE_PATH_ATTR 27282
#define NS_PATHS_ATTR 27283
#define UIDMAP_ATTR 27284
#define GIDMAP_ATTR 27285
#define SETGROUP_ATTR 27286
#define NS_PATHS_ATTR 27282
#define UIDMAP_ATTR 27283
#define GIDMAP_ATTR 27284
#define SETGROUP_ATTR 27285
#define OOM_SCORE_ADJ_ATTR 27286
#define ROOTLESS_ATTR 27287
/*
* 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)
policy = "deny";
break;
case SETGROUPS_DEFAULT:
default:
/* Nothing to do. */
return;
}
@ -186,7 +192,7 @@ static void update_setgroups(int pid, enum policy_t setgroup)
}
}
static void update_uidmap(int pid, char *map, int map_len)
static void update_uidmap(int pid, char *map, size_t map_len)
{
if (map == NULL || map_len <= 0)
return;
@ -195,7 +201,7 @@ static void update_uidmap(int pid, char *map, int map_len)
bail("failed to update /proc/%d/uid_map", pid);
}
static void update_gidmap(int pid, char *map, int map_len)
static void update_gidmap(int pid, char *map, size_t map_len)
{
if (map == NULL || map_len <= 0)
return;
@ -204,6 +210,15 @@ static void update_gidmap(int pid, char *map, int map_len)
bail("failed to update /proc/%d/gid_map", pid);
}
static void update_oom_score_adj(char *data, size_t len)
{
if (data == NULL || len <= 0)
return;
if (write_file(data, len, "/proc/self/oom_score_adj") < 0)
bail("failed to update /proc/self/oom_score_adj");
}
/* A dummy function that just jumps to the given jumpval. */
static int child_func(void *arg) __attribute__ ((noinline));
static int child_func(void *arg)
@ -285,7 +300,7 @@ static void nl_parse(int fd, struct nlconfig_t *config)
/* Retrieve the netlink header. */
len = read(fd, &hdr, NLMSG_HDRLEN);
if (len != NLMSG_HDRLEN)
bail("invalid netlink header length %lu", len);
bail("invalid netlink header length %zu", len);
if (hdr.nlmsg_type == NLMSG_ERROR)
bail("failed to read netlink message");
@ -301,11 +316,10 @@ static void nl_parse(int fd, struct nlconfig_t *config)
len = read(fd, data, size);
if (len != size)
bail("failed to read netlink payload, %lu != %lu", len, size);
bail("failed to read netlink payload, %zu != %zu", len, size);
/* Parse the netlink payload. */
config->data = data;
config->consolefd = -1;
while (current < data + size) {
struct nlattr *nlattr = (struct nlattr *)current;
size_t payload_len = nlattr->nla_len - NLA_HDRLEN;
@ -318,14 +332,12 @@ static void nl_parse(int fd, struct nlconfig_t *config)
case CLONE_FLAGS_ATTR:
config->cloneflags = readint32(current);
break;
case CONSOLE_PATH_ATTR:
/*
* We open the console here because we currently evaluate console
* paths from the *host* namespaces.
*/
config->consolefd = open(current, O_RDWR);
if (config->consolefd < 0)
bail("failed to open console %s", current);
case ROOTLESS_ATTR:
config->is_rootless = readint8(current);
break;
case OOM_SCORE_ADJ_ATTR:
config->oom_score_adj = current;
config->oom_score_adj_len = payload_len;
break;
case NS_PATHS_ATTR:
config->namespaces = current;
@ -394,7 +406,7 @@ void join_namespaces(char *nslist)
fd = open(path, O_RDONLY);
if (fd < 0)
bail("failed to open %s", namespace);
bail("failed to open %s", path);
ns->fd = fd;
ns->ns = nsflag(namespace);
@ -424,7 +436,7 @@ void nsexec(void)
{
int pipenum;
jmp_buf env;
int syncpipe[2];
int sync_child_pipe[2], sync_grandchild_pipe[2];
struct nlconfig_t config = {0};
/*
@ -435,18 +447,43 @@ void nsexec(void)
if (pipenum == -1)
return;
/* make the process non-dumpable */
if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) {
bail("failed to set process as non-dumpable");
}
/* Parse all of the netlink configuration. */
nl_parse(pipenum, &config);
/* Set oom_score_adj. This has to be done before !dumpable because
* /proc/self/oom_score_adj is not writeable unless you're an privileged
* user (if !dumpable is set). All children inherit their parent's
* oom_score_adj value on fork(2) so this will always be propagated
* properly.
*/
update_oom_score_adj(config.oom_score_adj, config.oom_score_adj_len);
/*
* Make the process non-dumpable, to avoid various race conditions that
* could cause processes in namespaces we're joining to access host
* resources (or potentially execute code).
*
* However, if the number of namespaces we are joining is 0, we are not
* going to be switching to a different security context. Thus setting
* ourselves to be non-dumpable only breaks things (like rootless
* containers), which is the recommendation from the kernel folks.
*/
if (config.namespaces) {
if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) < 0)
bail("failed to set process as non-dumpable");
}
/* Pipe so we can tell the child when we've finished setting up. */
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, syncpipe) < 0)
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sync_child_pipe) < 0)
bail("failed to setup sync pipe between parent and child");
/*
* We need a new socketpair to sync with grandchild so we don't have
* race condition with child.
*/
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sync_grandchild_pipe) < 0)
bail("failed to setup sync pipe between parent and grandchild");
/* TODO: Currently we aren't dealing with child deaths properly. */
/*
@ -508,6 +545,7 @@ void nsexec(void)
int len;
pid_t child;
char buf[JSON_MAX];
bool ready = false;
/* For debugging. */
prctl(PR_SET_NAME, (unsigned long) "runc:[0:PARENT]", 0, 0, 0);
@ -517,31 +555,46 @@ void nsexec(void)
if (child < 0)
bail("unable to fork: child_func");
/* State machine for synchronisation with the children. */
while (true) {
/*
* State machine for synchronisation with the children.
*
* Father only return when both child and grandchild are
* ready, so we can receive all possible error codes
* generated by children.
*/
while (!ready) {
enum sync_t s;
int ret;
/* This doesn't need to be global, we're in the parent. */
int syncfd = syncpipe[1];
syncfd = sync_child_pipe[1];
close(sync_child_pipe[0]);
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
bail("failed to sync with child: next state");
switch (s) {
case SYNC_ERR: {
case SYNC_ERR:
/* We have to mirror the error code of the child. */
int ret;
if (read(syncfd, &ret, sizeof(ret)) != sizeof(ret))
bail("failed to sync with child: read(error code)");
exit(ret);
}
break;
case SYNC_USERMAP_PLS:
/* Enable setgroups(2) if we've been asked to. */
/*
* Enable setgroups(2) if we've been asked to. But we also
* have to explicitly disable setgroups(2) if we're
* creating a rootless container (this is required since
* Linux 3.19).
*/
if (config.is_rootless && config.is_setgroup) {
kill(child, SIGKILL);
bail("cannot allow setgroup in an unprivileged user namespace setup");
}
if (config.is_setgroup)
update_setgroups(child, SETGROUPS_ALLOW);
if (config.is_rootless)
update_setgroups(child, SETGROUPS_DENY);
/* Set up mappings. */
update_uidmap(child, config.uidmap, config.uidmap_len);
@ -553,11 +606,6 @@ void nsexec(void)
bail("failed to sync with child: write(SYNC_USERMAP_ACK)");
}
break;
case SYNC_USERMAP_ACK:
/* We should _never_ receive acks. */
kill(child, SIGKILL);
bail("failed to sync with child: unexpected SYNC_USERMAP_ACK");
break;
case SYNC_RECVPID_PLS: {
pid_t old = child;
@ -575,18 +623,49 @@ void nsexec(void)
bail("failed to sync with child: write(SYNC_RECVPID_ACK)");
}
}
/* Leave the loop. */
goto out;
case SYNC_RECVPID_ACK:
/* We should _never_ receive acks. */
kill(child, SIGKILL);
bail("failed to sync with child: unexpected SYNC_RECVPID_ACK");
break;
case SYNC_CHILD_READY:
ready = true;
break;
default:
bail("unexpected sync value: %u", s);
}
}
/* Now sync with grandchild. */
ready = false;
while (!ready) {
enum sync_t s;
int ret;
syncfd = sync_grandchild_pipe[1];
close(sync_grandchild_pipe[0]);
s = SYNC_GRANDCHILD;
if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
kill(child, SIGKILL);
bail("failed to sync with child: write(SYNC_GRANDCHILD)");
}
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
bail("failed to sync with child: next state");
switch (s) {
case SYNC_ERR:
/* We have to mirror the error code of the child. */
if (read(syncfd, &ret, sizeof(ret)) != sizeof(ret))
bail("failed to sync with child: read(error code)");
exit(ret);
case SYNC_CHILD_READY:
ready = true;
break;
default:
bail("unexpected sync value: %u", s);
}
}
out:
/* Send the init_func pid back to our parent. */
len = snprintf(buf, JSON_MAX, "{\"pid\": %d}\n", child);
if (len < 0) {
@ -615,7 +694,8 @@ void nsexec(void)
enum sync_t s;
/* We're in a child and thus need to tell the parent if we die. */
syncfd = syncpipe[0];
syncfd = sync_child_pipe[0];
close(sync_child_pipe[1]);
/* For debugging. */
prctl(PR_SET_NAME, (unsigned long) "runc:[1:CHILD]", 0, 0, 0);
@ -653,6 +733,11 @@ void nsexec(void)
* clone_parent rant). So signal our parent to hook us up.
*/
/* Switching is only necessary if we joined namespaces. */
if (config.namespaces) {
if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0)
bail("failed to set process as dumpable");
}
s = SYNC_USERMAP_PLS;
if (write(syncfd, &s, sizeof(s)) != sizeof(s))
bail("failed to sync with parent: write(SYNC_USERMAP_PLS)");
@ -663,6 +748,11 @@ void nsexec(void)
bail("failed to sync with parent: read(SYNC_USERMAP_ACK)");
if (s != SYNC_USERMAP_ACK)
bail("failed to sync with parent: SYNC_USERMAP_ACK: got %u", s);
/* Switching is only necessary if we joined namespaces. */
if (config.namespaces) {
if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) < 0)
bail("failed to set process as dumpable");
}
}
/*
@ -700,6 +790,12 @@ void nsexec(void)
bail("failed to sync with parent: SYNC_RECVPID_ACK: got %u", s);
}
s = SYNC_CHILD_READY;
if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
kill(child, SIGKILL);
bail("failed to sync with parent: write(SYNC_CHILD_READY)");
}
/* Our work is done. [Stage 2: JUMP_INIT] is doing the rest of the work. */
exit(0);
}
@ -715,14 +811,22 @@ void nsexec(void)
* We're inside the child now, having jumped from the
* start_child() code after forking in the parent.
*/
int consolefd = config.consolefd;
enum sync_t s;
/* We're in a child and thus need to tell the parent if we die. */
syncfd = syncpipe[0];
syncfd = sync_grandchild_pipe[0];
close(sync_grandchild_pipe[1]);
close(sync_child_pipe[0]);
close(sync_child_pipe[1]);
/* For debugging. */
prctl(PR_SET_NAME, (unsigned long) "runc:[2:INIT]", 0, 0, 0);
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
bail("failed to sync with parent: read(SYNC_GRANDCHILD)");
if (s != SYNC_GRANDCHILD)
bail("failed to sync with parent: SYNC_GRANDCHILD: got %u", s);
if (setsid() < 0)
bail("setsid failed");
@ -732,23 +836,17 @@ void nsexec(void)
if (setgid(0) < 0)
bail("setgid failed");
if (!config.is_rootless && config.is_setgroup) {
if (setgroups(0, NULL) < 0)
bail("setgroups failed");
if (consolefd != -1) {
if (ioctl(consolefd, TIOCSCTTY, 0) < 0)
bail("ioctl TIOCSCTTY failed");
if (dup3(consolefd, STDIN_FILENO, 0) != STDIN_FILENO)
bail("failed to dup stdin");
if (dup3(consolefd, STDOUT_FILENO, 0) != STDOUT_FILENO)
bail("failed to dup stdout");
if (dup3(consolefd, STDERR_FILENO, 0) != STDERR_FILENO)
bail("failed to dup stderr");
}
s = SYNC_CHILD_READY;
if (write(syncfd, &s, sizeof(s)) != sizeof(s))
bail("failed to sync with patent: write(SYNC_CHILD_READY)");
/* Close sync pipes. */
close(syncpipe[0]);
close(syncpipe[1]);
close(sync_grandchild_pipe[0]);
/* Free netlink data. */
nl_free(&config);
@ -758,7 +856,6 @@ void nsexec(void)
}
default:
bail("unexpected jump value");
break;
}
/* Should never be reached. */

View file

@ -199,18 +199,16 @@ type ExecUser struct {
// files cannot be opened for any reason, the error is ignored and a nil
// io.Reader is passed instead.
func GetExecUserPath(userSpec string, defaults *ExecUser, passwdPath, groupPath string) (*ExecUser, error) {
passwd, err := os.Open(passwdPath)
if err != nil {
passwd = nil
} else {
defer passwd.Close()
var passwd, group io.Reader
if passwdFile, err := os.Open(passwdPath); err == nil {
passwd = passwdFile
defer passwdFile.Close()
}
group, err := os.Open(groupPath)
if err != nil {
group = nil
} else {
defer group.Close()
if groupFile, err := os.Open(groupPath); err == nil {
group = groupFile
defer groupFile.Close()
}
return GetExecUser(userSpec, defaults, passwd, group)
@ -343,7 +341,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
if len(groups) > 0 {
// First match wins, even if there's more than one matching entry.
user.Gid = groups[0].Gid
} else if groupArg != "" {
} else {
// If we can't find a group with the given name, the only other valid
// option is if it's a numeric group name with no associated entry in group.
@ -433,9 +431,11 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err
// that opens the groupPath given and gives it as an argument to
// GetAdditionalGroups.
func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int, error) {
group, err := os.Open(groupPath)
if err == nil {
defer group.Close()
var group io.Reader
if groupFile, err := os.Open(groupPath); err == nil {
group = groupFile
defer groupFile.Close()
}
return GetAdditionalGroups(additionalGroups, group)
}

21
vendor/github.com/opencontainers/runc/vendor.conf generated vendored Normal file
View file

@ -0,0 +1,21 @@
# OCI runtime-spec. When updating this, make sure you use a version tag rather
# than a commit ID so it's much more obvious what version of the spec we are
# using.
github.com/opencontainers/runtime-spec v1.0.0-rc5
# Core libcontainer functionality.
github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
github.com/opencontainers/selinux v1.0.0-rc1
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
github.com/Sirupsen/logrus 26709e2714106fb8ad40b773b711ebce25b78914
github.com/syndtr/gocapability e7cb7fa329f456b3855136a2642b197bad7366ba
github.com/vishvananda/netlink 1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270
# systemd integration.
github.com/coreos/go-systemd v14
github.com/coreos/pkg v3
github.com/godbus/dbus v3
github.com/golang/protobuf f7137ae6b19afbfd61a94b746fda3b3fe0491874
# Command-line interface.
github.com/docker/docker 0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d
github.com/docker/go-units v0.2.0
github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
golang.org/x/sys 9a7256cb28ed514b4e1e5f68959914c4c28a92e0 https://github.com/golang/sys

View file

@ -1,76 +1,53 @@
# Open Container Initiative Runtime Specification
The [Open Container Initiative](http://www.opencontainers.org/) develops specifications for standards on Operating System process and application containers.
The [Open Container Initiative][oci] develops specifications for standards on Operating System process and application containers.
The specification can be found [here](spec.md).
Table of Contents
## Table of Contents
- [Introduction](README.md)
- [Code of Conduct](#code-of-conduct)
- [Container Principles](principles.md)
Additional documentation about how this group operates:
- [Code of Conduct][code-of-conduct]
- [Style and Conventions](style.md)
- [Roadmap](ROADMAP.md)
- [Implementations](implementations.md)
- [Releases](RELEASES.md)
- [project](project.md)
- [Filesystem Bundle](bundle.md)
- Runtime and Lifecycle
- [General Runtime and Lifecycle](runtime.md)
- [Linux-specific Runtime and Lifecycle](runtime-linux.md)
- Configuration
- [General Configuration](config.md)
- [Linux-specific Configuration](config-linux.md)
- [Solaris-specific Configuration](config-solaris.md)
- [Windows-specific Configuration](config-windows.md)
- [Glossary](glossary.md)
- [charter][charter]
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).
The keywords "unspecified", "undefined", and "implementation-defined" are to be interpreted as described in the [rationale for the C99 standard][c99-unspecified].
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.
An implementation is compliant for a given CPU architecture if it satisfies all the MUST, REQUIRED, and SHALL requirements for the protocols it implements.
Protocols defined by this specification are:
* Linux containers: [runtime.md](runtime.md), [config.md](config.md), [config-linux.md](config-linux.md), and [runtime-linux.md](runtime-linux.md).
* Solaris containers: [runtime.md](runtime.md), [config.md](config.md), and [config-solaris.md](config-solaris.md).
* Windows containers: [runtime.md](runtime.md), [config.md](config.md), and [config-windows.md](config-windows.md).
# Use Cases
## Use Cases
To provide context for users the following section gives example use cases for each part of the spec.
#### Application Bundle Builders
### Application Bundle Builders
Application bundle builders can create a [bundle](bundle.md) directory that includes all of the files required for launching an application as a container.
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).
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).
Because the configuration includes host-specific settings, application bundle directories copied between two hosts may require configuration adjustments.
#### Hook Developers
### Hook Developers
[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.
Example use cases include sophisticated network configuration, volume garbage collection, etc.
#### Runtime Developers
### Runtime Developers
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.
# Releases
## Releases
There is a loose [Road Map](./ROADMAP.md).
During the `0.x` series of OCI releases we make no backwards compatibility guarantees and intend to break the schema during this series.
# Contributing
## Contributing
Development happens on GitHub for the spec.
Issues are used for bugs and actionable items and longer discussions can happen on the [mailing list](#mailing-list).
The specification and code is licensed under the Apache 2.0 license found in the [LICENSE](./LICENSE) file.
## Code of Conduct
Participation in the OpenContainers community is governed by [OpenContainer's Code of Conduct](https://github.com/opencontainers/tob/blob/d2f9d68c1332870e40693fe077d311e0742bc73d/code-of-conduct.md).
## Discuss your design
### Discuss your design
The project welcomes submissions, but please let everyone know what you are working on.
@ -81,27 +58,27 @@ It also guarantees that the design is sound before code is written; a GitHub pul
Typos and grammatical errors can go straight to a pull-request.
When in doubt, start on the [mailing-list](#mailing-list).
## Weekly Call
### Weekly Call
The contributors and maintainers of all OCI projects have a weekly meeting Wednesdays at 2:00 PM (USA Pacific).
Everyone is welcome to participate via [UberConference web][UberConference] or audio-only: 415-968-0849 (no PIN needed.)
Everyone is welcome to participate via [UberConference web][uberconference] or audio-only: 415-968-0849 (no PIN needed.)
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.
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.
Minutes are posted to the [mailing list](#mailing-list) and minutes from past calls are archived to the [wiki][runtime-wiki].
## Mailing List
### Mailing List
You can subscribe and join the mailing list on [Google Groups](https://groups.google.com/a/opencontainers.org/forum/#!forum/dev).
You can subscribe and join the mailing list on [Google Groups][dev-list].
## IRC
### IRC
OCI discussion happens on #opencontainers on Freenode ([logs][irc-logs]).
## Git commit
### Git commit
### Sign your work
#### Sign your work
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.
The rules are pretty simple: if you can certify the below (from [developercertificate.org](http://developercertificate.org/)):
The rules are pretty simple: if you can certify the below (from http://developercertificate.org):
```
Developer Certificate of Origin
@ -150,10 +127,10 @@ using your real name (sorry, no pseudonyms or anonymous contributions.)
You can add the sign off when creating the git commit via `git commit -s`.
### Commit Style
#### Commit Style
Simple house-keeping for clean git history.
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).
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].
1. Separate the subject from body with a blank line
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
* If there was important/useful/essential conversation or information, copy or include a reference
8. When possible, one keyword to scope the change in the subject (i.e. "README: ...", "runtime: ...")
[c99-unspecified]: http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf#page=18
[UberConference]: https://www.uberconference.com/opencontainers
[charter]: https://www.opencontainers.org/about/governance
[code-of-conduct]: https://github.com/opencontainers/tob/blob/master/code-of-conduct.md
[dev-list]: https://groups.google.com/a/opencontainers.org/forum/#!forum/dev
[how-to-git-commit]: http://chris.beams.io/posts/git-commit
[irc-logs]: http://ircbot.wl.linuxfoundation.org/eavesdrop/%23opencontainers/
[oci]: https://www.opencontainers.org
[runtime-wiki]: https://github.com/opencontainers/runtime-spec/wiki
[uberconference]: https://www.uberconference.com/opencontainers
[git-commit.1]: http://git-scm.com/docs/git-commit

View file

@ -17,7 +17,7 @@ type Spec struct {
// Mounts configures additional mounts (on top of Root).
Mounts []Mount `json:"mounts,omitempty"`
// Hooks configures callbacks for container lifecycle events.
Hooks Hooks `json:"hooks"`
Hooks *Hooks `json:"hooks,omitempty"`
// Annotations contains arbitrary metadata for the container.
Annotations map[string]string `json:"annotations,omitempty"`
@ -44,10 +44,10 @@ type Process struct {
// Cwd is the current working directory for the process and must be
// relative to the container's root.
Cwd string `json:"cwd"`
// Capabilities are Linux capabilities that are kept for the container.
Capabilities []string `json:"capabilities,omitempty" platform:"linux"`
// Capabilities are Linux capabilities that are kept for the process.
Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"`
// Rlimits specifies rlimit options to apply to the process.
Rlimits []Rlimit `json:"rlimits,omitempty" platform:"linux"`
Rlimits []LinuxRlimit `json:"rlimits,omitempty" platform:"linux"`
// NoNewPrivileges controls whether additional privileges could be gained by processes in the container.
NoNewPrivileges bool `json:"noNewPrivileges,omitempty" platform:"linux"`
// ApparmorProfile specifies the apparmor profile for the container.
@ -56,6 +56,21 @@ type Process struct {
SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"`
}
// LinuxCapabilities specifies the whitelist of capabilities that are kept for a process.
// http://man7.org/linux/man-pages/man7/capabilities.7.html
type LinuxCapabilities struct {
// Bounding is the set of capabilities checked by the kernel.
Bounding []string `json:"bounding,omitempty" platform:"linux"`
// Effective is the set of capabilities checked by the kernel.
Effective []string `json:"effective,omitempty" platform:"linux"`
// Inheritable is the capabilities preserved across execve.
Inheritable []string `json:"inheritable,omitempty" platform:"linux"`
// Permitted is the limiting superset for effective capabilities.
Permitted []string `json:"permitted,omitempty" platform:"linux"`
// Ambient is the ambient set of capabilities that are kept.
Ambient []string `json:"ambient,omitempty" platform:"linux"`
}
// Box specifies dimensions of a rectangle. Used for specifying the size of a console.
type Box struct {
// Height is the vertical dimension of a box.
@ -98,10 +113,10 @@ type Mount struct {
// 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.
Destination string `json:"destination"`
// Type specifies the mount kind.
Type string `json:"type"`
Type string `json:"type,omitempty"`
// Source specifies the source path of the mount. In the case of bind mounts on
// Linux based systems this would be the file on the host.
Source string `json:"source"`
Source string `json:"source,omitempty"`
// Options are fstab style mount options.
Options []string `json:"options,omitempty"`
}
@ -128,24 +143,24 @@ type Hooks struct {
// Linux contains platform specific configuration for Linux based containers.
type Linux struct {
// UIDMapping specifies user mappings for supporting user namespaces on Linux.
UIDMappings []IDMapping `json:"uidMappings,omitempty"`
UIDMappings []LinuxIDMapping `json:"uidMappings,omitempty"`
// GIDMapping specifies group mappings for supporting user namespaces on Linux.
GIDMappings []IDMapping `json:"gidMappings,omitempty"`
GIDMappings []LinuxIDMapping `json:"gidMappings,omitempty"`
// Sysctl are a set of key value pairs that are set for the container on start
Sysctl map[string]string `json:"sysctl,omitempty"`
// Resources contain cgroup information for handling resource constraints
// for the container
Resources *Resources `json:"resources,omitempty"`
Resources *LinuxResources `json:"resources,omitempty"`
// CgroupsPath specifies the path to cgroups that are created and/or joined by the container.
// The path is expected to be relative to the cgroups mountpoint.
// If resources are specified, the cgroups at CgroupsPath will be updated based on resources.
CgroupsPath *string `json:"cgroupsPath,omitempty"`
CgroupsPath string `json:"cgroupsPath,omitempty"`
// Namespaces contains the namespaces that are created and/or joined by the container
Namespaces []Namespace `json:"namespaces,omitempty"`
Namespaces []LinuxNamespace `json:"namespaces,omitempty"`
// Devices are a list of device nodes that are created for the container
Devices []Device `json:"devices,omitempty"`
Devices []LinuxDevice `json:"devices,omitempty"`
// Seccomp specifies the seccomp security settings for the container.
Seccomp *Seccomp `json:"seccomp,omitempty"`
Seccomp *LinuxSeccomp `json:"seccomp,omitempty"`
// RootfsPropagation is the rootfs mount propagation mode for the container.
RootfsPropagation string `json:"rootfsPropagation,omitempty"`
// MaskedPaths masks over the provided paths inside the container.
@ -156,21 +171,21 @@ type Linux struct {
MountLabel string `json:"mountLabel,omitempty"`
}
// Namespace is the configuration for a Linux namespace
type Namespace struct {
// LinuxNamespace is the configuration for a Linux namespace
type LinuxNamespace struct {
// Type is the type of Linux namespace
Type NamespaceType `json:"type"`
Type LinuxNamespaceType `json:"type"`
// Path is a path to an existing namespace persisted on disk that can be joined
// and is of the same type
Path string `json:"path,omitempty"`
}
// NamespaceType is one of the Linux namespaces
type NamespaceType string
// LinuxNamespaceType is one of the Linux namespaces
type LinuxNamespaceType string
const (
// PIDNamespace for isolating process IDs
PIDNamespace NamespaceType = "pid"
PIDNamespace LinuxNamespaceType = "pid"
// NetworkNamespace for isolating network devices, stacks, ports, etc
NetworkNamespace = "network"
// MountNamespace for isolating mount points
@ -185,18 +200,18 @@ const (
CgroupNamespace = "cgroup"
)
// IDMapping specifies UID/GID mappings
type IDMapping struct {
// HostID is the UID/GID of the host user or group
// LinuxIDMapping specifies UID/GID mappings
type LinuxIDMapping struct {
// HostID is the starting UID/GID on the host to be mapped to 'ContainerID'
HostID uint32 `json:"hostID"`
// ContainerID is the UID/GID of the container's user or group
// ContainerID is the starting UID/GID in the container
ContainerID uint32 `json:"containerID"`
// Size is the length of the range of IDs mapped between the two namespaces
// Size is the number of IDs to be mapped
Size uint32 `json:"size"`
}
// Rlimit type and restrictions
type Rlimit struct {
// LinuxRlimit type and restrictions
type LinuxRlimit struct {
// Type of the rlimit to set
Type string `json:"type"`
// Hard is the hard limit for the specified type
@ -205,66 +220,66 @@ type Rlimit struct {
Soft uint64 `json:"soft"`
}
// HugepageLimit structure corresponds to limiting kernel hugepages
type HugepageLimit struct {
// LinuxHugepageLimit structure corresponds to limiting kernel hugepages
type LinuxHugepageLimit struct {
// Pagesize is the hugepage size
Pagesize *string `json:"pageSize,omitempty"`
Pagesize string `json:"pageSize"`
// Limit is the limit of "hugepagesize" hugetlb usage
Limit *uint64 `json:"limit,omitempty"`
Limit uint64 `json:"limit"`
}
// InterfacePriority for network interfaces
type InterfacePriority struct {
// LinuxInterfacePriority for network interfaces
type LinuxInterfacePriority struct {
// Name is the name of the network interface
Name string `json:"name"`
// Priority for the interface
Priority uint32 `json:"priority"`
}
// blockIODevice holds major:minor format supported in blkio cgroup
type blockIODevice struct {
// linuxBlockIODevice holds major:minor format supported in blkio cgroup
type linuxBlockIODevice struct {
// Major is the device's major number.
Major int64 `json:"major"`
// Minor is the device's minor number.
Minor int64 `json:"minor"`
}
// WeightDevice struct holds a `major:minor weight` pair for blkioWeightDevice
type WeightDevice struct {
blockIODevice
// LinuxWeightDevice struct holds a `major:minor weight` pair for blkioWeightDevice
type LinuxWeightDevice struct {
linuxBlockIODevice
// Weight is the bandwidth rate for the device, range is from 10 to 1000
Weight *uint16 `json:"weight,omitempty"`
// 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
LeafWeight *uint16 `json:"leafWeight,omitempty"`
}
// ThrottleDevice struct holds a `major:minor rate_per_second` pair
type ThrottleDevice struct {
blockIODevice
// LinuxThrottleDevice struct holds a `major:minor rate_per_second` pair
type LinuxThrottleDevice struct {
linuxBlockIODevice
// Rate is the IO rate limit per cgroup per device
Rate *uint64 `json:"rate,omitempty"`
Rate uint64 `json:"rate"`
}
// BlockIO for Linux cgroup 'blkio' resource management
type BlockIO struct {
// LinuxBlockIO for Linux cgroup 'blkio' resource management
type LinuxBlockIO struct {
// Specifies per cgroup weight, range is from 10 to 1000
Weight *uint16 `json:"blkioWeight,omitempty"`
// Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, range is from 10 to 1000, CFQ scheduler only
LeafWeight *uint16 `json:"blkioLeafWeight,omitempty"`
// Weight per cgroup per device, can override BlkioWeight
WeightDevice []WeightDevice `json:"blkioWeightDevice,omitempty"`
WeightDevice []LinuxWeightDevice `json:"blkioWeightDevice,omitempty"`
// IO read rate limit per cgroup per device, bytes per second
ThrottleReadBpsDevice []ThrottleDevice `json:"blkioThrottleReadBpsDevice,omitempty"`
ThrottleReadBpsDevice []LinuxThrottleDevice `json:"blkioThrottleReadBpsDevice,omitempty"`
// IO write rate limit per cgroup per device, bytes per second
ThrottleWriteBpsDevice []ThrottleDevice `json:"blkioThrottleWriteBpsDevice,omitempty"`
ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"blkioThrottleWriteBpsDevice,omitempty"`
// IO read rate limit per cgroup per device, IO per second
ThrottleReadIOPSDevice []ThrottleDevice `json:"blkioThrottleReadIOPSDevice,omitempty"`
ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleReadIOPSDevice,omitempty"`
// IO write rate limit per cgroup per device, IO per second
ThrottleWriteIOPSDevice []ThrottleDevice `json:"blkioThrottleWriteIOPSDevice,omitempty"`
ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleWriteIOPSDevice,omitempty"`
}
// Memory for Linux cgroup 'memory' resource management
type Memory struct {
// LinuxMemory for Linux cgroup 'memory' resource management
type LinuxMemory struct {
// Memory limit (in bytes).
Limit *uint64 `json:"limit,omitempty"`
// Memory reservation or soft_limit (in bytes).
@ -279,62 +294,62 @@ type Memory struct {
Swappiness *uint64 `json:"swappiness,omitempty"`
}
// CPU for Linux cgroup 'cpu' resource management
type CPU struct {
// LinuxCPU for Linux cgroup 'cpu' resource management
type LinuxCPU struct {
// CPU shares (relative weight (ratio) vs. other cgroups with cpu shares).
Shares *uint64 `json:"shares,omitempty"`
// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
Quota *uint64 `json:"quota,omitempty"`
Quota *int64 `json:"quota,omitempty"`
// CPU period to be used for hardcapping (in usecs).
Period *uint64 `json:"period,omitempty"`
// How much time realtime scheduling may use (in usecs).
RealtimeRuntime *uint64 `json:"realtimeRuntime,omitempty"`
RealtimeRuntime *int64 `json:"realtimeRuntime,omitempty"`
// CPU period to be used for realtime scheduling (in usecs).
RealtimePeriod *uint64 `json:"realtimePeriod,omitempty"`
// CPUs to use within the cpuset. Default is to use any CPU available.
Cpus *string `json:"cpus,omitempty"`
Cpus string `json:"cpus,omitempty"`
// List of memory nodes in the cpuset. Default is to use any available memory node.
Mems *string `json:"mems,omitempty"`
Mems string `json:"mems,omitempty"`
}
// Pids for Linux cgroup 'pids' resource management (Linux 4.3)
type Pids struct {
// LinuxPids for Linux cgroup 'pids' resource management (Linux 4.3)
type LinuxPids struct {
// Maximum number of PIDs. Default is "no limit".
Limit *int64 `json:"limit,omitempty"`
Limit int64 `json:"limit"`
}
// Network identification and priority configuration
type Network struct {
// LinuxNetwork identification and priority configuration
type LinuxNetwork struct {
// Set class identifier for container's network packets
ClassID *uint32 `json:"classID,omitempty"`
// Set priority of network traffic for container
Priorities []InterfacePriority `json:"priorities,omitempty"`
Priorities []LinuxInterfacePriority `json:"priorities,omitempty"`
}
// Resources has container runtime resource constraints
type Resources struct {
// LinuxResources has container runtime resource constraints
type LinuxResources struct {
// Devices configures the device whitelist.
Devices []DeviceCgroup `json:"devices,omitempty"`
Devices []LinuxDeviceCgroup `json:"devices,omitempty"`
// DisableOOMKiller disables the OOM killer for out of memory conditions
DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
// Specify an oom_score_adj for the container.
OOMScoreAdj *int `json:"oomScoreAdj,omitempty"`
// Memory restriction configuration
Memory *Memory `json:"memory,omitempty"`
Memory *LinuxMemory `json:"memory,omitempty"`
// CPU resource restriction configuration
CPU *CPU `json:"cpu,omitempty"`
CPU *LinuxCPU `json:"cpu,omitempty"`
// Task resource restriction configuration.
Pids *Pids `json:"pids,omitempty"`
Pids *LinuxPids `json:"pids,omitempty"`
// BlockIO restriction configuration
BlockIO *BlockIO `json:"blockIO,omitempty"`
BlockIO *LinuxBlockIO `json:"blockIO,omitempty"`
// Hugetlb limit (in bytes)
HugepageLimits []HugepageLimit `json:"hugepageLimits,omitempty"`
HugepageLimits []LinuxHugepageLimit `json:"hugepageLimits,omitempty"`
// Network restriction configuration
Network *Network `json:"network,omitempty"`
Network *LinuxNetwork `json:"network,omitempty"`
}
// Device represents the mknod information for a Linux special device file
type Device struct {
// LinuxDevice represents the mknod information for a Linux special device file
type LinuxDevice struct {
// Path to the device.
Path string `json:"path"`
// Device type, block, char, etc.
@ -351,25 +366,18 @@ type Device struct {
GID *uint32 `json:"gid,omitempty"`
}
// DeviceCgroup represents a device rule for the whitelist controller
type DeviceCgroup struct {
// LinuxDeviceCgroup represents a device rule for the whitelist controller
type LinuxDeviceCgroup struct {
// Allow or deny
Allow bool `json:"allow"`
// Device type, block, char, etc.
Type *string `json:"type,omitempty"`
Type string `json:"type,omitempty"`
// Major is the device's major number.
Major *int64 `json:"major,omitempty"`
// Minor is the device's minor number.
Minor *int64 `json:"minor,omitempty"`
// Cgroup access permissions format, rwm.
Access *string `json:"access,omitempty"`
}
// Seccomp represents syscall restrictions
type Seccomp struct {
DefaultAction Action `json:"defaultAction"`
Architectures []Arch `json:"architectures"`
Syscalls []Syscall `json:"syscalls,omitempty"`
Access string `json:"access,omitempty"`
}
// Solaris contains platform specific configuration for Solaris application containers.
@ -381,26 +389,26 @@ type Solaris struct {
// The maximum amount of shared memory allowed for this container.
MaxShmMemory string `json:"maxShmMemory,omitempty"`
// Specification for automatic creation of network resources for this container.
Anet []Anet `json:"anet,omitempty"`
Anet []SolarisAnet `json:"anet,omitempty"`
// Set limit on the amount of CPU time that can be used by container.
CappedCPU *CappedCPU `json:"cappedCPU,omitempty"`
CappedCPU *SolarisCappedCPU `json:"cappedCPU,omitempty"`
// The physical and swap caps on the memory that can be used by this container.
CappedMemory *CappedMemory `json:"cappedMemory,omitempty"`
CappedMemory *SolarisCappedMemory `json:"cappedMemory,omitempty"`
}
// CappedCPU allows users to set limit on the amount of CPU time that can be used by container.
type CappedCPU struct {
// SolarisCappedCPU allows users to set limit on the amount of CPU time that can be used by container.
type SolarisCappedCPU struct {
Ncpus string `json:"ncpus,omitempty"`
}
// CappedMemory allows users to set the physical and swap caps on the memory that can be used by this container.
type CappedMemory struct {
// SolarisCappedMemory allows users to set the physical and swap caps on the memory that can be used by this container.
type SolarisCappedMemory struct {
Physical string `json:"physical,omitempty"`
Swap string `json:"swap,omitempty"`
}
// Anet provides the specification for automatic creation of network resources for this container.
type Anet struct {
// SolarisAnet provides the specification for automatic creation of network resources for this container.
type SolarisAnet struct {
// Specify a name for the automatically created VNIC datalink.
Linkname string `json:"linkname,omitempty"`
// Specify the link over which the VNIC will be created.
@ -469,6 +477,13 @@ type WindowsNetworkResources struct {
EgressBandwidth *uint64 `json:"egressBandwidth,omitempty"`
}
// LinuxSeccomp represents syscall restrictions
type LinuxSeccomp struct {
DefaultAction LinuxSeccompAction `json:"defaultAction"`
Architectures []Arch `json:"architectures,omitempty"`
Syscalls []LinuxSyscall `json:"syscalls"`
}
// Arch used for additional architectures
type Arch string
@ -491,45 +506,48 @@ const (
ArchPPC64LE Arch = "SCMP_ARCH_PPC64LE"
ArchS390 Arch = "SCMP_ARCH_S390"
ArchS390X Arch = "SCMP_ARCH_S390X"
ArchPARISC Arch = "SCMP_ARCH_PARISC"
ArchPARISC64 Arch = "SCMP_ARCH_PARISC64"
)
// Action taken upon Seccomp rule match
type Action string
// LinuxSeccompAction taken upon Seccomp rule match
type LinuxSeccompAction string
// Define actions for Seccomp rules
const (
ActKill Action = "SCMP_ACT_KILL"
ActTrap Action = "SCMP_ACT_TRAP"
ActErrno Action = "SCMP_ACT_ERRNO"
ActTrace Action = "SCMP_ACT_TRACE"
ActAllow Action = "SCMP_ACT_ALLOW"
ActKill LinuxSeccompAction = "SCMP_ACT_KILL"
ActTrap LinuxSeccompAction = "SCMP_ACT_TRAP"
ActErrno LinuxSeccompAction = "SCMP_ACT_ERRNO"
ActTrace LinuxSeccompAction = "SCMP_ACT_TRACE"
ActAllow LinuxSeccompAction = "SCMP_ACT_ALLOW"
)
// Operator used to match syscall arguments in Seccomp
type Operator string
// LinuxSeccompOperator used to match syscall arguments in Seccomp
type LinuxSeccompOperator string
// Define operators for syscall arguments in Seccomp
const (
OpNotEqual Operator = "SCMP_CMP_NE"
OpLessThan Operator = "SCMP_CMP_LT"
OpLessEqual Operator = "SCMP_CMP_LE"
OpEqualTo Operator = "SCMP_CMP_EQ"
OpGreaterEqual Operator = "SCMP_CMP_GE"
OpGreaterThan Operator = "SCMP_CMP_GT"
OpMaskedEqual Operator = "SCMP_CMP_MASKED_EQ"
OpNotEqual LinuxSeccompOperator = "SCMP_CMP_NE"
OpLessThan LinuxSeccompOperator = "SCMP_CMP_LT"
OpLessEqual LinuxSeccompOperator = "SCMP_CMP_LE"
OpEqualTo LinuxSeccompOperator = "SCMP_CMP_EQ"
OpGreaterEqual LinuxSeccompOperator = "SCMP_CMP_GE"
OpGreaterThan LinuxSeccompOperator = "SCMP_CMP_GT"
OpMaskedEqual LinuxSeccompOperator = "SCMP_CMP_MASKED_EQ"
)
// Arg used for matching specific syscall arguments in Seccomp
type Arg struct {
// LinuxSeccompArg used for matching specific syscall arguments in Seccomp
type LinuxSeccompArg struct {
Index uint `json:"index"`
Value uint64 `json:"value"`
ValueTwo uint64 `json:"valueTwo"`
Op Operator `json:"op"`
Op LinuxSeccompOperator `json:"op"`
}
// Syscall is used to match a syscall in Seccomp
type Syscall struct {
Name string `json:"name"`
Action Action `json:"action"`
Args []Arg `json:"args,omitempty"`
// LinuxSyscall is used to match a syscall in Seccomp
type LinuxSyscall struct {
Names []string `json:"names"`
Action LinuxSeccompAction `json:"action"`
Args []LinuxSeccompArg `json:"args"`
Comment string `json:"comment"`
}

View file

@ -3,15 +3,15 @@ package specs
// State holds information about the runtime state of the container.
type State struct {
// Version is the version of the specification that is supported.
Version string `json:"version"`
Version string `json:"ociVersion"`
// ID is the container ID
ID string `json:"id"`
// Status is the runtime state of the container.
// Status is the runtime status of the container.
Status string `json:"status"`
// Pid is the process ID for the container process.
Pid int `json:"pid"`
// BundlePath is the path to the container's bundle directory.
BundlePath string `json:"bundlePath"`
// Annotations are the annotations associated with the container.
Annotations map[string]string `json:"annotations"`
// Bundle is the path to the container's bundle directory.
Bundle string `json:"bundle"`
// Annotations are key values associated with the container.
Annotations map[string]string `json:"annotations,omitempty"`
}

View file

@ -11,7 +11,7 @@ const (
VersionPatch = 0
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = "-rc2-dev"
VersionDev = "-rc5"
)
// Version is the specification version that the package types support.

View file

@ -24,28 +24,3 @@ please note that a Google account is not required to subscribe to the mailing
list.
-> https://groups.google.com/d/forum/libseccomp
Documentation is also available at:
-> https://godoc.org/github.com/seccomp/libseccomp-golang
* Installing the package
The libseccomp-golang bindings require at least Go v1.2.1 and GCC v4.8.4;
earlier versions may yield unpredictable results. If you meet these
requirements you can install this package using the command below:
$ go get github.com/seccomp/libseccomp-golang
* Testing the Library
A number of tests and lint related recipes are provided in the Makefile, if
you want to run the standard regression tests, you can excute the following:
$ make check
In order to execute the 'make lint' recipe the 'golint' tool is needed, it
can be found at:
-> https://github.com/golang/lint

View file

@ -27,28 +27,6 @@ import "C"
// Exported types
// VersionError denotes that the system libseccomp version is incompatible
// with this package.
type VersionError struct {
message string
minimum string
}
func (e VersionError) Error() string {
format := "Libseccomp version too low: "
if e.message != "" {
format += e.message + ": "
}
format += "minimum supported is "
if e.minimum != "" {
format += e.minimum + ": "
} else {
format += "2.1.0: "
}
format += "detected %d.%d.%d"
return fmt.Sprintf(format, verMajor, verMinor, verMicro)
}
// ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a
// per-architecture basis.
type ScmpArch uint
@ -173,10 +151,6 @@ const (
// GetArchFromString returns an ScmpArch constant from a string representing an
// architecture
func GetArchFromString(arch string) (ScmpArch, error) {
if err := ensureSupportedVersion(); err != nil {
return ArchInvalid, err
}
switch strings.ToLower(arch) {
case "x86":
return ArchX86, nil
@ -364,10 +338,6 @@ func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) {
// Returns the number of the syscall, or an error if no syscall with that name
// was found.
func GetSyscallFromName(name string) (ScmpSyscall, error) {
if err := ensureSupportedVersion(); err != nil {
return 0, err
}
cString := C.CString(name)
defer C.free(unsafe.Pointer(cString))
@ -385,9 +355,6 @@ func GetSyscallFromName(name string) (ScmpSyscall, error) {
// Returns the number of the syscall, or an error if an invalid architecture is
// passed or a syscall with that name was not found.
func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
if err := ensureSupportedVersion(); err != nil {
return 0, err
}
if err := sanitizeArch(arch); err != nil {
return 0, err
}
@ -419,10 +386,6 @@ func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) {
var condStruct ScmpCondition
if err := ensureSupportedVersion(); err != nil {
return condStruct, err
}
if comparison == CompareInvalid {
return condStruct, fmt.Errorf("invalid comparison operator")
} else if arg > 5 {
@ -450,10 +413,6 @@ func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCo
// GetNativeArch returns architecture token representing the native kernel
// architecture
func GetNativeArch() (ScmpArch, error) {
if err := ensureSupportedVersion(); err != nil {
return ArchInvalid, err
}
arch := C.seccomp_arch_native()
return archFromNative(arch)
@ -476,10 +435,6 @@ type ScmpFilter struct {
// Returns a reference to a valid filter context, or nil and an error if the
// filter context could not be created or an invalid default action was given.
func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
if err := ensureSupportedVersion(); err != nil {
return nil, err
}
if err := sanitizeAction(defaultAction); err != nil {
return nil, err
}

View file

@ -7,6 +7,7 @@ package seccomp
import (
"fmt"
"os"
"syscall"
)
@ -191,12 +192,12 @@ func checkVersionAbove(major, minor, micro int) bool {
(verMajor == major && verMinor == minor && verMicro >= micro)
}
// Ensure that the library is supported, i.e. >= 2.1.0.
func ensureSupportedVersion() error {
// Init function: Verify library version is appropriate
func init() {
if !checkVersionAbove(2, 1, 0) {
return VersionError{}
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)
os.Exit(-1)
}
return nil
}
// Filter helpers
@ -216,10 +217,7 @@ func (f *ScmpFilter) getFilterAttr(attr scmpFilterAttr) (C.uint32_t, error) {
}
if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
return 0x0, VersionError{
message: "thread synchronization attribute is not supported",
minimum: "2.2.0",
}
return 0x0, fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
}
var attribute C.uint32_t
@ -242,10 +240,7 @@ func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) error
}
if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
return VersionError{
message: "thread synchronization attribute is not supported",
minimum: "2.2.0",
}
return fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
}
retCode := C.seccomp_attr_set(f.filterCtx, attr.toNative(), value)
@ -301,10 +296,7 @@ func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact b
} else {
// We don't support conditional filtering in library version v2.1
if !checkVersionAbove(2, 2, 1) {
return VersionError{
message: "conditional filtering is not supported",
minimum: "2.2.1",
}
return fmt.Errorf("conditional filtering requires libseccomp version >= 2.2.1")
}
for _, cond := range conds {