From 2e9ea5c194e5fbb83f59e30f8bda5467086598fe Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Thu, 9 Jun 2016 14:56:14 -0700 Subject: [PATCH 1/7] Update containerd and runc vendoring containerd: 860f3a94940894ac0a106eff4bd1616a67407ee2 runc: 85873d917e86676e44ccb80719fcb47a794676a1 runtime-specs: v1.0.0-rc1 Signed-off-by: Kenfe-Mickael Laventure --- Dockerfile | 4 +- Dockerfile.aarch64 | 4 +- Dockerfile.armhf | 4 +- Dockerfile.gccgo | 4 +- Dockerfile.ppc64le | 4 +- Dockerfile.s390x | 4 +- Dockerfile.simple | 4 +- daemon/update_linux.go | 16 +- hack/vendor.sh | 6 +- .../containerd/api/grpc/types/api.pb.go | 326 +++++++++--------- .../containerd/api/grpc/types/api.proto | 19 +- .../runc/libcontainer/configs/config.go | 4 + .../runc/libcontainer/system/sysconfig.go | 17 +- .../opencontainers/specs/specs-go/config.go | 70 +++- .../opencontainers/specs/specs-go/state.go | 4 + .../opencontainers/specs/specs-go/version.go | 6 +- 16 files changed, 287 insertions(+), 209 deletions(-) diff --git a/Dockerfile b/Dockerfile index e340dc2133..00861ec26f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -233,7 +233,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT d49ece5a83da3dcb820121d6850e2b61bd0a5fbe +ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ @@ -244,7 +244,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install containerd -ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509 +ENV CONTAINERD_COMMIT 860f3a94940894ac0a106eff4bd1616a67407ee2 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 20402436b5..0011ad617c 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -180,7 +180,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT d49ece5a83da3dcb820121d6850e2b61bd0a5fbe +ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ @@ -191,7 +191,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install containerd -ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509 +ENV CONTAINERD_COMMIT 860f3a94940894ac0a106eff4bd1616a67407ee2 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \ diff --git a/Dockerfile.armhf b/Dockerfile.armhf index 3147de7191..d5462eddcb 100644 --- a/Dockerfile.armhf +++ b/Dockerfile.armhf @@ -189,7 +189,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT d49ece5a83da3dcb820121d6850e2b61bd0a5fbe +ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ @@ -200,7 +200,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install containerd -ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509 +ENV CONTAINERD_COMMIT 860f3a94940894ac0a106eff4bd1616a67407ee2 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \ diff --git a/Dockerfile.gccgo b/Dockerfile.gccgo index 221418e3c4..98011d9223 100644 --- a/Dockerfile.gccgo +++ b/Dockerfile.gccgo @@ -74,7 +74,7 @@ WORKDIR /go/src/github.com/docker/docker ENV DOCKER_BUILDTAGS apparmor seccomp selinux # Install runc -ENV RUNC_COMMIT d49ece5a83da3dcb820121d6850e2b61bd0a5fbe +ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ @@ -85,7 +85,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install containerd -ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509 +ENV CONTAINERD_COMMIT 860f3a94940894ac0a106eff4bd1616a67407ee2 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \ diff --git a/Dockerfile.ppc64le b/Dockerfile.ppc64le index b09be972ec..a8e1708287 100644 --- a/Dockerfile.ppc64le +++ b/Dockerfile.ppc64le @@ -204,7 +204,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT d49ece5a83da3dcb820121d6850e2b61bd0a5fbe +ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ @@ -215,7 +215,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install containerd -ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509 +ENV CONTAINERD_COMMIT 860f3a94940894ac0a106eff4bd1616a67407ee2 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \ diff --git a/Dockerfile.s390x b/Dockerfile.s390x index 4969f68452..8f887b2702 100644 --- a/Dockerfile.s390x +++ b/Dockerfile.s390x @@ -197,7 +197,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT d49ece5a83da3dcb820121d6850e2b61bd0a5fbe +ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ @@ -208,7 +208,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install containerd -ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509 +ENV CONTAINERD_COMMIT 860f3a94940894ac0a106eff4bd1616a67407ee2 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \ diff --git a/Dockerfile.simple b/Dockerfile.simple index 106b49cfc1..2c19fd249c 100644 --- a/Dockerfile.simple +++ b/Dockerfile.simple @@ -57,7 +57,7 @@ ENV GOPATH /go:/go/src/github.com/docker/docker/vendor ENV CGO_LDFLAGS -L/lib # Install runc -ENV RUNC_COMMIT d49ece5a83da3dcb820121d6850e2b61bd0a5fbe +ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ @@ -68,7 +68,7 @@ RUN set -x \ && rm -rf "$GOPATH" # Install containerd -ENV CONTAINERD_COMMIT cf554d59dd96e459544748290eb9167f4bcde509 +ENV CONTAINERD_COMMIT 860f3a94940894ac0a106eff4bd1616a67407ee2 RUN set -x \ && export GOPATH="$(mktemp -d)" \ && git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \ diff --git a/daemon/update_linux.go b/daemon/update_linux.go index 97ba7c09a4..69cc0840ab 100644 --- a/daemon/update_linux.go +++ b/daemon/update_linux.go @@ -9,17 +9,17 @@ import ( func toContainerdResources(resources container.Resources) libcontainerd.Resources { var r libcontainerd.Resources - r.BlkioWeight = uint32(resources.BlkioWeight) - r.CpuShares = uint32(resources.CPUShares) - r.CpuPeriod = uint32(resources.CPUPeriod) - r.CpuQuota = uint32(resources.CPUQuota) + r.BlkioWeight = uint64(resources.BlkioWeight) + r.CpuShares = uint64(resources.CPUShares) + r.CpuPeriod = uint64(resources.CPUPeriod) + r.CpuQuota = uint64(resources.CPUQuota) r.CpusetCpus = resources.CpusetCpus r.CpusetMems = resources.CpusetMems - r.MemoryLimit = uint32(resources.Memory) + r.MemoryLimit = uint64(resources.Memory) if resources.MemorySwap > 0 { - r.MemorySwap = uint32(resources.MemorySwap) + r.MemorySwap = uint64(resources.MemorySwap) } - r.MemoryReservation = uint32(resources.MemoryReservation) - r.KernelMemoryLimit = uint32(resources.KernelMemory) + r.MemoryReservation = uint64(resources.MemoryReservation) + r.KernelMemoryLimit = uint64(resources.KernelMemory) return r } diff --git a/hack/vendor.sh b/hack/vendor.sh index 5edc70a793..e2ee7a08f8 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -102,8 +102,8 @@ clone git github.com/miekg/pkcs11 df8ae6ca730422dba20c768ff38ef7d79077a59f clone git github.com/docker/go v1.5.1-1-1-gbaf439e clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c -clone git github.com/opencontainers/runc d49ece5a83da3dcb820121d6850e2b61bd0a5fbe # libcontainer -clone git github.com/opencontainers/specs f955d90e70a98ddfb886bd930ffd076da9b67998 # specs +clone git github.com/opencontainers/runc 85873d917e86676e44ccb80719fcb47a794676a1 # libcontainer +clone git github.com/opencontainers/specs v1.0.0-rc1 # specs clone git github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0 # libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json) clone git github.com/coreos/go-systemd v4 @@ -136,7 +136,7 @@ clone git google.golang.org/cloud dae7e3d993bc3812a2185af60552bb6b847e52a0 https clone git github.com/docker/docker-credential-helpers v0.3.0 # containerd -clone git github.com/docker/containerd cf554d59dd96e459544748290eb9167f4bcde509 +clone git github.com/docker/containerd 860f3a94940894ac0a106eff4bd1616a67407ee2 # cluster clone git github.com/docker/swarmkit 45094b473cbdb2d45e4d8f703fb615989399ae29 diff --git a/vendor/src/github.com/docker/containerd/api/grpc/types/api.pb.go b/vendor/src/github.com/docker/containerd/api/grpc/types/api.pb.go index 2013db1f50..e6fd0af4b6 100644 --- a/vendor/src/github.com/docker/containerd/api/grpc/types/api.pb.go +++ b/vendor/src/github.com/docker/containerd/api/grpc/types/api.pb.go @@ -291,11 +291,12 @@ func (*ListCheckpointRequest) ProtoMessage() {} func (*ListCheckpointRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } type Checkpoint struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Exit bool `protobuf:"varint,2,opt,name=exit" json:"exit,omitempty"` - Tcp bool `protobuf:"varint,3,opt,name=tcp" json:"tcp,omitempty"` - UnixSockets bool `protobuf:"varint,4,opt,name=unixSockets" json:"unixSockets,omitempty"` - Shell bool `protobuf:"varint,5,opt,name=shell" json:"shell,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Exit bool `protobuf:"varint,2,opt,name=exit" json:"exit,omitempty"` + Tcp bool `protobuf:"varint,3,opt,name=tcp" json:"tcp,omitempty"` + UnixSockets bool `protobuf:"varint,4,opt,name=unixSockets" json:"unixSockets,omitempty"` + Shell bool `protobuf:"varint,5,opt,name=shell" json:"shell,omitempty"` + EmptyNS []string `protobuf:"bytes,6,rep,name=emptyNS" json:"emptyNS,omitempty"` } func (m *Checkpoint) Reset() { *m = Checkpoint{} } @@ -452,17 +453,17 @@ func (m *UpdateContainerRequest) GetResources() *UpdateResource { } type UpdateResource struct { - BlkioWeight uint32 `protobuf:"varint,1,opt,name=blkioWeight" json:"blkioWeight,omitempty"` - CpuShares uint32 `protobuf:"varint,2,opt,name=cpuShares" json:"cpuShares,omitempty"` - CpuPeriod uint32 `protobuf:"varint,3,opt,name=cpuPeriod" json:"cpuPeriod,omitempty"` - CpuQuota uint32 `protobuf:"varint,4,opt,name=cpuQuota" json:"cpuQuota,omitempty"` + BlkioWeight uint64 `protobuf:"varint,1,opt,name=blkioWeight" json:"blkioWeight,omitempty"` + CpuShares uint64 `protobuf:"varint,2,opt,name=cpuShares" json:"cpuShares,omitempty"` + CpuPeriod uint64 `protobuf:"varint,3,opt,name=cpuPeriod" json:"cpuPeriod,omitempty"` + CpuQuota uint64 `protobuf:"varint,4,opt,name=cpuQuota" json:"cpuQuota,omitempty"` CpusetCpus string `protobuf:"bytes,5,opt,name=cpusetCpus" json:"cpusetCpus,omitempty"` CpusetMems string `protobuf:"bytes,6,opt,name=cpusetMems" json:"cpusetMems,omitempty"` - MemoryLimit uint32 `protobuf:"varint,7,opt,name=memoryLimit" json:"memoryLimit,omitempty"` - MemorySwap uint32 `protobuf:"varint,8,opt,name=memorySwap" json:"memorySwap,omitempty"` - MemoryReservation uint32 `protobuf:"varint,9,opt,name=memoryReservation" json:"memoryReservation,omitempty"` - KernelMemoryLimit uint32 `protobuf:"varint,10,opt,name=kernelMemoryLimit" json:"kernelMemoryLimit,omitempty"` - KernelTCPMemoryLimit uint32 `protobuf:"varint,11,opt,name=kernelTCPMemoryLimit" json:"kernelTCPMemoryLimit,omitempty"` + MemoryLimit uint64 `protobuf:"varint,7,opt,name=memoryLimit" json:"memoryLimit,omitempty"` + MemorySwap uint64 `protobuf:"varint,8,opt,name=memorySwap" json:"memorySwap,omitempty"` + MemoryReservation uint64 `protobuf:"varint,9,opt,name=memoryReservation" json:"memoryReservation,omitempty"` + KernelMemoryLimit uint64 `protobuf:"varint,10,opt,name=kernelMemoryLimit" json:"kernelMemoryLimit,omitempty"` + KernelTCPMemoryLimit uint64 `protobuf:"varint,11,opt,name=kernelTCPMemoryLimit" json:"kernelTCPMemoryLimit,omitempty"` } func (m *UpdateResource) Reset() { *m = UpdateResource{} } @@ -1315,152 +1316,153 @@ var _API_serviceDesc = grpc.ServiceDesc{ } var fileDescriptor0 = []byte{ - // 2348 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x59, 0x4b, 0x73, 0x1c, 0x49, - 0x11, 0xf6, 0x3c, 0xa5, 0xc9, 0x79, 0x48, 0xea, 0xd5, 0x63, 0x3c, 0xbb, 0xf6, 0x9a, 0x8e, 0x05, - 0x0c, 0x2c, 0xc2, 0x8c, 0x77, 0x03, 0x07, 0x44, 0x10, 0x61, 0x4b, 0x66, 0x31, 0x6b, 0x2d, 0xe3, - 0x96, 0xc4, 0x1e, 0x27, 0x5a, 0xdd, 0xe5, 0x99, 0x46, 0x33, 0xdd, 0xbd, 0xdd, 0x35, 0xd2, 0xe8, - 0xc2, 0x81, 0x03, 0xdc, 0xf8, 0x03, 0x10, 0x5c, 0xb8, 0x71, 0xe7, 0xc0, 0x2f, 0x20, 0x82, 0x1f, - 0xc2, 0x8d, 0x3b, 0x47, 0xb2, 0xaa, 0xb2, 0xab, 0xab, 0xe7, 0x21, 0x99, 0x03, 0xc1, 0x85, 0xcb, - 0x44, 0xd5, 0x57, 0x59, 0x99, 0x59, 0xf9, 0xaa, 0xec, 0x1a, 0x68, 0xb8, 0x71, 0x70, 0x18, 0x27, - 0x11, 0x8f, 0xac, 0x1a, 0xbf, 0x89, 0x59, 0x6a, 0xdf, 0x87, 0x83, 0xcf, 0x18, 0x3f, 0x65, 0xc9, - 0x15, 0x4b, 0x7e, 0xc1, 0x92, 0x34, 0x88, 0x42, 0x87, 0x7d, 0x35, 0x63, 0x29, 0xb7, 0xe7, 0xd0, - 0x5d, 0x5e, 0x4a, 0xe3, 0x28, 0x4c, 0x99, 0xb5, 0x0b, 0xb5, 0xa9, 0xfb, 0xcb, 0x28, 0xe9, 0x96, - 0x1e, 0x95, 0x1e, 0xb7, 0x1d, 0x35, 0x91, 0x68, 0x10, 0x22, 0x5a, 0x26, 0x54, 0x4c, 0x04, 0x1a, - 0xbb, 0xdc, 0x1b, 0x77, 0x2b, 0x0a, 0x95, 0x13, 0xab, 0x07, 0x9b, 0x09, 0xbb, 0x0a, 0x04, 0xd7, - 0x6e, 0x15, 0x17, 0x1a, 0x8e, 0x9e, 0xdb, 0xbf, 0x29, 0xc1, 0xee, 0x79, 0xec, 0xbb, 0x9c, 0x0d, - 0x92, 0xc8, 0x63, 0x69, 0x4a, 0x2a, 0x59, 0x1d, 0x28, 0x07, 0xbe, 0x94, 0xd9, 0x70, 0x70, 0x64, - 0x6d, 0x43, 0x25, 0x46, 0xa0, 0x2c, 0x01, 0x31, 0xb4, 0x1e, 0x02, 0x78, 0x93, 0x28, 0x65, 0xa7, - 0xdc, 0x0f, 0x42, 0x29, 0x71, 0xd3, 0x31, 0x10, 0xa1, 0xcc, 0x75, 0xe0, 0xf3, 0xb1, 0x94, 0x89, - 0xca, 0xc8, 0x89, 0xb5, 0x0f, 0xf5, 0x31, 0x0b, 0x46, 0x63, 0xde, 0xad, 0x49, 0x98, 0x66, 0xf6, - 0x01, 0xec, 0x2d, 0xe8, 0xa1, 0xce, 0x6f, 0xff, 0xbd, 0x0c, 0xfb, 0x47, 0x09, 0xc3, 0x95, 0xa3, - 0x28, 0xe4, 0x6e, 0x10, 0xb2, 0x64, 0x9d, 0x8e, 0xa8, 0xd1, 0xc5, 0x2c, 0xf4, 0x27, 0x6c, 0xe0, - 0xa2, 0x58, 0xa5, 0xaa, 0x81, 0x48, 0x8d, 0xc7, 0xcc, 0xbb, 0x8c, 0xa3, 0x20, 0xe4, 0x52, 0x63, - 0x5c, 0xcf, 0x11, 0xa1, 0x71, 0x2a, 0x0f, 0xa3, 0xac, 0xa4, 0x26, 0x42, 0x63, 0x1c, 0x44, 0x33, - 0xa5, 0x71, 0xc3, 0xa1, 0x19, 0xe1, 0x2c, 0x49, 0xba, 0x75, 0x8d, 0xe3, 0x4c, 0xe0, 0x13, 0xf7, - 0x82, 0x4d, 0xd2, 0xee, 0xc6, 0xa3, 0x8a, 0xc0, 0xd5, 0xcc, 0x7a, 0x04, 0xcd, 0x30, 0x1a, 0x04, - 0x57, 0x11, 0x77, 0xa2, 0x88, 0x77, 0x37, 0xa5, 0xc1, 0x4c, 0xc8, 0xea, 0xc2, 0x46, 0x32, 0x0b, - 0x79, 0x30, 0x65, 0xdd, 0x86, 0x64, 0x99, 0x4d, 0xc5, 0x5e, 0x1a, 0x3e, 0x4f, 0x46, 0x69, 0x17, - 0x24, 0x63, 0x13, 0xb2, 0x3e, 0x82, 0x76, 0x7e, 0x92, 0xe3, 0x20, 0xe9, 0x36, 0x25, 0x87, 0x22, - 0x68, 0xbf, 0x82, 0x83, 0x25, 0x5b, 0x52, 0x9c, 0x1d, 0x42, 0xc3, 0xcb, 0x40, 0x69, 0xd3, 0x66, - 0x7f, 0xfb, 0x50, 0x46, 0xee, 0x61, 0x4e, 0x9c, 0x93, 0x20, 0xab, 0xf6, 0x69, 0x30, 0x0a, 0xdd, - 0xc9, 0xbb, 0x47, 0x8c, 0xb0, 0x98, 0xdc, 0x42, 0xf1, 0x49, 0x33, 0x7b, 0x1b, 0x3a, 0x19, 0x2b, - 0x72, 0xfa, 0x5f, 0x2a, 0xb0, 0xf3, 0xdc, 0xf7, 0xef, 0x88, 0x49, 0x0c, 0x6c, 0xce, 0x12, 0x0c, - 0x7d, 0xe4, 0x58, 0x96, 0xe6, 0xd4, 0x73, 0xeb, 0x43, 0xa8, 0xce, 0x52, 0x3c, 0x49, 0x45, 0x9e, - 0xa4, 0x49, 0x27, 0x39, 0x47, 0xc8, 0x91, 0x0b, 0x96, 0x05, 0x55, 0x57, 0xd8, 0xb2, 0x2a, 0x6d, - 0x29, 0xc7, 0x42, 0x65, 0x16, 0x5e, 0xa1, 0x9f, 0x05, 0x24, 0x86, 0x02, 0xf1, 0xae, 0x7d, 0xf2, - 0xb0, 0x18, 0x66, 0xc7, 0xda, 0xc8, 0x8f, 0xa5, 0xc3, 0x66, 0x73, 0x75, 0xd8, 0x34, 0xd6, 0x84, - 0x0d, 0x14, 0xc2, 0xc6, 0x86, 0x96, 0xe7, 0xc6, 0xee, 0x45, 0x30, 0x09, 0x78, 0xc0, 0x52, 0xf4, - 0x9f, 0x50, 0xa2, 0x80, 0x59, 0x8f, 0x61, 0xcb, 0x8d, 0x63, 0x37, 0x99, 0x46, 0x09, 0x9a, 0xe6, - 0x6d, 0x30, 0x61, 0xdd, 0x96, 0x64, 0xb2, 0x08, 0x0b, 0x6e, 0x29, 0x9b, 0x04, 0xe1, 0x6c, 0xfe, - 0x5a, 0x44, 0x5f, 0xb7, 0x2d, 0xc9, 0x0a, 0x98, 0xe0, 0x16, 0x46, 0x5f, 0xb0, 0xeb, 0x41, 0x12, - 0x5c, 0xe1, 0x9e, 0x11, 0x0a, 0xed, 0x48, 0x2b, 0x2e, 0xc2, 0xd6, 0x37, 0x31, 0x30, 0x27, 0xc1, - 0x34, 0xe0, 0x69, 0x77, 0x0b, 0xd5, 0x6a, 0xf6, 0xdb, 0x64, 0x4f, 0x47, 0xa2, 0x4e, 0xb6, 0x6a, - 0x1f, 0x43, 0x5d, 0x41, 0xc2, 0xbc, 0x82, 0x84, 0xbc, 0x25, 0xc7, 0x02, 0x4b, 0xa3, 0xb7, 0x5c, - 0xfa, 0xaa, 0xea, 0xc8, 0xb1, 0xc0, 0xc6, 0x6e, 0xe2, 0x4b, 0x3f, 0x21, 0x26, 0xc6, 0xb6, 0x03, - 0x55, 0xe1, 0x28, 0x61, 0xea, 0x19, 0x39, 0xbc, 0xed, 0x88, 0xa1, 0x40, 0x46, 0x14, 0x53, 0x88, - 0xe0, 0xd0, 0xfa, 0x06, 0x74, 0x5c, 0xdf, 0x47, 0xf3, 0x44, 0xe8, 0xf5, 0xcf, 0x02, 0x3f, 0x45, - 0x4e, 0x15, 0x5c, 0x5c, 0x40, 0xed, 0x5d, 0xb0, 0xcc, 0x80, 0xa2, 0x38, 0xfb, 0x75, 0x49, 0x27, - 0x84, 0xce, 0x93, 0x75, 0xd1, 0xf6, 0xfd, 0x42, 0xf5, 0x28, 0xcb, 0xb8, 0xda, 0xc9, 0x32, 0x24, - 0xdf, 0x6d, 0x16, 0x94, 0xa5, 0xa4, 0xac, 0xac, 0x4a, 0xca, 0x1e, 0x74, 0x97, 0x75, 0x20, 0x05, - 0x3d, 0x38, 0x38, 0x66, 0x13, 0xf6, 0x2e, 0xfa, 0xa1, 0x25, 0x43, 0x17, 0x4b, 0x87, 0x4a, 0x38, - 0x39, 0x7e, 0x77, 0x05, 0x96, 0x85, 0x90, 0x02, 0x27, 0xb0, 0xf7, 0x3a, 0x48, 0xf9, 0xdd, 0xe2, - 0x97, 0x44, 0x95, 0x57, 0x89, 0xfa, 0x15, 0x40, 0xce, 0x4a, 0xab, 0x5c, 0x32, 0x54, 0x46, 0x8c, - 0xcd, 0x03, 0x4e, 0x09, 0x2d, 0xc7, 0xc2, 0xed, 0xdc, 0x8b, 0xe9, 0x8e, 0x11, 0x43, 0x51, 0x10, - 0x67, 0x61, 0x30, 0x3f, 0x8d, 0xbc, 0x4b, 0xc6, 0x53, 0x59, 0xb0, 0xb1, 0x98, 0x1a, 0x90, 0xcc, - 0xca, 0x31, 0x9b, 0x4c, 0x64, 0xd5, 0xde, 0x74, 0xd4, 0x04, 0x8f, 0xb3, 0xbf, 0x78, 0x1c, 0xaa, - 0x7f, 0x4f, 0xa1, 0x99, 0xab, 0x9a, 0xa2, 0x4a, 0x95, 0xd5, 0xfe, 0x35, 0xa9, 0xec, 0x87, 0xd0, - 0x3a, 0xe5, 0xe8, 0xb9, 0x35, 0x46, 0xb1, 0x1f, 0x43, 0x47, 0x17, 0x4f, 0x49, 0xa8, 0xd2, 0xdf, - 0xe5, 0xb3, 0x94, 0xa8, 0x68, 0x66, 0xff, 0xb5, 0x02, 0x1b, 0x14, 0x9d, 0x59, 0x89, 0x29, 0xe5, - 0x25, 0xe6, 0x7f, 0x52, 0xe9, 0x3e, 0x80, 0x46, 0x7a, 0x93, 0x72, 0x36, 0x1d, 0x50, 0xbd, 0x6b, - 0x3b, 0x39, 0xf0, 0xff, 0xaa, 0x97, 0x57, 0xbd, 0xbf, 0x95, 0xa0, 0xa1, 0xdd, 0xfc, 0x1f, 0x77, - 0x25, 0x1f, 0x43, 0x23, 0x56, 0x8e, 0x67, 0xaa, 0x78, 0x35, 0xfb, 0x1d, 0x12, 0x94, 0x95, 0xab, - 0x9c, 0xc0, 0x88, 0x9f, 0xaa, 0x19, 0x3f, 0x46, 0xd7, 0x51, 0x2b, 0x74, 0x1d, 0xe8, 0xfc, 0x58, - 0x54, 0xc5, 0xba, 0xac, 0x8a, 0x72, 0x6c, 0xf6, 0x19, 0x1b, 0x85, 0x3e, 0xc3, 0xfe, 0x14, 0x36, - 0x4e, 0x5c, 0x6f, 0x8c, 0xe7, 0x10, 0x1b, 0xbd, 0x98, 0xc2, 0x14, 0x37, 0x8a, 0xb1, 0x10, 0x32, - 0x65, 0x68, 0xef, 0x1b, 0x2a, 0xe1, 0x34, 0xb3, 0x2f, 0xb1, 0x17, 0x50, 0x69, 0x40, 0xc9, 0xf4, - 0x04, 0x6b, 0x65, 0x66, 0x90, 0x2c, 0x97, 0x96, 0xbb, 0x09, 0x83, 0x06, 0xdd, 0xb2, 0x31, 0x55, - 0x92, 0xa9, 0xb4, 0x66, 0x36, 0x20, 0x7d, 0x9c, 0x6c, 0xd9, 0xfe, 0x6d, 0x09, 0xf6, 0x55, 0xab, - 0x78, 0x67, 0x43, 0xb8, 0xba, 0x05, 0x51, 0xe6, 0xab, 0x14, 0xcc, 0xf7, 0x14, 0x1a, 0x09, 0x4b, - 0xa3, 0x59, 0x82, 0x66, 0x96, 0x96, 0x6d, 0xf6, 0xf7, 0xb2, 0x4c, 0x92, 0xb2, 0x1c, 0x5a, 0x75, - 0x72, 0x3a, 0xfb, 0x0f, 0x15, 0xe8, 0x14, 0x57, 0x45, 0x5d, 0xba, 0x98, 0x5c, 0x06, 0xd1, 0x97, - 0xaa, 0xc7, 0x55, 0xc6, 0x33, 0x21, 0x91, 0x55, 0x68, 0xcb, 0x53, 0xbc, 0xe8, 0x50, 0x92, 0xba, - 0xc8, 0x72, 0x80, 0x56, 0x07, 0x2c, 0x09, 0x22, 0x9f, 0xba, 0xa4, 0x1c, 0x10, 0x65, 0x00, 0x27, - 0x6f, 0x66, 0x11, 0x77, 0xa9, 0xab, 0xd6, 0x73, 0xd9, 0xdc, 0xa2, 0x8f, 0x18, 0x3f, 0x12, 0x5e, - 0xab, 0x51, 0x73, 0xab, 0x91, 0x7c, 0xfd, 0x84, 0x4d, 0x53, 0x4a, 0x73, 0x03, 0x11, 0x9a, 0x2b, - 0x6f, 0xbe, 0x16, 0x41, 0x4d, 0xf9, 0x6e, 0x42, 0x82, 0x83, 0x9a, 0x9e, 0x5e, 0xbb, 0xb1, 0x4c, - 0xfb, 0xb6, 0x63, 0x20, 0x18, 0xc8, 0x3b, 0x6a, 0x86, 0xd6, 0xc0, 0x4f, 0x19, 0x57, 0xdc, 0xbe, - 0xb2, 0x0c, 0xb4, 0x9d, 0xe5, 0x05, 0x41, 0x7d, 0xc9, 0x92, 0x90, 0x4d, 0x4e, 0x0c, 0xa9, 0xa0, - 0xa8, 0x97, 0x16, 0xac, 0x3e, 0xec, 0x2a, 0xf0, 0xec, 0x68, 0x60, 0x6e, 0x68, 0xca, 0x0d, 0x2b, - 0xd7, 0xc4, 0x07, 0xd7, 0x52, 0x9c, 0xd0, 0xad, 0xf6, 0x5d, 0x68, 0xbf, 0xbc, 0x62, 0x58, 0xc1, - 0xb3, 0xc8, 0x41, 0xbb, 0x8b, 0x04, 0xc0, 0x68, 0x98, 0xc6, 0xd2, 0x6b, 0x55, 0x27, 0x07, 0xec, - 0x14, 0x6a, 0x92, 0x7c, 0x65, 0x57, 0xa3, 0x82, 0xae, 0xac, 0x83, 0xae, 0x18, 0x62, 0x6d, 0x1d, - 0x62, 0x14, 0x8c, 0xd5, 0x3c, 0x18, 0x0b, 0x42, 0x6b, 0x8b, 0x42, 0x7f, 0x57, 0x86, 0xd6, 0x17, - 0x8c, 0x5f, 0x47, 0xc9, 0xa5, 0x48, 0xae, 0x74, 0xe5, 0x6d, 0x79, 0x1f, 0xbf, 0xed, 0xe6, 0xc3, - 0x8b, 0x1b, 0x4e, 0xc1, 0x54, 0xc5, 0x5c, 0x9e, 0xbf, 0x10, 0x53, 0xeb, 0x01, 0x00, 0x2e, 0x0d, - 0x5c, 0x75, 0x43, 0xaa, 0xfe, 0xaa, 0x91, 0xcc, 0x09, 0xb0, 0xde, 0x87, 0x86, 0x33, 0x1f, 0x62, - 0x0d, 0x8e, 0x12, 0x15, 0xf1, 0x55, 0xfc, 0x2c, 0x9c, 0xbf, 0x94, 0x73, 0xb1, 0x17, 0x17, 0xfd, - 0x24, 0x8a, 0x63, 0xe6, 0x67, 0xaa, 0x25, 0xf3, 0x63, 0x05, 0x08, 0xa9, 0x67, 0x99, 0xd4, 0xba, - 0x92, 0xca, 0x73, 0xa9, 0xb8, 0x14, 0x93, 0xd4, 0x0d, 0x3a, 0x94, 0x29, 0xf5, 0x4c, 0x4b, 0xdd, - 0x54, 0x52, 0xb9, 0x21, 0xf5, 0x2c, 0x97, 0xda, 0xc8, 0xf6, 0x92, 0x54, 0xfb, 0xcf, 0x25, 0xd8, - 0xc4, 0x50, 0x3e, 0x4f, 0xdd, 0x11, 0xc3, 0x5b, 0xaf, 0xc9, 0x31, 0xec, 0x27, 0xc3, 0x99, 0x98, - 0x92, 0xcb, 0x40, 0x42, 0x8a, 0xe0, 0x6b, 0xd0, 0x8a, 0x59, 0x82, 0x01, 0x4e, 0x14, 0x65, 0x2c, - 0x42, 0x55, 0xa7, 0xa9, 0x30, 0x45, 0x72, 0x08, 0xef, 0xc9, 0xb5, 0x61, 0x10, 0x0e, 0x55, 0x04, - 0x4d, 0x23, 0x9f, 0x91, 0xa9, 0x76, 0xe4, 0xd2, 0xab, 0xf0, 0x73, 0xbd, 0x60, 0x7d, 0x1b, 0x76, - 0x34, 0xbd, 0xb8, 0x59, 0x25, 0xb5, 0x32, 0xdd, 0x16, 0x51, 0x9f, 0x13, 0x8c, 0x8d, 0x4e, 0xe7, - 0x6c, 0x8c, 0x9f, 0xff, 0x1c, 0xaf, 0x9e, 0xd1, 0xb1, 0x8b, 0x09, 0x8a, 0x55, 0x37, 0x96, 0x69, - 0x9c, 0x92, 0xb6, 0xd9, 0xd4, 0xfa, 0x0e, 0xec, 0x70, 0x45, 0xcb, 0xfc, 0x61, 0x46, 0xa3, 0xbc, - 0xb9, 0xad, 0x17, 0x06, 0x44, 0xfc, 0x75, 0xe8, 0xe4, 0xc4, 0xb2, 0x86, 0x2b, 0x7d, 0xdb, 0x1a, - 0x3d, 0x13, 0x95, 0xfc, 0xf7, 0xca, 0x58, 0x2a, 0x72, 0x3e, 0x96, 0x55, 0xc5, 0x30, 0x55, 0xb3, - 0xbf, 0x95, 0x55, 0x63, 0x32, 0x86, 0xac, 0x24, 0xca, 0x2c, 0x3f, 0x86, 0x2d, 0xae, 0x55, 0x1f, - 0x62, 0x02, 0xb9, 0x54, 0x92, 0xb3, 0x8a, 0x58, 0x3c, 0x98, 0xd3, 0xe1, 0xc5, 0x83, 0xa2, 0xe5, - 0x55, 0x9b, 0x40, 0x02, 0x95, 0x7e, 0x4d, 0x85, 0x49, 0x11, 0xf6, 0x8f, 0xa0, 0x81, 0x3d, 0x44, - 0xaa, 0xb4, 0x43, 0xc3, 0x78, 0xb3, 0x24, 0xc1, 0xfc, 0xca, 0x0c, 0x43, 0x53, 0xd1, 0x63, 0xc8, - 0x2b, 0x96, 0x8c, 0xa1, 0x26, 0x76, 0x04, 0xa0, 0xd2, 0x5c, 0x4a, 0x43, 0x1a, 0x33, 0x04, 0xd4, - 0x44, 0xc4, 0xd9, 0xd4, 0x9d, 0x6b, 0xd7, 0xcb, 0x38, 0x43, 0x40, 0x1d, 0x10, 0x05, 0xbe, 0x75, - 0x83, 0x89, 0x47, 0x8f, 0x00, 0x28, 0x90, 0xa6, 0xb9, 0xc0, 0xaa, 0x29, 0xf0, 0x4f, 0x65, 0x68, - 0x2a, 0x89, 0x4a, 0x61, 0xa4, 0xf2, 0xf0, 0x32, 0xd2, 0x22, 0xe5, 0x04, 0xdb, 0x85, 0x5a, 0x2e, - 0x2e, 0x6f, 0x1d, 0x73, 0x55, 0x33, 0xdd, 0xf0, 0x72, 0x4c, 0xb1, 0x5e, 0x1a, 0xd6, 0x59, 0x49, - 0xdd, 0x10, 0x44, 0x4a, 0xe1, 0x4f, 0xa0, 0xa5, 0xe2, 0x93, 0xf6, 0x54, 0xd7, 0xed, 0x69, 0x2a, - 0x32, 0xb5, 0xeb, 0xa9, 0xe8, 0xd0, 0x50, 0x5f, 0xd9, 0x11, 0x34, 0xfb, 0x0f, 0x0a, 0xe4, 0xf2, - 0x24, 0x87, 0xf2, 0xf7, 0x65, 0xc8, 0xb1, 0x34, 0x2b, 0xda, 0xde, 0x33, 0x80, 0x1c, 0x14, 0x35, - 0xeb, 0x92, 0xdd, 0x64, 0x9d, 0x28, 0x0e, 0xc5, 0xd9, 0xaf, 0xdc, 0xc9, 0x2c, 0x33, 0xaa, 0x9a, - 0xfc, 0xb0, 0xfc, 0xac, 0x84, 0x9f, 0x2a, 0x5b, 0x2f, 0xc4, 0x3d, 0x67, 0x6c, 0x2f, 0xbc, 0x5d, - 0x55, 0x57, 0xbe, 0x5d, 0x55, 0xb3, 0xb7, 0x2b, 0x2c, 0xa3, 0x51, 0x4c, 0xb7, 0x32, 0x8e, 0x72, - 0x41, 0x55, 0x43, 0x90, 0xfd, 0x8f, 0x2a, 0x40, 0x2e, 0xc5, 0x3a, 0x85, 0x5e, 0x10, 0x0d, 0xc5, - 0xa5, 0x12, 0x78, 0x4c, 0x15, 0xa4, 0x61, 0xc2, 0x30, 0x7c, 0xd2, 0xe0, 0x8a, 0x51, 0xdf, 0xb1, - 0x4f, 0xe7, 0x5e, 0x50, 0xce, 0x39, 0xc0, 0x99, 0xda, 0x28, 0x2b, 0x97, 0x93, 0x6d, 0xb3, 0x7e, - 0x06, 0x7b, 0x39, 0x53, 0xdf, 0xe0, 0x57, 0xbe, 0x95, 0xdf, 0x7b, 0x9a, 0x9f, 0x9f, 0xf3, 0xfa, - 0x09, 0x20, 0x3c, 0xc4, 0x3b, 0x66, 0x56, 0xe0, 0x54, 0xb9, 0x95, 0xd3, 0x4e, 0x10, 0xbd, 0x91, - 0x3b, 0x72, 0x3e, 0x6f, 0xe0, 0xbe, 0x71, 0x50, 0x91, 0xf6, 0x06, 0xb7, 0xea, 0xad, 0xdc, 0xf6, - 0xb5, 0x5e, 0xa2, 0x30, 0xe4, 0x2c, 0x3f, 0x07, 0x5c, 0x19, 0x5e, 0xbb, 0x01, 0x5f, 0xe4, 0x57, - 0xbb, 0xeb, 0x9c, 0x5f, 0xe2, 0xa6, 0x22, 0x33, 0x75, 0xce, 0x29, 0x4b, 0x46, 0x85, 0x73, 0xd6, - 0xef, 0x3a, 0xe7, 0x89, 0xdc, 0x91, 0xf3, 0x79, 0x01, 0x08, 0x2e, 0xea, 0xb3, 0x71, 0x2b, 0x97, - 0xad, 0x20, 0x2a, 0xea, 0x72, 0x04, 0x3b, 0x29, 0xf3, 0x38, 0xde, 0x28, 0x06, 0x8f, 0xcd, 0x5b, - 0x79, 0x6c, 0xd3, 0x06, 0xcd, 0xc4, 0xfe, 0x0a, 0x5a, 0x3f, 0x9d, 0x8d, 0x18, 0x9f, 0x5c, 0xe8, - 0x9c, 0xff, 0x6f, 0x97, 0x99, 0x7f, 0x61, 0x99, 0x39, 0x1a, 0x25, 0xd1, 0x2c, 0x2e, 0x54, 0x6d, - 0x95, 0xc3, 0x4b, 0x55, 0x5b, 0xd2, 0xc8, 0xaa, 0xad, 0xa8, 0x3f, 0x85, 0x96, 0x6a, 0xb2, 0x68, - 0x83, 0xaa, 0x42, 0xd6, 0x72, 0xd2, 0x67, 0x4d, 0x9d, 0xda, 0xd6, 0xa7, 0x86, 0x95, 0x76, 0x15, - 0xab, 0x51, 0x6e, 0x26, 0xfc, 0x62, 0xc9, 0xb3, 0xee, 0x15, 0xb4, 0xc7, 0xca, 0x36, 0xb4, 0x4b, - 0x05, 0xe0, 0x47, 0x99, 0x72, 0xf9, 0x19, 0x0e, 0x4d, 0x1b, 0x2a, 0x53, 0xb7, 0xc6, 0xa6, 0x59, - 0xbf, 0x07, 0x20, 0x3e, 0x49, 0x86, 0x59, 0xa1, 0x32, 0x9f, 0x1d, 0xf5, 0x0d, 0x81, 0xdf, 0x3f, - 0xd9, 0xb0, 0x77, 0x06, 0x3b, 0x4b, 0x3c, 0x57, 0x94, 0xa9, 0x6f, 0x99, 0x65, 0xaa, 0xd9, 0x7f, - 0x8f, 0x58, 0x9a, 0x5b, 0xcd, 0xda, 0xf5, 0xc7, 0x92, 0xfa, 0x82, 0xd1, 0x2f, 0x43, 0xd6, 0x33, - 0x68, 0x87, 0xaa, 0xf9, 0xd2, 0x0e, 0xa8, 0x18, 0x8c, 0xcc, 0xc6, 0xcc, 0x69, 0x85, 0x66, 0x9b, - 0x86, 0x8e, 0xf0, 0xa4, 0x05, 0x56, 0x3a, 0xc2, 0x30, 0x8e, 0xd3, 0xf4, 0x0c, 0x6f, 0x17, 0x9a, - 0xc1, 0xca, 0x62, 0x33, 0x48, 0x0f, 0x0d, 0xeb, 0x9e, 0x42, 0xfb, 0xff, 0xac, 0x43, 0xe5, 0xf9, - 0xe0, 0x95, 0x75, 0x0e, 0xdb, 0x8b, 0xff, 0x24, 0x58, 0x0f, 0x49, 0xf4, 0x9a, 0x7f, 0x1f, 0x7a, - 0x1f, 0xae, 0x5d, 0xa7, 0x6e, 0xf9, 0x9e, 0xe5, 0xc0, 0xd6, 0xc2, 0xbb, 0xb1, 0x95, 0x5d, 0x27, - 0xab, 0xdf, 0xe6, 0x7b, 0x0f, 0xd7, 0x2d, 0x9b, 0x3c, 0x17, 0xda, 0x73, 0xcd, 0x73, 0xf5, 0xe7, - 0x9d, 0xe6, 0xb9, 0xae, 0xab, 0xbf, 0x67, 0xfd, 0x00, 0xea, 0xea, 0x25, 0xd9, 0xda, 0x25, 0xda, - 0xc2, 0x1b, 0x75, 0x6f, 0x6f, 0x01, 0xd5, 0x1b, 0x5f, 0x43, 0xbb, 0xf0, 0xf7, 0x83, 0xf5, 0x7e, - 0x41, 0x56, 0xf1, 0x21, 0xba, 0xf7, 0xc1, 0xea, 0x45, 0xcd, 0xed, 0x08, 0x20, 0x7f, 0x6c, 0xb4, - 0xba, 0x44, 0xbd, 0xf4, 0xa0, 0xdd, 0xbb, 0xbf, 0x62, 0x45, 0x33, 0x41, 0x57, 0x2e, 0x3e, 0x0b, - 0x5a, 0x0b, 0x56, 0x5d, 0x7c, 0x94, 0xd3, 0xae, 0x5c, 0xfb, 0x9e, 0x28, 0xd9, 0x2e, 0x3e, 0xf6, - 0x69, 0xb6, 0x6b, 0x9e, 0x1a, 0x35, 0xdb, 0xb5, 0xaf, 0x84, 0xf7, 0xac, 0x9f, 0x43, 0xa7, 0xf8, - 0xb0, 0x66, 0x65, 0x46, 0x5a, 0xf9, 0x7c, 0xd8, 0x7b, 0xb0, 0x66, 0x55, 0x33, 0xfc, 0x04, 0x6a, - 0xea, 0xc5, 0x2c, 0x4b, 0x39, 0xf3, 0xa1, 0xad, 0xb7, 0x5b, 0x04, 0xf5, 0xae, 0x27, 0x50, 0x57, - 0x1f, 0x76, 0x3a, 0x00, 0x0a, 0xdf, 0x79, 0xbd, 0x96, 0x89, 0xda, 0xf7, 0x9e, 0x94, 0x32, 0x39, - 0x69, 0x41, 0x4e, 0xba, 0x4a, 0x8e, 0xe1, 0x9c, 0x8b, 0xba, 0xfc, 0x6b, 0xef, 0xe9, 0xbf, 0x03, - 0x00, 0x00, 0xff, 0xff, 0x58, 0xa9, 0x0a, 0x41, 0xe7, 0x1b, 0x00, 0x00, + // 2361 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x59, 0xcd, 0x73, 0x1b, 0x4b, + 0x11, 0x8f, 0xbe, 0xad, 0xd6, 0x87, 0xed, 0x8d, 0x3f, 0x14, 0xbd, 0x97, 0xbc, 0xb0, 0xf5, 0x80, + 0x00, 0x0f, 0x13, 0x94, 0xf7, 0x8a, 0x14, 0x54, 0x51, 0x95, 0xd8, 0xe1, 0x11, 0x5e, 0x1c, 0x94, + 0xb5, 0xcd, 0x3b, 0xaa, 0xd6, 0xab, 0x89, 0xb4, 0x58, 0xda, 0xdd, 0xec, 0x8e, 0x6c, 0xf9, 0xc2, + 0x81, 0x03, 0xdc, 0x38, 0x53, 0x05, 0xc5, 0x85, 0x1b, 0x77, 0x0e, 0xfc, 0x05, 0x54, 0xf1, 0x87, + 0x70, 0xe3, 0xce, 0x91, 0x9e, 0x9e, 0xd9, 0xd9, 0x59, 0x7d, 0xd8, 0xe1, 0x40, 0x71, 0x79, 0x17, + 0xd5, 0xf4, 0x6f, 0x7a, 0xba, 0x7b, 0xba, 0x7b, 0x7a, 0x7a, 0x47, 0x50, 0x77, 0x23, 0xff, 0x20, + 0x8a, 0x43, 0x1e, 0x5a, 0x15, 0x7e, 0x1d, 0xb1, 0xc4, 0xbe, 0x07, 0xfb, 0x9f, 0x33, 0x7e, 0xc2, + 0xe2, 0x4b, 0x16, 0xff, 0x82, 0xc5, 0x89, 0x1f, 0x06, 0x0e, 0x7b, 0x37, 0x63, 0x09, 0xb7, 0xe7, + 0xd0, 0x59, 0x9e, 0x4a, 0xa2, 0x30, 0x48, 0x98, 0xb5, 0x03, 0x95, 0xa9, 0xfb, 0xcb, 0x30, 0xee, + 0x14, 0x1e, 0x16, 0x1e, 0xb5, 0x1c, 0x49, 0x10, 0xea, 0x07, 0x88, 0x16, 0x15, 0x2a, 0x08, 0x81, + 0x46, 0x2e, 0xf7, 0xc6, 0x9d, 0x92, 0x44, 0x89, 0xb0, 0xba, 0xb0, 0x11, 0xb3, 0x4b, 0x5f, 0x48, + 0xed, 0x94, 0x71, 0xa2, 0xee, 0x68, 0xda, 0xfe, 0x4d, 0x01, 0x76, 0xce, 0xa2, 0xa1, 0xcb, 0x59, + 0x3f, 0x0e, 0x3d, 0x96, 0x24, 0xca, 0x24, 0xab, 0x0d, 0x45, 0x7f, 0x48, 0x3a, 0xeb, 0x0e, 0x8e, + 0xac, 0x2d, 0x28, 0x45, 0x08, 0x14, 0x09, 0x10, 0x43, 0xeb, 0x01, 0x80, 0x37, 0x09, 0x13, 0x76, + 0xc2, 0x87, 0x7e, 0x40, 0x1a, 0x37, 0x1c, 0x03, 0x11, 0xc6, 0x5c, 0xf9, 0x43, 0x3e, 0x26, 0x9d, + 0x68, 0x0c, 0x11, 0xd6, 0x1e, 0x54, 0xc7, 0xcc, 0x1f, 0x8d, 0x79, 0xa7, 0x42, 0xb0, 0xa2, 0xec, + 0x7d, 0xd8, 0x5d, 0xb0, 0x43, 0xee, 0xdf, 0xfe, 0x47, 0x11, 0xf6, 0x0e, 0x63, 0x86, 0x33, 0x87, + 0x61, 0xc0, 0x5d, 0x3f, 0x60, 0xf1, 0x3a, 0x1b, 0xd1, 0xa2, 0xf3, 0x59, 0x30, 0x9c, 0xb0, 0xbe, + 0x8b, 0x6a, 0xa5, 0xa9, 0x06, 0x42, 0x16, 0x8f, 0x99, 0x77, 0x11, 0x85, 0x7e, 0xc0, 0xc9, 0x62, + 0x9c, 0xcf, 0x10, 0x61, 0x71, 0x42, 0x9b, 0x91, 0x5e, 0x92, 0x84, 0xb0, 0x18, 0x07, 0xe1, 0x4c, + 0x5a, 0x5c, 0x77, 0x14, 0xa5, 0x70, 0x16, 0xc7, 0x9d, 0xaa, 0xc6, 0x91, 0x12, 0xf8, 0xc4, 0x3d, + 0x67, 0x93, 0xa4, 0x53, 0x7b, 0x58, 0x12, 0xb8, 0xa4, 0xac, 0x87, 0xd0, 0x08, 0xc2, 0xbe, 0x7f, + 0x19, 0x72, 0x27, 0x0c, 0x79, 0x67, 0x83, 0x1c, 0x66, 0x42, 0x56, 0x07, 0x6a, 0xf1, 0x2c, 0xe0, + 0xfe, 0x94, 0x75, 0xea, 0x24, 0x32, 0x25, 0xc5, 0x5a, 0x35, 0x7c, 0x16, 0x8f, 0x92, 0x0e, 0x90, + 0x60, 0x13, 0xb2, 0x3e, 0x86, 0x56, 0xb6, 0x93, 0x23, 0x3f, 0xee, 0x34, 0x48, 0x42, 0x1e, 0xb4, + 0x5f, 0xc2, 0xfe, 0x92, 0x2f, 0x55, 0x9e, 0x1d, 0x40, 0xdd, 0x4b, 0x41, 0xf2, 0x69, 0xa3, 0xb7, + 0x75, 0x40, 0x99, 0x7b, 0x90, 0x31, 0x67, 0x2c, 0x28, 0xaa, 0x75, 0xe2, 0x8f, 0x02, 0x77, 0xf2, + 0xfe, 0x19, 0x23, 0x3c, 0x46, 0x4b, 0x54, 0x7e, 0x2a, 0xca, 0xde, 0x82, 0x76, 0x2a, 0x4a, 0x05, + 0xfd, 0xaf, 0x25, 0xd8, 0x7e, 0x36, 0x1c, 0xde, 0x92, 0x93, 0x98, 0xd8, 0x9c, 0xc5, 0x98, 0xfa, + 0x28, 0xb1, 0x48, 0xee, 0xd4, 0xb4, 0xf5, 0x11, 0x94, 0x67, 0x09, 0xee, 0xa4, 0x44, 0x3b, 0x69, + 0xa8, 0x9d, 0x9c, 0x21, 0xe4, 0xd0, 0x84, 0x65, 0x41, 0xd9, 0x15, 0xbe, 0x2c, 0x93, 0x2f, 0x69, + 0x2c, 0x4c, 0x66, 0xc1, 0x25, 0xc6, 0x59, 0x40, 0x62, 0x28, 0x10, 0xef, 0x6a, 0xa8, 0x22, 0x2c, + 0x86, 0xe9, 0xb6, 0x6a, 0xd9, 0xb6, 0x74, 0xda, 0x6c, 0xac, 0x4e, 0x9b, 0xfa, 0x9a, 0xb4, 0x81, + 0x5c, 0xda, 0xd8, 0xd0, 0xf4, 0xdc, 0xc8, 0x3d, 0xf7, 0x27, 0x3e, 0xf7, 0x59, 0x82, 0xf1, 0x13, + 0x46, 0xe4, 0x30, 0xeb, 0x11, 0x6c, 0xba, 0x51, 0xe4, 0xc6, 0xd3, 0x30, 0x46, 0xd7, 0xbc, 0xf5, + 0x27, 0xac, 0xd3, 0x24, 0x21, 0x8b, 0xb0, 0x90, 0x96, 0xb0, 0x89, 0x1f, 0xcc, 0xe6, 0xaf, 0x44, + 0xf6, 0x75, 0x5a, 0xc4, 0x96, 0xc3, 0x84, 0xb4, 0x20, 0x7c, 0xcd, 0xae, 0xfa, 0xb1, 0x7f, 0x89, + 0x6b, 0x46, 0xa8, 0xb4, 0x4d, 0x5e, 0x5c, 0x84, 0xad, 0x6f, 0x62, 0x62, 0x4e, 0xfc, 0xa9, 0xcf, + 0x93, 0xce, 0x26, 0x9a, 0xd5, 0xe8, 0xb5, 0x94, 0x3f, 0x1d, 0x42, 0x9d, 0x74, 0xd6, 0x3e, 0x82, + 0xaa, 0x84, 0x84, 0x7b, 0x05, 0x8b, 0x8a, 0x16, 0x8d, 0x05, 0x96, 0x84, 0x6f, 0x39, 0xc5, 0xaa, + 0xec, 0xd0, 0x58, 0x60, 0x63, 0x37, 0x1e, 0x52, 0x9c, 0x10, 0x13, 0x63, 0xdb, 0x81, 0xb2, 0x08, + 0x94, 0x70, 0xf5, 0x4c, 0x05, 0xbc, 0xe5, 0x88, 0xa1, 0x40, 0x46, 0x2a, 0xa7, 0x10, 0xc1, 0xa1, + 0xf5, 0x0d, 0x68, 0xbb, 0xc3, 0x21, 0xba, 0x27, 0xc4, 0xa8, 0x7f, 0xee, 0x0f, 0x13, 0x94, 0x54, + 0xc2, 0xc9, 0x05, 0xd4, 0xde, 0x01, 0xcb, 0x4c, 0x28, 0x95, 0x67, 0xbf, 0x2e, 0xe8, 0x03, 0xa1, + 0xcf, 0xc9, 0xba, 0x6c, 0xfb, 0x7e, 0xae, 0x7a, 0x14, 0x29, 0xaf, 0xb6, 0xd3, 0x13, 0x92, 0xad, + 0x36, 0x0b, 0xca, 0xd2, 0xa1, 0x2c, 0xad, 0x3a, 0x94, 0x5d, 0xe8, 0x2c, 0xdb, 0xa0, 0x0c, 0xf4, + 0x60, 0xff, 0x88, 0x4d, 0xd8, 0xfb, 0xd8, 0x87, 0x9e, 0x0c, 0x5c, 0x2c, 0x1d, 0xf2, 0xc0, 0xd1, + 0xf8, 0xfd, 0x0d, 0x58, 0x56, 0xa2, 0x0c, 0x38, 0x86, 0xdd, 0x57, 0x7e, 0xc2, 0x6f, 0x57, 0xbf, + 0xa4, 0xaa, 0xb8, 0x4a, 0xd5, 0xef, 0x0b, 0x00, 0x99, 0x2c, 0x6d, 0x73, 0xc1, 0xb0, 0x19, 0x31, + 0x36, 0xf7, 0xb9, 0x3a, 0xd1, 0x34, 0x16, 0x71, 0xe7, 0x5e, 0xa4, 0x2e, 0x19, 0x31, 0x14, 0x15, + 0x71, 0x16, 0xf8, 0xf3, 0x93, 0xd0, 0xbb, 0x60, 0x3c, 0xa1, 0x8a, 0x8d, 0xd5, 0xd4, 0x80, 0xe8, + 0x58, 0x8e, 0xd9, 0x64, 0x42, 0x65, 0x7b, 0xc3, 0x91, 0x84, 0xa8, 0xb1, 0x6c, 0x1a, 0xf1, 0xeb, + 0xd7, 0x27, 0x78, 0xa8, 0xc5, 0x09, 0x4b, 0x49, 0xdc, 0xe9, 0xde, 0xe2, 0x4e, 0x55, 0x69, 0x7c, + 0x02, 0x8d, 0x6c, 0x17, 0x09, 0x1a, 0x5b, 0x5a, 0x1d, 0x7a, 0x93, 0xcb, 0x7e, 0x00, 0xcd, 0x13, + 0x8e, 0x41, 0x5d, 0xe3, 0x2f, 0xfb, 0x11, 0xb4, 0x75, 0x5d, 0x25, 0x46, 0x59, 0x19, 0x5c, 0x3e, + 0x4b, 0x14, 0x97, 0xa2, 0xec, 0xbf, 0x95, 0xa0, 0xa6, 0x12, 0x37, 0xad, 0x3e, 0x85, 0xac, 0xfa, + 0xfc, 0x5f, 0x8a, 0xe0, 0x87, 0x50, 0x4f, 0xae, 0x13, 0xce, 0xa6, 0x7d, 0x55, 0x0a, 0x5b, 0x4e, + 0x06, 0x7c, 0x55, 0x10, 0xb3, 0x82, 0xf8, 0xf7, 0x02, 0xd4, 0x75, 0x98, 0xff, 0xeb, 0x86, 0xe5, + 0x13, 0xa8, 0x47, 0x32, 0xf0, 0x4c, 0xd6, 0xb5, 0x46, 0xaf, 0xad, 0x14, 0xa5, 0x95, 0x2c, 0x63, + 0x30, 0xf2, 0xa7, 0x6c, 0xe6, 0x8f, 0xd1, 0x90, 0x54, 0x72, 0x0d, 0x09, 0x06, 0x3f, 0x12, 0x05, + 0xb3, 0x4a, 0x05, 0x93, 0xc6, 0x66, 0x0b, 0x52, 0xcb, 0xb5, 0x20, 0xf6, 0x67, 0x50, 0x3b, 0x76, + 0xbd, 0x31, 0xee, 0x43, 0x2c, 0xf4, 0x22, 0x95, 0xa6, 0xb8, 0x50, 0x8c, 0x85, 0x92, 0x29, 0x43, + 0x7f, 0x5f, 0xab, 0xea, 0xae, 0x28, 0xfb, 0x02, 0xdb, 0x04, 0x79, 0x0c, 0xd4, 0x61, 0x7a, 0x8c, + 0x65, 0x34, 0x75, 0x48, 0x7a, 0x96, 0x96, 0x1b, 0x0d, 0x83, 0x07, 0xc3, 0x52, 0x9b, 0x4a, 0xcd, + 0xaa, 0xea, 0xa6, 0x3e, 0x50, 0xf6, 0x38, 0xe9, 0xb4, 0xfd, 0xdb, 0x02, 0xec, 0xc9, 0x2e, 0xf2, + 0xd6, 0x5e, 0x71, 0x75, 0x77, 0x22, 0xdd, 0x57, 0xca, 0xb9, 0xef, 0x09, 0xd4, 0x63, 0x96, 0x84, + 0xb3, 0x18, 0xdd, 0x4c, 0x9e, 0x6d, 0xf4, 0x76, 0xd3, 0x93, 0x44, 0xba, 0x1c, 0x35, 0xeb, 0x64, + 0x7c, 0xf6, 0x1f, 0x4b, 0xd0, 0xce, 0xcf, 0x8a, 0x8a, 0x75, 0x3e, 0xb9, 0xf0, 0xc3, 0x2f, 0x65, + 0xfb, 0x5b, 0x20, 0x37, 0x99, 0x90, 0x38, 0x55, 0xe8, 0xcb, 0x13, 0xbc, 0x03, 0x51, 0x93, 0x74, + 0x63, 0x06, 0xa8, 0xd9, 0x3e, 0x8b, 0xfd, 0x30, 0xbd, 0x2e, 0x33, 0x40, 0x94, 0x01, 0x24, 0xde, + 0xcc, 0x42, 0xee, 0x92, 0x91, 0x65, 0x47, 0xd3, 0xd4, 0xf7, 0x62, 0x8c, 0x18, 0x3f, 0x14, 0x51, + 0xab, 0xa8, 0xbe, 0x57, 0x23, 0xd9, 0xfc, 0x31, 0x9b, 0x26, 0xea, 0x98, 0x1b, 0x88, 0xb0, 0x5c, + 0x46, 0xf3, 0x95, 0x48, 0x6a, 0x4a, 0x0c, 0xb4, 0xdc, 0x80, 0x84, 0x04, 0x49, 0x9e, 0x5c, 0xb9, + 0x11, 0x1d, 0xfb, 0xb2, 0x63, 0x20, 0x98, 0xc8, 0xdb, 0x92, 0x42, 0x6f, 0xe0, 0x57, 0x8e, 0x2b, + 0x2e, 0x66, 0x2a, 0x03, 0x65, 0x67, 0x79, 0x42, 0x70, 0x5f, 0xb0, 0x38, 0x60, 0x93, 0x63, 0x43, + 0x2b, 0x48, 0xee, 0xa5, 0x09, 0xab, 0x07, 0x3b, 0x12, 0x3c, 0x3d, 0xec, 0x9b, 0x0b, 0x1a, 0xb4, + 0x60, 0xe5, 0x9c, 0xf8, 0x16, 0x5b, 0xca, 0x13, 0x75, 0xe1, 0x7d, 0x17, 0x5a, 0x2f, 0x2e, 0x19, + 0x56, 0xf0, 0x34, 0x73, 0xd0, 0xef, 0xe2, 0x00, 0x60, 0x36, 0x4c, 0x23, 0x15, 0xb5, 0x0c, 0xb0, + 0x13, 0xa8, 0x10, 0xfb, 0xca, 0x86, 0x47, 0x26, 0x5d, 0x51, 0x27, 0x5d, 0x3e, 0xc5, 0x5a, 0x3a, + 0xc5, 0x54, 0x32, 0x96, 0xb3, 0x64, 0xcc, 0x29, 0xad, 0x2c, 0x2a, 0xfd, 0x5d, 0x11, 0x9a, 0xaf, + 0x19, 0xbf, 0x0a, 0xe3, 0x0b, 0x71, 0xb8, 0x92, 0x95, 0xf7, 0xe8, 0x3d, 0xfc, 0xec, 0x9b, 0x0f, + 0xce, 0xaf, 0xb9, 0x4e, 0xa6, 0x5a, 0x3c, 0x7f, 0x2e, 0x48, 0xeb, 0x3e, 0x00, 0x4e, 0xf5, 0x5d, + 0x79, 0x77, 0xaa, 0x5c, 0x8a, 0xe7, 0x0a, 0xb0, 0x3e, 0x80, 0xba, 0x33, 0x1f, 0x60, 0x0d, 0x0e, + 0xe3, 0x24, 0x4d, 0xa6, 0x78, 0xfe, 0x82, 0x68, 0xb1, 0x16, 0x27, 0x87, 0x71, 0x18, 0x45, 0x6c, + 0x98, 0x9a, 0x16, 0xcf, 0x8f, 0x24, 0x20, 0xb4, 0x9e, 0xa6, 0x5a, 0xab, 0x52, 0x2b, 0xcf, 0xb4, + 0xe2, 0x54, 0xa4, 0xb4, 0xd6, 0xd4, 0xa6, 0x4c, 0xad, 0xa7, 0x5a, 0xab, 0x4c, 0xa1, 0x0d, 0x6e, + 0x68, 0x3d, 0xcd, 0xb4, 0xd6, 0xd3, 0xb5, 0x4a, 0xab, 0xfd, 0x97, 0x02, 0x6c, 0x60, 0x2a, 0x9f, + 0x25, 0xee, 0x88, 0xe1, 0xad, 0xd7, 0xe0, 0x98, 0xf6, 0x93, 0xc1, 0x4c, 0x90, 0x2a, 0x64, 0x40, + 0x90, 0x64, 0xf8, 0x1a, 0x34, 0x23, 0x16, 0x63, 0x82, 0x2b, 0x8e, 0x22, 0x16, 0x21, 0x4c, 0x68, + 0x89, 0x49, 0x96, 0x03, 0xb8, 0x4b, 0x73, 0x03, 0x3f, 0x18, 0xc8, 0x0c, 0x9a, 0x86, 0x43, 0xa6, + 0x5c, 0xb5, 0x4d, 0x53, 0x2f, 0x83, 0x2f, 0xf4, 0x84, 0xf5, 0x6d, 0xd8, 0xd6, 0xfc, 0xe2, 0x66, + 0x25, 0x6e, 0xe9, 0xba, 0x4d, 0xc5, 0x7d, 0xa6, 0x60, 0xfb, 0x57, 0xd0, 0x3e, 0x1d, 0xc7, 0x21, + 0xe7, 0x78, 0xf5, 0x8c, 0x8e, 0x5c, 0x3c, 0xa0, 0x58, 0x75, 0x23, 0x3a, 0xc6, 0x89, 0xb2, 0x36, + 0x25, 0xad, 0xef, 0xc0, 0x36, 0x97, 0xbc, 0x6c, 0x38, 0x48, 0x79, 0x64, 0x34, 0xb7, 0xf4, 0x44, + 0x5f, 0x31, 0x7f, 0x1d, 0xda, 0x19, 0x33, 0xd5, 0x70, 0x69, 0x6f, 0x4b, 0xa3, 0xa7, 0xa2, 0x92, + 0xff, 0x41, 0x3a, 0x4b, 0x66, 0xce, 0x27, 0x54, 0x55, 0x0c, 0x57, 0x35, 0x7a, 0x9b, 0x69, 0x35, + 0x56, 0xce, 0xa0, 0x4a, 0x22, 0xdd, 0xf2, 0x63, 0xd8, 0xe4, 0xda, 0xf4, 0x01, 0x1e, 0x20, 0x57, + 0x95, 0xe4, 0xb4, 0x22, 0xe6, 0x37, 0xe6, 0xb4, 0x79, 0x7e, 0xa3, 0xe8, 0x79, 0xd9, 0x26, 0x28, + 0x85, 0xd2, 0xbe, 0x86, 0xc4, 0x48, 0x85, 0xfd, 0x23, 0xa8, 0x63, 0x0f, 0x91, 0x48, 0xeb, 0xd0, + 0x31, 0xde, 0x2c, 0x8e, 0xf1, 0x7c, 0xa5, 0x8e, 0x51, 0xa4, 0xe8, 0x31, 0xe8, 0x8a, 0x55, 0xce, + 0x90, 0x84, 0x1d, 0x02, 0xc8, 0x63, 0x4e, 0xda, 0x90, 0xc7, 0x4c, 0x01, 0x49, 0x88, 0x3c, 0x9b, + 0xba, 0x73, 0x1d, 0x7a, 0xca, 0x33, 0x04, 0xe4, 0x06, 0x51, 0xe1, 0x5b, 0xd7, 0x9f, 0x78, 0xea, + 0x7d, 0x00, 0x15, 0x2a, 0x32, 0x53, 0x58, 0x36, 0x15, 0xfe, 0xb9, 0x08, 0x0d, 0xa9, 0x51, 0x1a, + 0x8c, 0x5c, 0x1e, 0x5e, 0x46, 0x5a, 0x25, 0x11, 0xd8, 0x2e, 0x54, 0x32, 0x75, 0x59, 0xeb, 0x98, + 0x99, 0x9a, 0xda, 0x86, 0x97, 0x63, 0x82, 0xf5, 0xd2, 0xf0, 0xce, 0x4a, 0xee, 0xba, 0x60, 0x92, + 0x06, 0x7f, 0x0a, 0x4d, 0x99, 0x9f, 0x6a, 0x4d, 0x79, 0xdd, 0x9a, 0x86, 0x64, 0x93, 0xab, 0x9e, + 0x88, 0x0e, 0x0d, 0xed, 0xa5, 0x8e, 0xa0, 0xd1, 0xbb, 0x9f, 0x63, 0xa7, 0x9d, 0x1c, 0xd0, 0xef, + 0x8b, 0x80, 0x63, 0x69, 0x96, 0xbc, 0xdd, 0xa7, 0x00, 0x19, 0x28, 0x6a, 0xd6, 0x05, 0xbb, 0x4e, + 0x3b, 0x51, 0x1c, 0x8a, 0xbd, 0x5f, 0xba, 0x93, 0x59, 0xea, 0x54, 0x49, 0xfc, 0xb0, 0xf8, 0xb4, + 0x80, 0x5f, 0x31, 0x9b, 0xcf, 0xc5, 0x3d, 0x67, 0x2c, 0xcf, 0x3d, 0x6b, 0x95, 0x57, 0x3e, 0x6b, + 0x95, 0xd3, 0x67, 0x2d, 0x2c, 0xa3, 0x61, 0xa4, 0x6e, 0x65, 0x1c, 0x65, 0x8a, 0xca, 0x86, 0x22, + 0xfb, 0x9f, 0x65, 0x80, 0x4c, 0x8b, 0x75, 0x02, 0x5d, 0x3f, 0x1c, 0x88, 0x4b, 0xc5, 0xf7, 0x98, + 0x2c, 0x48, 0x83, 0x98, 0x61, 0xfa, 0x24, 0xfe, 0x25, 0x53, 0x7d, 0xc7, 0x9e, 0xda, 0xf7, 0x82, + 0x71, 0xce, 0x3e, 0x52, 0x72, 0x21, 0x55, 0x2e, 0x27, 0x5d, 0x66, 0xfd, 0x0c, 0x76, 0x33, 0xa1, + 0x43, 0x43, 0x5e, 0xf1, 0x46, 0x79, 0x77, 0xb5, 0xbc, 0x61, 0x26, 0xeb, 0x27, 0x80, 0xf0, 0x00, + 0xef, 0x98, 0x59, 0x4e, 0x52, 0xe9, 0x46, 0x49, 0xdb, 0x7e, 0xf8, 0x86, 0x56, 0x64, 0x72, 0xde, + 0xc0, 0x3d, 0x63, 0xa3, 0xe2, 0xd8, 0x1b, 0xd2, 0xca, 0x37, 0x4a, 0xdb, 0xd3, 0x76, 0x89, 0xc2, + 0x90, 0x89, 0xfc, 0x02, 0x70, 0x66, 0x70, 0xe5, 0xfa, 0x7c, 0x51, 0x5e, 0xe5, 0xb6, 0x7d, 0x7e, + 0x89, 0x8b, 0xf2, 0xc2, 0xe4, 0x3e, 0xa7, 0x2c, 0x1e, 0xe5, 0xf6, 0x59, 0xbd, 0x6d, 0x9f, 0xc7, + 0xb4, 0x22, 0x93, 0xf3, 0x1c, 0x10, 0x5c, 0xb4, 0xa7, 0x76, 0xa3, 0x94, 0x4d, 0x3f, 0xcc, 0xdb, + 0x72, 0x08, 0xdb, 0x09, 0xf3, 0x38, 0xde, 0x28, 0x86, 0x8c, 0x8d, 0x1b, 0x65, 0x6c, 0xa9, 0x05, + 0x5a, 0x88, 0xfd, 0x0e, 0x9a, 0x3f, 0x9d, 0x8d, 0x18, 0x9f, 0x9c, 0xeb, 0x33, 0xff, 0xbf, 0x2e, + 0x33, 0xff, 0xc6, 0x32, 0x73, 0x38, 0x8a, 0xc3, 0x59, 0x94, 0xab, 0xda, 0xf2, 0x0c, 0x2f, 0x55, + 0x6d, 0xe2, 0xa1, 0xaa, 0x2d, 0xb9, 0x3f, 0x83, 0xa6, 0x6c, 0xb2, 0xd4, 0x02, 0x59, 0x85, 0xac, + 0xe5, 0x43, 0x9f, 0x36, 0x75, 0x72, 0x59, 0x4f, 0x35, 0xac, 0x6a, 0x55, 0xbe, 0x1a, 0x65, 0x6e, + 0xc2, 0x2f, 0x96, 0xec, 0xd4, 0xbd, 0x84, 0xd6, 0x58, 0xfa, 0x46, 0xad, 0x92, 0x09, 0xf8, 0x71, + 0x6a, 0x5c, 0xb6, 0x87, 0x03, 0xd3, 0x87, 0xd2, 0xd5, 0xcd, 0xb1, 0xe9, 0xd6, 0xef, 0x01, 0x88, + 0x4f, 0x92, 0x41, 0x5a, 0xa8, 0xcc, 0x17, 0x49, 0x7d, 0x43, 0xe0, 0xf7, 0x4f, 0x3a, 0xec, 0x9e, + 0xc2, 0xf6, 0x92, 0xcc, 0x15, 0x65, 0xea, 0x5b, 0x66, 0x99, 0x6a, 0xf4, 0xee, 0x2a, 0x91, 0xe6, + 0x52, 0xb3, 0x76, 0xfd, 0xa9, 0x20, 0xbf, 0x60, 0xf4, 0xa3, 0x91, 0xf5, 0x14, 0x5a, 0x81, 0x6c, + 0xbe, 0x74, 0x00, 0x4a, 0x86, 0x20, 0xb3, 0x31, 0x73, 0x9a, 0x81, 0xd9, 0xa6, 0x61, 0x20, 0x3c, + 0xf2, 0xc0, 0xca, 0x40, 0x18, 0xce, 0x71, 0x1a, 0x9e, 0x11, 0xed, 0x5c, 0x33, 0x58, 0x5a, 0x6c, + 0x06, 0xd5, 0x43, 0xc3, 0xba, 0x57, 0xd2, 0xde, 0xbf, 0xaa, 0x50, 0x7a, 0xd6, 0x7f, 0x69, 0x9d, + 0xc1, 0xd6, 0xe2, 0x9f, 0x0c, 0xd6, 0x03, 0xa5, 0x7a, 0xcd, 0x1f, 0x13, 0xdd, 0x8f, 0xd6, 0xce, + 0xab, 0x6e, 0xf9, 0x8e, 0xe5, 0xc0, 0xe6, 0xc2, 0x93, 0xb2, 0x95, 0x5e, 0x27, 0xab, 0x9f, 0xed, + 0xbb, 0x0f, 0xd6, 0x4d, 0x9b, 0x32, 0x17, 0xda, 0x73, 0x2d, 0x73, 0xf5, 0xe7, 0x9d, 0x96, 0xb9, + 0xae, 0xab, 0xbf, 0x63, 0xfd, 0x00, 0xaa, 0xf2, 0x91, 0xd9, 0xda, 0x51, 0xbc, 0xb9, 0xe7, 0xeb, + 0xee, 0xee, 0x02, 0xaa, 0x17, 0xbe, 0x82, 0x56, 0xee, 0x9f, 0x09, 0xeb, 0x83, 0x9c, 0xae, 0xfc, + 0x1b, 0x75, 0xf7, 0xc3, 0xd5, 0x93, 0x5a, 0xda, 0x21, 0x40, 0xf6, 0x0e, 0x69, 0x75, 0x14, 0xf7, + 0xd2, 0x5b, 0x77, 0xf7, 0xde, 0x8a, 0x19, 0x2d, 0x04, 0x43, 0xb9, 0xf8, 0x62, 0x68, 0x2d, 0x78, + 0x75, 0xf1, 0xbd, 0x4e, 0x87, 0x72, 0xed, 0x53, 0x23, 0x89, 0x5d, 0x7c, 0x07, 0xd4, 0x62, 0xd7, + 0xbc, 0x42, 0x6a, 0xb1, 0x6b, 0x1f, 0x10, 0xef, 0x58, 0x3f, 0x87, 0x76, 0xfe, 0x61, 0xcd, 0x4a, + 0x9d, 0xb4, 0xf2, 0x65, 0xb1, 0x7b, 0x7f, 0xcd, 0xac, 0x16, 0xf8, 0x29, 0x54, 0xe4, 0x8b, 0x59, + 0x7a, 0xe4, 0xcc, 0x87, 0xb6, 0xee, 0x4e, 0x1e, 0xd4, 0xab, 0x1e, 0x43, 0x55, 0x7e, 0xd8, 0xe9, + 0x04, 0xc8, 0x7d, 0xe7, 0x75, 0x9b, 0x26, 0x6a, 0xdf, 0x79, 0x5c, 0x48, 0xf5, 0x24, 0x39, 0x3d, + 0xc9, 0x2a, 0x3d, 0x46, 0x70, 0xce, 0xab, 0xf4, 0xaf, 0xdf, 0x93, 0xff, 0x04, 0x00, 0x00, 0xff, + 0xff, 0xbf, 0xea, 0xc8, 0x11, 0x02, 0x1c, 0x00, 0x00, } diff --git a/vendor/src/github.com/docker/containerd/api/grpc/types/api.proto b/vendor/src/github.com/docker/containerd/api/grpc/types/api.proto index 7ae3a3dd64..478f990e79 100644 --- a/vendor/src/github.com/docker/containerd/api/grpc/types/api.proto +++ b/vendor/src/github.com/docker/containerd/api/grpc/types/api.proto @@ -127,6 +127,7 @@ message Checkpoint { bool tcp = 3; // allow open tcp connections bool unixSockets = 4; // allow external unix sockets bool shell = 5; // allow shell-jobs + repeated string emptyNS = 6; } message ListCheckpointResponse { @@ -189,17 +190,17 @@ message UpdateContainerRequest { } message UpdateResource { - uint32 blkioWeight =1; - uint32 cpuShares = 2; - uint32 cpuPeriod = 3; - uint32 cpuQuota = 4; + uint64 blkioWeight =1; + uint64 cpuShares = 2; + uint64 cpuPeriod = 3; + uint64 cpuQuota = 4; string cpusetCpus = 5; string cpusetMems = 6; - uint32 memoryLimit = 7; - uint32 memorySwap = 8; - uint32 memoryReservation = 9; - uint32 kernelMemoryLimit = 10; - uint32 kernelTCPMemoryLimit = 11; + uint64 memoryLimit = 7; + uint64 memorySwap = 8; + uint64 memoryReservation = 9; + uint64 kernelMemoryLimit = 10; + uint64 kernelTCPMemoryLimit = 11; } message UpdateContainerResponse { diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/configs/config.go b/vendor/src/github.com/opencontainers/runc/libcontainer/configs/config.go index ef232222ca..806e0be960 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/configs/config.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/configs/config.go @@ -187,6 +187,10 @@ type Config struct { // Labels are user defined metadata that is stored in the config and populated on the state Labels []string `json:"labels"` + + // 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"` } type Hooks struct { diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/system/sysconfig.go b/vendor/src/github.com/opencontainers/runc/libcontainer/system/sysconfig.go index 3e3d7e01e3..4fba6c2b70 100644 --- a/vendor/src/github.com/opencontainers/runc/libcontainer/system/sysconfig.go +++ b/vendor/src/github.com/opencontainers/runc/libcontainer/system/sysconfig.go @@ -4,6 +4,21 @@ package system /* #include +#include + +int GetLongBit() { +#ifdef _SC_LONG_BIT + int longbits; + + longbits = sysconf(_SC_LONG_BIT); + if (longbits < 0) { + longbits = (CHAR_BIT * sizeof(long)); + } + return longbits; +#else + return (CHAR_BIT * sizeof(long)); +#endif +} */ import "C" @@ -12,5 +27,5 @@ func GetClockTicks() int { } func GetLongBit() int { - return int(C.sysconf(C._SC_LONG_BIT)) + return int(C.GetLongBit()) } diff --git a/vendor/src/github.com/opencontainers/specs/specs-go/config.go b/vendor/src/github.com/opencontainers/specs/specs-go/config.go index 45e604cc3d..ec99035bbc 100644 --- a/vendor/src/github.com/opencontainers/specs/specs-go/config.go +++ b/vendor/src/github.com/opencontainers/specs/specs-go/config.go @@ -2,9 +2,7 @@ package specs import "os" -// Spec is the base configuration for the container. It specifies platform -// independent configuration. This information must be included when the -// bundle is packaged for distribution. +// Spec is the base configuration for the container. type Spec struct { // Version is the version of the specification that is supported. Version string `json:"ociVersion"` @@ -17,20 +15,22 @@ type Spec struct { // Hostname is the container's host name. Hostname string `json:"hostname,omitempty"` // Mounts profile configuration for adding mounts to the container's filesystem. - Mounts []Mount `json:"mounts"` + Mounts []Mount `json:"mounts,omitempty"` // Hooks are the commands run at various lifecycle events of the container. Hooks Hooks `json:"hooks"` // Annotations is an unstructured key value map that may be set by external tools to store and retrieve arbitrary metadata. Annotations map[string]string `json:"annotations,omitempty"` // Linux is platform specific configuration for Linux based containers. - Linux Linux `json:"linux" platform:"linux"` + Linux Linux `json:"linux" platform:"linux,omitempty"` + // Solaris is platform specific configuration for Solaris containers. + Solaris Solaris `json:"solaris" platform:"solaris,omitempty"` } // Process contains information to start a specific application inside the container. type Process struct { // Terminal creates an interactive terminal for the container. - Terminal bool `json:"terminal"` + Terminal bool `json:"terminal,omitempty"` // User specifies user information for the process. User User `json:"user"` // Args specifies the binary and arguments for the application to execute. @@ -57,9 +57,9 @@ type Process struct { // main process. type User struct { // UID is the user id. (this field is platform dependent) - UID uint32 `json:"uid,omitempty" platform:"linux"` + UID uint32 `json:"uid" platform:"linux"` // GID is the group id. (this field is platform dependent) - GID uint32 `json:"gid,omitempty" platform:"linux"` + GID uint32 `json:"gid" platform:"linux"` // AdditionalGids are additional group ids set for the container's process. (this field is platform dependent) AdditionalGids []uint32 `json:"additionalGids,omitempty" platform:"linux"` } @@ -69,7 +69,7 @@ type Root struct { // Path is the absolute path to the container's root filesystem. Path string `json:"path"` // Readonly makes the root filesystem for the container readonly before the process is executed. - Readonly bool `json:"readonly"` + Readonly bool `json:"readonly,omitempty"` } // Platform specifies OS and arch information for the host system that the container @@ -169,6 +169,8 @@ const ( UTSNamespace = "uts" // UserNamespace for isolating user and group IDs UserNamespace = "user" + // CgroupNamespace for isolating cgroup hierarchies + CgroupNamespace = "cgroup" ) // IDMapping specifies UID/GID mappings @@ -358,6 +360,51 @@ type Seccomp struct { Syscalls []Syscall `json:"syscalls,omitempty"` } +// Solaris contains platform specific configuration for Solaris application containers. +type Solaris struct { + // SMF FMRI which should go "online" before we start the container process. + Milestone string `json:"milestone,omitempty"` + // Maximum set of privileges any process in this container can obtain. + LimitPriv string `json:"limitpriv,omitempty"` + // 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"` + // Set limit on the amount of CPU time that can be used by container. + CappedCPU CappedCPU `json:"cappedCPU,omitempty"` + // The physical and swap caps on the memory that can be used by this container. + CappedMemory CappedMemory `json:"cappedMemory,omitempty"` +} + +// CappedCPU allows users to set limit on the amount of CPU time that can be used by container. +type CappedCPU 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 { + 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 { + // Specify a name for the automatically created VNIC datalink. + Linkname string `json:"linkname,omitempty"` + // Specify the link over which the VNIC will be created. + Lowerlink string `json:"lowerLink,omitempty"` + // The set of IP addresses that the container can use. + Allowedaddr string `json:"allowedAddress,omitempty"` + // Specifies whether allowedAddress limitation is to be applied to the VNIC. + Configallowedaddr string `json:"configureAllowedAddress,omitempty"` + // The value of the optional default router. + Defrouter string `json:"defrouter,omitempty"` + // Enable one or more types of link protection. + Linkprotection string `json:"linkProtection,omitempty"` + // Set the VNIC's macAddress + Macaddress string `json:"macAddress,omitempty"` +} + // Arch used for additional architectures type Arch string @@ -375,6 +422,11 @@ const ( ArchMIPSEL Arch = "SCMP_ARCH_MIPSEL" ArchMIPSEL64 Arch = "SCMP_ARCH_MIPSEL64" ArchMIPSEL64N32 Arch = "SCMP_ARCH_MIPSEL64N32" + ArchPPC Arch = "SCMP_ARCH_PPC" + ArchPPC64 Arch = "SCMP_ARCH_PPC64" + ArchPPC64LE Arch = "SCMP_ARCH_PPC64LE" + ArchS390 Arch = "SCMP_ARCH_S390" + ArchS390X Arch = "SCMP_ARCH_S390X" ) // Action taken upon Seccomp rule match diff --git a/vendor/src/github.com/opencontainers/specs/specs-go/state.go b/vendor/src/github.com/opencontainers/specs/specs-go/state.go index d3ad79d9c2..445f8c5c0c 100644 --- a/vendor/src/github.com/opencontainers/specs/specs-go/state.go +++ b/vendor/src/github.com/opencontainers/specs/specs-go/state.go @@ -6,8 +6,12 @@ type State struct { Version string `json:"version"` // ID is the container ID ID string `json:"id"` + // Status is the runtime state of the container. + Status string `json:"status"` // Pid is the process id for the container's main 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"` } diff --git a/vendor/src/github.com/opencontainers/specs/specs-go/version.go b/vendor/src/github.com/opencontainers/specs/specs-go/version.go index 371289aea5..2dbd302e3c 100644 --- a/vendor/src/github.com/opencontainers/specs/specs-go/version.go +++ b/vendor/src/github.com/opencontainers/specs/specs-go/version.go @@ -4,14 +4,14 @@ import "fmt" const ( // VersionMajor is for an API incompatible changes - VersionMajor = 0 + VersionMajor = 1 // VersionMinor is for functionality in a backwards-compatible manner - VersionMinor = 6 + VersionMinor = 0 // VersionPatch is for backwards-compatible bug fixes VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "-dev" + VersionDev = "-rc1" ) // Version is the specification version that the package types support. From 7b2e5216b89b4c454d67473f1fa06c52a4624680 Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Mon, 23 May 2016 14:49:50 -0700 Subject: [PATCH 2/7] Add support for multiples runtimes Signed-off-by: Kenfe-Mickael Laventure --- api/client/info.go | 12 +- cmd/dockerd/daemon.go | 4 + cmd/dockerd/daemon_unix.go | 1 + daemon/config.go | 31 ++- daemon/config_test.go | 12 +- daemon/config_unix.go | 34 ++++ daemon/config_windows.go | 17 ++ daemon/daemon.go | 22 ++- daemon/daemon_solaris.go | 4 + daemon/daemon_unix.go | 43 +++++ daemon/daemon_windows.go | 4 + daemon/info.go | 2 + daemon/start.go | 18 +- daemon/start_linux.go | 20 ++ daemon/start_windows.go | 10 + docs/reference/commandline/create.md | 1 + docs/reference/commandline/dockerd.md | 45 ++++- docs/reference/commandline/run.md | 1 + integration-cli/docker_cli_daemon_test.go | 180 ++++++++++++++++++ .../docker_cli_events_unix_test.go | 3 +- integration-cli/docker_cli_info_test.go | 4 + libcontainerd/container_linux.go | 24 ++- libcontainerd/remote_linux.go | 22 ++- runconfig/opts/parse.go | 4 +- runconfig/opts/runtime.go | 73 +++++++ 25 files changed, 568 insertions(+), 23 deletions(-) create mode 100644 daemon/start_linux.go create mode 100644 daemon/start_windows.go create mode 100644 runconfig/opts/runtime.go diff --git a/api/client/info.go b/api/client/info.go index 4566f6c1a6..df1415c9cb 100644 --- a/api/client/info.go +++ b/api/client/info.go @@ -55,7 +55,7 @@ func (cli *DockerCli) CmdInfo(args ...string) error { ioutils.FprintfIfNotEmpty(cli.out, "Logging Driver: %s\n", info.LoggingDriver) ioutils.FprintfIfNotEmpty(cli.out, "Cgroup Driver: %s\n", info.CgroupDriver) - fmt.Fprintf(cli.out, "Plugins: \n") + fmt.Fprintf(cli.out, "Plugins:\n") fmt.Fprintf(cli.out, " Volume:") fmt.Fprintf(cli.out, " %s", strings.Join(info.Plugins.Volume, " ")) fmt.Fprintf(cli.out, "\n") @@ -84,6 +84,16 @@ func (cli *DockerCli) CmdInfo(args ...string) error { fmt.Fprintf(cli.out, " IsManager: No\n") } } + + if len(info.Runtimes) > 0 { + fmt.Fprintf(cli.out, "Runtimes:") + for name := range info.Runtimes { + fmt.Fprintf(cli.out, " %s", name) + } + fmt.Fprint(cli.out, "\n") + fmt.Fprintf(cli.out, "Default Runtime: %s\n", info.DefaultRuntime) + } + ioutils.FprintfIfNotEmpty(cli.out, "Kernel Version: %s\n", info.KernelVersion) ioutils.FprintfIfNotEmpty(cli.out, "Operating System: %s\n", info.OperatingSystem) ioutils.FprintfIfNotEmpty(cli.out, "OSType: %s\n", info.OSType) diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 2b39aae8c4..2717ee3132 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -388,6 +388,10 @@ func loadDaemonCliConfig(config *daemon.Config, flags *flag.FlagSet, commonConfi } } + if err := daemon.ValidateConfiguration(config); err != nil { + return nil, err + } + // Regardless of whether the user sets it to true or false, if they // specify TLSVerify at all then we need to turn on TLS if config.IsValueSet(cliflags.TLSVerifyKey) { diff --git a/cmd/dockerd/daemon_unix.go b/cmd/dockerd/daemon_unix.go index 50588b9e24..3e197c498f 100644 --- a/cmd/dockerd/daemon_unix.go +++ b/cmd/dockerd/daemon_unix.go @@ -74,6 +74,7 @@ func (cli *DaemonCli) getPlatformRemoteOptions() []libcontainerd.RemoteOption { if cli.Config.LiveRestore { opts = append(opts, libcontainerd.WithLiveRestore(true)) } + opts = append(opts, libcontainerd.WithRuntimePath(daemon.DefaultRuntimeBinary)) return opts } diff --git a/daemon/config.go b/daemon/config.go index 2331045fdb..e41eb49884 100644 --- a/daemon/config.go +++ b/daemon/config.go @@ -14,6 +14,7 @@ import ( "github.com/docker/docker/pkg/discovery" flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/registry" + "github.com/docker/engine-api/types" "github.com/imdario/mergo" ) @@ -40,6 +41,7 @@ const ( var flatOptions = map[string]bool{ "cluster-store-opts": true, "log-opts": true, + "runtimes": true, } // LogConfig represents the default log configuration. @@ -200,7 +202,7 @@ func ReloadConfiguration(configFile string, flags *flag.FlagSet, reload func(*Co return err } - if err := validateConfiguration(newConfig); err != nil { + if err := ValidateConfiguration(newConfig); err != nil { return fmt.Errorf("file configuration validation failed (%v)", err) } @@ -224,7 +226,7 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *flag.FlagSet, configF return nil, err } - if err := validateConfiguration(fileConfig); err != nil { + if err := ValidateConfiguration(fileConfig); err != nil { return nil, fmt.Errorf("file configuration validation failed (%v)", err) } @@ -233,6 +235,12 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *flag.FlagSet, configF return nil, err } + // We need to validate again once both fileConfig and flagsConfig + // have been merged + if err := ValidateConfiguration(fileConfig); err != nil { + return nil, fmt.Errorf("file configuration validation failed (%v)", err) + } + return fileConfig, nil } @@ -381,10 +389,10 @@ func findConfigurationConflicts(config map[string]interface{}, flags *flag.FlagS return nil } -// validateConfiguration validates some specific configs. +// ValidateConfiguration validates some specific configs. // such as config.DNS, config.Labels, config.DNSSearch, // as well as config.MaxConcurrentDownloads, config.MaxConcurrentUploads. -func validateConfiguration(config *Config) error { +func ValidateConfiguration(config *Config) error { // validate DNS for _, dns := range config.DNS { if _, err := opts.ValidateIPAddress(dns); err != nil { @@ -415,5 +423,20 @@ func validateConfiguration(config *Config) error { if config.IsValueSet("max-concurrent-uploads") && config.MaxConcurrentUploads != nil && *config.MaxConcurrentUploads < 0 { return fmt.Errorf("invalid max concurrent uploads: %d", *config.MaxConcurrentUploads) } + + // validate that "default" runtime is not reset + if runtimes := config.GetAllRuntimes(); len(runtimes) > 0 { + if _, ok := runtimes[types.DefaultRuntimeName]; ok { + return fmt.Errorf("runtime name '%s' is reserved", types.DefaultRuntimeName) + } + } + + if defaultRuntime := config.GetDefaultRuntimeName(); defaultRuntime != "" && defaultRuntime != types.DefaultRuntimeName { + runtimes := config.GetAllRuntimes() + if _, ok := runtimes[defaultRuntime]; !ok { + return fmt.Errorf("specified default runtime '%s' does not exist", defaultRuntime) + } + } + return nil } diff --git a/daemon/config_test.go b/daemon/config_test.go index 7647f4d3cb..0375c1ae21 100644 --- a/daemon/config_test.go +++ b/daemon/config_test.go @@ -216,7 +216,7 @@ func TestValidateConfiguration(t *testing.T) { }, } - err := validateConfiguration(c1) + err := ValidateConfiguration(c1) if err == nil { t.Fatal("expected error, got nil") } @@ -227,7 +227,7 @@ func TestValidateConfiguration(t *testing.T) { }, } - err = validateConfiguration(c2) + err = ValidateConfiguration(c2) if err != nil { t.Fatalf("expected no error, got error %v", err) } @@ -238,7 +238,7 @@ func TestValidateConfiguration(t *testing.T) { }, } - err = validateConfiguration(c3) + err = ValidateConfiguration(c3) if err != nil { t.Fatalf("expected no error, got error %v", err) } @@ -249,7 +249,7 @@ func TestValidateConfiguration(t *testing.T) { }, } - err = validateConfiguration(c4) + err = ValidateConfiguration(c4) if err == nil { t.Fatal("expected error, got nil") } @@ -260,7 +260,7 @@ func TestValidateConfiguration(t *testing.T) { }, } - err = validateConfiguration(c5) + err = ValidateConfiguration(c5) if err != nil { t.Fatalf("expected no error, got error %v", err) } @@ -271,7 +271,7 @@ func TestValidateConfiguration(t *testing.T) { }, } - err = validateConfiguration(c6) + err = ValidateConfiguration(c6) if err == nil { t.Fatal("expected error, got nil") } diff --git a/daemon/config_unix.go b/daemon/config_unix.go index 7e8d2bb6f4..4cb5390c21 100644 --- a/daemon/config_unix.go +++ b/daemon/config_unix.go @@ -8,6 +8,7 @@ import ( "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" runconfigopts "github.com/docker/docker/runconfig/opts" + "github.com/docker/engine-api/types" "github.com/docker/go-units" ) @@ -30,6 +31,8 @@ type Config struct { ExecRoot string `json:"exec-root,omitempty"` RemappedRoot string `json:"userns-remap,omitempty"` Ulimits map[string]*units.Ulimit `json:"default-ulimits,omitempty"` + Runtimes map[string]types.Runtime `json:"runtimes,omitempty"` + DefaultRuntime string `json:"default-runtime,omitempty"` } // bridgeConfig stores all the bridge driver specific @@ -83,6 +86,37 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin cmd.StringVar(&config.RemappedRoot, []string{"-userns-remap"}, "", usageFn("User/Group setting for user namespaces")) cmd.StringVar(&config.ContainerdAddr, []string{"-containerd"}, "", usageFn("Path to containerd socket")) cmd.BoolVar(&config.LiveRestore, []string{"-live-restore"}, false, usageFn("Enable live restore of docker when containers are still running")) + config.Runtimes = make(map[string]types.Runtime) + cmd.Var(runconfigopts.NewNamedRuntimeOpt("runtimes", &config.Runtimes), []string{"-add-runtime"}, usageFn("Register an additional OCI compatible runtime")) + cmd.StringVar(&config.DefaultRuntime, []string{"-default-runtime"}, types.DefaultRuntimeName, usageFn("Default OCI runtime to be used")) config.attachExperimentalFlags(cmd, usageFn) } + +// GetRuntime returns the runtime path and arguments for a given +// runtime name +func (config *Config) GetRuntime(name string) *types.Runtime { + config.reloadLock.Lock() + defer config.reloadLock.Unlock() + if rt, ok := config.Runtimes[name]; ok { + return &rt + } + return nil +} + +// GetDefaultRuntimeName returns the current default runtime +func (config *Config) GetDefaultRuntimeName() string { + config.reloadLock.Lock() + rt := config.DefaultRuntime + config.reloadLock.Unlock() + + return rt +} + +// GetAllRuntimes returns a copy of the runtimes map +func (config *Config) GetAllRuntimes() map[string]types.Runtime { + config.reloadLock.Lock() + rts := config.Runtimes + config.reloadLock.Unlock() + return rts +} diff --git a/daemon/config_windows.go b/daemon/config_windows.go index 2d17b14e0a..f62ae95e73 100644 --- a/daemon/config_windows.go +++ b/daemon/config_windows.go @@ -4,6 +4,7 @@ import ( "os" flag "github.com/docker/docker/pkg/mflag" + "github.com/docker/engine-api/types" ) var ( @@ -40,3 +41,19 @@ func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) strin cmd.StringVar(&config.bridgeConfig.Iface, []string{"b", "-bridge"}, "", "Attach containers to a virtual switch") cmd.StringVar(&config.SocketGroup, []string{"G", "-group"}, "", usageFn("Users or groups that can access the named pipe")) } + +// GetRuntime returns the runtime path and arguments for a given +// runtime name +func (config *Config) GetRuntime(name string) *types.Runtime { + return nil +} + +// GetDefaultRuntimeName returns the current default runtime +func (config *Config) GetDefaultRuntimeName() string { + return types.DefaultRuntimeName +} + +// GetAllRuntimes returns a copy of the runtimes map +func (config *Config) GetAllRuntimes() map[string]types.Runtime { + return map[string]types.Runtime{} +} diff --git a/daemon/daemon.go b/daemon/daemon.go index ed37e0b30e..0c34c35359 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -60,6 +60,10 @@ import ( ) var ( + // DefaultRuntimeBinary is the default runtime to be used by + // containerd if none is specified + DefaultRuntimeBinary = "docker-runc" + errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.") ) @@ -811,10 +815,24 @@ func (daemon *Daemon) initDiscovery(config *Config) error { // - Cluster discovery (reconfigure and restart). // - Daemon live restore func (daemon *Daemon) Reload(config *Config) error { + var err error + // used to hold reloaded changes + attributes := map[string]string{} + + // We need defer here to ensure the lock is released as + // daemon.SystemInfo() will try to get it too + defer func() { + if err == nil { + daemon.LogDaemonEventWithAttributes("reload", attributes) + } + }() + daemon.configStore.reloadLock.Lock() defer daemon.configStore.reloadLock.Unlock() - if err := daemon.reloadClusterDiscovery(config); err != nil { + daemon.platformReload(config, &attributes) + + if err = daemon.reloadClusterDiscovery(config); err != nil { return err } @@ -859,7 +877,6 @@ func (daemon *Daemon) Reload(config *Config) error { } // We emit daemon reload event here with updatable configurations - attributes := map[string]string{} attributes["debug"] = fmt.Sprintf("%t", daemon.configStore.Debug) attributes["cluster-store"] = daemon.configStore.ClusterStore if daemon.configStore.ClusterOpts != nil { @@ -877,7 +894,6 @@ func (daemon *Daemon) Reload(config *Config) error { } attributes["max-concurrent-downloads"] = fmt.Sprintf("%d", *daemon.configStore.MaxConcurrentDownloads) attributes["max-concurrent-uploads"] = fmt.Sprintf("%d", *daemon.configStore.MaxConcurrentUploads) - daemon.LogDaemonEventWithAttributes("reload", attributes) return nil } diff --git a/daemon/daemon_solaris.go b/daemon/daemon_solaris.go index b43ec68481..942525569a 100644 --- a/daemon/daemon_solaris.go +++ b/daemon/daemon_solaris.go @@ -73,6 +73,10 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. return warnings, nil } +// platformReload update configuration with platform specific options +func (daemon *Daemon) platformReload(config *Config, attributes *map[string]string) { +} + // verifyDaemonSettings performs validation of daemon config struct func verifyDaemonSettings(config *Config) error { // checkSystem validates platform-specific requirements diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 3ef3ec1338..03095b920e 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -3,6 +3,7 @@ package daemon import ( + "bytes" "fmt" "io/ioutil" "net" @@ -515,9 +516,42 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. return warnings, fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"") } } + if hostConfig.Runtime == "" { + hostConfig.Runtime = daemon.configStore.GetDefaultRuntimeName() + } + + if rt := daemon.configStore.GetRuntime(hostConfig.Runtime); rt == nil { + return warnings, fmt.Errorf("Unknown runtime specified %s", hostConfig.Runtime) + } + return warnings, nil } +// platformReload update configuration with platform specific options +func (daemon *Daemon) platformReload(config *Config, attributes *map[string]string) { + if config.IsValueSet("runtimes") { + daemon.configStore.Runtimes = config.Runtimes + // Always set the default one + daemon.configStore.Runtimes[types.DefaultRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary} + } + + if config.DefaultRuntime != "" { + daemon.configStore.DefaultRuntime = config.DefaultRuntime + } + + // Update attributes + var runtimeList bytes.Buffer + for name, rt := range daemon.configStore.Runtimes { + if runtimeList.Len() > 0 { + runtimeList.WriteRune(' ') + } + runtimeList.WriteString(fmt.Sprintf("%s:%s", name, rt)) + } + + (*attributes)["runtimes"] = runtimeList.String() + (*attributes)["default-runtime"] = daemon.configStore.DefaultRuntime +} + // verifyDaemonSettings performs validation of daemon config struct func verifyDaemonSettings(config *Config) error { // Check for mutually incompatible config options @@ -538,6 +572,15 @@ func verifyDaemonSettings(config *Config) error { return fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"") } } + + if config.DefaultRuntime == "" { + config.DefaultRuntime = types.DefaultRuntimeName + } + if config.Runtimes == nil { + config.Runtimes = make(map[string]types.Runtime) + } + config.Runtimes[types.DefaultRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary} + return nil } diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index 0ba7e3a6d1..423b86b5e5 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -156,6 +156,10 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. return warnings, nil } +// platformReload update configuration with platform specific options +func (daemon *Daemon) platformReload(config *Config, attributes *map[string]string) { +} + // verifyDaemonSettings performs validation of daemon config struct func verifyDaemonSettings(config *Config) error { return nil diff --git a/daemon/info.go b/daemon/info.go index 433f92421c..00d659a0ff 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -131,6 +131,8 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) { v.CPUCfsQuota = sysInfo.CPUCfsQuota v.CPUShares = sysInfo.CPUShares v.CPUSet = sysInfo.Cpuset + v.Runtimes = daemon.configStore.GetAllRuntimes() + v.DefaultRuntime = daemon.configStore.GetDefaultRuntimeName() } hostname := "" diff --git a/daemon/start.go b/daemon/start.go index 89525d404e..7ced9e1440 100644 --- a/daemon/start.go +++ b/daemon/start.go @@ -132,15 +132,25 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error) return err } - if err := daemon.containerd.Create(container.ID, *spec, libcontainerd.WithRestartManager(container.RestartManager(true))); err != nil { + createOptions := []libcontainerd.CreateOption{libcontainerd.WithRestartManager(container.RestartManager(true))} + copts, err := daemon.getLibcontainerdCreateOptions(container) + if err != nil { + return err + } + if copts != nil { + createOptions = append(createOptions, *copts...) + } + + if err := daemon.containerd.Create(container.ID, *spec, createOptions...); err != nil { errDesc := grpc.ErrorDesc(err) logrus.Errorf("Create container failed with error: %s", errDesc) // if we receive an internal error from the initial start of a container then lets // return it instead of entering the restart loop // set to 127 for container cmd not found/does not exist) - if strings.Contains(errDesc, "executable file not found") || - strings.Contains(errDesc, "no such file or directory") || - strings.Contains(errDesc, "system cannot find the file specified") { + if strings.Contains(errDesc, container.Path) && + (strings.Contains(errDesc, "executable file not found") || + strings.Contains(errDesc, "no such file or directory") || + strings.Contains(errDesc, "system cannot find the file specified")) { container.ExitCode = 127 } // set to 126 for container cmd can't be invoked errors diff --git a/daemon/start_linux.go b/daemon/start_linux.go new file mode 100644 index 0000000000..50a9148a9f --- /dev/null +++ b/daemon/start_linux.go @@ -0,0 +1,20 @@ +package daemon + +import ( + "fmt" + + "github.com/docker/docker/container" + "github.com/docker/docker/libcontainerd" +) + +func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) (*[]libcontainerd.CreateOption, error) { + createOptions := []libcontainerd.CreateOption{} + + rt := daemon.configStore.GetRuntime(container.HostConfig.Runtime) + if rt == nil { + return nil, fmt.Errorf("No such runtime '%s'", container.HostConfig.Runtime) + } + createOptions = append(createOptions, libcontainerd.WithRuntime(rt.Path, rt.Args)) + + return &createOptions, nil +} diff --git a/daemon/start_windows.go b/daemon/start_windows.go new file mode 100644 index 0000000000..af3fe7602b --- /dev/null +++ b/daemon/start_windows.go @@ -0,0 +1,10 @@ +package daemon + +import ( + "github.com/docker/docker/container" + "github.com/docker/docker/libcontainerd" +) + +func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) (*[]libcontainerd.CreateOption, error) { + return &[]libcontainerd.CreateOption{}, nil +} diff --git a/docs/reference/commandline/create.md b/docs/reference/commandline/create.md index 03d3779237..37769a02e7 100644 --- a/docs/reference/commandline/create.md +++ b/docs/reference/commandline/create.md @@ -78,6 +78,7 @@ Creates a new container. --privileged Give extended privileges to this container --read-only Mount the container's root filesystem as read only --restart="no" Restart policy (no, on-failure[:max-retry], always, unless-stopped) + --runtime="" Name of the runtime to be used for that container --security-opt=[] Security options --stop-signal="SIGTERM" Signal to stop a container --shm-size=[] Size of `/dev/shm`. The format is ``. `number` must be greater than `0`. Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`. diff --git a/docs/reference/commandline/dockerd.md b/docs/reference/commandline/dockerd.md index 1d500433d4..ec44c0ab90 100644 --- a/docs/reference/commandline/dockerd.md +++ b/docs/reference/commandline/dockerd.md @@ -60,6 +60,7 @@ weight = -1 -p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file --raw-logs Full timestamps without ANSI coloring --registry-mirror=[] Preferred Docker registry mirror + --add-runtime=[] Register an additional OCI compatible runtime -s, --storage-driver="" Storage driver to use --selinux-enabled Enable selinux support --storage-opt=[] Set storage driver options @@ -572,6 +573,31 @@ The Docker daemon relies on a (invoked via the `containerd` daemon) as its interface to the Linux kernel `namespaces`, `cgroups`, and `SELinux`. +Runtimes can be registered with the daemon either via the +configuration file or using the `--add-runtime` command line argument. + +The following is an example adding 2 runtimes via the configuration: +```json + "default-runtime": "runc", + "runtimes": { + "runc": { + "path": "runc" + }, + "custom": { + "path": "/usr/local/bin/my-runc-replacement", + "runtimeArgs": [ + "--debug" + ] + } + } +``` + +This is the same example via the command line: + + $ sudo dockerd --add-runtime runc=runc --add-runtime custom=/usr/local/bin/my-runc-replacement + +**Note**: defining runtime arguments via the command line is not supported. + ## Options for the runtime You can configure the runtime using options specified @@ -1014,7 +1040,19 @@ This is a full example of the allowed configuration options in the file: "raw-logs": false, "registry-mirrors": [], "insecure-registries": [], - "disable-legacy-registry": false + "disable-legacy-registry": false, + "default-runtime": "runc", + "runtimes": { + "runc": { + "path": "runc" + }, + "custom": { + "path": "/usr/local/bin/my-runc-replacement", + "runtimeArgs": [ + "--debug" + ] + } + } } ``` @@ -1036,6 +1074,11 @@ The list of currently supported options that can be reconfigured is this: - `labels`: it replaces the daemon labels with a new set of labels. - `max-concurrent-downloads`: it updates the max concurrent downloads for each pull. - `max-concurrent-uploads`: it updates the max concurrent uploads for each push. +- `default-runtime`: it updates the runtime to be used if not is + specified at container creation. It defaults to "default" which is + the runtime shipped with the official docker packages. +- `runtimes`: it updates the list of available OCI runtimes that can + be used to run containers Updating and reloading the cluster configurations such as `--cluster-store`, `--cluster-advertise` and `--cluster-store-opts` will take effect only if diff --git a/docs/reference/commandline/run.md b/docs/reference/commandline/run.md index 6b66c394a8..e1e98a02a9 100644 --- a/docs/reference/commandline/run.md +++ b/docs/reference/commandline/run.md @@ -89,6 +89,7 @@ parent = "smn_cli" --read-only Mount the container's root filesystem as read only --restart="no" Restart policy (no, on-failure[:max-retry], always, unless-stopped) --rm Automatically remove the container when it exits + --runtime="" Name of the runtime to be used for that container --shm-size=[] Size of `/dev/shm`. The format is ``. `number` must be greater than `0`. Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`. --security-opt=[] Security Options --sig-proxy=true Proxy received signals to the process diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index 9546f3bf80..363bca3073 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -2378,3 +2378,183 @@ func (s *DockerDaemonSuite) TestDaemonDnsOptionsInHostMode(c *check.C) { out, _ := s.d.Cmd("run", "--net=host", "busybox", "cat", "/etc/resolv.conf") c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out)) } + +func (s *DockerDaemonSuite) TestRunWithRuntimeFromConfigFile(c *check.C) { + conf, err := ioutil.TempFile("", "config-file-") + c.Assert(err, check.IsNil) + configName := conf.Name() + conf.Close() + defer os.Remove(configName) + + config := ` +{ + "runtimes": { + "oci": { + "path": "docker-runc" + }, + "vm": { + "path": "/usr/local/bin/vm-manager", + "runtimeArgs": [ + "--debug" + ] + } + } +} +` + ioutil.WriteFile(configName, []byte(config), 0644) + err = s.d.Start("--config-file", configName) + c.Assert(err, check.IsNil) + + // Run with default runtime + out, err := s.d.Cmd("run", "--rm", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) + + // Run with default runtime explicitely + out, err = s.d.Cmd("run", "--rm", "--runtime=default", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) + + // Run with oci (same path as default) but keep it around + out, err = s.d.Cmd("run", "--name", "oci-runtime-ls", "--runtime=oci", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) + + // Run with "vm" + out, err = s.d.Cmd("run", "--rm", "--runtime=vm", "busybox", "ls") + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "/usr/local/bin/vm-manager: no such file or directory") + + // Reset config to only have the default + config = ` +{ + "runtimes": { + } +} +` + ioutil.WriteFile(configName, []byte(config), 0644) + syscall.Kill(s.d.cmd.Process.Pid, syscall.SIGHUP) + // Give daemon time to reload config + <-time.After(1 * time.Second) + + // Run with default runtime + out, err = s.d.Cmd("run", "--rm", "--runtime=default", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) + + // Run with "oci" + out, err = s.d.Cmd("run", "--rm", "--runtime=oci", "busybox", "ls") + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "Unknown runtime specified oci") + + // Start previously created container with oci + out, err = s.d.Cmd("start", "oci-runtime-ls") + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "Unknown runtime specified oci") + + // Check that we can't override the default runtime + config = ` +{ + "runtimes": { + "default": { + "path": "docker-runc" + } + } +} +` + ioutil.WriteFile(configName, []byte(config), 0644) + syscall.Kill(s.d.cmd.Process.Pid, syscall.SIGHUP) + // Give daemon time to reload config + <-time.After(1 * time.Second) + + content, _ := ioutil.ReadFile(s.d.logFile.Name()) + c.Assert(string(content), checker.Contains, `file configuration validation failed (runtime name 'default' is reserved)`) + + // Check that we can select a default runtime + config = ` +{ + "default-runtime": "vm", + "runtimes": { + "oci": { + "path": "docker-runc" + }, + "vm": { + "path": "/usr/local/bin/vm-manager", + "runtimeArgs": [ + "--debug" + ] + } + } +} +` + ioutil.WriteFile(configName, []byte(config), 0644) + syscall.Kill(s.d.cmd.Process.Pid, syscall.SIGHUP) + // Give daemon time to reload config + <-time.After(1 * time.Second) + + out, err = s.d.Cmd("run", "--rm", "busybox", "ls") + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "/usr/local/bin/vm-manager: no such file or directory") + + // Run with default runtime explicitely + out, err = s.d.Cmd("run", "--rm", "--runtime=default", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) +} + +func (s *DockerDaemonSuite) TestRunWithRuntimeFromCommandLine(c *check.C) { + err := s.d.Start("--add-runtime", "oci=docker-runc", "--add-runtime", "vm=/usr/local/bin/vm-manager") + c.Assert(err, check.IsNil) + + // Run with default runtime + out, err := s.d.Cmd("run", "--rm", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) + + // Run with default runtime explicitely + out, err = s.d.Cmd("run", "--rm", "--runtime=default", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) + + // Run with oci (same path as default) but keep it around + out, err = s.d.Cmd("run", "--name", "oci-runtime-ls", "--runtime=oci", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) + + // Run with "vm" + out, err = s.d.Cmd("run", "--rm", "--runtime=vm", "busybox", "ls") + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "/usr/local/bin/vm-manager: no such file or directory") + + // Start a daemon without any extra runtimes + s.d.Stop() + err = s.d.Start() + c.Assert(err, check.IsNil) + + // Run with default runtime + out, err = s.d.Cmd("run", "--rm", "--runtime=default", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) + + // Run with "oci" + out, err = s.d.Cmd("run", "--rm", "--runtime=oci", "busybox", "ls") + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "Unknown runtime specified oci") + + // Start previously created container with oci + out, err = s.d.Cmd("start", "oci-runtime-ls") + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "Unknown runtime specified oci") + + // Check that we can't override the default runtime + s.d.Stop() + err = s.d.Start("--add-runtime", "default=docker-runc") + c.Assert(err, check.NotNil) + + content, _ := ioutil.ReadFile(s.d.logFile.Name()) + c.Assert(string(content), checker.Contains, `runtime name 'default' is reserved`) + + // Check that we can select a default runtime + s.d.Stop() + err = s.d.Start("--default-runtime=vm", "--add-runtime", "oci=docker-runc", "--add-runtime", "vm=/usr/local/bin/vm-manager") + c.Assert(err, check.IsNil) + + out, err = s.d.Cmd("run", "--rm", "busybox", "ls") + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "/usr/local/bin/vm-manager: no such file or directory") + + // Run with default runtime explicitely + out, err = s.d.Cmd("run", "--rm", "--runtime=default", "busybox", "ls") + c.Assert(err, check.IsNil, check.Commentf(out)) +} diff --git a/integration-cli/docker_cli_events_unix_test.go b/integration-cli/docker_cli_events_unix_test.go index d0a25ed2bf..892d80a8a5 100644 --- a/integration-cli/docker_cli_events_unix_test.go +++ b/integration-cli/docker_cli_events_unix_test.go @@ -436,7 +436,8 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) { out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c)) c.Assert(err, checker.IsNil) - c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, labels=[\"bar=foo\"], max-concurrent-downloads=1, max-concurrent-uploads=5, name=%s)", daemonID, daemonName)) + + c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, default-runtime=default, labels=[\"bar=foo\"], max-concurrent-downloads=1, max-concurrent-uploads=5, name=%s, runtimes=default:{docker-runc []})", daemonID, daemonName)) } func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *check.C) { diff --git a/integration-cli/docker_cli_info_test.go b/integration-cli/docker_cli_info_test.go index 2e3400582a..816cbfdde2 100644 --- a/integration-cli/docker_cli_info_test.go +++ b/integration-cli/docker_cli_info_test.go @@ -34,6 +34,10 @@ func (s *DockerSuite) TestInfoEnsureSucceeds(c *check.C) { "Network:", } + if DaemonIsLinux.Condition() { + stringsToCheck = append(stringsToCheck, "Runtimes:", "Default Runtime: default") + } + if utils.ExperimentalBuild() { stringsToCheck = append(stringsToCheck, "Experimental: true") } diff --git a/libcontainerd/container_linux.go b/libcontainerd/container_linux.go index 00f86f9a81..52214167f5 100644 --- a/libcontainerd/container_linux.go +++ b/libcontainerd/container_linux.go @@ -21,7 +21,27 @@ type container struct { // Platform specific fields are below here. pauseMonitor - oom bool + oom bool + runtime string + runtimeArgs []string +} + +type runtime struct { + path string + args []string +} + +// WithRuntime sets the runtime to be used for the created container +func WithRuntime(path string, args []string) CreateOption { + return runtime{path, args} +} + +func (rt runtime) Apply(p interface{}) error { + if pr, ok := p.(*container); ok { + pr.runtime = rt.path + pr.runtimeArgs = rt.args + } + return nil } func (ctr *container) clean() error { @@ -84,6 +104,8 @@ func (ctr *container) start() error { Stderr: ctr.fifo(syscall.Stderr), // check to see if we are running in ramdisk to disable pivot root NoPivotRoot: os.Getenv("DOCKER_RAMDISK") != "", + Runtime: ctr.runtime, + RuntimeArgs: ctr.runtimeArgs, } ctr.client.appendContainer(ctr) diff --git a/libcontainerd/remote_linux.go b/libcontainerd/remote_linux.go index 3ef40674ac..5f4e812cfb 100644 --- a/libcontainerd/remote_linux.go +++ b/libcontainerd/remote_linux.go @@ -50,6 +50,7 @@ type remote struct { clients []*client eventTsPath string pastEvents map[string]*containerd.Event + runtime string runtimeArgs []string daemonWaitCh chan struct{} liveRestore bool @@ -366,11 +367,14 @@ func (r *remote) runContainerdDaemon() error { args := []string{ "-l", fmt.Sprintf("unix://%s", r.rpcAddr), "--shim", "docker-containerd-shim", - "--runtime", "docker-runc", "--metrics-interval=0", "--start-timeout", "2m", "--state-dir", filepath.Join(r.stateDir, containerdStateDir), } + if r.runtime != "" { + args = append(args, "--runtime") + args = append(args, r.runtime) + } if r.debugLog { args = append(args, "--debug") } @@ -428,6 +432,22 @@ func (a rpcAddr) Apply(r Remote) error { return fmt.Errorf("WithRemoteAddr option not supported for this remote") } +// WithRuntimePath sets the path of the runtime to be used as the +// default by containerd +func WithRuntimePath(rt string) RemoteOption { + return runtimePath(rt) +} + +type runtimePath string + +func (rt runtimePath) Apply(r Remote) error { + if remote, ok := r.(*remote); ok { + remote.runtime = string(rt) + return nil + } + return fmt.Errorf("WithRuntime option not supported for this remote") +} + // WithRuntimeArgs sets the list of runtime args passed to containerd func WithRuntimeArgs(args []string) RemoteOption { return runtimeArgs(args) diff --git a/runconfig/opts/parse.go b/runconfig/opts/parse.go index 77254e05f4..4f1b533d96 100644 --- a/runconfig/opts/parse.go +++ b/runconfig/opts/parse.go @@ -101,6 +101,7 @@ type ContainerOptions struct { flHealthInterval *time.Duration flHealthTimeout *time.Duration flHealthRetries *int + flRuntime *string Image string Args []string @@ -189,6 +190,7 @@ func AddFlags(flags *pflag.FlagSet) *ContainerOptions { flHealthInterval: flags.Duration("health-interval", 0, "Time between running the check"), flHealthTimeout: flags.Duration("health-timeout", 0, "Maximum time to allow one check to run"), flHealthRetries: flags.Int("health-retries", 0, "Consecutive failures needed to report unhealthy"), + flRuntime: flags.String("runtime", "", "Runtime to use for this container"), } flags.VarP(&copts.flAttach, "attach", "a", "Attach to STDIN, STDOUT or STDERR") @@ -229,7 +231,6 @@ func AddFlags(flags *pflag.FlagSet) *ContainerOptions { // a HostConfig and returns them with the specified command. // If the specified args are not valid, it will return an error. func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) { - var ( attachStdin = copts.flAttach.Get("stdin") attachStdout = copts.flAttach.Get("stdout") @@ -564,6 +565,7 @@ func Parse(flags *pflag.FlagSet, copts *ContainerOptions) (*container.Config, *c Resources: resources, Tmpfs: tmpfs, Sysctls: copts.flSysctls.GetAll(), + Runtime: *copts.flRuntime, } // When allocating stdin in attached mode, close stdin at client disconnect diff --git a/runconfig/opts/runtime.go b/runconfig/opts/runtime.go new file mode 100644 index 0000000000..8302eb1321 --- /dev/null +++ b/runconfig/opts/runtime.go @@ -0,0 +1,73 @@ +package opts + +import ( + "fmt" + "strings" + + "github.com/docker/engine-api/types" +) + +// RuntimeOpt defines a map of Runtimes +type RuntimeOpt struct { + name string + values *map[string]types.Runtime +} + +// NewNamedRuntimeOpt creates a new RuntimeOpt +func NewNamedRuntimeOpt(name string, ref *map[string]types.Runtime) *RuntimeOpt { + if ref == nil { + ref = &map[string]types.Runtime{} + } + return &RuntimeOpt{name: name, values: ref} +} + +// Name returns the name of the NamedListOpts in the configuration. +func (o *RuntimeOpt) Name() string { + return o.name +} + +// Set validates and updates the list of Runtimes +func (o *RuntimeOpt) Set(val string) error { + parts := strings.SplitN(val, "=", 2) + if len(parts) != 2 { + return fmt.Errorf("invalid runtime argument: %s", val) + } + + parts[0] = strings.TrimSpace(parts[0]) + parts[1] = strings.TrimSpace(parts[1]) + if parts[0] == "" || parts[1] == "" { + return fmt.Errorf("invalid runtime argument: %s", val) + } + + parts[0] = strings.ToLower(parts[0]) + if parts[0] == types.DefaultRuntimeName { + return fmt.Errorf("runtime name 'default' is reserved") + } + + if _, ok := (*o.values)[parts[0]]; ok { + return fmt.Errorf("runtime '%s' was already defined", parts[0]) + } + + (*o.values)[parts[0]] = types.Runtime{Path: parts[1]} + + return nil +} + +// String returns Runtime values as a string. +func (o *RuntimeOpt) String() string { + var out []string + for k := range *o.values { + out = append(out, k) + } + + return fmt.Sprintf("%v", out) +} + +// GetMap returns a map of Runtimes (name: path) +func (o *RuntimeOpt) GetMap() map[string]types.Runtime { + if o.values != nil { + return *o.values + } + + return map[string]types.Runtime{} +} From 1a6ed50e1f295714f6e514ec2c6127717b281216 Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Tue, 24 May 2016 17:07:23 -0700 Subject: [PATCH 3/7] Add missing completion for --config-file Signed-off-by: Kenfe-Mickael Laventure --- contrib/completion/bash/docker | 3 ++- contrib/completion/zsh/_docker | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index ba85cd22ac..79475f861c 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -799,6 +799,7 @@ _docker_daemon() { --cluster-advertise --cluster-store --cluster-store-opt + --config-file --containerd --default-gateway --default-gateway-v6 @@ -878,7 +879,7 @@ _docker_daemon() { __docker_complete_log_drivers return ;; - --containerd|--pidfile|-p|--tlscacert|--tlscert|--tlskey) + --config-file|--containerd|--pidfile|-p|--tlscacert|--tlscert|--tlskey) _filedir return ;; diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index fc57b8a6bc..69e7dbd3fa 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -936,6 +936,7 @@ __docker_subcommand() { "($help -b --bridge)"{-b=,--bridge=}"[Attach containers to a network bridge]:bridge:_net_interfaces" \ "($help)--bip=[Network bridge IP]:IP address: " \ "($help)--cgroup-parent=[Parent cgroup for all containers]:cgroup: " \ + "($help)--config-file=[Path to daemon configuration file]:Config File:_files" \ "($help)--containerd=[Path to containerd socket]:socket:_files -g \"*.sock\"" \ "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \ "($help)--default-gateway[Container default gateway IPv4 address]:IPv4 address: " \ From 6e9bf4d3167c19bed0b8136d38bc1fe9146a45e5 Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Fri, 3 Jun 2016 09:12:20 -0700 Subject: [PATCH 4/7] Add bash completion support for --runtime and --add-runtime Signed-off-by: Kenfe-Mickael Laventure --- contrib/completion/bash/docker | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/contrib/completion/bash/docker b/contrib/completion/bash/docker index 79475f861c..6928ebcb00 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -189,6 +189,14 @@ __docker_complete_plugins() { COMPREPLY=( $(compgen -W "$(__docker_plugins $1)" -- "$cur") ) } +__docker_runtimes() { + __docker_q info | sed -n 's/^Runtimes: \(.*\)/\1/p' +} + +__docker_complete_runtimes() { + COMPREPLY=( $(compgen -W "$(__docker_runtimes)" -- "$cur") ) +} + # Finds the position of the first word that is neither option nor an option's argument. # If there are options that require arguments, you should pass a glob describing those # options, e.g. "--option1|-o|--option2" @@ -791,6 +799,7 @@ _docker_daemon() { " local options_with_args=" $global_options_with_args + --add-runtime --api-cors-header --authorization-plugin --bip @@ -1706,6 +1715,7 @@ _docker_run() { --pids-limit --publish -p --restart + --runtime --security-opt --shm-size --stop-signal @@ -1884,6 +1894,10 @@ _docker_run() { esac return ;; + --runtime) + __docker_complete_runtimes + return + ;; --security-opt) COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") ) if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then From 1f266d40f3844d1e398186cb98b4deb2272ebd6c Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Mon, 13 Jun 2016 17:18:31 -0700 Subject: [PATCH 5/7] Fix race in DockerExternalGraphdriverSuite.TestExternalGraphDriver Signed-off-by: Kenfe-Mickael Laventure --- integration-cli/docker_cli_external_graphdriver_unix_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-cli/docker_cli_external_graphdriver_unix_test.go b/integration-cli/docker_cli_external_graphdriver_unix_test.go index 1c3daa425f..014b85c284 100644 --- a/integration-cli/docker_cli_external_graphdriver_unix_test.go +++ b/integration-cli/docker_cli_external_graphdriver_unix_test.go @@ -348,7 +348,7 @@ func (s *DockerExternalGraphdriverSuite) testExternalGraphDriver(name string, ex c.Assert(err, check.IsNil, check.Commentf("\n%s", string(b))) } - out, err := s.d.Cmd("run", "-d", "--name=graphtest", "busybox", "sh", "-c", "echo hello > /hello") + out, err := s.d.Cmd("run", "--name=graphtest", "busybox", "sh", "-c", "echo hello > /hello") c.Assert(err, check.IsNil, check.Commentf(out)) err = s.d.Restart("-s", name) @@ -359,7 +359,7 @@ func (s *DockerExternalGraphdriverSuite) testExternalGraphDriver(name string, ex out, err = s.d.Cmd("diff", "graphtest") c.Assert(err, check.IsNil, check.Commentf(out)) - c.Assert(strings.Contains(out, "A /hello"), check.Equals, true) + c.Assert(strings.Contains(out, "A /hello"), check.Equals, true, check.Commentf("diff ouput: %s", out)) out, err = s.d.Cmd("rm", "-f", "graphtest") c.Assert(err, check.IsNil, check.Commentf(out)) From 1aec3bacfd754e1ed72ec5a59dfd20d653f794a3 Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Mon, 13 Jun 2016 19:33:00 -0700 Subject: [PATCH 6/7] Vendor in new runc binary with userns fix Signed-off-by: Kenfe-Mickael Laventure --- Dockerfile | 4 ++-- Dockerfile.aarch64 | 4 ++-- Dockerfile.armhf | 4 ++-- Dockerfile.gccgo | 4 ++-- Dockerfile.ppc64le | 4 ++-- Dockerfile.s390x | 4 ++-- Dockerfile.simple | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Dockerfile b/Dockerfile index 00861ec26f..ab58e3732f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -233,10 +233,10 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 +ENV RUNC_COMMIT 5ce88a95f6cf218ba7f3309562f95464a968e890 RUN set -x \ && export GOPATH="$(mktemp -d)" \ - && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ + && git clone https://github.com/crosbymichael/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ && cd "$GOPATH/src/github.com/opencontainers/runc" \ && git checkout -q "$RUNC_COMMIT" \ && make static BUILDTAGS="seccomp apparmor selinux" \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 0011ad617c..2333d474fe 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -180,10 +180,10 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 +ENV RUNC_COMMIT 5ce88a95f6cf218ba7f3309562f95464a968e890 RUN set -x \ && export GOPATH="$(mktemp -d)" \ - && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ + && git clone https://github.com/crosbymichael/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ && cd "$GOPATH/src/github.com/opencontainers/runc" \ && git checkout -q "$RUNC_COMMIT" \ && make static BUILDTAGS="seccomp apparmor selinux" \ diff --git a/Dockerfile.armhf b/Dockerfile.armhf index d5462eddcb..08b4d31d4d 100644 --- a/Dockerfile.armhf +++ b/Dockerfile.armhf @@ -189,10 +189,10 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 +ENV RUNC_COMMIT 5ce88a95f6cf218ba7f3309562f95464a968e890 RUN set -x \ && export GOPATH="$(mktemp -d)" \ - && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ + && git clone https://github.com/crosbymichael/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ && cd "$GOPATH/src/github.com/opencontainers/runc" \ && git checkout -q "$RUNC_COMMIT" \ && make static BUILDTAGS="seccomp apparmor selinux" \ diff --git a/Dockerfile.gccgo b/Dockerfile.gccgo index 98011d9223..03e8a2afae 100644 --- a/Dockerfile.gccgo +++ b/Dockerfile.gccgo @@ -74,10 +74,10 @@ WORKDIR /go/src/github.com/docker/docker ENV DOCKER_BUILDTAGS apparmor seccomp selinux # Install runc -ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 +ENV RUNC_COMMIT 5ce88a95f6cf218ba7f3309562f95464a968e890 RUN set -x \ && export GOPATH="$(mktemp -d)" \ - && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ + && git clone https://github.com/crosbymichael/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ && cd "$GOPATH/src/github.com/opencontainers/runc" \ && git checkout -q "$RUNC_COMMIT" \ && make static BUILDTAGS="seccomp apparmor selinux" \ diff --git a/Dockerfile.ppc64le b/Dockerfile.ppc64le index a8e1708287..4ceed03da4 100644 --- a/Dockerfile.ppc64le +++ b/Dockerfile.ppc64le @@ -204,10 +204,10 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 +ENV RUNC_COMMIT 5ce88a95f6cf218ba7f3309562f95464a968e890 RUN set -x \ && export GOPATH="$(mktemp -d)" \ - && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ + && git clone https://github.com/crosbymichael/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ && cd "$GOPATH/src/github.com/opencontainers/runc" \ && git checkout -q "$RUNC_COMMIT" \ && make static BUILDTAGS="apparmor seccomp selinux" \ diff --git a/Dockerfile.s390x b/Dockerfile.s390x index 8f887b2702..ebb72c91c5 100644 --- a/Dockerfile.s390x +++ b/Dockerfile.s390x @@ -197,10 +197,10 @@ RUN set -x \ && rm -rf "$GOPATH" # Install runc -ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 +ENV RUNC_COMMIT 5ce88a95f6cf218ba7f3309562f95464a968e890 RUN set -x \ && export GOPATH="$(mktemp -d)" \ - && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ + && git clone https://github.com/crosbymichael/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ && cd "$GOPATH/src/github.com/opencontainers/runc" \ && git checkout -q "$RUNC_COMMIT" \ && make static BUILDTAGS="seccomp apparmor selinux" \ diff --git a/Dockerfile.simple b/Dockerfile.simple index 2c19fd249c..00d53bdf06 100644 --- a/Dockerfile.simple +++ b/Dockerfile.simple @@ -57,10 +57,10 @@ ENV GOPATH /go:/go/src/github.com/docker/docker/vendor ENV CGO_LDFLAGS -L/lib # Install runc -ENV RUNC_COMMIT 85873d917e86676e44ccb80719fcb47a794676a1 +ENV RUNC_COMMIT 5ce88a95f6cf218ba7f3309562f95464a968e890 RUN set -x \ && export GOPATH="$(mktemp -d)" \ - && git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ + && git clone https://github.com/crosbymichael/runc.git "$GOPATH/src/github.com/opencontainers/runc" \ && cd "$GOPATH/src/github.com/opencontainers/runc" \ && git checkout -q "$RUNC_COMMIT" \ && make static BUILDTAGS="seccomp apparmor selinux" \ From 77efe6dffcd337a45831c5294fc402627251e915 Mon Sep 17 00:00:00 2001 From: Kenfe-Mickael Laventure Date: Mon, 13 Jun 2016 21:27:26 -0700 Subject: [PATCH 7/7] Skip TestRunResolvconfUpdate as it is unstable Signed-off-by: Kenfe-Mickael Laventure --- integration-cli/docker_cli_run_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 1f631acdcd..627d0a33f8 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -1434,6 +1434,7 @@ func (s *DockerSuite) TestRunNonRootUserResolvName(c *check.C) { func (s *DockerSuite) TestRunResolvconfUpdate(c *check.C) { // Not applicable on Windows as testing unix specific functionality testRequires(c, SameHostDaemon, DaemonIsLinux) + c.Skip("Unstable test, to be re-activated once #19937 is resolved") tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\n") tmpLocalhostResolvConf := []byte("nameserver 127.0.0.1")