summaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/containerd/go-runc
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/containerd/go-runc')
-rw-r--r--vendor/github.com/containerd/go-runc/LICENSE201
-rw-r--r--vendor/github.com/containerd/go-runc/README.md14
-rw-r--r--vendor/github.com/containerd/go-runc/command_linux.go41
-rw-r--r--vendor/github.com/containerd/go-runc/command_other.go35
-rw-r--r--vendor/github.com/containerd/go-runc/console.go165
-rw-r--r--vendor/github.com/containerd/go-runc/container.go30
-rw-r--r--vendor/github.com/containerd/go-runc/events.go100
-rw-r--r--vendor/github.com/containerd/go-runc/io.go218
-rw-r--r--vendor/github.com/containerd/go-runc/io_unix.go76
-rw-r--r--vendor/github.com/containerd/go-runc/io_windows.go62
-rw-r--r--vendor/github.com/containerd/go-runc/monitor.go76
-rw-r--r--vendor/github.com/containerd/go-runc/runc.go707
-rw-r--r--vendor/github.com/containerd/go-runc/utils.go107
13 files changed, 1832 insertions, 0 deletions
diff --git a/vendor/github.com/containerd/go-runc/LICENSE b/vendor/github.com/containerd/go-runc/LICENSE
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/github.com/containerd/go-runc/README.md b/vendor/github.com/containerd/go-runc/README.md
new file mode 100644
index 000000000..239601f1e
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/README.md
@@ -0,0 +1,14 @@
+# go-runc
+
+[![Build Status](https://travis-ci.org/containerd/go-runc.svg?branch=master)](https://travis-ci.org/containerd/go-runc)
+
+
+This is a package for consuming the [runc](https://github.com/opencontainers/runc) binary in your Go applications.
+It tries to expose all the settings and features of the runc CLI. If there is something missing then add it, its opensource!
+
+This needs runc @ [a9610f2c0](https://github.com/opencontainers/runc/commit/a9610f2c0237d2636d05a031ec8659a70e75ffeb)
+or greater.
+
+## Docs
+
+Docs can be found at [godoc.org](https://godoc.org/github.com/containerd/go-runc).
diff --git a/vendor/github.com/containerd/go-runc/command_linux.go b/vendor/github.com/containerd/go-runc/command_linux.go
new file mode 100644
index 000000000..71b52f9de
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/command_linux.go
@@ -0,0 +1,41 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import (
+ "context"
+ "os"
+ "os/exec"
+ "syscall"
+)
+
+func (r *Runc) command(context context.Context, args ...string) *exec.Cmd {
+ command := r.Command
+ if command == "" {
+ command = DefaultCommand
+ }
+ cmd := exec.CommandContext(context, command, append(r.args(), args...)...)
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Setpgid: r.Setpgid,
+ }
+ cmd.Env = os.Environ()
+ if r.PdeathSignal != 0 {
+ cmd.SysProcAttr.Pdeathsig = r.PdeathSignal
+ }
+
+ return cmd
+}
diff --git a/vendor/github.com/containerd/go-runc/command_other.go b/vendor/github.com/containerd/go-runc/command_other.go
new file mode 100644
index 000000000..b8fd4b866
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/command_other.go
@@ -0,0 +1,35 @@
+// +build !linux
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import (
+ "context"
+ "os"
+ "os/exec"
+)
+
+func (r *Runc) command(context context.Context, args ...string) *exec.Cmd {
+ command := r.Command
+ if command == "" {
+ command = DefaultCommand
+ }
+ cmd := exec.CommandContext(context, command, append(r.args(), args...)...)
+ cmd.Env = os.Environ()
+ return cmd
+}
diff --git a/vendor/github.com/containerd/go-runc/console.go b/vendor/github.com/containerd/go-runc/console.go
new file mode 100644
index 000000000..ff223e427
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/console.go
@@ -0,0 +1,165 @@
+// +build !windows
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import (
+ "fmt"
+ "io/ioutil"
+ "net"
+ "os"
+ "path/filepath"
+
+ "github.com/containerd/console"
+ "golang.org/x/sys/unix"
+)
+
+// NewConsoleSocket creates a new unix socket at the provided path to accept a
+// pty master created by runc for use by the container
+func NewConsoleSocket(path string) (*Socket, error) {
+ abs, err := filepath.Abs(path)
+ if err != nil {
+ return nil, err
+ }
+ addr, err := net.ResolveUnixAddr("unix", abs)
+ if err != nil {
+ return nil, err
+ }
+ l, err := net.ListenUnix("unix", addr)
+ if err != nil {
+ return nil, err
+ }
+ return &Socket{
+ l: l,
+ }, nil
+}
+
+// NewTempConsoleSocket returns a temp console socket for use with a container
+// On Close(), the socket is deleted
+func NewTempConsoleSocket() (*Socket, error) {
+ runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
+ dir, err := ioutil.TempDir(runtimeDir, "pty")
+ if err != nil {
+ return nil, err
+ }
+ abs, err := filepath.Abs(filepath.Join(dir, "pty.sock"))
+ if err != nil {
+ return nil, err
+ }
+ addr, err := net.ResolveUnixAddr("unix", abs)
+ if err != nil {
+ return nil, err
+ }
+ l, err := net.ListenUnix("unix", addr)
+ if err != nil {
+ return nil, err
+ }
+ if runtimeDir != "" {
+ if err := os.Chmod(abs, 0755|os.ModeSticky); err != nil {
+ return nil, err
+ }
+ }
+ return &Socket{
+ l: l,
+ rmdir: true,
+ }, nil
+}
+
+// Socket is a unix socket that accepts the pty master created by runc
+type Socket struct {
+ rmdir bool
+ l *net.UnixListener
+}
+
+// Path returns the path to the unix socket on disk
+func (c *Socket) Path() string {
+ return c.l.Addr().String()
+}
+
+// recvFd waits for a file descriptor to be sent over the given AF_UNIX
+// socket. The file name of the remote file descriptor will be recreated
+// locally (it is sent as non-auxiliary data in the same payload).
+func recvFd(socket *net.UnixConn) (*os.File, error) {
+ const MaxNameLen = 4096
+ var oobSpace = unix.CmsgSpace(4)
+
+ name := make([]byte, MaxNameLen)
+ oob := make([]byte, oobSpace)
+
+ n, oobn, _, _, err := socket.ReadMsgUnix(name, oob)
+ if err != nil {
+ return nil, err
+ }
+
+ if n >= MaxNameLen || oobn != oobSpace {
+ return nil, fmt.Errorf("recvfd: incorrect number of bytes read (n=%d oobn=%d)", n, oobn)
+ }
+
+ // Truncate.
+ name = name[:n]
+ oob = oob[:oobn]
+
+ scms, err := unix.ParseSocketControlMessage(oob)
+ if err != nil {
+ return nil, err
+ }
+ if len(scms) != 1 {
+ return nil, fmt.Errorf("recvfd: number of SCMs is not 1: %d", len(scms))
+ }
+ scm := scms[0]
+
+ fds, err := unix.ParseUnixRights(&scm)
+ if err != nil {
+ return nil, err
+ }
+ if len(fds) != 1 {
+ return nil, fmt.Errorf("recvfd: number of fds is not 1: %d", len(fds))
+ }
+ fd := uintptr(fds[0])
+
+ return os.NewFile(fd, string(name)), nil
+}
+
+// ReceiveMaster blocks until the socket receives the pty master
+func (c *Socket) ReceiveMaster() (console.Console, error) {
+ conn, err := c.l.Accept()
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+ uc, ok := conn.(*net.UnixConn)
+ if !ok {
+ return nil, fmt.Errorf("received connection which was not a unix socket")
+ }
+ f, err := recvFd(uc)
+ if err != nil {
+ return nil, err
+ }
+ return console.ConsoleFromFile(f)
+}
+
+// Close closes the unix socket
+func (c *Socket) Close() error {
+ err := c.l.Close()
+ if c.rmdir {
+ if rerr := os.RemoveAll(filepath.Dir(c.Path())); err == nil {
+ err = rerr
+ }
+ }
+ return err
+}
diff --git a/vendor/github.com/containerd/go-runc/container.go b/vendor/github.com/containerd/go-runc/container.go
new file mode 100644
index 000000000..107381a55
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/container.go
@@ -0,0 +1,30 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import "time"
+
+// Container hold information for a runc container
+type Container struct {
+ ID string `json:"id"`
+ Pid int `json:"pid"`
+ Status string `json:"status"`
+ Bundle string `json:"bundle"`
+ Rootfs string `json:"rootfs"`
+ Created time.Time `json:"created"`
+ Annotations map[string]string `json:"annotations"`
+}
diff --git a/vendor/github.com/containerd/go-runc/events.go b/vendor/github.com/containerd/go-runc/events.go
new file mode 100644
index 000000000..d610aeb34
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/events.go
@@ -0,0 +1,100 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+type Event struct {
+ // Type are the event type generated by runc
+ // If the type is "error" then check the Err field on the event for
+ // the actual error
+ Type string `json:"type"`
+ ID string `json:"id"`
+ Stats *Stats `json:"data,omitempty"`
+ // Err has a read error if we were unable to decode the event from runc
+ Err error `json:"-"`
+}
+
+type Stats struct {
+ Cpu Cpu `json:"cpu"`
+ Memory Memory `json:"memory"`
+ Pids Pids `json:"pids"`
+ Blkio Blkio `json:"blkio"`
+ Hugetlb map[string]Hugetlb `json:"hugetlb"`
+}
+
+type Hugetlb struct {
+ Usage uint64 `json:"usage,omitempty"`
+ Max uint64 `json:"max,omitempty"`
+ Failcnt uint64 `json:"failcnt"`
+}
+
+type BlkioEntry struct {
+ Major uint64 `json:"major,omitempty"`
+ Minor uint64 `json:"minor,omitempty"`
+ Op string `json:"op,omitempty"`
+ Value uint64 `json:"value,omitempty"`
+}
+
+type Blkio struct {
+ IoServiceBytesRecursive []BlkioEntry `json:"ioServiceBytesRecursive,omitempty"`
+ IoServicedRecursive []BlkioEntry `json:"ioServicedRecursive,omitempty"`
+ IoQueuedRecursive []BlkioEntry `json:"ioQueueRecursive,omitempty"`
+ IoServiceTimeRecursive []BlkioEntry `json:"ioServiceTimeRecursive,omitempty"`
+ IoWaitTimeRecursive []BlkioEntry `json:"ioWaitTimeRecursive,omitempty"`
+ IoMergedRecursive []BlkioEntry `json:"ioMergedRecursive,omitempty"`
+ IoTimeRecursive []BlkioEntry `json:"ioTimeRecursive,omitempty"`
+ SectorsRecursive []BlkioEntry `json:"sectorsRecursive,omitempty"`
+}
+
+type Pids struct {
+ Current uint64 `json:"current,omitempty"`
+ Limit uint64 `json:"limit,omitempty"`
+}
+
+type Throttling struct {
+ Periods uint64 `json:"periods,omitempty"`
+ ThrottledPeriods uint64 `json:"throttledPeriods,omitempty"`
+ ThrottledTime uint64 `json:"throttledTime,omitempty"`
+}
+
+type CpuUsage struct {
+ // Units: nanoseconds.
+ Total uint64 `json:"total,omitempty"`
+ Percpu []uint64 `json:"percpu,omitempty"`
+ Kernel uint64 `json:"kernel"`
+ User uint64 `json:"user"`
+}
+
+type Cpu struct {
+ Usage CpuUsage `json:"usage,omitempty"`
+ Throttling Throttling `json:"throttling,omitempty"`
+}
+
+type MemoryEntry struct {
+ Limit uint64 `json:"limit"`
+ Usage uint64 `json:"usage,omitempty"`
+ Max uint64 `json:"max,omitempty"`
+ Failcnt uint64 `json:"failcnt"`
+}
+
+type Memory struct {
+ Cache uint64 `json:"cache,omitempty"`
+ Usage MemoryEntry `json:"usage,omitempty"`
+ Swap MemoryEntry `json:"swap,omitempty"`
+ Kernel MemoryEntry `json:"kernel,omitempty"`
+ KernelTCP MemoryEntry `json:"kernelTCP,omitempty"`
+ Raw map[string]uint64 `json:"raw,omitempty"`
+}
diff --git a/vendor/github.com/containerd/go-runc/io.go b/vendor/github.com/containerd/go-runc/io.go
new file mode 100644
index 000000000..6cf0410c9
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/io.go
@@ -0,0 +1,218 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import (
+ "io"
+ "os"
+ "os/exec"
+)
+
+type IO interface {
+ io.Closer
+ Stdin() io.WriteCloser
+ Stdout() io.ReadCloser
+ Stderr() io.ReadCloser
+ Set(*exec.Cmd)
+}
+
+type StartCloser interface {
+ CloseAfterStart() error
+}
+
+// IOOpt sets I/O creation options
+type IOOpt func(*IOOption)
+
+// IOOption holds I/O creation options
+type IOOption struct {
+ OpenStdin bool
+ OpenStdout bool
+ OpenStderr bool
+}
+
+func defaultIOOption() *IOOption {
+ return &IOOption{
+ OpenStdin: true,
+ OpenStdout: true,
+ OpenStderr: true,
+ }
+}
+
+func newPipe() (*pipe, error) {
+ r, w, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+ return &pipe{
+ r: r,
+ w: w,
+ }, nil
+}
+
+type pipe struct {
+ r *os.File
+ w *os.File
+}
+
+func (p *pipe) Close() error {
+ err := p.w.Close()
+ if rerr := p.r.Close(); err == nil {
+ err = rerr
+ }
+ return err
+}
+
+type pipeIO struct {
+ in *pipe
+ out *pipe
+ err *pipe
+}
+
+func (i *pipeIO) Stdin() io.WriteCloser {
+ if i.in == nil {
+ return nil
+ }
+ return i.in.w
+}
+
+func (i *pipeIO) Stdout() io.ReadCloser {
+ if i.out == nil {
+ return nil
+ }
+ return i.out.r
+}
+
+func (i *pipeIO) Stderr() io.ReadCloser {
+ if i.err == nil {
+ return nil
+ }
+ return i.err.r
+}
+
+func (i *pipeIO) Close() error {
+ var err error
+ for _, v := range []*pipe{
+ i.in,
+ i.out,
+ i.err,
+ } {
+ if v != nil {
+ if cerr := v.Close(); err == nil {
+ err = cerr
+ }
+ }
+ }
+ return err
+}
+
+func (i *pipeIO) CloseAfterStart() error {
+ for _, f := range []*pipe{
+ i.out,
+ i.err,
+ } {
+ if f != nil {
+ f.w.Close()
+ }
+ }
+ return nil
+}
+
+// Set sets the io to the exec.Cmd
+func (i *pipeIO) Set(cmd *exec.Cmd) {
+ if i.in != nil {
+ cmd.Stdin = i.in.r
+ }
+ if i.out != nil {
+ cmd.Stdout = i.out.w
+ }
+ if i.err != nil {
+ cmd.Stderr = i.err.w
+ }
+}
+
+func NewSTDIO() (IO, error) {
+ return &stdio{}, nil
+}
+
+type stdio struct {
+}
+
+func (s *stdio) Close() error {
+ return nil
+}
+
+func (s *stdio) Set(cmd *exec.Cmd) {
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+}
+
+func (s *stdio) Stdin() io.WriteCloser {
+ return os.Stdin
+}
+
+func (s *stdio) Stdout() io.ReadCloser {
+ return os.Stdout
+}
+
+func (s *stdio) Stderr() io.ReadCloser {
+ return os.Stderr
+}
+
+// NewNullIO returns IO setup for /dev/null use with runc
+func NewNullIO() (IO, error) {
+ f, err := os.Open(os.DevNull)
+ if err != nil {
+ return nil, err
+ }
+ return &nullIO{
+ devNull: f,
+ }, nil
+}
+
+type nullIO struct {
+ devNull *os.File
+}
+
+func (n *nullIO) Close() error {
+ // this should be closed after start but if not
+ // make sure we close the file but don't return the error
+ n.devNull.Close()
+ return nil
+}
+
+func (n *nullIO) Stdin() io.WriteCloser {
+ return nil
+}
+
+func (n *nullIO) Stdout() io.ReadCloser {
+ return nil
+}
+
+func (n *nullIO) Stderr() io.ReadCloser {
+ return nil
+}
+
+func (n *nullIO) Set(c *exec.Cmd) {
+ // don't set STDIN here
+ c.Stdout = n.devNull
+ c.Stderr = n.devNull
+}
+
+func (n *nullIO) CloseAfterStart() error {
+ return n.devNull.Close()
+}
diff --git a/vendor/github.com/containerd/go-runc/io_unix.go b/vendor/github.com/containerd/go-runc/io_unix.go
new file mode 100644
index 000000000..567cd072e
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/io_unix.go
@@ -0,0 +1,76 @@
+// +build !windows
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import (
+ "github.com/pkg/errors"
+ "golang.org/x/sys/unix"
+)
+
+// NewPipeIO creates pipe pairs to be used with runc
+func NewPipeIO(uid, gid int, opts ...IOOpt) (i IO, err error) {
+ option := defaultIOOption()
+ for _, o := range opts {
+ o(option)
+ }
+ var (
+ pipes []*pipe
+ stdin, stdout, stderr *pipe
+ )
+ // cleanup in case of an error
+ defer func() {
+ if err != nil {
+ for _, p := range pipes {
+ p.Close()
+ }
+ }
+ }()
+ if option.OpenStdin {
+ if stdin, err = newPipe(); err != nil {
+ return nil, err
+ }
+ pipes = append(pipes, stdin)
+ if err = unix.Fchown(int(stdin.r.Fd()), uid, gid); err != nil {
+ return nil, errors.Wrap(err, "failed to chown stdin")
+ }
+ }
+ if option.OpenStdout {
+ if stdout, err = newPipe(); err != nil {
+ return nil, err
+ }
+ pipes = append(pipes, stdout)
+ if err = unix.Fchown(int(stdout.w.Fd()), uid, gid); err != nil {
+ return nil, errors.Wrap(err, "failed to chown stdout")
+ }
+ }
+ if option.OpenStderr {
+ if stderr, err = newPipe(); err != nil {
+ return nil, err
+ }
+ pipes = append(pipes, stderr)
+ if err = unix.Fchown(int(stderr.w.Fd()), uid, gid); err != nil {
+ return nil, errors.Wrap(err, "failed to chown stderr")
+ }
+ }
+ return &pipeIO{
+ in: stdin,
+ out: stdout,
+ err: stderr,
+ }, nil
+}
diff --git a/vendor/github.com/containerd/go-runc/io_windows.go b/vendor/github.com/containerd/go-runc/io_windows.go
new file mode 100644
index 000000000..fc56ac4f3
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/io_windows.go
@@ -0,0 +1,62 @@
+// +build windows
+
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+// NewPipeIO creates pipe pairs to be used with runc
+func NewPipeIO(opts ...IOOpt) (i IO, err error) {
+ option := defaultIOOption()
+ for _, o := range opts {
+ o(option)
+ }
+ var (
+ pipes []*pipe
+ stdin, stdout, stderr *pipe
+ )
+ // cleanup in case of an error
+ defer func() {
+ if err != nil {
+ for _, p := range pipes {
+ p.Close()
+ }
+ }
+ }()
+ if option.OpenStdin {
+ if stdin, err = newPipe(); err != nil {
+ return nil, err
+ }
+ pipes = append(pipes, stdin)
+ }
+ if option.OpenStdout {
+ if stdout, err = newPipe(); err != nil {
+ return nil, err
+ }
+ pipes = append(pipes, stdout)
+ }
+ if option.OpenStderr {
+ if stderr, err = newPipe(); err != nil {
+ return nil, err
+ }
+ pipes = append(pipes, stderr)
+ }
+ return &pipeIO{
+ in: stdin,
+ out: stdout,
+ err: stderr,
+ }, nil
+}
diff --git a/vendor/github.com/containerd/go-runc/monitor.go b/vendor/github.com/containerd/go-runc/monitor.go
new file mode 100644
index 000000000..ff06a3fca
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/monitor.go
@@ -0,0 +1,76 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import (
+ "os/exec"
+ "syscall"
+ "time"
+)
+
+var Monitor ProcessMonitor = &defaultMonitor{}
+
+type Exit struct {
+ Timestamp time.Time
+ Pid int
+ Status int
+}
+
+// ProcessMonitor is an interface for process monitoring
+//
+// It allows daemons using go-runc to have a SIGCHLD handler
+// to handle exits without introducing races between the handler
+// and go's exec.Cmd
+// These methods should match the methods exposed by exec.Cmd to provide
+// a consistent experience for the caller
+type ProcessMonitor interface {
+ Start(*exec.Cmd) (chan Exit, error)
+ Wait(*exec.Cmd, chan Exit) (int, error)
+}
+
+type defaultMonitor struct {
+}
+
+func (m *defaultMonitor) Start(c *exec.Cmd) (chan Exit, error) {
+ if err := c.Start(); err != nil {
+ return nil, err
+ }
+ ec := make(chan Exit, 1)
+ go func() {
+ var status int
+ if err := c.Wait(); err != nil {
+ status = 255
+ if exitErr, ok := err.(*exec.ExitError); ok {
+ if ws, ok := exitErr.Sys().(syscall.WaitStatus); ok {
+ status = ws.ExitStatus()
+ }
+ }
+ }
+ ec <- Exit{
+ Timestamp: time.Now(),
+ Pid: c.Process.Pid,
+ Status: status,
+ }
+ close(ec)
+ }()
+ return ec, nil
+}
+
+func (m *defaultMonitor) Wait(c *exec.Cmd, ec chan Exit) (int, error) {
+ e := <-ec
+ return e.Status, nil
+}
diff --git a/vendor/github.com/containerd/go-runc/runc.go b/vendor/github.com/containerd/go-runc/runc.go
new file mode 100644
index 000000000..96262afab
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/runc.go
@@ -0,0 +1,707 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "syscall"
+ "time"
+
+ specs "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+// Format is the type of log formatting options avaliable
+type Format string
+
+// TopBody represents the structured data of the full ps output
+type TopResults struct {
+ // Processes running in the container, where each is process is an array of values corresponding to the headers
+ Processes [][]string `json:"Processes"`
+
+ // Headers are the names of the columns
+ Headers []string `json:"Headers"`
+}
+
+const (
+ none Format = ""
+ JSON Format = "json"
+ Text Format = "text"
+ // DefaultCommand is the default command for Runc
+ DefaultCommand = "runc"
+)
+
+// Runc is the client to the runc cli
+type Runc struct {
+ //If command is empty, DefaultCommand is used
+ Command string
+ Root string
+ Debug bool
+ Log string
+ LogFormat Format
+ PdeathSignal syscall.Signal
+ Setpgid bool
+ Criu string
+ SystemdCgroup bool
+ Rootless *bool // nil stands for "auto"
+}
+
+// List returns all containers created inside the provided runc root directory
+func (r *Runc) List(context context.Context) ([]*Container, error) {
+ data, err := cmdOutput(r.command(context, "list", "--format=json"), false)
+ if err != nil {
+ return nil, err
+ }
+ var out []*Container
+ if err := json.Unmarshal(data, &out); err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// State returns the state for the container provided by id
+func (r *Runc) State(context context.Context, id string) (*Container, error) {
+ data, err := cmdOutput(r.command(context, "state", id), true)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %s", err, data)
+ }
+ var c Container
+ if err := json.Unmarshal(data, &c); err != nil {
+ return nil, err
+ }
+ return &c, nil
+}
+
+type ConsoleSocket interface {
+ Path() string
+}
+
+type CreateOpts struct {
+ IO
+ // PidFile is a path to where a pid file should be created
+ PidFile string
+ ConsoleSocket ConsoleSocket
+ Detach bool
+ NoPivot bool
+ NoNewKeyring bool
+ ExtraFiles []*os.File
+}
+
+func (o *CreateOpts) args() (out []string, err error) {
+ if o.PidFile != "" {
+ abs, err := filepath.Abs(o.PidFile)
+ if err != nil {
+ return nil, err
+ }
+ out = append(out, "--pid-file", abs)
+ }
+ if o.ConsoleSocket != nil {
+ out = append(out, "--console-socket", o.ConsoleSocket.Path())
+ }
+ if o.NoPivot {
+ out = append(out, "--no-pivot")
+ }
+ if o.NoNewKeyring {
+ out = append(out, "--no-new-keyring")
+ }
+ if o.Detach {
+ out = append(out, "--detach")
+ }
+ if o.ExtraFiles != nil {
+ out = append(out, "--preserve-fds", strconv.Itoa(len(o.ExtraFiles)))
+ }
+ return out, nil
+}
+
+// Create creates a new container and returns its pid if it was created successfully
+func (r *Runc) Create(context context.Context, id, bundle string, opts *CreateOpts) error {
+ args := []string{"create", "--bundle", bundle}
+ if opts != nil {
+ oargs, err := opts.args()
+ if err != nil {
+ return err
+ }
+ args = append(args, oargs...)
+ }
+ cmd := r.command(context, append(args, id)...)
+ if opts != nil && opts.IO != nil {
+ opts.Set(cmd)
+ }
+ cmd.ExtraFiles = opts.ExtraFiles
+
+ if cmd.Stdout == nil && cmd.Stderr == nil {
+ data, err := cmdOutput(cmd, true)
+ if err != nil {
+ return fmt.Errorf("%s: %s", err, data)
+ }
+ return nil
+ }
+ ec, err := Monitor.Start(cmd)
+ if err != nil {
+ return err
+ }
+ if opts != nil && opts.IO != nil {
+ if c, ok := opts.IO.(StartCloser); ok {
+ if err := c.CloseAfterStart(); err != nil {
+ return err
+ }
+ }
+ }
+ status, err := Monitor.Wait(cmd, ec)
+ if err == nil && status != 0 {
+ err = fmt.Errorf("%s did not terminate sucessfully", cmd.Args[0])
+ }
+ return err
+}
+
+// Start will start an already created container
+func (r *Runc) Start(context context.Context, id string) error {
+ return r.runOrError(r.command(context, "start", id))
+}
+
+type ExecOpts struct {
+ IO
+ PidFile string
+ ConsoleSocket ConsoleSocket
+ Detach bool
+}
+
+func (o *ExecOpts) args() (out []string, err error) {
+ if o.ConsoleSocket != nil {
+ out = append(out, "--console-socket", o.ConsoleSocket.Path())
+ }
+ if o.Detach {
+ out = append(out, "--detach")
+ }
+ if o.PidFile != "" {
+ abs, err := filepath.Abs(o.PidFile)
+ if err != nil {
+ return nil, err
+ }
+ out = append(out, "--pid-file", abs)
+ }
+ return out, nil
+}
+
+// Exec executres and additional process inside the container based on a full
+// OCI Process specification
+func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts *ExecOpts) error {
+ f, err := ioutil.TempFile(os.Getenv("XDG_RUNTIME_DIR"), "runc-process")
+ if err != nil {
+ return err
+ }
+ defer os.Remove(f.Name())
+ err = json.NewEncoder(f).Encode(spec)
+ f.Close()
+ if err != nil {
+ return err
+ }
+ args := []string{"exec", "--process", f.Name()}
+ if opts != nil {
+ oargs, err := opts.args()
+ if err != nil {
+ return err
+ }
+ args = append(args, oargs...)
+ }
+ cmd := r.command(context, append(args, id)...)
+ if opts != nil && opts.IO != nil {
+ opts.Set(cmd)
+ }
+ if cmd.Stdout == nil && cmd.Stderr == nil {
+ data, err := cmdOutput(cmd, true)
+ if err != nil {
+ return fmt.Errorf("%s: %s", err, data)
+ }
+ return nil
+ }
+ ec, err := Monitor.Start(cmd)
+ if err != nil {
+ return err
+ }
+ if opts != nil && opts.IO != nil {
+ if c, ok := opts.IO.(StartCloser); ok {
+ if err := c.CloseAfterStart(); err != nil {
+ return err
+ }
+ }
+ }
+ status, err := Monitor.Wait(cmd, ec)
+ if err == nil && status != 0 {
+ err = fmt.Errorf("%s did not terminate sucessfully", cmd.Args[0])
+ }
+ return err
+}
+
+// Run runs the create, start, delete lifecycle of the container
+// and returns its exit status after it has exited
+func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts) (int, error) {
+ args := []string{"run", "--bundle", bundle}
+ if opts != nil {
+ oargs, err := opts.args()
+ if err != nil {
+ return -1, err
+ }
+ args = append(args, oargs...)
+ }
+ cmd := r.command(context, append(args, id)...)
+ if opts != nil && opts.IO != nil {
+ opts.Set(cmd)
+ }
+ ec, err := Monitor.Start(cmd)
+ if err != nil {
+ return -1, err
+ }
+ return Monitor.Wait(cmd, ec)
+}
+
+type DeleteOpts struct {
+ Force bool
+}
+
+func (o *DeleteOpts) args() (out []string) {
+ if o.Force {
+ out = append(out, "--force")
+ }
+ return out
+}
+
+// Delete deletes the container
+func (r *Runc) Delete(context context.Context, id string, opts *DeleteOpts) error {
+ args := []string{"delete"}
+ if opts != nil {
+ args = append(args, opts.args()...)
+ }
+ return r.runOrError(r.command(context, append(args, id)...))
+}
+
+// KillOpts specifies options for killing a container and its processes
+type KillOpts struct {
+ All bool
+}
+
+func (o *KillOpts) args() (out []string) {
+ if o.All {
+ out = append(out, "--all")
+ }
+ return out
+}
+
+// Kill sends the specified signal to the container
+func (r *Runc) Kill(context context.Context, id string, sig int, opts *KillOpts) error {
+ args := []string{
+ "kill",
+ }
+ if opts != nil {
+ args = append(args, opts.args()...)
+ }
+ return r.runOrError(r.command(context, append(args, id, strconv.Itoa(sig))...))
+}
+
+// Stats return the stats for a container like cpu, memory, and io
+func (r *Runc) Stats(context context.Context, id string) (*Stats, error) {
+ cmd := r.command(context, "events", "--stats", id)
+ rd, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, err
+ }
+ ec, err := Monitor.Start(cmd)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ rd.Close()
+ Monitor.Wait(cmd, ec)
+ }()
+ var e Event
+ if err := json.NewDecoder(rd).Decode(&e); err != nil {
+ return nil, err
+ }
+ return e.Stats, nil
+}
+
+// Events returns an event stream from runc for a container with stats and OOM notifications
+func (r *Runc) Events(context context.Context, id string, interval time.Duration) (chan *Event, error) {
+ cmd := r.command(context, "events", fmt.Sprintf("--interval=%ds", int(interval.Seconds())), id)
+ rd, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, err
+ }
+ ec, err := Monitor.Start(cmd)
+ if err != nil {
+ rd.Close()
+ return nil, err
+ }
+ var (
+ dec = json.NewDecoder(rd)
+ c = make(chan *Event, 128)
+ )
+ go func() {
+ defer func() {
+ close(c)
+ rd.Close()
+ Monitor.Wait(cmd, ec)
+ }()
+ for {
+ var e Event
+ if err := dec.Decode(&e); err != nil {
+ if err == io.EOF {
+ return
+ }
+ e = Event{
+ Type: "error",
+ Err: err,
+ }
+ }
+ c <- &e
+ }
+ }()
+ return c, nil
+}
+
+// Pause the container with the provided id
+func (r *Runc) Pause(context context.Context, id string) error {
+ return r.runOrError(r.command(context, "pause", id))
+}
+
+// Resume the container with the provided id
+func (r *Runc) Resume(context context.Context, id string) error {
+ return r.runOrError(r.command(context, "resume", id))
+}
+
+// Ps lists all the processes inside the container returning their pids
+func (r *Runc) Ps(context context.Context, id string) ([]int, error) {
+ data, err := cmdOutput(r.command(context, "ps", "--format", "json", id), true)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %s", err, data)
+ }
+ var pids []int
+ if err := json.Unmarshal(data, &pids); err != nil {
+ return nil, err
+ }
+ return pids, nil
+}
+
+// Top lists all the processes inside the container returning the full ps data
+func (r *Runc) Top(context context.Context, id string, psOptions string) (*TopResults, error) {
+ data, err := cmdOutput(r.command(context, "ps", "--format", "table", id, psOptions), true)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %s", err, data)
+ }
+
+ topResults, err := ParsePSOutput(data)
+ if err != nil {
+ return nil, fmt.Errorf("%s: ", err)
+ }
+ return topResults, nil
+}
+
+type CheckpointOpts struct {
+ // ImagePath is the path for saving the criu image file
+ ImagePath string
+ // WorkDir is the working directory for criu
+ WorkDir string
+ // ParentPath is the path for previous image files from a pre-dump
+ ParentPath string
+ // AllowOpenTCP allows open tcp connections to be checkpointed
+ AllowOpenTCP bool
+ // AllowExternalUnixSockets allows external unix sockets to be checkpointed
+ AllowExternalUnixSockets bool
+ // AllowTerminal allows the terminal(pty) to be checkpointed with a container
+ AllowTerminal bool
+ // CriuPageServer is the address:port for the criu page server
+ CriuPageServer string
+ // FileLocks handle file locks held by the container
+ FileLocks bool
+ // Cgroups is the cgroup mode for how to handle the checkpoint of a container's cgroups
+ Cgroups CgroupMode
+ // EmptyNamespaces creates a namespace for the container but does not save its properties
+ // Provide the namespaces you wish to be checkpointed without their settings on restore
+ EmptyNamespaces []string
+}
+
+type CgroupMode string
+
+const (
+ Soft CgroupMode = "soft"
+ Full CgroupMode = "full"
+ Strict CgroupMode = "strict"
+)
+
+func (o *CheckpointOpts) args() (out []string) {
+ if o.ImagePath != "" {
+ out = append(out, "--image-path", o.ImagePath)
+ }
+ if o.WorkDir != "" {
+ out = append(out, "--work-path", o.WorkDir)
+ }
+ if o.ParentPath != "" {
+ out = append(out, "--parent-path", o.ParentPath)
+ }
+ if o.AllowOpenTCP {
+ out = append(out, "--tcp-established")
+ }
+ if o.AllowExternalUnixSockets {
+ out = append(out, "--ext-unix-sk")
+ }
+ if o.AllowTerminal {
+ out = append(out, "--shell-job")
+ }
+ if o.CriuPageServer != "" {
+ out = append(out, "--page-server", o.CriuPageServer)
+ }
+ if o.FileLocks {
+ out = append(out, "--file-locks")
+ }
+ if string(o.Cgroups) != "" {
+ out = append(out, "--manage-cgroups-mode", string(o.Cgroups))
+ }
+ for _, ns := range o.EmptyNamespaces {
+ out = append(out, "--empty-ns", ns)
+ }
+ return out
+}
+
+type CheckpointAction func([]string) []string
+
+// LeaveRunning keeps the container running after the checkpoint has been completed
+func LeaveRunning(args []string) []string {
+ return append(args, "--leave-running")
+}
+
+// PreDump allows a pre-dump of the checkpoint to be made and completed later
+func PreDump(args []string) []string {
+ return append(args, "--pre-dump")
+}
+
+// Checkpoint allows you to checkpoint a container using criu
+func (r *Runc) Checkpoint(context context.Context, id string, opts *CheckpointOpts, actions ...CheckpointAction) error {
+ args := []string{"checkpoint"}
+ if opts != nil {
+ args = append(args, opts.args()...)
+ }
+ for _, a := range actions {
+ args = a(args)
+ }
+ return r.runOrError(r.command(context, append(args, id)...))
+}
+
+type RestoreOpts struct {
+ CheckpointOpts
+ IO
+
+ Detach bool
+ PidFile string
+ NoSubreaper bool
+ NoPivot bool
+ ConsoleSocket ConsoleSocket
+}
+
+func (o *RestoreOpts) args() ([]string, error) {
+ out := o.CheckpointOpts.args()
+ if o.Detach {
+ out = append(out, "--detach")
+ }
+ if o.PidFile != "" {
+ abs, err := filepath.Abs(o.PidFile)
+ if err != nil {
+ return nil, err
+ }
+ out = append(out, "--pid-file", abs)
+ }
+ if o.ConsoleSocket != nil {
+ out = append(out, "--console-socket", o.ConsoleSocket.Path())
+ }
+ if o.NoPivot {
+ out = append(out, "--no-pivot")
+ }
+ if o.NoSubreaper {
+ out = append(out, "-no-subreaper")
+ }
+ return out, nil
+}
+
+// Restore restores a container with the provide id from an existing checkpoint
+func (r *Runc) Restore(context context.Context, id, bundle string, opts *RestoreOpts) (int, error) {
+ args := []string{"restore"}
+ if opts != nil {
+ oargs, err := opts.args()
+ if err != nil {
+ return -1, err
+ }
+ args = append(args, oargs...)
+ }
+ args = append(args, "--bundle", bundle)
+ cmd := r.command(context, append(args, id)...)
+ if opts != nil && opts.IO != nil {
+ opts.Set(cmd)
+ }
+ ec, err := Monitor.Start(cmd)
+ if err != nil {
+ return -1, err
+ }
+ if opts != nil && opts.IO != nil {
+ if c, ok := opts.IO.(StartCloser); ok {
+ if err := c.CloseAfterStart(); err != nil {
+ return -1, err
+ }
+ }
+ }
+ return Monitor.Wait(cmd, ec)
+}
+
+// Update updates the current container with the provided resource spec
+func (r *Runc) Update(context context.Context, id string, resources *specs.LinuxResources) error {
+ buf := getBuf()
+ defer putBuf(buf)
+
+ if err := json.NewEncoder(buf).Encode(resources); err != nil {
+ return err
+ }
+ args := []string{"update", "--resources", "-", id}
+ cmd := r.command(context, args...)
+ cmd.Stdin = buf
+ return r.runOrError(cmd)
+}
+
+var ErrParseRuncVersion = errors.New("unable to parse runc version")
+
+type Version struct {
+ Runc string
+ Commit string
+ Spec string
+}
+
+// Version returns the runc and runtime-spec versions
+func (r *Runc) Version(context context.Context) (Version, error) {
+ data, err := cmdOutput(r.command(context, "--version"), false)
+ if err != nil {
+ return Version{}, err
+ }
+ return parseVersion(data)
+}
+
+func parseVersion(data []byte) (Version, error) {
+ var v Version
+ parts := strings.Split(strings.TrimSpace(string(data)), "\n")
+ if len(parts) != 3 {
+ return v, nil
+ }
+ for i, p := range []struct {
+ dest *string
+ split string
+ }{
+ {
+ dest: &v.Runc,
+ split: "version ",
+ },
+ {
+ dest: &v.Commit,
+ split: ": ",
+ },
+ {
+ dest: &v.Spec,
+ split: ": ",
+ },
+ } {
+ p2 := strings.Split(parts[i], p.split)
+ if len(p2) != 2 {
+ return v, fmt.Errorf("unable to parse version line %q", parts[i])
+ }
+ *p.dest = p2[1]
+ }
+ return v, nil
+}
+
+func (r *Runc) args() (out []string) {
+ if r.Root != "" {
+ out = append(out, "--root", r.Root)
+ }
+ if r.Debug {
+ out = append(out, "--debug")
+ }
+ if r.Log != "" {
+ out = append(out, "--log", r.Log)
+ }
+ if r.LogFormat != none {
+ out = append(out, "--log-format", string(r.LogFormat))
+ }
+ if r.Criu != "" {
+ out = append(out, "--criu", r.Criu)
+ }
+ if r.SystemdCgroup {
+ out = append(out, "--systemd-cgroup")
+ }
+ if r.Rootless != nil {
+ // nil stands for "auto" (differs from explicit "false")
+ out = append(out, "--rootless="+strconv.FormatBool(*r.Rootless))
+ }
+ return out
+}
+
+// runOrError will run the provided command. If an error is
+// encountered and neither Stdout or Stderr was set the error and the
+// stderr of the command will be returned in the format of <error>:
+// <stderr>
+func (r *Runc) runOrError(cmd *exec.Cmd) error {
+ if cmd.Stdout != nil || cmd.Stderr != nil {
+ ec, err := Monitor.Start(cmd)
+ if err != nil {
+ return err
+ }
+ status, err := Monitor.Wait(cmd, ec)
+ if err == nil && status != 0 {
+ err = fmt.Errorf("%s did not terminate sucessfully", cmd.Args[0])
+ }
+ return err
+ }
+ data, err := cmdOutput(cmd, true)
+ if err != nil {
+ return fmt.Errorf("%s: %s", err, data)
+ }
+ return nil
+}
+
+func cmdOutput(cmd *exec.Cmd, combined bool) ([]byte, error) {
+ b := getBuf()
+ defer putBuf(b)
+
+ cmd.Stdout = b
+ if combined {
+ cmd.Stderr = b
+ }
+ ec, err := Monitor.Start(cmd)
+ if err != nil {
+ return nil, err
+ }
+
+ status, err := Monitor.Wait(cmd, ec)
+ if err == nil && status != 0 {
+ err = fmt.Errorf("%s did not terminate sucessfully", cmd.Args[0])
+ }
+
+ return b.Bytes(), err
+}
diff --git a/vendor/github.com/containerd/go-runc/utils.go b/vendor/github.com/containerd/go-runc/utils.go
new file mode 100644
index 000000000..69ad6ead7
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/utils.go
@@ -0,0 +1,107 @@
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package runc
+
+import (
+ "bytes"
+ "io/ioutil"
+ "strconv"
+ "strings"
+ "sync"
+ "syscall"
+)
+
+// ReadPidFile reads the pid file at the provided path and returns
+// the pid or an error if the read and conversion is unsuccessful
+func ReadPidFile(path string) (int, error) {
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ return -1, err
+ }
+ return strconv.Atoi(string(data))
+}
+
+const exitSignalOffset = 128
+
+// exitStatus returns the correct exit status for a process based on if it
+// was signaled or exited cleanly
+func exitStatus(status syscall.WaitStatus) int {
+ if status.Signaled() {
+ return exitSignalOffset + int(status.Signal())
+ }
+ return status.ExitStatus()
+}
+
+var bytesBufferPool = sync.Pool{
+ New: func() interface{} {
+ return bytes.NewBuffer(nil)
+ },
+}
+
+func getBuf() *bytes.Buffer {
+ return bytesBufferPool.Get().(*bytes.Buffer)
+}
+
+func putBuf(b *bytes.Buffer) {
+ b.Reset()
+ bytesBufferPool.Put(b)
+}
+
+// fieldsASCII is similar to strings.Fields but only allows ASCII whitespaces
+func fieldsASCII(s string) []string {
+ fn := func(r rune) bool {
+ switch r {
+ case '\t', '\n', '\f', '\r', ' ':
+ return true
+ }
+ return false
+ }
+ return strings.FieldsFunc(s, fn)
+}
+
+// ParsePSOutput parses the runtime's ps raw output and returns a TopResults
+func ParsePSOutput(output []byte) (*TopResults, error) {
+ topResults := &TopResults{}
+
+ lines := strings.Split(string(output), "\n")
+ topResults.Headers = fieldsASCII(lines[0])
+
+ pidIndex := -1
+ for i, name := range topResults.Headers {
+ if name == "PID" {
+ pidIndex = i
+ }
+ }
+
+ for _, line := range lines[1:] {
+ if len(line) == 0 {
+ continue
+ }
+
+ fields := fieldsASCII(line)
+
+ if fields[pidIndex] == "-" {
+ continue
+ }
+
+ process := fields[:len(topResults.Headers)-1]
+ process = append(process, strings.Join(fields[len(topResults.Headers)-1:], " "))
+ topResults.Processes = append(topResults.Processes, process)
+
+ }
+ return topResults, nil
+}